20200505 Terragon General Image Classification V2

Terragon Image Classifier (TIC-Torch)

based on a PyTorch Convolutional Neural Network

Why TIC-Torch?

The TIC-Torch application offers a convenient, fast and effective workflow to create, train and deploy individual and versatile image classifiers.

What's the workflow?

  1. Collect many jpg files of the objects you want to classify and arrange them in the "raw" directory. Create one subfolder for each object you want to classify and put the images inside. Example:
    • raw/dogs
    • raw/cats
    • raw/humans
  2. Run the TIC-Torch app to resize and vary the images and to train the Neural Network.
  3. Run the TIC-Torch app to classify a new jpg.

Import OS and Image manipulation libraries

In [1]:
# System Librariesimportos,sysfromdistutils.dir_utilimportcopy_treefromPILimportImage,ImageEnhanceimportPIL.ImageOpsimportrandom# PyTorch Librariesimporttorchimporttorchvisionimporttorchvision.transformsastransformsimporttorch.nnasnnimporttorch.optimasoptimfromtorch.autogradimportVariableimporttorch.nn.functionalasF# Other Libraries we'll useimportnumpyasnpimportmatplotlib.pyplotasplt%matplotlib inline

print("Libraries imported - ready to use PyTorch",torch.__version__)
Libraries imported - ready to use PyTorch 1.4.0+cpu

Define Variables

In [2]:
path_images_raw="raw/"path_images_resized="resized/"resize_x=128resize_y=128batch_size=50shuffle=Trueepochs=100

raw/

In [3]:
path_images_raw_subdirs=os.listdir(path_images_raw)print("raw subdirs: ",path_images_raw_subdirs)
raw subdirs:  ['eos', 'golf']

resized/ copy

In [4]:
defImagesCopy(path_images_raw,path_images_resized):copy_tree(path_images_raw,path_images_resized)path_images_resized_subdirs=os.listdir(path_images_resized)print("copy from raw to resized folder")print("resized subdirs: ",path_images_resized_subdirs)ImagesCopy(path_images_raw,path_images_resized)
copy from raw to resized folder
resized subdirs:  ['eos', 'golf']

Resize

In [5]:
defImagesResize():forsubdir,dirs,filesinos.walk(path_images_resized):forfileinfiles:path_image=os.path.join(subdir,file)ifos.path.isfile(path_image):im=Image.open(path_image)f,e=os.path.splitext(path_image)imResize=im.resize((resize_x,resize_y),Image.ANTIALIAS)imResize.save(f+'_resized.jpg','JPEG',quality=90)os.remove(path_image)print("resized all images in folder resized/")ImagesResize()
resized all images in folder resized/

Variations

In [6]:
defImageVariations():forsubdir,dirs,filesinos.walk(path_images_resized):forfileinfiles:path_image=os.path.join(subdir,file)ifos.path.isfile(path_image):im=Image.open(path_image)f,e=os.path.splitext(path_image)enhancer=ImageEnhance.Brightness(im)imLighter=enhancer.enhance(1.8)imLighter.save(f+'_lighter.jpg','JPEG',quality=90)imDarker=enhancer.enhance(0.5)imDarker.save(f+'_darker.jpg','JPEG',quality=90)imInverted=PIL.ImageOps.invert(im)imInverted.save(f+'_inverted.jpg','JPEG',quality=90)randomRotate=random.randrange(-45,45)imRotated=im.rotate(randomRotate)imRotated.save(f+'_rotated.jpg','JPEG',quality=90)imMirror=im.transpose(Image.FLIP_LEFT_RIGHT)imMirror.save(f+'_mirrored.jpg','JPEG',quality=90)imGrey=im.convert('L')imGrey.save(f+'_greyscale.jpg','JPEG',quality=90)print("added a mirror and greyscale images for all images in folder resized/")ImageVariations()
added a mirror and greyscale images for all images in folder resized/

Images to Tensors

In [7]:
# Function to ingest data using training and test loaders# Now load the images from the resized folderdefload_dataset(path_images_resized):# Load all of the imagestransformation=transforms.Compose([# transform to tensorstransforms.ToTensor(),# Normalize the pixel values (in R, G, and B channels)transforms.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5])])# Load all of the images, transforming themfull_dataset=torchvision.datasets.ImageFolder(root=path_images_resized,transform=transformation)# Split into training (70% and testing (30%) datasets)train_size=int(0.7*len(full_dataset))test_size=len(full_dataset)-train_sizetrain_dataset,test_dataset=torch.utils.data.random_split(full_dataset,[train_size,test_size])# define a loader for the training data we can iterate through in 50-image batchestrain_loader=torch.utils.data.DataLoader(train_dataset,batch_size=batch_size,num_workers=0,shuffle=shuffle)# define a loader for the testing data we can iterate through in 50-image batchestest_loader=torch.utils.data.DataLoader(test_dataset,batch_size=batch_size,num_workers=0,shuffle=shuffle)returntrain_loader,test_loader# Get the class namesclasses=os.listdir(path_images_resized)classes.sort()classes_amount=len(classes)print(len(classes),'classes:')print(classes)# Get the iterative dataloaders for test and training datatrain_loader,test_loader=load_dataset(path_images_resized)
2 classes:
['eos', 'golf']

Neural Net Model

In [8]:
# Create a neural net classclassNet(nn.Module):# Constructordef__init__(self,num_classes=classes_amount):super(Net,self).__init__()# Our images are RGB, so input channels = 3. wW'll apply 12 filters in the first convolutional layerself.conv1=nn.Conv2d(in_channels=3,out_channels=12,kernel_size=3,stride=1,padding=1)# We'll apply max pooling with a kernel size of 2self.pool=nn.MaxPool2d(kernel_size=2)# A second convolutional layer takes 12 input channels, and generates 12 outputsself.conv2=nn.Conv2d(in_channels=12,out_channels=12,kernel_size=3,stride=1,padding=1)# A third convolutional layer takes 12 inputs and generates 24 outputsself.conv3=nn.Conv2d(in_channels=12,out_channels=24,kernel_size=3,stride=1,padding=1)# A drop layer deletes 20% of the features to help prevent overfittingself.drop=nn.Dropout2d(p=0.2)# Our 128x128 image tensors will be pooled twice with a kernel size of 2. 128/2/2 is 32.# So our feature tensors are now 32 x 32, and we've generated 24 of them# We need to flatten these to map them to  the probability for each classself.fc=nn.Linear(in_features=32*32*24,out_features=num_classes)defforward(self,x):# Use a relu activation function after layer 1 (convolution 1 and pool)x=F.relu(self.pool(self.conv1(x)))# Use a relu activation function after layer 1 (convolution 2 and drop)# Use a relu activation function after layer 3 (convolution 3)x=F.relu(self.pool(self.conv2(x)))# Drop some features after the 3rd convolution to prevent overfittingx=F.relu(self.drop(self.conv3(x)))# Only drop the features if this is a training passx=F.dropout(x,training=self.training)# Flattenx=x.view(-1,32*32*24)x=self.fc(x)# Return class probabilities via a softmax function returnF.log_softmax(x,dim=1)print("CNN model class defined!")
CNN model class defined!

Train and Test

In [10]:
deftrain(model,device,train_loader,optimizer,epoch):# Set the model to training modemodel.train()train_loss=0print("Epoch:",epoch)# Process the images in batchesforbatch_idx,(data,target)inenumerate(train_loader):# Use the CPU or GPU as appropriatedata,target=data.to(device),target.to(device)# Reset the optimizeroptimizer.zero_grad()# Push the data forward through the model layersoutput=model(data)# Get the lossloss=loss_criteria(output,target)# Keep a running totaltrain_loss+=loss.item()# Backpropagateloss.backward()optimizer.step()# Print metrics for every 10 batches so we see some progressifbatch_idx%10==0:print('Training set [{}/{} ({:.0f}%)] Loss: {:.6f}'.format(batch_idx*len(data),len(train_loader.dataset),100.*batch_idx/len(train_loader),loss.item()))# return average loss for the epochreturntrain_loss/len(train_loader.dataset)deftest(model,device,test_loader):# Switch the model to evaluation mode (so we don't backpropagate or drop)model.eval()test_loss=0correct=0withtorch.no_grad():fordata,targetintest_loader:data,target=data.to(device),target.to(device)# Get the predicted classes for this batchoutput=model(data)# calculate the loss and successful predictions for this batchtest_loss+=loss_criteria(output,target).item()pred=output.max(1,keepdim=True)[1]correct+=pred.eq(target.view_as(pred)).sum().item()# Calculate the average loss and total accuracy for this epochtest_loss/=len(test_loader.dataset)print('Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss,correct,len(test_loader.dataset),100.*correct/len(test_loader.dataset)))# return average loss for the epochreturntest_loss# Now use the train and test functions to train and test the model    device="cpu"if(torch.cuda.is_available()):# if GPU available, use cuda (on a cpu, training will take a considerable length of time!)device="cuda"print('Training on',device)# Create an instance of the model class and allocate it to the devicemodel=Net(num_classes=len(classes)).to(device)# Use an "Adam" optimizer to adjust weights# (see https://pytorch.org/docs/stable/optim.html#algorithms for details of supported algorithms)optimizer=optim.Adam(model.parameters(),lr=0.001)# Specify the loss criterialoss_criteria=nn.CrossEntropyLoss()# Track metrics in these arraysepoch_nums=[]training_loss=[]validation_loss=[]# Train over 5 epochs (in a real scenario, you'd likely use many more)epochs=epochsifos.path.isfile("model.pt"):print("model.pt already exists and is now loaded, no training!")model=torch.load("model.pt")else:forepochinrange(1,epochs+1):train_loss=train(model,device,train_loader,optimizer,epoch)test_loss=test(model,device,test_loader)epoch_nums.append(epoch)training_loss.append(train_loss)validation_loss.append(test_loss)%matplotlib inline
    frommatplotlibimportpyplotaspltplt.plot(epoch_nums,training_loss)plt.plot(epoch_nums,validation_loss)plt.xlabel('epoch')plt.ylabel('loss')plt.legend(['training','validation'],loc='upper right')plt.show()torch.save(model,"model.pt")
Training on cpu
Epoch: 1
Training set [0/112 (0%)] Loss: 0.691371
Test set: Average loss: 0.0120, Accuracy: 29/49 (59%)

Epoch: 2
Training set [0/112 (0%)] Loss: 0.622824
Test set: Average loss: 0.0128, Accuracy: 29/49 (59%)

Epoch: 3
Training set [0/112 (0%)] Loss: 0.654215
Test set: Average loss: 0.0087, Accuracy: 41/49 (84%)

Epoch: 4
Training set [0/112 (0%)] Loss: 0.451296
Test set: Average loss: 0.0070, Accuracy: 46/49 (94%)

Epoch: 5
Training set [0/112 (0%)] Loss: 0.333172
Test set: Average loss: 0.0073, Accuracy: 41/49 (84%)

Epoch: 6
Training set [0/112 (0%)] Loss: 0.406803
Test set: Average loss: 0.0083, Accuracy: 40/49 (82%)

Epoch: 7
Training set [0/112 (0%)] Loss: 0.399547
Test set: Average loss: 0.0058, Accuracy: 47/49 (96%)

Epoch: 8
Training set [0/112 (0%)] Loss: 0.252477
Test set: Average loss: 0.0060, Accuracy: 43/49 (88%)

Epoch: 9
Training set [0/112 (0%)] Loss: 0.238711
Test set: Average loss: 0.0035, Accuracy: 48/49 (98%)

Epoch: 10
Training set [0/112 (0%)] Loss: 0.186587
Test set: Average loss: 0.0038, Accuracy: 46/49 (94%)

Epoch: 11
Training set [0/112 (0%)] Loss: 0.154513
Test set: Average loss: 0.0028, Accuracy: 47/49 (96%)

Epoch: 12
Training set [0/112 (0%)] Loss: 0.098874
Test set: Average loss: 0.0023, Accuracy: 49/49 (100%)

Epoch: 13
Training set [0/112 (0%)] Loss: 0.121914
Test set: Average loss: 0.0015, Accuracy: 49/49 (100%)

Epoch: 14
Training set [0/112 (0%)] Loss: 0.068651
Test set: Average loss: 0.0012, Accuracy: 49/49 (100%)

Epoch: 15
Training set [0/112 (0%)] Loss: 0.045200
Test set: Average loss: 0.0013, Accuracy: 48/49 (98%)

Epoch: 16
Training set [0/112 (0%)] Loss: 0.021630
Test set: Average loss: 0.0011, Accuracy: 49/49 (100%)

Epoch: 17
Training set [0/112 (0%)] Loss: 0.033522
Test set: Average loss: 0.0013, Accuracy: 47/49 (96%)

Epoch: 18
Training set [0/112 (0%)] Loss: 0.040066
Test set: Average loss: 0.0011, Accuracy: 48/49 (98%)

Epoch: 19
Training set [0/112 (0%)] Loss: 0.012665
Test set: Average loss: 0.0005, Accuracy: 49/49 (100%)

Epoch: 20
Training set [0/112 (0%)] Loss: 0.020029
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 21
Training set [0/112 (0%)] Loss: 0.012471
Test set: Average loss: 0.0005, Accuracy: 49/49 (100%)

Epoch: 22
Training set [0/112 (0%)] Loss: 0.022450
Test set: Average loss: 0.0009, Accuracy: 48/49 (98%)

Epoch: 23
Training set [0/112 (0%)] Loss: 0.005536
Test set: Average loss: 0.0012, Accuracy: 48/49 (98%)

Epoch: 24
Training set [0/112 (0%)] Loss: 0.005461
Test set: Average loss: 0.0010, Accuracy: 48/49 (98%)

Epoch: 25
Training set [0/112 (0%)] Loss: 0.019365
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 26
Training set [0/112 (0%)] Loss: 0.005849
Test set: Average loss: 0.0003, Accuracy: 49/49 (100%)

Epoch: 27
Training set [0/112 (0%)] Loss: 0.021827
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 28
Training set [0/112 (0%)] Loss: 0.004919
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 29
Training set [0/112 (0%)] Loss: 0.002215
Test set: Average loss: 0.0005, Accuracy: 49/49 (100%)

Epoch: 30
Training set [0/112 (0%)] Loss: 0.003710
Test set: Average loss: 0.0007, Accuracy: 48/49 (98%)

Epoch: 31
Training set [0/112 (0%)] Loss: 0.004821
Test set: Average loss: 0.0009, Accuracy: 48/49 (98%)

Epoch: 32
Training set [0/112 (0%)] Loss: 0.006066
Test set: Average loss: 0.0008, Accuracy: 48/49 (98%)

Epoch: 33
Training set [0/112 (0%)] Loss: 0.001534
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 34
Training set [0/112 (0%)] Loss: 0.004307
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 35
Training set [0/112 (0%)] Loss: 0.003381
Test set: Average loss: 0.0003, Accuracy: 49/49 (100%)

Epoch: 36
Training set [0/112 (0%)] Loss: 0.003292
Test set: Average loss: 0.0003, Accuracy: 49/49 (100%)

Epoch: 37
Training set [0/112 (0%)] Loss: 0.000991
Test set: Average loss: 0.0003, Accuracy: 49/49 (100%)

Epoch: 38
Training set [0/112 (0%)] Loss: 0.003176
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 39
Training set [0/112 (0%)] Loss: 0.011791
Test set: Average loss: 0.0011, Accuracy: 48/49 (98%)

Epoch: 40
Training set [0/112 (0%)] Loss: 0.001556
Test set: Average loss: 0.0013, Accuracy: 48/49 (98%)

Epoch: 41
Training set [0/112 (0%)] Loss: 0.004759
Test set: Average loss: 0.0010, Accuracy: 48/49 (98%)

Epoch: 42
Training set [0/112 (0%)] Loss: 0.004795
Test set: Average loss: 0.0006, Accuracy: 48/49 (98%)

Epoch: 43
Training set [0/112 (0%)] Loss: 0.002801
Test set: Average loss: 0.0003, Accuracy: 49/49 (100%)

Epoch: 44
Training set [0/112 (0%)] Loss: 0.000921
Test set: Average loss: 0.0003, Accuracy: 49/49 (100%)

Epoch: 45
Training set [0/112 (0%)] Loss: 0.003772
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 46
Training set [0/112 (0%)] Loss: 0.003966
Test set: Average loss: 0.0009, Accuracy: 48/49 (98%)

Epoch: 47
Training set [0/112 (0%)] Loss: 0.003178
Test set: Average loss: 0.0012, Accuracy: 48/49 (98%)

Epoch: 48
Training set [0/112 (0%)] Loss: 0.003016
Test set: Average loss: 0.0011, Accuracy: 48/49 (98%)

Epoch: 49
Training set [0/112 (0%)] Loss: 0.001345
Test set: Average loss: 0.0009, Accuracy: 48/49 (98%)

Epoch: 50
Training set [0/112 (0%)] Loss: 0.002383
Test set: Average loss: 0.0006, Accuracy: 48/49 (98%)

Epoch: 51
Training set [0/112 (0%)] Loss: 0.001230
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 52
Training set [0/112 (0%)] Loss: 0.000762
Test set: Average loss: 0.0003, Accuracy: 49/49 (100%)

Epoch: 53
Training set [0/112 (0%)] Loss: 0.002377
Test set: Average loss: 0.0003, Accuracy: 49/49 (100%)

Epoch: 54
Training set [0/112 (0%)] Loss: 0.000535
Test set: Average loss: 0.0003, Accuracy: 49/49 (100%)

Epoch: 55
Training set [0/112 (0%)] Loss: 0.000913
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 56
Training set [0/112 (0%)] Loss: 0.001733
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 57
Training set [0/112 (0%)] Loss: 0.002246
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 58
Training set [0/112 (0%)] Loss: 0.001445
Test set: Average loss: 0.0006, Accuracy: 48/49 (98%)

Epoch: 59
Training set [0/112 (0%)] Loss: 0.000717
Test set: Average loss: 0.0007, Accuracy: 48/49 (98%)

Epoch: 60
Training set [0/112 (0%)] Loss: 0.001148
Test set: Average loss: 0.0007, Accuracy: 48/49 (98%)

Epoch: 61
Training set [0/112 (0%)] Loss: 0.000555
Test set: Average loss: 0.0007, Accuracy: 48/49 (98%)

Epoch: 62
Training set [0/112 (0%)] Loss: 0.000397
Test set: Average loss: 0.0006, Accuracy: 48/49 (98%)

Epoch: 63
Training set [0/112 (0%)] Loss: 0.005688
Test set: Average loss: 0.0010, Accuracy: 48/49 (98%)

Epoch: 64
Training set [0/112 (0%)] Loss: 0.000639
Test set: Average loss: 0.0012, Accuracy: 48/49 (98%)

Epoch: 65
Training set [0/112 (0%)] Loss: 0.000976
Test set: Average loss: 0.0011, Accuracy: 48/49 (98%)

Epoch: 66
Training set [0/112 (0%)] Loss: 0.000687
Test set: Average loss: 0.0010, Accuracy: 48/49 (98%)

Epoch: 67
Training set [0/112 (0%)] Loss: 0.000416
Test set: Average loss: 0.0012, Accuracy: 47/49 (96%)

Epoch: 68
Training set [0/112 (0%)] Loss: 0.001927
Test set: Average loss: 0.0013, Accuracy: 47/49 (96%)

Epoch: 69
Training set [0/112 (0%)] Loss: 0.001267
Test set: Average loss: 0.0013, Accuracy: 48/49 (98%)

Epoch: 70
Training set [0/112 (0%)] Loss: 0.004324
Test set: Average loss: 0.0007, Accuracy: 48/49 (98%)

Epoch: 71
Training set [0/112 (0%)] Loss: 0.000839
Test set: Average loss: 0.0005, Accuracy: 49/49 (100%)

Epoch: 72
Training set [0/112 (0%)] Loss: 0.001406
Test set: Average loss: 0.0005, Accuracy: 49/49 (100%)

Epoch: 73
Training set [0/112 (0%)] Loss: 0.001187
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 74
Training set [0/112 (0%)] Loss: 0.000489
Test set: Average loss: 0.0006, Accuracy: 48/49 (98%)

Epoch: 75
Training set [0/112 (0%)] Loss: 0.000617
Test set: Average loss: 0.0007, Accuracy: 48/49 (98%)

Epoch: 76
Training set [0/112 (0%)] Loss: 0.001584
Test set: Average loss: 0.0006, Accuracy: 48/49 (98%)

Epoch: 77
Training set [0/112 (0%)] Loss: 0.002593
Test set: Average loss: 0.0007, Accuracy: 48/49 (98%)

Epoch: 78
Training set [0/112 (0%)] Loss: 0.001084
Test set: Average loss: 0.0006, Accuracy: 48/49 (98%)

Epoch: 79
Training set [0/112 (0%)] Loss: 0.000239
Test set: Average loss: 0.0006, Accuracy: 48/49 (98%)

Epoch: 80
Training set [0/112 (0%)] Loss: 0.000903
Test set: Average loss: 0.0007, Accuracy: 48/49 (98%)

Epoch: 81
Training set [0/112 (0%)] Loss: 0.000566
Test set: Average loss: 0.0008, Accuracy: 48/49 (98%)

Epoch: 82
Training set [0/112 (0%)] Loss: 0.000447
Test set: Average loss: 0.0008, Accuracy: 48/49 (98%)

Epoch: 83
Training set [0/112 (0%)] Loss: 0.000403
Test set: Average loss: 0.0005, Accuracy: 49/49 (100%)

Epoch: 84
Training set [0/112 (0%)] Loss: 0.000146
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 85
Training set [0/112 (0%)] Loss: 0.000580
Test set: Average loss: 0.0003, Accuracy: 49/49 (100%)

Epoch: 86
Training set [0/112 (0%)] Loss: 0.000942
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 87
Training set [0/112 (0%)] Loss: 0.000710
Test set: Average loss: 0.0004, Accuracy: 49/49 (100%)

Epoch: 88
Training set [0/112 (0%)] Loss: 0.000263
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 89
Training set [0/112 (0%)] Loss: 0.000151
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 90
Training set [0/112 (0%)] Loss: 0.000214
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 91
Training set [0/112 (0%)] Loss: 0.000233
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 92
Training set [0/112 (0%)] Loss: 0.001173
Test set: Average loss: 0.0004, Accuracy: 48/49 (98%)

Epoch: 93
Training set [0/112 (0%)] Loss: 0.000109
Test set: Average loss: 0.0004, Accuracy: 48/49 (98%)

Epoch: 94
Training set [0/112 (0%)] Loss: 0.000942
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 95
Training set [0/112 (0%)] Loss: 0.001447
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 96
Training set [0/112 (0%)] Loss: 0.000231
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 97
Training set [0/112 (0%)] Loss: 0.000170
Test set: Average loss: 0.0005, Accuracy: 48/49 (98%)

Epoch: 98
Training set [0/112 (0%)] Loss: 0.000144
Test set: Average loss: 0.0006, Accuracy: 48/49 (98%)

Epoch: 99
Training set [0/112 (0%)] Loss: 0.000087
Test set: Average loss: 0.0006, Accuracy: 48/49 (98%)

Epoch: 100
Training set [0/112 (0%)] Loss: 0.000346
Test set: Average loss: 0.0007, Accuracy: 48/49 (98%)

c:\python377\lib\site-packages\torch\serialization.py:360: UserWarning: Couldn't retrieve source code for container of type Net. It won't be checked for correctness upon loading.
  "type " + obj.__name__ + ". It won't be checked "

Evaluate - Confusion Matrix

In [11]:
#Pytorch doesn't have a built-in confusion matrix metric, so we'll use SciKit-Learnfromsklearn.metricsimportconfusion_matrix# Set the model to evaluate modemodel.eval()# Get predictions for the test data and convert to numpy arrays for use with SciKit-Learnprint("Getting predictions from test set...")truelabels=[]predictions=[]fordata,targetintest_loader:forlabelintarget.cpu().data.numpy():truelabels.append(label)forpredictioninmodel.cpu()(data).data.numpy().argmax(1):predictions.append(prediction)# Plot the confusion matrixcm=confusion_matrix(truelabels,predictions)plt.imshow(cm,interpolation="nearest",cmap=plt.cm.Greys)plt.colorbar()tick_marks=np.arange(len(classes))plt.xticks(tick_marks,classes,rotation=45)plt.yticks(tick_marks,classes)plt.xlabel("Predicted Shape")plt.ylabel("True Shape")plt.show()
Getting predictions from test set...

Predict

In [13]:
# Function to predict the class of an imagedefpredict_image(classifier,image):importnumpy# Set the classifer model to evaluation modeclassifier.eval()# Apply the same transformations as we did for the training imagestransformation=transforms.Compose([transforms.ToTensor(),transforms.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5])])# Preprocess the imageimage_tensor=transformation(image).float()# Add an extra batch dimension since pytorch treats all inputs as batchesimage_tensor=image_tensor.unsqueeze_(0)# Turn the input into a Variableinput_features=Variable(image_tensor)# Predict the class of the imageoutput=classifier(input_features)index=output.data.numpy().argmax()returnindex#Now let's try it with a new imagefromrandomimportrandintfromPILimportImageimportos,shutilimgFile=Image.open("classify3.jpg")imgFile=imgFile.resize((resize_x,resize_y),Image.ANTIALIAS)# Display the imageplt.imshow(imgFile)# Call the predction functionindex=predict_image(model,imgFile)print(classes[index])
eos
In [ ]: