pytorch官⽅⽂档(迁移学习)
本⽂参考pytorch官⽅⽂档迁移学习的计算机视觉教程
传送门:
为什么要⽤到迁移学习呢?
我们这次使⽤的数据集是⽐较⼩的,⼤约 120 张训练图像,然后 每个类别有 75 个验证图像。 如果仅仅使⽤这些图⽚是达不到⾜够⾼的准确率的,因此我们可以把已经训练好的模型参数迁移过来进⾏训练,这样准确率就能⼤⼤提⾼了。
代码如下:
from __future__ import print_function, division
import torch
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 PIL import Image
plt.ion()
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/hymenoptera_data'
image_dataset ={x: datasets.ImageFolder(os.path.join(data_dir, x),
data_transforms[x])
for x in['train','val']}
dataloaders ={x: torch.utils.data.DataLoader(image_dataset[x], batch_size=4,
shuffle=True, num_workers=4)
for x in['train','val']}
dataset_sizes ={x:len(image_dataset[x])for x in['train','val']}
class_names = image_dataset['train'].classes
device = torch.device("cuda:0"if torch.cuda.is_available()else"cpu")
def imshow(inp, title=None):
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.title(title)
plt.pause(0.001)
# plt.savefig('save_img.png')
#
# inputs, classes =next(iter(dataloaders['train']))
#
# out = torchvision.utils.make_grid(inputs)
#
# imshow(out, title=[class_names[x]for x in classes])
def train_model(model, criterion, optimizer, scheduler, num_epochs=25): since = time.time()
best_model_wts = copy.deepcopy(model.state_dict())
best_acc =0.0
for epoch in range(num_epochs):
print('Epoch {}/{}'.format(epoch, num_epochs -1))
print('_'*10)
for phase in['train','val']:
if phase =='train':
else:
model.eval()
running_loss =0.0
running_corrects =0
for inputs, labels in dataloaders[phase]:
inputs = (device)
labels = (device)
<_grad()
with torch.set_grad_enabled(phase =='train'):
outputs =model(inputs)
_, preds = torch.max(outputs,1)
loss =criterion(outputs, labels)
if phase =='train':
loss.backward()
optimizer.step()
running_loss += loss.item()* inputs.size(0)
running_corrects += torch.sum(preds == labels.data)
if phase =='train':
scheduler.step()
epoch_loss = running_loss / dataset_sizes[phase]
epoch_acc = running_corrects.double()/ dataset_sizes[phase]
print('{} Loss: {:.4f} Acc: {:.4f}'.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())
print()
time_elapsed = time.time()- since
print('Training complete in {:.0f}m {:.0f}s'.format(
time_elapsed // 60, time_elapsed % 60
time_elapsed // 60, time_elapsed % 60
))
print('Best val Acc: {:.4f}'.format(best_acc))
model.load_state_dict(best_model_wts)
return model
def visualize_model(model, num_images=6):
was_training = aining
model.eval()
images_so_far =0
fig = plt.figure()
_grad():
for i,(inputs, labels)in enumerate(dataloaders['val']):
inputs = (device)
labels = (device)
outputs =model(inputs)
_, preds = torch.max(outputs,1)
for j in range(inputs.size()[0]):
images_so_far +=1
ax = plt.subplot(num_images//2, 2, images_so_far)
ax.axis('off')
ax.set_title('predicted: {}'.format(class_names[preds[j]]))
imshow(inputs.cpu().data[j])
if images_so_far == num_images:
return
model_ft = snet18(pretrained=True)
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs,2)
model_ft = (device)
criterion = nn.CrossEntropyLoss()
optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)
model_ft =train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler, num_epochs=25) visualize_model(model_ft)
plt.ioff()
plt.show()
训练结果如下:
训练时间⼤约为31s,准确率为92.81%
我们可以冻结除最后⼀层之外的所有⽹络来提⾼运⾏速度。 通过设置requires_grad == False冻结参数,以便不在backward()中计算梯度。
model_conv = snet18(pretrained=True)
for param in model_conv.parameters():
num_ftrs = model_conv.fc.in_features
model_conv.fc = nn.Linear(num_ftrs,2)
model_conv = (device)
criterion = nn.CrossEntropyLoss()
optimizer_conv = optim.SGD(model_conv.fc.parameters(), lr=0.001, momentum=0.9)
exp_lr_schedule = lr_scheduler.StepLR(optimizer_conv, step_size=7, gamma=0.1)
model_conv =train_model(model_conv, criterion, optimizer_conv, exp_lr_schedule, num_epochs=25)
visualize_model(model_conv)
plt.ioff()
plt.show()
运⾏结果如下:
可以看出运⾏时间提⾼了很多,现在只⽤⼤约19s,准确率为96.73%
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论