pytorch入门学习第五课图片分类代码实现

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
print("PyTorch Version: ",torch.version)
PyTorch Version: 1.0.0
首先我们定义一个基于ConvNet的简单神经网络

class Net(nn.Module):
def init(self):
super(Net, self).init()
self.conv1 = nn.Conv2d(1, 20, 5, 1)
self.conv2 = nn.Conv2d(20, 50, 5, 1)
self.fc1 = nn.Linear(4450, 500)
self.fc2 = nn.Linear(500, 10)

def forward(self, x):
    x = F.relu(self.conv1(x))
    x = F.max_pool2d(x, 2, 2)
    x = F.relu(self.conv2(x))
    x = F.max_pool2d(x, 2, 2)
    x = x.view(-1, 4*4*50)
    x = F.relu(self.fc1(x))
    x = self.fc2(x)
    return F.log_softmax(x, dim=1)

NLL loss的定义

ℓ(x,y)=L={l1,…,lN}⊤,ln=−wynxn,yn,wc=weight[c]⋅1{c≠ignore_index}
def train(model, device, train_loader, optimizer, epoch, log_interval=100):
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizer.step()
if batch_idx % log_interval == 0:
print(“Train Epoch: {} [{}/{} ({:0f}%)]\tLoss: {:.6f}”.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()
))
def test(model, device, test_loader):
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
data, target = data.to(device), target.to(device)
output = model(data)
test_loss += F.nll_loss(output, target, reduction=‘sum’).item() # sum up batch loss
pred = output.argmax(dim=1, keepdim=True) # get the index of the max log-probability
correct += pred.eq(target.view_as(pred)).sum().item()

test_loss /= len(test_loader.dataset)

print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
    test_loss, correct, len(test_loader.dataset),
    100. * correct / len(test_loader.dataset)))

torch.manual_seed(53113)

use_cuda = torch.cuda.is_available()
device = torch.device(“cuda” if use_cuda else “cpu”)
batch_size = test_batch_size = 32
kwargs = {‘num_workers’: 1, ‘pin_memory’: True} if use_cuda else {}
train_loader = torch.utils.data.DataLoader(
datasets.MNIST(’./mnist_data’, train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True, **kwargs)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST(’./mnist_data’, train=False, transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=test_batch_size, shuffle=True, **kwargs)

lr = 0.01
momentum = 0.5
model = Net().to(device)
optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

epochs = 2
for epoch in range(1, epochs + 1):
train(model, device, train_loader, optimizer, epoch)
test(model, device, test_loader)

save_model = True
if (save_model):
torch.save(model.state_dict(),“mnist_cnn.pt”)
Train Epoch: 1 [0/60000 (0.000000%)] Loss: 2.297938
Train Epoch: 1 [3200/60000 (5.333333%)] Loss: 0.567845
Train Epoch: 1 [6400/60000 (10.666667%)] Loss: 0.206370
Train Epoch: 1 [9600/60000 (16.000000%)] Loss: 0.094653
Train Epoch: 1 [12800/60000 (21.333333%)] Loss: 0.180530
Train Epoch: 1 [16000/60000 (26.666667%)] Loss: 0.041645
Train Epoch: 1 [19200/60000 (32.000000%)] Loss: 0.135092
Train Epoch: 1 [22400/60000 (37.333333%)] Loss: 0.054001
Train Epoch: 1 [25600/60000 (42.666667%)] Loss: 0.111863
Train Epoch: 1 [28800/60000 (48.000000%)] Loss: 0.059039
Train Epoch: 1 [32000/60000 (53.333333%)] Loss: 0.089227
Train Epoch: 1 [35200/60000 (58.666667%)] Loss: 0.186015
Train Epoch: 1 [38400/60000 (64.000000%)] Loss: 0.093208
Train Epoch: 1 [41600/60000 (69.333333%)] Loss: 0.077090
Train Epoch: 1 [44800/60000 (74.666667%)] Loss: 0.038075
Train Epoch: 1 [48000/60000 (80.000000%)] Loss: 0.036247
Train Epoch: 1 [51200/60000 (85.333333%)] Loss: 0.052358
Train Epoch: 1 [54400/60000 (90.666667%)] Loss: 0.013201
Train Epoch: 1 [57600/60000 (96.000000%)] Loss: 0.036660

Test set: Average loss: 0.0644, Accuracy: 9802/10000 (98%)

Train Epoch: 2 [0/60000 (0.000000%)] Loss: 0.054402
Train Epoch: 2 [3200/60000 (5.333333%)] Loss: 0.032239
Train Epoch: 2 [6400/60000 (10.666667%)] Loss: 0.092350
Train Epoch: 2 [9600/60000 (16.000000%)] Loss: 0.058544
Train Epoch: 2 [12800/60000 (21.333333%)] Loss: 0.029762
Train Epoch: 2 [16000/60000 (26.666667%)] Loss: 0.012521
Train Epoch: 2 [19200/60000 (32.000000%)] Loss: 0.101891
Train Epoch: 2 [22400/60000 (37.333333%)] Loss: 0.127773
Train Epoch: 2 [25600/60000 (42.666667%)] Loss: 0.009259
Train Epoch: 2 [28800/60000 (48.000000%)] Loss: 0.013482
Train Epoch: 2 [32000/60000 (53.333333%)] Loss: 0.039676
Train Epoch: 2 [35200/60000 (58.666667%)] Loss: 0.016707
Train Epoch: 2 [38400/60000 (64.000000%)] Loss: 0.168691
Train Epoch: 2 [41600/60000 (69.333333%)] Loss: 0.056318
Train Epoch: 2 [44800/60000 (74.666667%)] Loss: 0.008174
Train Epoch: 2 [48000/60000 (80.000000%)] Loss: 0.075149
Train Epoch: 2 [51200/60000 (85.333333%)] Loss: 0.205798
Train Epoch: 2 [54400/60000 (90.666667%)] Loss: 0.019762
Train Epoch: 2 [57600/60000 (96.000000%)] Loss: 0.012056

Test set: Average loss: 0.0464, Accuracy: 9850/10000 (98%)

torch.manual_seed(53113)

use_cuda = torch.cuda.is_available()
device = torch.device(“cuda” if use_cuda else “cpu”)
batch_size = test_batch_size = 32
kwargs = {‘num_workers’: 1, ‘pin_memory’: True} if use_cuda else {}
train_loader = torch.utils.data.DataLoader(
datasets.FashionMNIST(’./fashion_mnist_data’, train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True, **kwargs)
test_loader = torch.utils.data.DataLoader(
datasets.FashionMNIST(’./fashion_mnist_data’, train=False, transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=test_batch_size, shuffle=True, **kwargs)

lr = 0.01
momentum = 0.5
model = Net().to(device)
optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

epochs = 2
for epoch in range(1, epochs + 1):
train(model, device, train_loader, optimizer, epoch)
test(model, device, test_loader)

save_model = True
if (save_model):
torch.save(model.state_dict(),“fashion_mnist_cnn.pt”)
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz
Processing…
Done!
Train Epoch: 1 [0/60000 (0.000000%)] Loss: 2.279603
Train Epoch: 1 [3200/60000 (5.333333%)] Loss: 0.962251
Train Epoch: 1 [6400/60000 (10.666667%)] Loss: 1.019635
Train Epoch: 1 [9600/60000 (16.000000%)] Loss: 0.544330
Train Epoch: 1 [12800/60000 (21.333333%)] Loss: 0.629807
Train Epoch: 1 [16000/60000 (26.666667%)] Loss: 0.514437
Train Epoch: 1 [19200/60000 (32.000000%)] Loss: 0.555741
Train Epoch: 1 [22400/60000 (37.333333%)] Loss: 0.528186
Train Epoch: 1 [25600/60000 (42.666667%)] Loss: 0.656440
Train Epoch: 1 [28800/60000 (48.000000%)] Loss: 0.294654
Train Epoch: 1 [32000/60000 (53.333333%)] Loss: 0.293626
Train Epoch: 1 [35200/60000 (58.666667%)] Loss: 0.227645
Train Epoch: 1 [38400/60000 (64.000000%)] Loss: 0.473842
Train Epoch: 1 [41600/60000 (69.333333%)] Loss: 0.724678
Train Epoch: 1 [44800/60000 (74.666667%)] Loss: 0.519580
Train Epoch: 1 [48000/60000 (80.000000%)] Loss: 0.465854
Train Epoch: 1 [51200/60000 (85.333333%)] Loss: 0.378200
Train Epoch: 1 [54400/60000 (90.666667%)] Loss: 0.503832
Train Epoch: 1 [57600/60000 (96.000000%)] Loss: 0.616502

Test set: Average loss: 0.4365, Accuracy: 8425/10000 (84%)

Train Epoch: 2 [0/60000 (0.000000%)] Loss: 0.385171
Train Epoch: 2 [3200/60000 (5.333333%)] Loss: 0.329045
Train Epoch: 2 [6400/60000 (10.666667%)] Loss: 0.308792
Train Epoch: 2 [9600/60000 (16.000000%)] Loss: 0.360471
Train Epoch: 2 [12800/60000 (21.333333%)] Loss: 0.445865
Train Epoch: 2 [16000/60000 (26.666667%)] Loss: 0.357145
Train Epoch: 2 [19200/60000 (32.000000%)] Loss: 0.376523
Train Epoch: 2 [22400/60000 (37.333333%)] Loss: 0.389735
Train Epoch: 2 [25600/60000 (42.666667%)] Loss: 0.308655
Train Epoch: 2 [28800/60000 (48.000000%)] Loss: 0.352300
Train Epoch: 2 [32000/60000 (53.333333%)] Loss: 0.499613
Train Epoch: 2 [35200/60000 (58.666667%)] Loss: 0.282398
Train Epoch: 2 [38400/60000 (64.000000%)] Loss: 0.330232
Train Epoch: 2 [41600/60000 (69.333333%)] Loss: 0.430427
Train Epoch: 2 [44800/60000 (74.666667%)] Loss: 0.406084
Train Epoch: 2 [48000/60000 (80.000000%)] Loss: 0.443538
Train Epoch: 2 [51200/60000 (85.333333%)] Loss: 0.348947
Train Epoch: 2 [54400/60000 (90.666667%)] Loss: 0.424920
Train Epoch: 2 [57600/60000 (96.000000%)] Loss: 0.231494

Test set: Average loss: 0.3742, Accuracy: 8652/10000 (87%)

CNN模型的迁移学习
很多时候当我们需要训练一个新的图像分类任务,我们不会完全从一个随机的模型开始训练,而是利用_预训练_的模型来加速训练的过程。我们经常使用在ImageNet上的预训练模型。
这是一种transfer learning的方法。我们常用以下两种方法做迁移学习。
fine tuning: 从一个预训练模型开始,我们改变一些模型的架构,然后继续训练整个模型的参数。
feature extraction: 我们不再改变与训练模型的参数,而是只更新我们改变过的部分模型参数。我们之所以叫它feature extraction是因为我们把预训练的CNN模型当做一个特征提取模型,利用提取出来的特征做来完成我们的训练任务。
以下是构建和训练迁移学习模型的基本步骤:

初始化预训练模型
把最后一层的输出层改变成我们想要分的类别总数
定义一个optimizer来更新参数
模型训练
import numpy as np
import torchvision
from torchvision import datasets, transforms, models

import matplotlib.pyplot as plt
import time
import os
import copy
print("Torchvision Version: ",torchvision.version)
Torchvision Version: 0.2.0
数据
我们会使用hymenoptera_data数据集,下载.

这个数据集包括两类图片, bees 和 ants, 这些数据都被处理成了可以使用ImageFolder https://pytorch.org/docs/stable/torchvision/datasets.html#torchvision.datasets.ImageFolder来读取的格式。我们只需要把data_dir设置成数据的根目录,然后把model_name设置成我们想要使用的与训练模型: :: [resnet, alexnet, vgg, squeezenet, densenet, inception]

其他的参数有:

num_classes表示数据集分类的类别数
batch_size
num_epochs
feature_extract表示我们训练的时候使用fine tuning还是feature extraction方法。如果feature_extract = False,整个模型都会被同时更新。如果feature_extract = True,只有模型的最后一层被更新。

Top level data directory. Here we assume the format of the directory conforms

to the ImageFolder structure

data_dir = “./hymenoptera_data”

Models to choose from [resnet, alexnet, vgg, squeezenet, densenet, inception]

model_name = “resnet”

Number of classes in the dataset

num_classes = 2

Batch size for training (change depending on how much memory you have)

batch_size = 32

Number of epochs to train for

num_epochs = 15

Flag for feature extracting. When False, we finetune the whole model,

when True we only update the reshaped layer params

feature_extract = True
def train_model(model, dataloaders, criterion, optimizer, num_epochs=5):
since = time.time()
val_acc_history = []
best_model_wts = copy.deepcopy(model.state_dict())
best_acc = 0.
for epoch in range(num_epochs):
print(“Epoch {}/{}”.format(epoch, num_epochs-1))
print("-"*10)

    for phase in ["train", "val"]:
        running_loss = 0.
        running_corrects = 0.
        if phase == "train":
            model.train()
        else: 
            model.eval()
        
        for inputs, labels in dataloaders[phase]:
            inputs = inputs.to(device)
            labels = labels.to(device)
            
            with torch.autograd.set_grad_enabled(phase=="train"):
                outputs = model(inputs)
                loss = criterion(outputs, labels)
                
            _, preds = torch.max(outputs, 1)
            if phase == "train":
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()
                
            running_loss += loss.item() * inputs.size(0)
            running_corrects += torch.sum(preds.view(-1) == labels.view(-1)).item()
        
        epoch_loss = running_loss / len(dataloaders[phase].dataset)
        epoch_acc = running_corrects / len(dataloaders[phase].dataset)
   
        print("{} Loss: {} Acc: {}".format(phase, epoch_loss, epoch_acc))
        if phase == "val" and epoch_acc > best_acc:
            best_acc = epoch_acc
            best_model_wts = copy.deepcopy(model.state_dict())
        if phase == "val":
            val_acc_history.append(epoch_acc)
        
    print()

time_elapsed = time.time() - since
print("Training compete in {}m {}s".format(time_elapsed // 60, time_elapsed % 60))
print("Best val Acc: {}".format(best_acc))

model.load_state_dict(best_model_wts)
return model, val_acc_history

it = iter(dataloaders_dict[“train”])

inputs, labels = next(it)

for inputs, labels in dataloaders_dict[“train”]:

print(labels.size())

def set_parameter_requires_grad(model, feature_extracting):
if feature_extracting:
for param in model.parameters():
param.requires_grad = False
def initialize_model(model_name, num_classes, feature_extract, use_pretrained=True):
if model_name == “resnet”:
model_ft = models.resnet18(pretrained=use_pretrained)
set_parameter_requires_grad(model_ft, feature_extract)
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs, num_classes)
input_size = 224

return model_ft, input_size

model_ft, input_size = initialize_model(model_name, num_classes, feature_extract, use_pretrained=True)
print(model_ft)
ResNet(
(conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
(layer1): Sequential(
(0): BasicBlock(
(conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
(1): BasicBlock(
(conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(layer2): Sequential(
(0): BasicBlock(
(conv1): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(downsample): Sequential(
(0): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): BasicBlock(
(conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(layer3): Sequential(
(0): BasicBlock(
(conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(downsample): Sequential(
(0): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): BasicBlock(
(conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(layer4): Sequential(
(0): BasicBlock(
(conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(downsample): Sequential(
(0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): BasicBlock(
(conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(avgpool): AvgPool2d(kernel_size=7, stride=1, padding=0)
(fc): Linear(in_features=512, out_features=2, bias=True)
)
读入数据
现在我们知道了模型输入的size,我们就可以把数据预处理成相应的格式。

all_imgs = datasets.ImageFolder(os.path.join(data_dir, “train”), transforms.Compose([
transforms.RandomResizedCrop(input_size),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
]))
loader = torch.utils.data.DataLoader(all_imgs, batch_size=batch_size, shuffle=True, num_workers=4)
img = next(iter(loader))[0]
unloader = transforms.ToPILImage() # reconvert into PIL image

plt.ion()

def imshow(tensor, title=None):
image = tensor.cpu().clone() # we clone the tensor to not do changes on it
image = image.squeeze(0) # remove the fake batch dimension
image = unloader(image)
plt.imshow(image)
if title is not None:
plt.title(title)
plt.pause(0.001) # pause a bit so that plots are updated

plt.figure()
imshow(img[31], title=‘Image’)
data_transforms = {
“train”: transforms.Compose([
transforms.RandomResizedCrop(input_size),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
“val”: transforms.Compose([
transforms.Resize(input_size),
transforms.CenterCrop(input_size),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
}

print(“Initializing Datasets and Dataloaders…”)

Create training and validation datasets

image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in [‘train’, ‘val’]}

Create training and validation dataloaders

dataloaders_dict = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size, shuffle=True, num_workers=4) for x in [‘train’, ‘val’]}

Detect if we have a GPU available

device = torch.device(“cuda:0” if torch.cuda.is_available() else “cpu”)
Initializing Datasets and Dataloaders…

Send the model to GPU

model_ft = model_ft.to(device)

Gather the parameters to be optimized/updated in this run. If we are

finetuning we will be updating all parameters. However, if we are

doing feature extract method, we will only update the parameters

that we have just initialized, i.e. the parameters with requires_grad

is True.

params_to_update = model_ft.parameters()
print(“Params to learn:”)
if feature_extract:
params_to_update = []
for name,param in model_ft.named_parameters():
if param.requires_grad == True:
params_to_update.append(param)
print("\t",name)
else:
for name,param in model_ft.named_parameters():
if param.requires_grad == True:
print("\t",name)

Observe that all parameters are being optimized

optimizer_ft = optim.SGD(params_to_update, lr=0.001, momentum=0.9)
Params to learn:
fc.weight
fc.bias

Setup the loss fxn

criterion = nn.CrossEntropyLoss()

Train and evaluate

model_ft, ohist = train_model(model_ft, dataloaders_dict, criterion, optimizer_ft, num_epochs=num_epochs)
Epoch 0/14

train Loss: 0.2623850886450439 Acc: 0.8975409836065574
val Loss: 0.22199168762350394 Acc: 0.9215686274509803

Epoch 1/14

train Loss: 0.20775875546893136 Acc: 0.9262295081967213
val Loss: 0.21329789413930544 Acc: 0.9215686274509803

Epoch 2/14

train Loss: 0.24463887243974405 Acc: 0.9098360655737705
val Loss: 0.2308054333613589 Acc: 0.9215686274509803

Epoch 3/14

train Loss: 0.2108444703406975 Acc: 0.930327868852459
val Loss: 0.20637644174831365 Acc: 0.954248366013072

Epoch 4/14

train Loss: 0.22102872954040279 Acc: 0.9221311475409836
val Loss: 0.19902625017695957 Acc: 0.9281045751633987

Epoch 5/14

train Loss: 0.22044393127081824 Acc: 0.9221311475409836
val Loss: 0.2212505256818011 Acc: 0.9281045751633987

Epoch 6/14

train Loss: 0.1636357441788814 Acc: 0.9467213114754098
val Loss: 0.1969745449380937 Acc: 0.934640522875817

Epoch 7/14

train Loss: 0.1707800094221459 Acc: 0.9385245901639344
val Loss: 0.20569930824578977 Acc: 0.934640522875817

Epoch 8/14

train Loss: 0.18224841185280535 Acc: 0.9344262295081968
val Loss: 0.192565394480244 Acc: 0.9411764705882353

Epoch 9/14

train Loss: 0.17762072372143387 Acc: 0.9385245901639344
val Loss: 0.19549715163466197 Acc: 0.9411764705882353

Epoch 10/14

train Loss: 0.19314993575948183 Acc: 0.9180327868852459
val Loss: 0.2000840900380627 Acc: 0.934640522875817

Epoch 11/14

train Loss: 0.21551114418467537 Acc: 0.9057377049180327
val Loss: 0.18960770005299374 Acc: 0.934640522875817

Epoch 12/14

train Loss: 0.1847396502729322 Acc: 0.9426229508196722
val Loss: 0.1871058808432685 Acc: 0.9411764705882353

Epoch 13/14

train Loss: 0.17342406132670699 Acc: 0.9508196721311475
val Loss: 0.20636656588199093 Acc: 0.9215686274509803

Epoch 14/14

train Loss: 0.16013679030488748 Acc: 0.9508196721311475
val Loss: 0.18491691759988374 Acc: 0.9411764705882353

Training compete in 0.0m 14.700076580047607s
Best val Acc: 0.954248366013072

Initialize the non-pretrained version of the model used for this run

scratch_model,_ = initialize_model(model_name, num_classes, feature_extract=False, use_pretrained=False)
scratch_model = scratch_model.to(device)
scratch_optimizer = optim.SGD(scratch_model.parameters(), lr=0.001, momentum=0.9)
scratch_criterion = nn.CrossEntropyLoss()
_,scratch_hist = train_model(scratch_model, dataloaders_dict, scratch_criterion, scratch_optimizer, num_epochs=num_epochs)
Epoch 0/14

train Loss: 0.7185551504619786 Acc: 0.4426229508196721
val Loss: 0.6956208067781785 Acc: 0.45751633986928103

Epoch 1/14

train Loss: 0.6852761008700387 Acc: 0.5778688524590164
val Loss: 0.6626271987273022 Acc: 0.6601307189542484

Epoch 2/14

train Loss: 0.6603062289660094 Acc: 0.5942622950819673
val Loss: 0.6489538297154545 Acc: 0.5816993464052288

Epoch 3/14

train Loss: 0.6203305486772881 Acc: 0.639344262295082
val Loss: 0.6013184107986151 Acc: 0.673202614379085

Epoch 4/14

train Loss: 0.5989709232674271 Acc: 0.6680327868852459
val Loss: 0.5929347966231552 Acc: 0.6993464052287581

Epoch 5/14

train Loss: 0.5821619336722327 Acc: 0.6557377049180327
val Loss: 0.5804777059679717 Acc: 0.6928104575163399

Epoch 6/14

train Loss: 0.6114685896967278 Acc: 0.6270491803278688
val Loss: 0.5674225290616354 Acc: 0.7189542483660131

Epoch 7/14

train Loss: 0.5681056575696977 Acc: 0.6680327868852459
val Loss: 0.5602688086188696 Acc: 0.7189542483660131

Epoch 8/14

train Loss: 0.5701596453541615 Acc: 0.7090163934426229
val Loss: 0.5554519264526616 Acc: 0.7450980392156863

Epoch 9/14

train Loss: 0.5476810380083615 Acc: 0.7254098360655737
val Loss: 0.5805927063125411 Acc: 0.7189542483660131

Epoch 10/14

train Loss: 0.5508710468401674 Acc: 0.6926229508196722
val Loss: 0.5859468777974447 Acc: 0.7058823529411765

Epoch 11/14

train Loss: 0.5344281519045595 Acc: 0.7172131147540983
val Loss: 0.5640550851821899 Acc: 0.7058823529411765

Epoch 12/14

train Loss: 0.5125471890949812 Acc: 0.7295081967213115
val Loss: 0.5665123891207128 Acc: 0.7058823529411765

Epoch 13/14

train Loss: 0.496260079204059 Acc: 0.7254098360655737
val Loss: 0.5820710787586137 Acc: 0.7058823529411765

Epoch 14/14

train Loss: 0.49067981907578767 Acc: 0.7704918032786885
val Loss: 0.5722863315756804 Acc: 0.7058823529411765

Training compete in 0.0m 18.418847799301147s
Best val Acc: 0.7450980392156863

Plot the training curves of validation accuracy vs. number

of training epochs for the transfer learning method and

the model trained from scratch

ohist = []

shist = []

ohist = [h.cpu().numpy() for h in ohist]

shist = [h.cpu().numpy() for h in scratch_hist]

plt.title(“Validation Accuracy vs. Number of Training Epochs”)
plt.xlabel(“Training Epochs”)
plt.ylabel(“Validation Accuracy”)
plt.plot(range(1,num_epochs+1),ohist,label=“Pretrained”)
plt.plot(range(1,num_epochs+1),scratch_hist,label=“Scratch”)
plt.ylim((0,1.))
plt.xticks(np.arange(1, num_epochs+1, 1.0))
plt.legend()
plt.show()
pytorch入门学习第五课图片分类代码实现_第1张图片

你可能感兴趣的:(python,pytorch)