从代码进阶到原理。一步步深入 torch 的 CNN 世界。
环境介绍
- python3.6
- pytorch 1.3.1
- 不同的版本差距非常大,要注意版本
相关资料
讲述 CNN 原理
pytorch 的代码案例
从案例入手
常规 CNN 网络结构
1 | import torch |
网络结构图

我们解析这个图「MNIST」,以及中间数据的变化。
首先,输入的数据维度为 N * 1 * 32 * 32 其中 N 代表的是 batch_size。 1 代表的通道为 1「灰度图」, 32 * 32 代表一张图片的矩阵大小。第一个卷积层是 nn.Conv2d(1, 6, 5) 代表的是,输出的通道是 6 ,卷积核的大小是 5 * 5。所以,卷积之后图片的大小是 32 - 5 + 1 = 28 ,也就是数据变成了 N * 6 * 28 * 28 。最大池化为 2 * 2,经过最大池化的维度是 28 / 2 = 14 此时,数据变成了 N * 6 * 14 * 14 ,然后,第二个卷积层 nn.Conv2d(6, 16, 5) ,输出的通道是 16,卷积核的大小是 5 * 5 ,所以,卷积后的图片大小变成了 14 - 5 + 1 = 10,数据变成了 N * 16 * 10 * 10,然后最大池化是 2 * 2 ,也就是,数据维度变成了 10 / 2 = 5 ,最后数据变成了 N * 16 * 5 * 5。
此时,来到了链接层,首先把数据变成 1 维的。变成一维后,使用链接层
1 | self.fc1 = nn.Linear(16 * 5 * 5, 120) |
最后的结果是十分类。
非常规 CNN 网络结构
1 | class ConvAutoEncoder(nn.Module): |
这是一个简单的 U-Net 网络结构,我们只看前面的 encoder 环节。
首先输入的数据是 N * 1 * 4 * 300,第一个卷积层是 nn.Conv2d(1, 8, (4, 7), stride=1, padding=(0, 3)),首先,先给 input 增加 padding。根据代码,是在上下两侧分别增加 3 列,所以,原始数据变成了 N * 1 * 4 * 306,卷积核的大小是 4 * 7,步长为 1,所以,经过卷积的维度变成了 306 - 7 + 1 = 300,输出维度为 8,最后,输出的数据为 N * 8 * 1 * 300,然后最大池化 2 * 2,数据变成了 300 / 2 = 150,即数据为 N * 8 * 1 * 150,接着,第二个卷积层是 nn.Conv2d(8, 4, 3, stride=1, padding=1),首先是增加 padding,在上下左右分别增加 1 ,所以,输入的数据变成了 N * 8 * 3 * 152,其卷积核是 3 * 3 ,所以,其维度是 152 - 3 + 1 = 150,输出维度是 4,最后,数据变成了 N * 4 * 1 * 150,最大池化是 2 * 2,所以,最后数据变成了 N * 4 * 1 * 75。
关于使用的方法,可以查看