一只菜鸟的PyTorch笔记!

1 前言
如今主流的学习框架有两个。其一是Google推出的TensorFlow
,其二是由Facebook推出的PyTorch
。相较之下后者更容易上手,且其动态图的设计也十分利于了解和调节神经网络结构,这也是其异军突起的原因。
笔者建议使用Jupyter Lab
来学习。因其即时交互和支持Markdown
等优点,许多Tutorial都是用采用的.ipynb
来记录的。初次学习需要对Python
有基础的了解。此文参考的是PyTorch官方教程。此外,多多查阅PyTorch官方文档会让你更快地上手。
所依赖的环境如下:
- Python 3.6.6
- PyTorch 0.4.1
- TorchVision 0.2.1
2 构建一个神经网络
构建一个神经网络的主要步骤为:
- 定义网络结构。
- 定义损失函数。
- 定义优化器。
2.1 网络结构
定义网络时,需要继承父类nn.Module
,调用父类的初始化函数__init__
,并实现它的forward
函数,把网络中具有可学习参数的层放在初始化函数__init__
中。如果某一层(如ReLU
)不具有可学习的参数,则既可以放在初始化函数中,也可以不放,建议是不放在其中,而在forward
中使用nn.functional
代替。
只要在nn.Module
的子类中定义了forward
函数,backward
函数就会自动被实现(利用autograd
)。在forward
函数中可使用任何tensor
支持的函数,还可以使用if
和for
循环,print
、log
等Python
语法,写法和标准的Python
写法一致。
定义一个简单的卷积神经网络LeNet,如下:
网络的可学习参数通过net.parameters()
返回:
net.named_parameters
可同时返回可学习的参数及名称:
需要注意的是,torch.nn
只支持mini-batches
,不支持一次只输入一个样本,即一次必须是一个batch
。但如果只想输入一个样本,则用input.unsqueeze(0)
将batch_size
设为1。例如nn.Conv2d
输入必须是4维张量,形如。可将nSample
设为1,即。
2.2 损失函数
输入和输出:
前向传播,计算损失:
反向传播,计算梯度:
2.3 优化器
在反向传播计算完所有参数的梯度后,还需要使用优化方法来更新网络的权重和参数,例如随机梯度下降法(SGD)的更新策略如下:
手动实现如下:
torch.optim
中实现了深度学习中绝大多数的优化方法,例如RMSProp
、Adam
、SGD
等,更便于使用,因此大多数时候并不需要手动写上述代码。
调用优化器进行操作如下:
就这样这样反复迭代下去,直到收敛,即可得到最终的模型。之后便是测试过程了。
3 小试牛刀:CIFAR-10分类
CIFAR-10是一个常用的彩色图片数据集,它有10个类别: ‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’。每张图片都是3×32×32
,也即3-通道彩色图片,分辨率为32×32。 通过百度网盘下载到本地会更有效率。
实现对CIFAR-10分类的步骤如下:
- 数据处理。
- 构建网络。
- 训练网络。
- 测试网络。
3.1 数据处理
加载并预处理CIFAR-10数据集,如下:
Dataset对象是一个数据集,可以按下标访问,返回形如(data, label)的数据。可尝试输出一张图片及其标签:
Dataloader是一个可迭代的对象,它将dataset返回的每一条数据拼接成一个batch,并提供多线程加速优化和数据打乱等操作。当程序对dataset的所有数据遍历完一遍之后,相应的对Dataloader也完成了一次迭代。可尝试输出一个batch的图片及其标签:
3.2 构建网络
拷贝前文中构建的LeNet网络,因CIFAR-10是3通道彩图,修改self.conv1第一个参数为3通道即可。
3.3 训练网络
使用处理好的数据分批训练:
3.4 测试网络
首先尝试一个batch中四张图片:
然后查看测试结果:
计算全局准确率:
比随机猜测的准确率百分之十要好,说明算法是有效的。
3.5 GPU加速
如使用GPU加速,则所需添加环境:
- CUDA Toolkit V9.0
- cuDNN v7.3
具体可参考笔者的前篇博文。
在上述的代码中,只需设置use_cuda = Ture
即可。如自行设置GPU加速,需注意:
4 后记
恭喜你已经初步掌握了PyTorch
,之后便是独自修行的过程了。望诸位早日成为一名合格的“炼丹师”!