本文基于B站up我是土堆所做的视频教程为基础创作的学习笔记,如有侵权请联系作者。
Pytorch入门实战
Pytorch官网:https://pytorch.org/
以下介绍的实际应用在官网的Docs下都有明确的教程文档
DataSet
1 | from torch.utils.data import Dataset |
Dataset顾名思义是用来自定义数据集的,我们可以理解为Java中的抽象类,需要你自定义一个数据集class来继承他,需要实现他的init()、getitem()、len()三种方法,具体实例如下:
1 | class MyData(Dataset): |
接下来我们只需要将我们的数据集复制到对应目录就可以使用了
1 | root_path = "data/hymenoptera_data/train" |
Tensorboard
Tensorboard可以对Pytorch训练过程进行可视化展示、主要用到SummaryWriter类
1 | writter = SummaryWriter("logs") |
运行完代码后,在控制台输入tensorboard —logdir=logs 启动可视化服务器(默认6006端口)
SummaryWriter除了能可视化线型图和图片外,还能将模型结构通过图化展示
1 | class Tudui(nn.Module): |
Transforms
Transforms是Pytorch常用的图像预处理方法,一般用于转化图片类型、大小、正则化、裁剪图像等等,具体应用如下:
1 | img_path = "images/001.png" |
我们一般用Transforms来实现图像由PIL类型转化为Tensor数据类型,因为在Pytorch中Tensor往往是后续很多方法参数所需要的类型
DataLoader
介绍DataLoader之前我们简单介绍一下如何使用官方给的数据集(torchvision.datasets)
Torchvision 在模块中提供了许多内置数据集torchvision.datasets
,以及用于构建您自己的数据集的实用程序类。
这些内置数据集都继承了上述的Dataset类,不需要我们手动去为它们实现方法
1 | dataset_transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()]) |
而DataLoader其实就是一个迭代器,方便我们从数据集从一次读取多个数据
1 | test_dataset = torchvision.datasets.CIFAR10(root="./data",train=False,transform=torchvision.transforms.ToTensor()) |
nn.Module
nn.Module是Pytorch中神经网络的基本骨架,如果我们想自定义一个神经网路模型类,我们必须要继承nn.Module这个类,并在这个类的init方法引用父类的init方法,重写forward()方法(就是input进去经过怎样的转换输出成output),其形参就是模型(块)的输入。
1 | class Demo(nn.Module): |
function的卷积操作
卷积操作主要就是用卷积核(kernel)对原始数据进行矩阵计算,得到一个新的输出,具体过程可以参照我《机器学习——Convolution》这篇博客
参数解读:input是输入的数据,kernel表示卷积核,stride表示步长,padding表示周围填充几层
1 | import torch.nn.functional as F |
卷积层
其实就是对nn.function的进一步封装,如nn.Conv2(),最常用的是这五个参数:in_channels、 out_channels、kernel_size、stride、 padding
以下示例就是把CIFAR10数据集中的图片经过一层卷积后的结果
1 | dataset = torchvision.datasets.CIFAR10("./data",train=True,transform=torchvision.transforms.ToTensor(),download=True) |
最大池化
Maxpooling作用(maxpool2d举例):
- 一是对卷积层所提取的信息做更一步降维,减少计算量
- 二是加强图像特征的不变性,使之增加图像的偏移、旋转等方面的鲁棒性
- 类似于观看视频时不同的清晰度,实际效果就像给图片打马赛克
示例:和上面代码差距不大,只是在模型中修改一下
1 | class Jy(nn.Module): |
非线性激活
非线性变换的主要目的就是给网中加入一些非线性特征,非线性越多才能训练出符合各种特征的模型。常见的非线性激活:Sigmod、ReLu
1 | class Tudui(nn.Module): |
线性层
线性层其实就是全连接层,也就是CNN过程中的最后一步
线性函数为:torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None),其中重要的3个参数in_features、out_features、bias说明如下:
- in_features:每个输入(x)样本的特征的大小
- out_features:每个输出(y)样本的特征的大小
- bias:如果设置为False,则图层不会学习附加偏差。默认值是True,表示增加学习偏置。
进线性层之前我们需要把数据Flatten铺平,变成一维数据,而Linear作用就是缩小一维的数据长度
1 | dataset = torchvision.datasets.CIFAR10("./data",False,transform=torchvision.transforms.ToTensor()) |
Sequential的使用
在我们定义模型时,往往需要经过一个复杂的神经网络结构才能得到最终的输出,在引入Sequential之前,我们来看看CIFAR10模型应该如何定义
这里我们需要自己计算一下padding值是多少,我们根据官方文档给出的公式进行计算得到padding = 2
1 | class Tudui(nn.Module): |
而引入Sequential后我们可以大大简化代码的书写:
1 | class Tudui(nn.Module): |
损失函数与优化器
损失函数(Loss):有多种计算方式
计算实际输出和目标之间的差距
为我们更新输出 提供一定的依据
更新输出:
- 反向传播(backward)–>
- 计算出梯度(grade)–>
- 根据梯度和学习率来更新参数–>
- 减小loss
而更新参数需要我们的优化器来做,在优化器中我们需要定义一个学习率Learning_rate,以下为一个简单优化实例:
1 | tudui = Tudui() |
现有的网络模型
我们可以直接加载torchvision给我们的模型,其中pretrained参数Flase表示使用默认神经网络参数,True表示使用ImageNet数据集更新好的参数
1 | import torchvision |
完整过程实例
训练实例:
1 | import torch |
验证实例:
1 | import torch |