Python
Ants and Bees using VGG16
Importing Libraries
import torchvision
import torch.nn as nn
import torch
import torch.nn.functional as F
from torchvision import transforms,models,datasets
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
from torch import optim
device = 'cuda' if torch.cuda.is_available() else 'cpu'
import cv2, glob, numpy as np, pandas as pd
import matplotlib.pyplot as plt
from glob import glob
import torchvision.transforms as transforms
from torch.utils.data import DataLoader, Dataset
Loading Data
train_data_dir = '.../hymenoptera_data/train'
val_data_dir = '../hymenoptera_data/val'
Make Class to load data for model
class ants_bees(Dataset):
def __init__(self, folder):
ants = glob(folder+'/ants/*.jpg')
bees = glob(folder+'/bees/*.jpg')
self.fpaths = ants + bees
self.normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])
from random import shuffle, seed; seed(10); shuffle(self.fpaths)
self.targets = [fpath.split('/')[-2].startswith('bees') for fpath in self.fpaths]
def __len__(self): return len(self.fpaths)
def __getitem__(self, ix):
f = self.fpaths[ix]
target = self.targets[ix]
im = (cv2.imread(f)[:,:,::-1])
im = cv2.resize(im, (224,224))
im = torch.tensor(im/255)
im = im.permute(2,0,1)
im = self.normalize(im)
return im.float().to(device), torch.tensor([target]).float().to(device)
Load data and display image
data = ants_bees(train_data_dir)
im, label = data[199]
plt.imshow(im.permute(1,2,0).cpu())
print(label)
Output
VGG16 Model
def get_model():
model = models.vgg16(pretrained=True)
for param in model.parameters():
param.requires_grad = False
model.avgpool = nn.AdaptiveAvgPool2d(output_size=(1,1))
model.classifier = nn.Sequential(nn.Flatten(),
nn.Linear(512, 128),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(128, 1),
nn.Sigmoid())
loss_fn = nn.BCELoss()
optimizer = torch.optim.Adam(model.parameters(), lr= 1e-3)
return model.to(device), loss_fn, optimizer
Summarize
!pip install torch_summary
from torchsummary import summary
model, criterion, optimizer = get_model()
summary(model, torch.zeros(1,3,224,224))
Function to train model
def train_batch(x, y, model, opt, loss_fn):
model.train()
prediction = model(x)
batch_loss = loss_fn(prediction, y)
batch_loss.backward()
optimizer.step()
optimizer.zero_grad()
return batch_loss.item()
Function to calculate Accuracy and validation loss
@torch.no_grad()
def val_loss(x, y, model):
prediction = model(x)
val_loss = loss_fn(prediction, y)
return val_loss.item()
Defining batch and function that load files batch-wise
def get_data():
train = ants_bees(train_data_dir)
trn_dl = DataLoader(train, batch_size=32, shuffle=True, drop_last = True)
val = ants_bees(val_data_dir)
val_dl = DataLoader(val, batch_size=32, shuffle=True, drop_last = True)
return trn_dl, val_dl
Get model and get data
trn_dl, val_dl = get_data()
model, loss_fn, optimizer = get_model()
Train model for 5 epochs
train_losses, train_accuracies = [], []
val_losses, val_accuracies = [], []
for epoch in range(5):
print(f" epoch {epoch + 1}/5")
train_epoch_losses, train_epoch_accuracies = [], []
val_epoch_accuracies = []
for ix, batch in enumerate(iter(trn_dl)):
x, y = batch
batch_loss = train_batch(x, y, model, optimizer, loss_fn)
train_epoch_losses.append(batch_loss)
train_epoch_loss = np.array(train_epoch_losses).mean()
for ix, batch in enumerate(iter(trn_dl)):
x, y = batch
is_correct = accuracy(x, y, model)
train_epoch_accuracies.extend(is_correct)
train_epoch_accuracy = np.mean(train_epoch_accuracies)
for ix, batch in enumerate(iter(val_dl)):
x, y = batch
val_is_correct = accuracy(x, y, model)
val_epoch_accuracies.extend(val_is_correct)
validation_loss = val_loss(x, y, model)
val_epoch_accuracy = np.mean(val_epoch_accuracies)
train_losses.append(train_epoch_loss)
train_accuracies.append(train_epoch_accuracy)
val_losses.append(validation_loss)
val_accuracies.append(val_epoch_accuracy)
Plotting accuracy and loss
epochs = np.arange(5)+1
import matplotlib.ticker as mtick
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
%matplotlib inline
plt.rcParams["figure.figsize"] = (10,5)
plt.subplot(211)
plt.plot(epochs, train_losses, 'bo', label='Training loss')
plt.plot(epochs, val_losses, 'r', label='Validation loss')
plt.gca().xaxis.set_major_locator(mticker.MultipleLocator(1))
plt.title('Training and validation loss with CNN')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.grid('off')
plt.show()
plt.subplot(212)
plt.plot(epochs, train_accuracies, 'bo', label='Training accuracy')
plt.plot(epochs, val_accuracies, 'r', label='Validation accuracy')
plt.gca().xaxis.set_major_locator(mticker.MultipleLocator(1))
plt.title('Training and validation accuracy with CNN')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.gca().set_yticklabels(['{:.0f}%'.format(x*100) for x in plt.gca().get_yticks()])
plt.legend()
plt.grid('off')
plt.show()
Save model
#save model
model_scripted = torch.jit.script(model) # Export to TorchScript
model_scripted.save('.../Trained_model/ants_bees_model_epoch_10_VGG16_scripted.pt')
Confusion Matrix
from sklearn.metrics import confusion_matrix
import seaborn as sn
import pandas as pd
y_pred = []
y_true = []
count = 0
data = ants_bees(train_data_dir)
print(len(data))
# iterate over test data
for inputs, labels in data:
im = torch.tensor(inputs).permute(2,0,1).to(device).float()
img = im
img = img.view(3,224, 224)
img2 = torch.tensor(img).to(device).float()
img3 = torch.tensor(img2).view(-1,3,224,224)
output = model(img3) # Feed Network
output = output.cpu().detach().numpy()
output = np.round(output[0][0],decimals=0)
y_pred.append(output) # Save Prediction
labels = labels.data.cpu().numpy()
y_true.extend(labels) # Save Truth
count=count+1
# constant for classes
classes = ('Ants','Bees')
# Build confusion matrix
cf_matrix = confusion_matrix(y_true, y_pred)
df_cm = pd.DataFrame(cf_matrix, index = [i for i in classes],
columns = [i for i in classes])
plt.figure(figsize = (12,7))
sn.heatmap(df_cm, annot=True)
plt.savefig('output.png')
Open a new file and load model
import torch
device = 'cuda' if torch.cuda.is_available() else 'cpu'
import cv2, glob, numpy as np, pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from glob import glob
from google.colab import files
import warnings
warnings.filterwarnings('ignore')
model = torch.jit.load('.../ants_bees_model_epoch_10_VGG16_scripted.pt')
model.eval()
Define function for prediction
def predict(img_file):
im = (cv2.imread(file_name)[:,:,::-1])
im = cv2.resize(im, (224,224))
im = torch.tensor(im/255).permute(2,0,1).to(device).float()
img = im
img = img.view(3,224, 224)
img2 = torch.tensor(img).to(device).float()
img3 = torch.tensor(img2).view(-1,3,224,224)
np_output = model(img3).cpu().detach().numpy()
print(np_output)
if((np.round(np_output[0][0],decimals=0))==1):
prediction = 'This is a bee'
else:
prediction = 'This is an ant'
plt.imshow(im.permute(1,2,0).cpu())
return prediction
Load Image and predict
uploaded = files.upload()
file_name = uploaded.keys()
file_name = list(file_name)[0]
predict(file_name)
More Predictions
pontu
0
Tags :