从上篇文章,我们分析通过Pytorch 封装的各种方法,解读了一遍图片识别训练到测试的流程。
这篇我们从理论上,理解下,图片是如何被识别的?
核心需要理解的内容有?
- 一张图片,如何被计算机读懂?
- pytorch 封装的网络,什么是卷积层,为什么要多层?层与层如何衔接?如何设计?
- 什么是池化?为什么要池化?
- 什么是全链接层?它有什么作用?
- 神经网络模型的前向传播?这个步骤的作用是什么?
- 什么梯度下降?梯度下降的价值?
- 什么是激活函数?为什么要用激活函数?
带着问题,我们找个教程看看:
一、初识图片识别过程
我们先理解上图,再结合我们自己的例子加深下理解。
MNIST上,下载的手写训练数字数据,也跟上面的INPUT一样,是一个28*28像素的图片
整个图片处理过程:
INPUT--》Conv_1--》Max-Pooling(1) --》Conv_2 --》Max-Pooling(2) -》全链接(full connected ReLU激活函数)-》全连接(with dropout)--》得出(0~9)每个数的概率值
Conv_1
没有经过padding(补充)、Stride(移动步长) 为1,n1 个通道(可以理解为特征,彩色图片,一般为RGB,3个通道),卷积核为5*5,也就就是INPUT中虚线的格子,经过从到右(每次格子移动1个像素),经过卷积层后,单通道变为了n1@24*24,即n1个图片大小为24*24 的图片(如下计算),
Max-Pooling(1)
max-pooling 2*2 可以理解为一个长*宽 为2的格子(如 n1 channels 24*24中的格子图);
把4(2*2)个像素的格子,经过平均/最大值计算,n1*24*24, 池化后,长24/2后为12,即变为第三幅图(n1 channels 12*12*n1)
Conv_2
没有经过padding(补充)、Stride(移动步长) 为1,n2 个通道,卷积核为5*5,
卷积后大小为: (12-5+2*0)/1 +1 = 8,经过 卷积层conv_2 ,n2@8*8
Max-Pooling(2)
max-pooling 2*2 可以理解为一个长*宽 为2的格子,池化后变为 n2@4*4;
fc_3 Full Connected
输入为:n2@4*4 ,把特征图展平,为n2个16个一维的向量(数组)
ReLU activation ReLU激活函数 ReLU(x)=max(0,x),即小于0为的经过函数,输出为0,大于0的,为数本身。
fc_4 Full Connected
(提到了Dropout ,补充到附录了,先不了解也没啥问题)
要把10个数字,最终拿到每个数字的概率值,那这层输出层通道数必须为10,且数据要控制在概率和为1。
所以这里应该会经过这么个环节的,pytorch中,criterion = nn.CrossEntropyLoss()
【nn.CrossEntropyLoss
在内部会自动应用 Softmax 激活函数,所以你只需将 logits(模型输出)和标签传递给它。】
我们解读了手写图片,经过神经网络后,输出的概率过程,接下来,我们结合我们自己的程序分析一下。
二、理解我们的程序网络
回顾我们代码如下:
输入为:28*28的原始图片
conv1
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)
定义一个神经网络层conv1,该层特点:2维的 输入为1个通道、输出为32个通道,卷积核为3*3,步长为1,补充为1
长=(28-3+2*1)/1 + 1 = 28,
即根据公式,经过conv1 后特征图为:32@ 28*28 ,特征图大小没变
conv2
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
定义一个神经网络层conv2,该层特点,conv1要衔接conv2,那么conv1的输出,是conv2的输入,即conv2的输入也为32.
卷积层conv2,为2维的,输入为32,输出为64 通道,卷积核为3,步长为1,补充为1
即根据公式,经过conv2后特征图为:64@ 28*28 ,特征图大小没变
Max-pooling
self.pool = nn.MaxPool2d(2, 2)
定义了池化,max pool 把4个像素中最大的标量,作为最终一个像素的标量值;还有一个常见的平均池化,即4个像素相加的平均值,作为最终一个像素的标量。
fc1
self.fc1 = nn.Linear(64 * 7 * 7, 128)
定义一个全连接层fc1,输入为64*7*7,即conv2后64*28*28,需要经过2次池化操作;输出为128
fc2
self.fc2 = nn.Linear(128, 10)
定义一个全链接层fc2,输入是fc1的输出大小,128,输出是10,即输出10个数字的概率值
OK,这篇先到这,我们理解了我们的网络如何连接的,下篇分析如何训练。
附录:
fc_3 Full Connected 图中提到了dropout,它是啥?
即防止过拟合问题,啥是过拟合,后面再补,如果dropout 比例为0.5,经过 ReLU 激活后,得到的 24*24 特征图在应用 Dropout 后,尺寸保持不变,仍然是 24×24,但激活值中大约有一半的值会被置为 0)