#!/usr/bin/env python # coding: utf-8 # ### 1. Import dependencies # In[1]: import numpy as np get_ipython().run_line_magic('matplotlib', 'inline') import matplotlib.pyplot as plt from PIL import Image # In[2]: import torch from torchvision import datasets, models, transforms import torch.nn as nn from torch.nn import functional as F import torch.optim as optim # In[3]: torch.__version__ # ### 2. Create PyTorch data generators # In[4]: normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) data_transforms = { 'train': transforms.Compose([ transforms.Resize((224,224)), transforms.RandomAffine(0, shear=10, scale=(0.8,1.2)), transforms.RandomHorizontalFlip(), transforms.ToTensor(), normalize ]), 'validation': transforms.Compose([ transforms.Resize((224,224)), transforms.ToTensor(), normalize ]), } image_datasets = { 'train': datasets.ImageFolder('data/train', data_transforms['train']), 'validation': datasets.ImageFolder('data/validation', data_transforms['validation']) } dataloaders = { 'train': torch.utils.data.DataLoader(image_datasets['train'], batch_size=32, shuffle=True, num_workers=4), 'validation': torch.utils.data.DataLoader(image_datasets['validation'], batch_size=32, shuffle=False, num_workers=4) } # ### 3. Create the network # In[5]: device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # In[6]: model = models.resnet50(pretrained=True).to(device) for param in model.parameters(): param.requires_grad = False model.fc = nn.Sequential( nn.Linear(2048, 128), nn.ReLU(inplace=True), nn.Linear(128, 2)).to(device) # In[7]: criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.fc.parameters()) # ### 4. Train the model # In[8]: def train_model(model, criterion, optimizer, num_epochs=3): for epoch in range(num_epochs): print('Epoch {}/{}'.format(epoch+1, num_epochs)) print('-' * 10) for phase in ['train', 'validation']: if phase == 'train': model.train() else: model.eval() running_loss = 0.0 running_corrects = 0 for inputs, labels in dataloaders[phase]: inputs = inputs.to(device) labels = labels.to(device) outputs = model(inputs) loss = criterion(outputs, labels) if phase == 'train': optimizer.zero_grad() loss.backward() optimizer.step() _, preds = torch.max(outputs, 1) running_loss += loss.detach() * inputs.size(0) running_corrects += torch.sum(preds == labels.data) epoch_loss = running_loss / len(image_datasets[phase]) epoch_acc = running_corrects.float() / len(image_datasets[phase]) print('{} loss: {:.4f}, acc: {:.4f}'.format(phase, epoch_loss.item(), epoch_acc.item())) return model # In[9]: model_trained = train_model(model, criterion, optimizer, num_epochs=3) # ### 5. Save and load the model # In[10]: torch.save(model_trained.state_dict(), 'models/pytorch/weights.h5') # In[11]: model = models.resnet50(pretrained=False).to(device) model.fc = nn.Sequential( nn.Linear(2048, 128), nn.ReLU(inplace=True), nn.Linear(128, 2)).to(device) model.load_state_dict(torch.load('models/pytorch/weights.h5')) # ### 6. Make predictions on sample test images # In[12]: validation_img_paths = ["data/validation/alien/11.jpg", "data/validation/alien/22.jpg", "data/validation/predator/33.jpg"] img_list = [Image.open(img_path) for img_path in validation_img_paths] # In[13]: validation_batch = torch.stack([data_transforms['validation'](img).to(device) for img in img_list]) # In[14]: pred_logits_tensor = model(validation_batch) pred_probs = F.softmax(pred_logits_tensor, dim=1).cpu().data.numpy() # In[15]: fig, axs = plt.subplots(1, len(img_list), figsize=(20, 5)) for i, img in enumerate(img_list): ax = axs[i] ax.axis('off') ax.set_title("{:.0f}% Alien, {:.0f}% Predator".format(100*pred_probs[i,0], 100*pred_probs[i,1])) ax.imshow(img)