1+ # -*- coding: utf-8 -*-
2+ """
3+ 4+ @description:
5+ """
6+
7+ import matplotlib .pyplot as plt
8+ import numpy as np
9+
10+ import torch
11+ import torchvision
12+ import torchvision .transforms as transforms
13+
14+ import torch .nn as nn
15+ import torch .nn .functional as F
16+ import torch .optim as optim
17+
18+ # transforms
19+ transform = transforms .Compose (
20+ [transforms .ToTensor (),
21+ transforms .Normalize ((0.5 ,), (0.5 ,))])
22+
23+ # datasets
24+ trainset = torchvision .datasets .FashionMNIST ('./data' ,
25+ download = True ,
26+ train = True ,
27+ transform = transform )
28+ testset = torchvision .datasets .FashionMNIST ('./data' ,
29+ download = True ,
30+ train = False ,
31+ transform = transform )
32+
33+ # dataloaders
34+ trainloader = torch .utils .data .DataLoader (trainset , batch_size = 4 ,
35+ shuffle = True , num_workers = 2 )
36+
37+
38+ testloader = torch .utils .data .DataLoader (testset , batch_size = 4 ,
39+ shuffle = False , num_workers = 2 )
40+
41+ # constant for classes
42+ classes = ('T-shirt/top' , 'Trouser' , 'Pullover' , 'Dress' , 'Coat' ,
43+ 'Sandal' , 'Shirt' , 'Sneaker' , 'Bag' , 'Ankle Boot' )
44+
45+ # helper function to show an image
46+ # (used in the `plot_classes_preds` function below)
47+ def matplotlib_imshow (img , one_channel = False ):
48+ if one_channel :
49+ img = img .mean (dim = 0 )
50+ img = img / 2 + 0.5 # unnormalize
51+ npimg = img .numpy ()
52+ if one_channel :
53+ plt .imshow (npimg , cmap = "Greys" )
54+ plt .savefig ('a.png' )
55+ else :
56+ plt .imshow (np .transpose (npimg , (1 , 2 , 0 )))
57+
58+
59+ class Net (nn .Module ):
60+ def __init__ (self ):
61+ super (Net , self ).__init__ ()
62+ self .conv1 = nn .Conv2d (1 , 6 , 5 )
63+ self .pool = nn .MaxPool2d (2 , 2 )
64+ self .conv2 = nn .Conv2d (6 , 16 , 5 )
65+ self .fc1 = nn .Linear (16 * 4 * 4 , 120 )
66+ self .fc2 = nn .Linear (120 , 84 )
67+ self .fc3 = nn .Linear (84 , 10 )
68+
69+ def forward (self , x ):
70+ x = self .pool (F .relu (self .conv1 (x )))
71+ x = self .pool (F .relu (self .conv2 (x )))
72+ x = x .view (- 1 , 16 * 4 * 4 )
73+ x = F .relu (self .fc1 (x ))
74+ x = F .relu (self .fc2 (x ))
75+ x = self .fc3 (x )
76+ return x
77+
78+
79+ net = Net ()
80+
81+ criterion = nn .CrossEntropyLoss ()
82+ optimizer = optim .SGD (net .parameters (), lr = 0.001 , momentum = 0.9 )
83+
84+ from torch .utils .tensorboard import SummaryWriter
85+
86+ # default `log_dir` is "runs" - we'll be more specific here
87+ writer = SummaryWriter ('runs/fashion_mnist_experiment_1' )
88+
89+ # get some random training images
90+ dataiter = iter (trainloader )
91+ images , labels = dataiter .next ()
92+
93+ # create grid of images
94+ img_grid = torchvision .utils .make_grid (images )
95+
96+ # show images
97+ matplotlib_imshow (img_grid , one_channel = True )
98+
99+ # write to tensorboard
100+ writer .add_image ('four_fashion_mnist_images' , img_grid )
101+
102+ # tensorboard --logdir=runs
103+
104+ writer .add_graph (net , images )
105+ # writer.close()
106+
107+ # helper function
108+ def select_n_random (data , labels , n = 100 ):
109+ '''
110+ Selects n random datapoints and their corresponding labels from a dataset
111+ '''
112+ assert len (data ) == len (labels )
113+
114+ perm = torch .randperm (len (data ))
115+ return data [perm ][:n ], labels [perm ][:n ]
116+
117+ # select random images and their target indices
118+ images , labels = select_n_random (trainset .train_data , trainset .train_labels )
119+
120+ # get the class labels for each image
121+ class_labels = [classes [lab ] for lab in labels ]
122+
123+ # log embeddings
124+ features = images .view (- 1 , 28 * 28 )
125+ # writer.add_embedding(features)
126+ # writer.close()
127+
128+ def images_to_probs (net , images ):
129+ '''
130+ Generates predictions and corresponding probabilities from a trained
131+ network and a list of images
132+ '''
133+ output = net (images )
134+ # convert output probabilities to predicted class
135+ _ , preds_tensor = torch .max (output , 1 )
136+ preds = np .squeeze (preds_tensor .numpy ())
137+ return preds , [F .softmax (el , dim = 0 )[i ].item () for i , el in zip (preds , output )]
138+
139+
140+ def plot_classes_preds (net , images , labels ):
141+ '''
142+ Generates matplotlib Figure using a trained network, along with images
143+ and labels from a batch, that shows the network's top prediction along
144+ with its probability, alongside the actual label, coloring this
145+ information based on whether the prediction was correct or not.
146+ Uses the "images_to_probs" function.
147+ '''
148+ preds , probs = images_to_probs (net , images )
149+ # plot the images in the batch, along with predicted and true labels
150+ fig = plt .figure (figsize = (12 , 48 ))
151+ for idx in np .arange (4 ):
152+ ax = fig .add_subplot (1 , 4 , idx + 1 , xticks = [], yticks = [])
153+ matplotlib_imshow (images [idx ], one_channel = True )
154+ ax .set_title ("{0}, {1:.1f}%\n (label: {2})" .format (
155+ classes [preds [idx ]],
156+ probs [idx ] * 100.0 ,
157+ classes [labels [idx ]]),
158+ color = ("green" if preds [idx ]== labels [idx ].item () else "red" ))
159+ return fig
160+ print ("training start." )
161+ running_loss = 0.0
162+ for epoch in range (1 ): # loop over the dataset multiple times
163+
164+ for i , data in enumerate (trainloader , 0 ):
165+
166+ # get the inputs; data is a list of [inputs, labels]
167+ inputs , labels = data
168+
169+ # zero the parameter gradients
170+ optimizer .zero_grad ()
171+
172+ # forward + backward + optimize
173+ outputs = net (inputs )
174+ loss = criterion (outputs , labels )
175+ loss .backward ()
176+ optimizer .step ()
177+
178+ running_loss += loss .item ()
179+ if i % 1000 == 999 : # every 1000 mini-batches...
180+
181+ # ...log the running loss
182+ writer .add_scalar ('training loss' ,
183+ running_loss / 1000 ,
184+ epoch * len (trainloader ) + i )
185+
186+ # ...log a Matplotlib Figure showing the model's predictions on a
187+ # random mini-batch
188+ writer .add_figure ('predictions vs. actuals' ,
189+ plot_classes_preds (net , inputs , labels ),
190+ global_step = epoch * len (trainloader ) + i )
191+ running_loss = 0.0
192+ print ('Finished Training' )
193+
194+ # 1. gets the probability predictions in a test_size x num_classes Tensor
195+ # 2. gets the preds in a test_size Tensor
196+ # takes ~10 seconds to run
197+ class_probs = []
198+ class_preds = []
199+ with torch .no_grad ():
200+ for data in testloader :
201+ images , labels = data
202+ output = net (images )
203+ class_probs_batch = [F .softmax (el , dim = 0 ) for el in output ]
204+ _ , class_preds_batch = torch .max (output , 1 )
205+
206+ class_probs .append (class_probs_batch )
207+ class_preds .append (class_preds_batch )
208+
209+ test_probs = torch .cat ([torch .stack (batch ) for batch in class_probs ])
210+ test_preds = torch .cat (class_preds )
211+
212+ # helper function
213+ def add_pr_curve_tensorboard (class_index , test_probs , test_preds , global_step = 0 ):
214+ '''
215+ Takes in a "class_index" from 0 to 9 and plots the corresponding
216+ precision-recall curve
217+ '''
218+ tensorboard_preds = test_preds == class_index
219+ tensorboard_probs = test_probs [:, class_index ]
220+
221+ writer .add_pr_curve (classes [class_index ],
222+ tensorboard_preds ,
223+ tensorboard_probs ,
224+ global_step = global_step )
225+ writer .close ()
226+
227+ # plot all the pr curves
228+ for i in range (len (classes )):
229+ add_pr_curve_tensorboard (i , test_probs , test_preds )
0 commit comments