pytorch-第五章使⽤迁移学习实现分类任务-torchvison torchvision 主要是由三⼤模块组成, model, transforms, datats
transforms 主要可以进⾏数据增强
datats 主要下载⼀些常⽤的数据集如mnist数据集
model 主要是将原来的模型进⾏下载
第⼀部分: 数据集的准备⼯作
第⼀步: 使⽤transforms进⾏数据的增强操作, 使⽤torch.utils.data.DataLoader()构造批量数据集
第⼆步: 将数据集重新转换为原来的样⼦, 即转换为numpy格式,变化颜⾊通道, 将均值和标准差弥补上,使⽤image.clip(0, 1) 将数据限制在0和1之间,最后进⾏图像的显⽰
第⼆部分: 数据集的训练⼯作
第⼀步: 使⽤ initiallize_model() 初始化⽹络
第⼆步: 对⽹络进⾏训练,将效果最好的结果保存在路径下,返回最好的模型的参数结果
第三部分: 数据集的测试⼯作
第⼀步: 对于输⼊的当张图⽚进⾏测试, 这⾥需要对输⼊的图⽚做valid操作
第⼆步: 对⼀个batch的valid进⾏测试,最后对结果进⾏显⽰
import os
import numpy as np
import torch
from torch import nn
from torch import optim
from torchvision import transforms, datats, models
import matplotlib.pyplot as plt
import time
import copy
from PIL import Image
# 第⼀部分数据的准备:
# 数据读取与预处理操作
data_dir = './flower_data'
train_dir = '/train'
test_dir = '/test'
# 第⼀步: 数据的制作
data_transform = {
"train": transforms.Compo([
transforms.Resize(256),
transforms.RandomRotation(45),
transforms.CenterCrop(224),
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomVerticalFlip(p=0.5),
transforms.ColorJitter(brightness=0.2, contrast=0.1, saturation=0.1, hue=0.1),
transforms.RandomGrayscale(p=0.025),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
'valid': transforms.Compo([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
}
def im_convert(tensor):
image = ('cpu').clone().detach() # clone() 修改image不会修改tensor
主陪副陪位置图解
image = image.numpy().squeeze() # 去除尺⼨为1的维度
image = anspo(1, 2, 0)
image = image * np.array((0.229, 0.224, 0.225)) + np.array((0.485, 0.456, 0.406))
image = image.clip(0, 1)
return image
batch_size = 8
image_datat = {x:datats.ImageFolder(os.path.join(data_dir + train_dir), data_transform[x]) for x in ['train', 'valid']} dataloaders = {x:torch.utils.data.DataLoader(image_datat[x], batch_size=batch_size, shuffle=True) for x in ['train', 'valid']} # 第⼆步:获得⼀个batch的验证集,进⾏图像的显⽰
dataiter = iter(dataloaders['valid'])
inputs, labels = ()
fig = plt.figure(figsize=(20, 12))
row = 2
columns = 4
for idx in range(row * columns):
ax = fig.add_subplot(row, columns, idx+1, xticks=[], yticks=[])
作家英文plt.imshow(im_convert(inputs[idx]))
plt.show()
# 第⼆部分: 进⾏模型的训练操作
# 进⾏模型的下载
model_name = 'resnet'
# 是否使⽤⼈家训练好的模型参数
feature_extract = True
train_on_gpu = torch.cuda.is_available()
if not train_on_gpu:
print('CUDA is not availabel.Training ')
el:
print('CUDA is not availabel! Training on CPU')
device = torch.device('cuda:0'if torch.cuda.is_available() el'cpu')
model_ft = snet152()
print(model_ft)
def t_parameter_requires_grad(model, feature_extract):
if feature_extract:
for param in model.parameters(): # 将反应的层数进⾏冻结
# 初始化模型
# 第⼀步: 进⾏模型的初始化操作
def initiallize_model(model_name, num_class, feature_extract, u_pretrained=True):
model_ft = None
input_size = 0
个人简
if model_name == 'resnet':
"""
Resnet 152
"""
model_ft = snet152(pretrained=u_pretrained)
t_parameter_requires_grad(model_ft, feature_extract)
num_ftrs = model_ft.fc.in_features # 最后⼀层全连接的个数
model_ft.fc = nn.Sequential(nn.Linear(num_ftrs, num_class),
nn.LogSoftmax(dim=1))
input_size = 224
return model_ft, input_size
model_ft, input_size = initiallize_model(model_name, 17, feature_extract, u_pretrained=True)
# 进⾏GPU训练
model_ft = (device)
# 模型保存
filename = 'checkpoint.pth'
param_to_update = model_ft.parameters()
print(param_to_update)
# # 进⾏所有层的训练
社会实践过程
# for param in model_ft.parameters():
# quires_grad = True
if feature_extract:
param_to_update = []
for name, param in model_ft.named_parameters():
quires_grad == True: # 如果quires_grad是否进⾏训练
param_to_update.append(param)
print('\t', name)
el:
for name, param in model_ft.named_parameters():
quires_grad == True:
print('\t', name)
print(model_ft)
# 优化器设置
optmizer_ft = optim.Adam(param_to_update, lr= 1e-2) # 输⼊为需要优化的参数
scheduler = optim.lr_scheduler.StepLR(optmizer_ft, step_size=7, gamma=0.1) # 对于学习率每7个epoch进⾏⼀次衰减criterion = nn.NLLLoss() #输⼊的是⼀个对数概率和标签值
# 第⼆步: 进⾏模型的训练模块
def train_model(model, dataloaders, criterion, optimizer, num_epochs=25, is_inception=Fal, filename=filename):
since = time.time()
best_acc = 0
if ists(filename):
checkpoint = torch.load(filename)
best_acc = checkpoint('best_acc')
model.load_state_dict(checkpoint['state_dict'])
optimizer.load_state_dict(checkpoint['optimizer'])
<(device)
val_acc_history = []
train_acc_history = []
train_loss = []
valid_loss = []
LRs = [optimizer.param_groups[0]['lr']]
best_model_wts = copy.deepcopy(model.state_dict())
for epoch in range(num_epochs):
print("Epoch {} / {}".format(epoch, num_epochs - 1))
print('-' *10)
# 训练和验证
for pha in ['train', 'valid']:
if pha == 'train':
el:
model.eval()
running_loss = 0.0
running_corrects = 0
for inputs, labels in dataloaders[pha]:
inputs = (device)
labels = (device)
print('runing')
# 清零操作
<_grad()
with torch.t_grad_enabled(pha == 'train'):
男龙女猴婚姻相配好吗if is_inception and pha == 'train':
家常爆炒大虾简单做法outputs, aux_outputs = model(inputs)
loss1 = criterion(outputs, labels)
loss2 = criterion(aux_outputs, labels)
loss = loss1 + 0.4 * loss2
el:
outputs = model(inputs)
loss = criterion(outputs, labels)
pred = torch.argmax(outputs, 1)
if pha == 'train':
loss.backward()
optimizer.step()
# 计算损失值
running_loss += loss.item() * inputs.size(0)
running_corrects += torch.sum(pred == labels.data)
epoch_loss = running_loss / len(dataloaders[pha].datat)
epoch_acc = running_corrects / len(dataloaders[pha].datat)
time_elapad = time.time() - since
print('Time elapd {:.0f}m {:.0f}s'.format(time_elapad // 60, time_elapad % 60))
print("{} loss:{:.4f} Acc:{.4f}".format(pha, epoch_loss, epoch_acc))
# 将效果最好的⼀次模型进⾏保存
if pha == 'valid'and epoch_acc > best_acc:
best_acc = epoch_acc
best_model_wts = copy.deepcopy(model.state_dict())
state = {
'static_dict':model.state_dict(),
'best_acc':best_acc,
'optimizer':optimizer.state_dict(),
}
torch.save(state, filename)
if pha == 'valid':
val_acc_history.append(epoch_acc)
valid_loss.append(epoch_loss)
scheduler.step()
if pha == 'train':
train_acc_history.append(epoch_acc)
train_loss.append(epoch_loss)
time_elapad = time.time() - since
print('Training complete in {:0.f}m {:0.f}s'.format(time_elapad // 60, time_elapad % 60)) print('Best val Acc{:4f}'.format(best_acc))
# 训练结束以后使⽤最好的⼀次模型当做模型保存的结果
model.load_state_dict(best_model_wts)
return model, val_acc_history, train_acc_history, valid_loss, train_loss, LRs
# 第三部分:进⾏模型的测试
def predict(model_name, num_class, feature_extract, image_path):
# 获得初始化的模型
model_ft, inputs_size = initiallize_model(model_name, num_class, feature_extract)
(device)
# 加载训练好的⽹络结构
filename = 'checkpoint.pth'
checkpoint = torch.load(filename)
best_acc = checkpoint['best_acc']
model_ft.load_state_dict(checkpoint['state_dict'])
# 将输⼊的图⽚进⾏处理,使得可以⽤于进⾏⽹络的训练
def process_image(image_path):
# 读取测试图⽚
img = Image.open(image_path)
if img.size[0] > img.size[1]:
img.thumbnail((10000, 256))
el:
img.thumbnail((256, 10000))
# Crop操作
left_margin = (img.width - 224) / 2
right_margin = left_margin + 224
bottom_margin = (img.height - 224) / 2
top_margin = bottom_margin + 224
img = p((left_margin, bottom_margin, right_margin, top_margin))
img = np.array(img) / 255
mean = np.array([0.485, 0.456, 0.406])积木搭建
std = np.array([0.229, 0.224, 0.225])
img = (img - mean) / std
img = anspo([2, 0, 1])
return img
img = process_image(image_path)
outputs = model_sor([img])) # 进⾏⼀张图⽚的测试
# 第⼆步: 获得⼀个batch的测试数据进⾏测试
平锅dataiter = iter(dataloaders['valid'])
images, labels = ()
model_ft.eval()
if train_on_gpu:
outputs = model_ft(images.cuda())
el:
outputs = model_ft(images)
_, preds_tensor = torch.max(outputs, 1)
preds = np.squeeze(preds_tensor.numpy()) if not train_on_gpu el np.squeeze(preds_tensor.cpu().numpy())
fig = plt.figure(figsize=(20, 20))
columns = 4
rows = 2
for idx in range(columns * rows):
ax = fig.add_subplot(row, columns, idx + 1, xticks=[], yticks=[])
plt.imshow(im_convert(images[idx]))
ax.t_title("{}?{}".format(preds[idx], labels.data[idx]),
color='green'if preds[idx] == labels.data[idx] el'red')
plt.show()
if__name__=='__main__':
# train_model(model_ft, dataloaders, criterion, optmizer_ft)
image_path = r'C:\Urs\qq302\Desktop\pytorch学习\第四章卷积神经⽹络实战\flower_data\train\4\image_0242.jpg' predict(model_name, 17, feature_extract, image_path)