CNN卷积神经网络
CNN属于网络架构的一种,其一般被用于影像领域。
如何去做图像分类
图片在计算机中的存储通常是以3维张量来进行的。例如一张图片是100像素*100像素,每个像素由RGB3个channel组成(这个数值代表这个颜色的强度);那么要表示这张图片就需要个数据。我们将这些数据做成应该向量作为神经网络的输入。
那么就会面临一个问题:例如第一层的神经元共1000个,输入向量为个,那么光第一层所需要的weight数量就高达个,这样会拖慢训练进度,还容易造成过拟合。
因此我们需要进行优化:
-
和人眼一样,图片分类时机器也只需要关注这张图片中最关键的部分就可以了。因此每个神经元的输入不需要是完整的图片。
我们为每个神经元分配一个Receptive field,该神经元只需要输入该Receptive field中的数据即可。Receptive field之间可以重叠,甚至可以多个神经元共用一个Receptive field。
在设计Receptive field时,其可以有不同的大小(不一定要是的,的都行);可以只看一个channel(比如只看RED);也可以是长方形;甚至不相连都行,关键是要看图片是啥样的,图片的关键在哪里。
经典的设计方法是这样的:
-
使用全部的channel,field大小一般取正方形(比如)
-
每个Receptive field对应多个神经元(例如64个、128个这种)
-
每两个Receptive field间有重叠部分,以最左上角的Receptive field为基准,向右或向下移动stride个单位(stride一般取1或2,也是一个超参数)。如此以保证当图像特征出现在中间时能有神经元关注这一块。
-
由于是,所以肯定会有突出的几块,这些采用padding进行处理,例如取0、取平均这种
-
-
对不同的图片而言,虽然是相同的特征,但是该特征分布在两张图片的不同位置,而这两种位置会对应两组不同的神经元。这两组神经元的参数是相似的,因此可以进行参数共享来减小总参数量。
上图中的两个神经元,其weight参数完全一样。
当然,如果Receptive field相同的神经元之间没必要共享参数,因为那样搞的话输出都是一样的了。
经典的设计方法是这样的:
这里颜色相同的神经元代表共享参数的神经元,依次记作filter xx这样子。
CNN的训练流程是什么样的?

Convolution卷积层:假设我们已经通过梯度下降得到了每一个神经元filter的权重。然后将filter的权重与图片数据各项相乘并相加。

在上图中,filter的斜线上全是1,就代表在图片上扫的时候,碰到同样的形状时,产生的值最大。
然后,对于每一个filter都搞相同的操作:

上图中,有几个filter就代表会有多少层这样的结果数据。我们把这些结果数据称为Feather Map。假设我们这一层卷积层有64个神经元,那么产生的Feather Map就会有64个channel,我们可以把这个Feather Map也看作是一个“图片”。
我们可以把这个Feather Map再扔进新的卷积层中,让这个新“图片”再和新的filter作用,注意这里的filter的channel数应该与Feather Map的channel数相同。
Pooling层:我们对原来的图片进行抽样,例如取图片中所有的偶数行、奇数列这样子,图片大小变为原来的,但是并不会影响识别结果。
在做Pooling时,我们会将由每一个filter产生的数字几个几个分组:

然后我们就需要在每个分组中选一个“代表”来表示这一组。以Max Pooling这种方法为例,就会取每个分组中的最大值(当然也会有Average Pooling、Min Pooling这种)

我们通常会在卷积层后使用Pooling(交替使用),可以缩小处理数据的大小:

当然,Pooling会造成信息损失,并不是必要的。如果要侦测微小的特征或者算力够够,不加Pooling是应该的。
HM3
Medium
首先给训练管道加上了数据增强操作(这里要注意不能增强过度),然后将训练epoch加了一点。
1 | train_tfm = transforms.Compose( |