cs231n study note 2
一. 学习内容
- 前馈神经网络 Feedforward Neural Network
- 卷积神经网络 Convolutional Neural Network
- 激活函数 Activation Function
1. 前馈神经网络
这里用depth只有1的灰度图来举例。 想要完成的任务是:在宽长为4x4的图片中识别是否有下图所示的“横折”。 图中,黄色圆点表示值为0的像素,深色圆点表示值为1的像素。 我们知道不管这个横折在图片中的什么位置,都会被认为是相同的横折。

若训练前馈神经网络来完成该任务,那么表达图像的三维张量将会被摊平成一个向量,作为网络的输入,即(width, height, depth)为(4, 4, 1)的图片会被展成维度为16的向量作为网络的输入层。再经过几层不同节点个数的隐藏层,最终输出两个节点,分别表示“有横折的概率”和“没有横折的概率”,如下图所示。
下面我们用数字(16进制)对图片中的每一个像素点(pixel)进行编号。 当使用右侧那种物体位于中间的训练数据来训练网络时,网络就只会对编号为5,6,9,a的节点的权重进行调节。 若让该网络识别位于右下角的“横折”时,则无法识别。
解决办法是用大量物体位于不同位置的数据训练,同时增加网络的隐藏层个数从而扩大网络学习这些变体的能力。
然而这样做十分不效率,因为我们知道在左侧的“横折”也好,还是在右侧的“横折”也罢,大家都是“横折”。 为什么相同的东西在位置变了之后要重新学习?有没有什么方法可以将中间所学到的规律也运用在其他的位置? 换句话说,也就是让不同位置用相同的权重。
2. 卷积神经网络
卷积神经网络就是让权重在不同位置共享的神经网络。
###局部连接
在卷积神经网络中,我们先选择一个局部区域,用这个局部区域去扫描整张图片。 局部区域所圈起来的所有节点会被连接到下一层的一个节点上。
为了更好的和前馈神经网络做比较,我将这些以矩阵排列的节点展成了向量。 下图展示了被红色方框所圈中编号为0,1,4,5的节点是如何通过 
这个带有连接强弱的红色方框就叫做 filter 或 kernel 或 feature detector。 而filter的范围叫做filter size,这里所展示的是2x2的filter size。
第二层的节点0的数值就是局部区域的线性组合,即被圈中节点的数值乘以对应的权重后相加。 用
注:在局部区域的线性组合后,也会和前馈神经网络一样,加上一个偏移量
空间共享
当filter扫到其他位置计算输出节点
下面这张动态图展示了当filter扫过不同区域时,节点的链接方式。 动态图的最后一帧则显示了所有连接。 可以注意到,每个输出节点并非像前馈神经网络中那样与全部的输入节点连接,而是部分连接。 这也就是为什么大家也叫前馈神经网络(feedforward neural network)为fully-connected neural network。 图中显示的是一步一步的移动filter来扫描全图,一次移动多少叫做stride。
空间共享也就是卷积神经网络所引入的先验知识。
输出表达
如先前在图像表达中提到的,图片不用向量去表示是为了保留图片平面结构的信息。 同样的,卷积后的输出若用上图的排列方式则丢失了平面结构信息。 所以我们依然用矩阵的方式排列它们,就得到了下图所展示的连接。
这也就是你们在网上所看到的下面这张图。在看这张图的时候请结合上图的连接一起理解,即输入(绿色)的每九个节点连接到输出(粉红色)的一个节点上的。
经过一个feature detector计算后得到的粉红色区域也叫做一个“Convolved Feature” 或 “Activation Map” 或 “Feature Map”。
Depth维的处理
现在我们已经知道了depth维度只有1的灰度图是如何处理的。 但前文提过,图片的普遍表达方式是下图这样有3个channels的RGB颜色模型。 当depth为复数的时候,每个feature detector是如何卷积的?
现象:2x2所表达的filter size中,一个2表示width维上的局部连接数,另一个2表示height维上的局部连接数,并却没有depth维上的局部连接数,是因为depth维上并非局部,而是全部连接的。
在2D卷积中,filter在张量的width维, height维上是局部连接,在depth维上是贯串全部channels的。
类比:想象在切蛋糕的时候,不管这个蛋糕有多少层,通常大家都会一刀切到底,但是在长和宽这两个维上是局部切割。
下面这张图展示了,在depth为复数时,filter是如何连接输入节点到输出节点的。 图中红、绿、蓝颜色的节点表示3个channels。 黄色节点表示一个feature detector卷积后得到的Feature Map。 其中被透明黑框圈中的12个节点会被连接到黄黑色的节点上。
- 在输入depth为1时:被filter size为2x2所圈中的4个输入节点连接到1个输出节点上。
- 在输入depth为3时:被filter size为2x2,但是贯串3个channels后,所圈中的12个输入节点连接到1个输出节点上。
- 在输入depth为n时:2x2xn个输入节点连接到1个输出节点上。

注意: 三个channels的权重并不共享。 即当深度变为3后,权重也跟着扩增到了三组,如式子(3)所示,不同channels用的是自己的权重。 式子中增加的角标r,g,b分别表示red channel, green channel, blue channel的权重。
计算例子:用 Xr0 表示red channel的编号为0的输入结点, Xg5表示green channel的编号为5的输入结点, Xb1表示blue channel. 如式子(4)所表达, 这时的一个输出结点实际上是12个输入结点的线性组合.
当filter扫到其他位置计算输出节点y_i时,那12个权重在不同位置是共用的,如下面的动态图所展示。 透明黑框圈中的12个节点会连接到被白色边框选中的黄色节点上。
Zero padding
4x4的图片被2x2的filter卷积后变成了3x3的图片,每次卷积后都会小一圈的话,经过若干层后岂不是变的越来越小? Zero padding就可以在这时帮助控制Feature Map的输出尺寸,同时避免了边缘信息被一步步舍弃的问题。
例如:下面4x4的图片在边缘Zero padding一圈后,再用3x3的filter卷积后,得到的Feature Map尺寸依然是4x4不变。
通常大家都想要在卷积时保持图片的原始尺寸。 选择3x3的filter和1的zero padding,或5x5的filter和2的zero padding可以保持图片的原始尺寸。 这也是为什么大家多选择3x3和5x5的filter的原因。 另一个原因是3x3的filter考虑到了像素与其距离为1以内的所有其他像素的关系,而5x5则是考虑像素与其距离为2以内的所有其他像素的关系。
尺寸:Feature Map的尺寸等于(input_size + 2 * padding_size − filter_size)/stride+1。
注意:上面的式子是计算width或height一维的。padding_size也表示的是单边补零的个数。例如(4+2-3)/1+1 = 4,保持原尺寸。
不用背这个式子。其中(input_size + 2 * padding_size)是经过Zero padding扩充后真正要卷积的尺寸。 减去 filter_size后表示可以滑动的范围。 再除以可以一次滑动(stride)多少后得到滑动了多少次,也就意味着得到了多少个输出节点。 再加上第一个不需要滑动也存在的输出节点后就是最后的尺寸。
形状、概念抓取
知道了每个filter在做什么之后,我们再来思考这样的一个filter会抓取到什么样的信息。
我们知道不同的形状都可由细小的“零件”组合而成的。比如下图中,用2x2的范围所形成的16种形状可以组合成格式各样的“更大”形状。
卷积的每个filter可以探测特定的形状。又由于Feature Map保持了抓取后的空间结构。若将探测到细小图形的Feature Map作为新的输入再次卷积后,则可以由此探测到“更大”的形状概念。 比如下图的第一个“大”形状可由2,3,4,5基础形状拼成。第二个可由2,4,5,6组成。第三个可由6,1组成。
除了基础形状之外,颜色、对比度等概念对画面的识别结果也有影响。卷积层也会根据需要去探测特定的概念。
可以从下面这张图中感受到不同数值的filters所卷积过后的Feature Map可以探测边缘,棱角,模糊,突出等概念。
如我们先前所提,图片被识别成什么不仅仅取决于图片本身,还取决于图片是如何被观察的。
而filter内的权重矩阵W是网络根据数据学习得到的,也就是说,我们让神经网络自己学习以什么样的方式去观察图片。
拿老妇与少女的那幅图片举例,当标签是少女时,卷积网络就会学习抓取可以成少女的形状、概念。 当标签是老妇时,卷积网络就会学习抓取可以成老妇的形状、概念。
下图展现了在人脸识别中经过层层的卷积后,所能够探测的形状、概念也变得越来越抽象和复杂。
卷积神经网络会尽可能寻找最能解释训练数据的抓取方式。
多filters
每个filter可以抓取探测特定的形状的存在。 假如我们要探测下图的长方框形状时,可以用4个filters去探测4个基础“零件”。
因此我们自然而然的会选择用多个不同的filters对同一个图片进行多次抓取。 如下图(动态图过大,如果显示不出,请看到该链接观看),同一个图片,经过两个(红色、绿色)不同的filters扫描过后可得到不同特点的Feature Maps。 每增加一个filter,就意味着你想让网络多抓取一个特征。
这样卷积层的输出也不再是depth为1的一个平面,而是和输入一样是depth为复数的长方体。
如下图所示,当我们增加一个filter(紫色表示)后,就又可以得到一个Feature Map。 将不同filters所卷积得到的Feature Maps按顺序堆叠后,就得到了一个卷积层的最终输出。
卷积层的输入是长方体,输出也是长方体。
这样卷积后输出的长方体可以作为新的输入送入另一个卷积层中处理。
加入非线性
和前馈神经网络一样,经过线性组合和偏移后,会加入非线性增强模型的拟合能力。
将卷积所得的Feature Map经过ReLU变换(elementwise)后所得到的output就如下图所展示。
输出长方体
现在我们知道了一个卷积层的输出也是一个长方体。 那么这个输出长方体的(width, height, depth)由哪些因素决定和控制。
这里直接用CS231n的Summary:
计算例子:参见CS231n的Convolution Demo部分的演示。
矩阵乘法执行卷积
如果按常规以扫描的方式一步步计算局部节点和filter的权重的点乘,则不能高效的利用GPU的并行能力。 所以更普遍的方法是用两个大矩阵的乘法来一次性囊括所有计算。
因为卷积层的每个输出节点都是由若干个输入节点的线性组合所计算。 因为输出的节点个数是
读过我写的线性代数教程的读者请回忆,矩阵乘矩阵的意义可以理解为批量的线性组合按顺序排列。 其中一个矩阵所表示的信息是多组权重,另一个矩阵所表示的信息是需要进行组合的向量。 大家习惯性的把组成成分放在矩阵乘法的右边,而把权重放在矩阵乘法的左边。 所以这个大型矩阵乘法可以用
表示,其中二者都是矩阵。
卷积的每个输出是由局部的输入节点和对应的filter权重展成向量后所计算的,如式子(2)。 那么W_{row}中的每一行则是每个filter的权重,有F\cdot F \cdot D_1个; 而X_{col}的每一列是所有需要进行组合的节点(上面的动态图中被黑色透明框圈中的节点),也有F\cdot F \cdot D_1个。 X_{col}的列的个数则表示每个filter要滑动多少次才可以把整个图片扫描完,有W_2\cdot H_2次。 因为我们有多个filters,W_{row}的行的个数则是filter的个数K。
最后我们得到:
当然矩阵乘法后需要将
整理成形状为
的三维张量以供后续处理(如再送入另一个卷积层)。
则也需要逐步的局部滑动图片,最后堆叠构成用于计算矩阵乘法的形式。
Max pooling
在卷积后还会有一个pooling的操作,尽管有其他的比如average pooling等,这里只提max pooling。
max pooling的操作如下图所示:整个图片被不重叠的分割成若干个同样大小的小块(pooling size)。每个小块内只取最大的数字,再舍弃其他节点后,保持原有的平面结构得出output。
max pooling在不同的depth上是分开执行的,且不需要参数控制。 那么问题就max pooling有什么作用?部分信息被舍弃后难道没有影响吗?
Max pooling的主要功能是downsamping,却不会损坏识别结果。 这意味着卷积后的Feature Map中有对于识别物体不必要的冗余信息。 那么我们就反过来思考,这些“冗余”信息是如何产生的。
直觉上,我们为了探测到某个特定形状的存在,用一个filter对整个图片进行逐步扫描。但只有出现了该特定形状的区域所卷积获得的输出才是真正有用的,用该filter卷积其他区域得出的数值就可能对该形状是否存在的判定影响较小。 比如下图中,我们还是考虑探测“横折”这个形状。 卷积后得到3x3的Feature Map中,真正有用的就是数字为3的那个节点,其余数值对于这个任务而言都是无关的。 所以用3x3的Max pooling后,并没有对“横折”的探测产生影响。 试想在这里例子中如果不使用Max pooling,而让网络自己去学习。 网络也会去学习与Max pooling近似效果的权重。因为是近似效果,增加了更多的parameters的代价,却还不如直接进行Max pooling。
Max pooling还有类似“选择句”的功能。假如有两个节点,其中第一个节点会在某些输入情况下最大,那么网络就只在这个节点上流通信息;而另一些输入又会让第二个节点的值最大,那么网络就转而走这个节点的分支。
但是Max pooling也有不好的地方。因为并非所有的抓取都像上图的例子。有些周边信息对某个概念是否存在的判定也有影响。 并且Max pooling是对所有的Feature Maps进行等价的操作。就好比用相同网孔的渔网打鱼,一定会有漏网之鱼。
全连接层
当抓取到足以用来识别图片的特征后,接下来的就是如何进行分类。 全连接层(也叫前馈层)就可以用来将最后的输出映射到线性可分的空间。 通常卷积网络的最后会将末端得到的长方体平摊(flatten)成一个长长的向量,并送入全连接层配合输出层进行分类。
卷积神经网络大致就是covolutional layer, pooling layer, ReLu layer, fully-connected layer的组合,例如下图所示的结构。
这里也体现了深层神经网络或deep learning之所以称deep的一个原因:模型将特征抓取层和分类层合在了一起。 负责特征抓取的卷积层主要是用来学习“如何观察”。
下图简述了机器学习的发展,从最初的人工定义特征再放入分类器的方法,到让机器自己学习特征,再到如今尽量减少人为干涉的deep learning。
结构发展
以上介绍了卷积神经网络的基本概念。 以下是几个比较有名的卷积神经网络结构
- LeNet:第一个成功的卷积神经网络应用
- AlexNet:类似LeNet,但更深更大。使用了层叠的卷积层来抓取特征(通常是一个卷积层马上一个max pooling层)
- ZF Net:增加了中间卷积层的尺寸,让第一层的stride和filter size更小。
- GoogLeNet:减少parameters数量,最后一层用max pooling层代替了全连接层,更重要的是Inception-v4模块的使用。
- VGGNet:只使用3x3 卷积层和2x2 pooling层从头到尾堆叠。
- ResNet:引入了跨层连接和batch normalization。
- DenseNet:将跨层连接从头进行到尾
总结一下:这些结构的发展趋势有:
- 使用small filter size的卷积层和pooling
- 去掉parameters过多的全连接层
- Inception(稍后会对其中的细节进行说明)
- 跳层连接
3. 激活函数
激活函数通常有如下一些性质:
非线性: 当激活函数是线性的时候,一个两层的神经网络就可以逼近基本上所有的函数了。但是,如果激活函数是恒等激活函数的时候(即f(x)=x),就不满足这个性质了,而且如果MLP使用的是恒等激活函数,那么其实整个网络跟单层神经网络是等价的。
可微性: 当优化方法是基于梯度的时候,这个性质是必须的。
**单调性: **当激活函数是单调的时候,单层网络能够保证是凸函数。
f(x)≈x: 当激活函数满足这个性质的时候,如果参数的初始化是random的很小的值,那么神经网络的训练将会很高效;如果不满足这个性质,那么就需要很用心的去设置初始值。
输出值的范围: 当激活函数输出值是 有限 的时候,基于梯度的优化方法会更加 稳定,因为特征的表示受有限权值的影响更显著;当激活函数的输出是 无限 的时候,模型的训练会更加高效,不过在这种情况小,一般需要更小的learning rate.
Sigmoid

ReLU

二. 工作相关
遗传算法
- 遗传算法与机器学习-不确定性优化
- 遗传算法原理简述
- 遗传算法解决机器视觉问题
- 遗传算法缺点与局限性