1+ import torch
2+ import torch .nn as nn
3+ import torchvision
4+ import torchvision .transforms as transforms
5+ import matplotlib .pyplot as plt
6+
7+ ############## TENSORBOARD ########################
8+ import sys
9+ import torch .nn .functional as F
10+ from torch .utils .tensorboard import SummaryWriter
11+ # default `log_dir` is "runs" - we'll be more specific here
12+ writer = SummaryWriter ('runs/mnist1' )
13+ ###################################################
14+
15+ # Device configuration
16+ device = torch .device ('cuda' if torch .cuda .is_available () else 'cpu' )
17+
18+ # Hyper-parameters
19+ input_size = 784 # 28x28
20+ hidden_size = 500
21+ num_classes = 10
22+ num_epochs = 1
23+ batch_size = 64
24+ learning_rate = 0.001
25+
26+ # MNIST dataset
27+ train_dataset = torchvision .datasets .MNIST (root = './data' ,
28+ train = True ,
29+ transform = transforms .ToTensor (),
30+ download = True )
31+
32+ test_dataset = torchvision .datasets .MNIST (root = './data' ,
33+ train = False ,
34+ transform = transforms .ToTensor ())
35+
36+ # Data loader
37+ train_loader = torch .utils .data .DataLoader (dataset = train_dataset ,
38+ batch_size = batch_size ,
39+ shuffle = True )
40+
41+ test_loader = torch .utils .data .DataLoader (dataset = test_dataset ,
42+ batch_size = batch_size ,
43+ shuffle = False )
44+
45+ examples = iter (test_loader )
46+ example_data , example_targets = examples .next ()
47+
48+ for i in range (6 ):
49+ plt .subplot (2 ,3 ,i + 1 )
50+ plt .imshow (example_data [i ][0 ], cmap = 'gray' )
51+ #plt.show()
52+
53+ ############## TENSORBOARD ########################
54+ img_grid = torchvision .utils .make_grid (example_data )
55+ writer .add_image ('mnist_images' , img_grid )
56+ #writer.close()
57+ #sys.exit()
58+ ###################################################
59+
60+ # Fully connected neural network with one hidden layer
61+ class NeuralNet (nn .Module ):
62+ def __init__ (self , input_size , hidden_size , num_classes ):
63+ super (NeuralNet , self ).__init__ ()
64+ self .input_size = input_size
65+ self .l1 = nn .Linear (input_size , hidden_size )
66+ self .relu = nn .ReLU ()
67+ self .l2 = nn .Linear (hidden_size , num_classes )
68+
69+ def forward (self , x ):
70+ out = self .l1 (x )
71+ out = self .relu (out )
72+ out = self .l2 (out )
73+ # no activation and no softmax at the end
74+ return out
75+
76+ model = NeuralNet (input_size , hidden_size , num_classes ).to (device )
77+
78+ # Loss and optimizer
79+ criterion = nn .CrossEntropyLoss ()
80+ optimizer = torch .optim .Adam (model .parameters (), lr = learning_rate )
81+
82+ ############## TENSORBOARD ########################
83+ writer .add_graph (model , example_data .reshape (- 1 , 28 * 28 ))
84+ #writer.close()
85+ #sys.exit()
86+ ###################################################
87+
88+ # Train the model
89+ running_loss = 0.0
90+ running_correct = 0
91+ n_total_steps = len (train_loader )
92+ for epoch in range (num_epochs ):
93+ for i , (images , labels ) in enumerate (train_loader ):
94+ # origin shape: [100, 1, 28, 28]
95+ # resized: [100, 784]
96+ images = images .reshape (- 1 , 28 * 28 ).to (device )
97+ labels = labels .to (device )
98+
99+ # Forward pass
100+ outputs = model (images )
101+ loss = criterion (outputs , labels )
102+
103+ # Backward and optimize
104+ optimizer .zero_grad ()
105+ loss .backward ()
106+ optimizer .step ()
107+
108+ running_loss += loss .item ()
109+
110+ _ , predicted = torch .max (outputs .data , 1 )
111+ running_correct += (predicted == labels ).sum ().item ()
112+ if (i + 1 ) % 100 == 0 :
113+ print (f'Epoch [{ epoch + 1 } /{ num_epochs } ], Step [{ i + 1 } /{ n_total_steps } ], Loss: { loss .item ():.4f} ' )
114+ ############## TENSORBOARD ########################
115+ writer .add_scalar ('training loss' , running_loss / 100 , epoch * n_total_steps + i )
116+ writer .add_scalar ('accuracy' , running_correct / 100 , epoch * n_total_steps + i )
117+ running_correct = 0
118+ running_loss = 0.0
119+ ###################################################
120+
121+ # Test the model
122+ # In test phase, we don't need to compute gradients (for memory efficiency)
123+ class_labels = []
124+ class_preds = []
125+ with torch .no_grad ():
126+ n_correct = 0
127+ n_samples = 0
128+ for images , labels in test_loader :
129+ images = images .reshape (- 1 , 28 * 28 ).to (device )
130+ labels = labels .to (device )
131+ outputs = model (images )
132+ # max returns (value ,index)
133+ values , predicted = torch .max (outputs .data , 1 )
134+ n_samples += labels .size (0 )
135+ n_correct += (predicted == labels ).sum ().item ()
136+
137+ class_probs_batch = [F .softmax (output , dim = 0 ) for output in outputs ]
138+
139+ class_preds .append (class_probs_batch )
140+ class_labels .append (predicted )
141+
142+ # 10000, 10, and 10000, 1
143+ # stack concatenates tensors along a new dimension
144+ # cat concatenates tensors in the given dimension
145+ class_preds = torch .cat ([torch .stack (batch ) for batch in class_preds ])
146+ class_labels = torch .cat (class_labels )
147+
148+ acc = 100.0 * n_correct / n_samples
149+ print (f'Accuracy of the network on the 10000 test images: { acc } %' )
150+
151+ ############## TENSORBOARD ########################
152+ classes = range (10 )
153+ for i in classes :
154+ labels_i = class_labels == i
155+ preds_i = class_preds [:, i ]
156+ writer .add_pr_curve (str (i ), labels_i , preds_i , global_step = 0 )
157+ writer .close ()
158+ ###################################################
0 commit comments