斯坦福CS231n课程确实很好,学了有两三遍,每次都有不一样的收获,理解的也更深刻。这里把自己觉得重要的东西记录下来,以加深印象,同时便于查阅。CS211n简书笔记链接:https://www.jianshu.com/p/182baeb82c71
卷积神经网络依旧是一个可导的评分函数,该函数输入为原始图像像素,输出是不同类别的评分。并假设输入数据是图像,基于该假设,向结构中添加一些特有性质。常规神经网络的输入是一个向量,对大尺寸图像效果不好,效率低下,大量参数导致网络过拟合。
神经元的各层三维排列:宽度,高度和深度(深度是指激活函数数据体的第3个维度,不是整个网络深度,整个网络深度指网络层数)。例如:CIFAR-10,32x32x3(宽度,高度,深度)。层中神经元只有前一层中的一小块区域连接,不是全连接。神经元排列形式实质上为数据的结构大小,连接线强度才是权重参数。卷积神经网络由层组成,每一层有一个简单的API:用一些含或者不含参数的可导函数,将输入的3D数据变换为3D的输出函数。普通神经网络与卷积神经网络:
用来构建卷积神经网络的各种层:
卷积神经网络中每个层使用一个可微风函数将激活数据从一个层传递到另一个层,主要包含:卷积层(convolution)、汇聚层(pooling)和全连接层(和常规网络相同)。例如对于CIFAR-10输入,形式可以为[输入层-卷积层-ReLU层-汇聚层-全连接层],32x32x3输入,卷积层中神经元与输入层一个局部区域相连,每个神经元都计算自己与输入层相连的小区域与自己权重的内积。卷积层计算所有神经元输出,若采用12个滤波器(核),输出为[32x32x12]。
ReLU层对逐个元素进行激活函数操作,如max(0,x),该层对数据尺寸没有改变,还是[32x32x12]。
汇聚层在空间维度(宽和高)上进行降采样(downsampling),如采用2x2尺寸为[16x16x12]。
卷积层和全连接层(CONV/FC)对输入执行变换时,不仅用到激活函数,还会用到很多参数(W,b),ReLU层和汇聚层进行固定不变的函数操作。ReLU层没有超参数,其他3层有。
卷积层(核心层):
卷积层的参数是由一些可学习的滤波器集合构成的,每个滤波器在空间上(宽和高)都比较小,深度与输入数据一致。如卷积神经网络第一层一个典型的滤波器尺寸可以是5x5x3,在前向传播时,让每个滤波器在输入数据的宽和高上滑动(卷积),计算整个滤波器和输入数据任一处的内积。生成一个2维激活图(activation map),激活图给出了在每个空间位置处滤波器的反应(网络会让滤波器学习到当它看到某些类型的视觉特性时就激活,如某些颜色斑点,车轮状图案等)。
每个卷积层上,有一整个集合的滤波器(如12个),每个都会生成一个不同的二维激活图,深度方向上层叠起来就生成了输出数据。3D数据中的每个数据项看成神经元的一个输出,且该神经元只观察输入数据中的一小部分,和空间上左右两边所有神经元共享参数(因为这些数字都是使用同一个滤波器得到的)。
局部连接:每个神经元只与输入数据的一个局部区域连接,该连接空间大小叫做神经元的感受野(receptive field),其尺寸为超参数,即滤波器的空间尺寸。在深度方向上的多个神经元,感受野大小相同,但权重不同。单个神经元保持不变,仍是计算权重和输入内积,然后进行激活函数(在ReLU层做激活),只是被限制在一个局部空间。
神经元空间排列:3个超参数:深度(depth),步长(stride),零填充(zero-padding)。
深度:与滤波器数量一致,沿深度方向排列,感受野相同的神经元集合称为深度列(depth column)。
步长:滤波器每次移动像素数,会让输出数据体在空间上变小。
零填充:用来保持输入数据体在空间上的尺寸,保证宽高相等。
输出数据体的空间尺寸为:(W-F+2P)/S+1 其中W为输入数据体尺寸(假设为正方形),F为神经元感受野尺寸,S为步长,P为零填充。当步长S为1时,零填充的值是P=(F-1)/2,可以保证输入输出空间尺寸相同,注意这些空间排列的超参数之间是相互限制的。
参数共享:如果一个特征在计算某个空间位置(x,y)的时候有用,那么它在计算另一个不同位置(x2,y2)的时候也有用。深度切片共享参数,反向传播时,需计算每个神经元对它权重的梯度,把同一个深度切片上所有神经元对权重的梯度累加,得到对共享权重的梯度。权重集合称为滤波器(filter)或卷积核(kernel)。
当卷积神经网络的输入图像是一些明确的中心结构时,参数共享假设可能没有意义。此时期望在图片的不同位置学习到完全不同的特征,如人脸,希望不同特征,如眼睛,头发在不同位置被学习。此时可以通过放松参数共享限制,将层称为局部连接层。
小节 卷积层性质:
输入数据体尺寸为:W1xH1xD1, 4个超参数:滤波器数量K,滤波器空间尺寸F,步长S,零填充P。
输出数据体尺寸为:W2xH2xD2,其中W2=(W1-F+2P)/S+1;H2=(H1-F+2P)/S+1(宽度和高度计算方法相同);D2=K。
由于滤波器参数共享,每个滤波器包含F•F•D1个权重,卷积层共有F•F•D1•K个权重和K个偏置。
超参数常见设置F=3,S=1,P=1。
用矩阵乘法实现:卷积运算本质上是在滤波器和输入的局部区域间做点积,利用这点,将前向传播变成一个巨大的矩阵乘法。
1.输入图像的局部区域被im2col操作拉伸为列。比如,如果输入是[227x227x3],要与尺寸为11x11x3的滤波器以步长为4进行卷积,就取输入中的[11x11x3]数据块,然后将其拉伸为长度为11x11x3=363的列向量。重复进行这一过程,因为步长为4,所以输出的宽高为(227-11)/4+1=55,所以得到im2col操作的输出矩阵X_col的尺寸是[363x3025],其中每列是拉伸的感受野,共有55x55=3,025个。注意因为感受野之间有重叠,所以输入数据体中的数字在不同的列中可能有重复。
2.卷积层的权重也同样被拉伸成行。举例,如果有96个尺寸为[11x11x3]的滤波器,就生成一个矩阵W_row,尺寸为[96x363]。
3.现在卷积的结果和进行一个大矩阵乘np.dot(W_row, X_col)是等价的了,能得到每个滤波器和每个感受野间的点积。在我们的例子中,这个操作的输出是[96x3025],给出了每个滤波器在每个位置的点积输出。
4.果最后必须被重新变为合理的输出尺寸[55x55x96]。
优点:举证乘法实现高效;缺点:占内存。
反向传播:卷积的反向传播(同时对于数量和权重)还是卷积(但是是空间上翻转的滤波器)。
汇聚层:
通常,在连续的卷积层之间会周期性地插入一个汇聚层。它的作用是逐渐降低数据体的空间尺寸,这样的话就能减少网络中参数的数量,使得计算资源耗费变少,也能有效控制过拟合。汇聚层使用MAX操作,对输入数据体的每一个深度切片独立进行操作,改变它的空间尺寸。最常见的形式是汇聚层使用尺寸2x2的滤波器,以步长为2来对每个深度切片进行降采样,将其中75%的激活信息都丢掉,深度不变。
MAX操作是从4个数字中取最大值(也就是在深度切片中某个2x2的区域),公式为:
输入数据体尺寸,有两个超参数:空间大小,步长S
输出数据体尺寸,其中:
在实践中,最大汇聚层通常只有两种形式:一种是,也叫重叠汇聚(overlapping pooling),另一个更常用的是。对更大感受野进行汇聚需要的汇聚尺寸也更大,而且往往对网络有破坏性。
反向传播:max(x,y)函数将梯度沿着最大数回传,在前向传播时,通常把最大元素索引记录下来(也叫道岔)。
也可在卷积层中使用更大步长来降低数据尺寸,不采用汇聚层。
全连接层:
与常规神经网络一样。全连接层和卷积层唯一不同就是卷积层中的神经元只与输入数据中的一个局部区域连接,且在卷积列中的神经元共享参数,故两者可相互转化。如全连接层→卷积层:将滤波器尺寸设置为和输入数据体尺寸一致。
卷积层神经网络的结构:
卷积神经网络最常见的形式就是将一些卷积层和ReLU层放在一起,其后紧跟汇聚层,然后重复如此直到图像在空间上被缩小到一个足够小的尺寸,在某个地方过渡成成全连接层也较为常见。最后的全连接层得到输出,比如分类评分等。换句话说,最常见的卷积神经网络结构如下:
INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC
其中*指的是重复次数,POOL?指的是一个可选的汇聚层。其中N >=0,通常N<=3,M>=0,K>=0,通常K<3。例如:
INPUT -> FC,实现一个线性分类器,此处N = M = K = 0
在执行具有破坏性的汇聚操作前,多重的卷积层可以从输入数据中学习到更多的复杂特征。
几个小滤波器卷积层的组合比一个大滤波器卷积层好。多层比单一层结构更能提取出深层的更好特征,参数也较少。缺点:反向传播时,中间卷积层导致占用内存多。
层的尺寸设置规律:
输入层(包含图像的)应该能被2整除很多次。
卷积层应该使用小尺寸滤波器(比如3x3或最多5x5),零填充保证尺寸不变,一般采用步长为1。
汇聚层负责对输入数据的空间维度进行降采样。最常用的设置是用用2x2感受野(即)的最大值汇聚,最大值汇聚感受野尺寸很少超过3,因为汇聚激烈,易造成数据信息丢失。
因为内存限制,通常在第一个卷积层做出妥协(如步长为2,7x7的滤波器来减少尺寸)。
常见卷积网络结构:
LeNet,AlexNet,GoogLeNet,VGGNet,ResNet等。注意,大部分内存和计算时间都被前面卷积占用,大部分参数都用在后面的全连接层。
占用内存来源:
(1)来自中间数据体尺寸:卷积神经网络中的每一层中都有激活数据体的原始数值,以及损失函数对它们的梯度(和激活数据体尺寸一致)。通常,大部分激活数据都是在网络中靠前的层中(比如第一个卷积层)。在训练时,这些数据需要放在内存中,因为反向传播的时候还会用到。但是在测试时可以聪明点:让网络在测试运行时候每层都只存储当前的激活数据,然后丢弃前面层的激活数据,这样就能减少巨大的激活数据量;
(2)来自参数尺寸:即整个网络的参数的数量,在反向传播时它们的梯度值,以及使用momentum、Adagrad或RMSProp等方法进行最优化时的每一步计算缓存。因此,存储参数向量的内存通常需要在参数向量的容量基础上乘以3或者更多;
(3)卷积神经网络实现还有各种零散的内存占用,比如成批的训练数据,扩充的数据等。
常用方法是降低批尺寸(batch size),因为绝大多数内存被激活数据消耗了。