pytorch基于经典网络架构训练图像分类模型

数据预处理部分:

  • 数据增强:torchvision中transforms模块自带功能,比较实用
  • 数据预处理:torchvision中transforms也帮我们实现好了,直接调用即可
  • DataLoader模块直接读取batch数据

网络模块设置:

  • 加载预训练模型,torchvision中有很多经典网络架构,调用起来十分方便,并且可以用人家训练好的权重参数来继续训练,也就是所谓的迁移学习
  • 需要注意的是别人训练好的任务跟咱们的可不是完全一样,需要把最后的head层改一改,一般也就是最后的全连接层,改成咱们自己的任务
  • 训练时可以全部重头训练,也可以只训练最后咱们任务的层,因为前几层都是做特征提取的,本质任务目标是一致的

网络模型保存与测试

  • 模型保存的时候可以带有选择性,例如在验证集中如果当前效果好则保存
  • 读取模型进行实际测试
import os
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import torch
from torch import nn
import torch.optim as optim
import torchvision
#pip install torchvision
from torchvision import transforms, models, datasets
#https://pytorch.org/docs/stable/torchvision/index.html
import imageio
import time
import warnings
import random
import sys
import copy
import json
from PIL import Image

数据读取与预处理操作

  • 指定数据路径
data_dir = './flower_data/'
train_dir = data_dir + '/train'
valid_dir = data_dir + '/valid'

制作好数据源:

  • data_transforms中指定了所有图像预处理操作
  • ImageFolder假设所有的文件按文件夹保存好,每个文件夹下面存贮同一类别的图片,文件夹的名字为分类的名字
data_transforms = {
    'train': transforms.Compose([transforms.RandomRotation(45),#随机旋转,-45到45度之间随机选
        transforms.CenterCrop(224),#从中心开始裁剪 统一图像大小
        transforms.RandomHorizontalFlip(p=0.5),#随机水平翻转 选择一个概率概率
        transforms.RandomVerticalFlip(p=0.5),#随机垂直翻转  p=0.5表示50%的可能性翻转一次
        transforms.ColorJitter(brightness=0.2, contrast=0.1, saturation=0.1, hue=0.1),#参数1为亮度,参数2为对比度,参数3为饱和度,参数4为色相
        transforms.RandomGrayscale(p=0.025),#概率转换成灰度率,3通道就是R=G=B
        transforms.ToTensor(),   #转换成tensor格式
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])#-均值,/标准差  用别人训练好的模型就要用别人类似的数据进行处理效果才会好,这里的均值和标准差和别人使用的保持一致
    ]),
    'valid': transforms.Compose([transforms.Resize(256),#测试集的照片一般比训练集的大所以要做一个resize统一规格
        transforms.CenterCrop(224),#和训练数据预处理保持一致
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}
batch_size = 8

image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'valid']}#构建数据集
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size, shuffle=True) for x in ['train', 'valid']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'valid']}
class_names = image_datasets['train'].classes
image_datasets

pytorch基于经典网络架构训练图像分类模型_第1张图片

dataloaders

pytorch基于经典网络架构训练图像分类模型_第2张图片

读取标签对应的实际名字

with open('cat_to_name.json', 'r') as f:
    cat_to_name = json.load(f)

pytorch基于经典网络架构训练图像分类模型_第3张图片

展示下数据

  • 注意tensor的数据需要转换成numpy的格式,而且还需要还原回标准化的结果才能展示

  • clone和detach的用法

  • Pytorch的Tensor变量与Numpy之间的转化

  • numpy.squeeze()函数

  • numpy中的squeeze()函数

  • numpy模块下的np.clip()的用法

def im_convert(tensor):
    """ 展示数据"""
    #现数据是tensor格式,要展示数据需要还原
    image = tensor.to("cpu").clone().detach()
    #实际上y = x.clone()类似于数学表达式中的y=x,但是在python里如果让y=x,是不会给y创建新的内存空间的,这就需要clone了
    #或者也可以y = x+0和y=x*1,detach的效果其实就是将一个Tensor的requires_grad置为False,从效果上来看其实就是以该Tensor为根节点的计算子图在反向传播中不再会得到梯度。
    image = image.numpy().squeeze()#squeeze()函数的功能是:从矩阵shape中,去掉维度为1的。例如一个矩阵是的shape是(5, 1),使用过这个函数后,结果为(5,)。
    #利用squeeze()函数将表示向量的数组转换为秩为1的数组,这样利用matplotlib库函数画图时,就可以正常的显示结果了。
    image = image.transpose(1,2,0)#tensor格式是c*h*w还原为h*w*c
    image = image * np.array((0.229, 0.224, 0.225)) + np.array((0.485, 0.456, 0.406)) #还原标准化
    image = image.clip(0, 1)
    #在求对数损失函数时会用到log函数,对数函数要求对数必须大于零,而从计算中得到的数据可能存在等于0或等于1的情况,这是就会出现inf的数据,影响后续的处理
    #为避免这样的情况出现,可以用到np.clip()
    return image
fig=plt.figure(figsize=(20, 12))
columns = 4
rows = 2

dataiter = iter(dataloaders['valid'])#iter()生成一个迭代器遍历dataloaders['valid']中的所有值
inputs, classes = dataiter.next()

for idx in range (columns*rows):
    ax = fig.add_subplot(rows, columns, idx+1, xticks=[], yticks=[])
    ax.set_title(cat_to_name[str(int(class_names[classes[idx]]))])
    plt.imshow(im_convert(inputs[idx]))
plt.show()

pytorch基于经典网络架构训练图像分类模型_第4张图片

加载models中提供的模型,并且直接用训练的好权重当做初始化参数

  • 第一次执行需要下载,可能会比较慢,我会提供给大家一份下载好的,可以直接放到相应路径
### 加载models中提供的模型,并且直接用训练的好权重当做初始化参数
- 第一次执行需要下载,可能会比较慢,我会提供给大家一份下载好的,可以直接放到相应路径
# 是否用GPU训练
train_on_gpu = torch.cuda.is_available()

if not train_on_gpu:   #if x is None=if not x:
    print('CUDA is not available.  Training on CPU ...')
else:
    print('CUDA is available!  Training on GPU ...')
    
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
def set_parameter_requires_grad(model, feature_extracting):
    if feature_extracting:
        for param in model.parameters():
            param.requires_grad = False
model_ft = models.resnet152()
model_ft

pytorch基于经典网络架构训练图像分类模型_第5张图片

你可能感兴趣的:(pytorch,pytorch,网络,架构)