参考资料:
《深度学习之pytorch实战计算机视觉》
本文是采用pytorch进行迁移学习的实战演练,实战目的是为了进一步学习和熟悉pytorch编程。
本文涉及以下内容
- 迁移学习的概念
- 数据集的介绍,读取,处理和预览
- 模型搭建和参数优化 涉及VGG16,Res50等模型
- 采用GPU进行网络训练
- 采用tensorboradX进行训练可视化
- 学习率的调整
- 模型的保存和加载
- 模型测试
一、迁移学习的概念
两种常见的迁移学习的做法是
1、finetuning:微调。采用在其他数据集上训练好的权重作为初始权重训练模型。
2、冻结前面部分层,只训练后面的一些层。
迁移学习的好处:节省训练的时间,解决小样本问题。
个人感觉迁移学习在自然图像上应用得比较多,尤其是采用ImageNet数据集上训练的权重作为初始权重是一种很普遍的做法。但是在医学影像上,我很少看到有用迁移学习的。
二、数据集读取和处理
采用的数据集是ImageNet的一个子集——蚂蚁和蜜蜂。每一类的训练数据和验证数据各为120,75。数据很少,从头训练肯定是不够的,但本文采用的是迁移学习。下载地址。
我们来看数据读取和预览的代码。
#--coding:utf-8--
import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import numpy as np
import torchvision
from torchvision import datasets, models, transforms
import matplotlib.pyplot as plt
import time
import os
import copy
# Data augmentation and normalization for training
# Just normalization for validation
data_transforms = {
'train': transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor()
]),
'val': transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor()
]),
}
#获得数据生成器,以字典的形式保存。
data_dir = 'data'
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
data_transforms[x])
for x in ['train', 'val']}
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,
shuffle=True, num_workers=4)
for x in ['train', 'val']}
#选择1batch的训练数据进行可视化
def imshow(inp, title=None):
"""Imshow for Tensor."""
inp = inp.numpy().transpose((1, 2, 0))
inp = np.clip(inp, 0, 1)
plt.imshow(inp)
if title is not None:
plt.title(title)
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
class_names = image_datasets['train'].classes
# Get a batch of training data
inputs, classes = next(iter(dataloaders['train']))
# Make a grid from batch
out = torchvision.utils.make_grid(inputs)
imshow(out, title=[class_names[x] for x in classes])
plt.show()
图片预览结果:
这部分如果有问题可以看前一篇博文 【Pytorch实战5】数据读取和处理(以脸部关键点检测的数据为例)
查看数据集大小和标签:
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
print(dataset_sizes)
index_classes = image_datasets['train'].class_to_idx
print(index_classes)
三、模型搭建、训练和测试
本节将搭建三个卷积神经网络模型用于分类:Res18,VGG16,ResNet50。并比较这三个模型的准确率和泛化能力。
本节还涉及以下内容:
- GPU训练网络
- tensorboardX训练可视化
- 计划学习率
- 保存最优模型和加载模型用于测试
1、Res18
先看完整的训练代码。
# --coding:utf-8--
import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import numpy as np
import torchvision
from torchvision import datasets, models, transforms
import matplotlib.pyplot as plt
import time
import os
import copy
from tensorboardX import SummaryWriter
# 获得数据生成器,以字典的形式保存。
data_transforms = {
'train': transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
'val': transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
}
data_dir = 'data'
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
data_transforms[x])
for x in ['train', 'val']}
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,
shuffle=True, num_workers=4)
for x in ['train', 'val']}
# 数据集的大小
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
# 类的名称
class_names = image_datasets['train'].classes
# 有GPU就用GPU训练
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 模型训练和参数优化
def train_model(model, criterion, optimizer, scheduler, num_epochs=25):
since = time.time()
best_model_wts = copy.deepcopy(model.state_dict())
best_acc = 0