ml_courses / code /resnet_transfer_learning_pytorch.py
johnnydevriese's picture
Upload 80 files
8938d1b verified
# https://www.pluralsight.com/guides/introduction-to-resnet
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import numpy as np
import torchvision
# from torchvision import *
from torch.utils.data import Dataset, DataLoader
import matplotlib.pyplot as plt
import torchvision.models as models
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import time
import copy
import os
batch_size = 128
learning_rate = 1e-3
transforms = transforms.Compose([transforms.ToTensor()])
train_dataset = datasets.ImageFolder(
root="/input/fruits-360-dataset/fruits-360/Training", transform=transforms
)
test_dataset = datasets.ImageFolder(
root="/input/fruits-360-dataset/fruits-360/Test", transform=transforms
)
train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=batch_size, shuffle=True)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
def imshow(inp, title=None):
inp = inp.cpu() if device else inp
inp = inp.numpy().transpose((1, 2, 0))
mean = np.array([0.485, 0.456, 0.406])
std = np.array([0.229, 0.224, 0.225])
inp = std * inp + mean
inp = np.clip(inp, 0, 1)
plt.imshow(inp)
if title is not None:
plt.title(title)
plt.pause(0.001)
images, labels = next(iter(train_dataloader))
print("images-size:", images.shape)
out = torchvision.utils.make_grid(images)
print("out-size:", out.shape)
imshow(out, title=[train_dataset.classes[x] for x in labels])
net = models.resnet18(pretrained=True)
net = net.cuda() if device else net
net
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.0001, momentum=0.9)
def accuracy(out, labels):
_, pred = torch.max(out, dim=1)
return torch.sum(pred == labels).item()
num_ftrs = net.fc.in_features
net.fc = nn.Linear(num_ftrs, 128)
net.fc = net.fc.cuda() if use_cuda else net.fc
## add a fully connected layer for transfer learnin g
_epochs = 5
print_every = 10
valid_loss_min = np.Inf
val_loss = []
val_acc = []
train_loss = []
train_acc = []
total_step = len(train_dataloader)
for epoch in range(1, n_epochs + 1):
running_loss = 0.0
correct = 0
total = 0
print(f"Epoch {epoch}\n")
for batch_idx, (data_, target_) in enumerate(train_dataloader):
data_, target_ = data_.to(device), target_.to(device)
optimizer.zero_grad()
outputs = net(data_)
loss = criterion(outputs, target_)
loss.backward()
optimizer.step()
running_loss += loss.item()
_, pred = torch.max(outputs, dim=1)
correct += torch.sum(pred == target_).item()
total += target_.size(0)
if (batch_idx) % 20 == 0:
print(
"Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}".format(
epoch, n_epochs, batch_idx, total_step, loss.item()
)
)
train_acc.append(100 * correct / total)
train_loss.append(running_loss / total_step)
print(
f"\ntrain-loss: {np.mean(train_loss):.4f}, train-acc: {(100 * correct/total):.4f}"
)
batch_loss = 0
total_t = 0
correct_t = 0
with torch.no_grad():
net.eval()
for data_t, target_t in test_dataloader:
data_t, target_t = data_t.to(device), target_t.to(device)
outputs_t = net(data_t)
loss_t = criterion(outputs_t, target_t)
batch_loss += loss_t.item()
_, pred_t = torch.max(outputs_t, dim=1)
correct_t += torch.sum(pred_t == target_t).item()
total_t += target_t.size(0)
val_acc.append(100 * correct_t / total_t)
val_loss.append(batch_loss / len(test_dataloader))
network_learned = batch_loss < valid_loss_min
print(
f"validation loss: {np.mean(val_loss):.4f}, validation acc: {(100 * correct_t/total_t):.4f}\n"
)
if network_learned:
valid_loss_min = batch_loss
torch.save(net.state_dict(), "resnet.pt")
print("Improvement-Detected, save-model")
net.train()