卷积神经网络组成:
- 输入层
- 卷积层
- 激活函数
- 池化层
- 全连接层
1、数据输入层
有3种常见的数据处理方式
- (1)去均值
把输入数据各个维度都中心化到0 - (2)归一化
幅度归一化到同样的范围
- (3)PCA/白化
PCA降维
白化是对数据每个特征轴上的幅度归一化
去相关与白化:
2、卷积
原始输入为三通道的彩色图片x1、x2、x3,经过核函数w1、w2的卷积,得到两个特征输出o1、o2
那如何计算输出特征的矩阵大小呢?
现有输入为7x7x1的图片,且步长为1,经过3x3x1的核函数(个数K),发现核函数在红框和绿色框中都可以移动5次,所以得到输出为5x5x1的矩阵
有以下计算公式:
设输入为长宽为w、h,stride(步长)为1,核函数为大小为f,则输出
- 长=(w - f)/s+1
- 宽=(h - f)/s+1
- 深度=K
*但步长不是任意取的,前提能够取整
卷积结果:
通过卷积,输出的矩阵长宽是越来越小的,并不能提取很高层的特征,可通过zero pading,给输入矩阵外层加0(卷积之后是没有影响的)即可保持输出与输入保持相同的大小 - 长=(w - f + 2*pad)/s+1
- 宽=(h - f + 2*pad)/s+1
f>=3,zero pad with 1
f>=5,zero pad with 2
f>=7,zero pad with 3
padding = “value”,N = [(W-F+2P)/S]+1,这里表示的是向下取整再加1
padding = “same”,N = [W/S],这里表示向上取整
权重共享:
首先了解一下权重个数的大小,现有输入为长宽为32x32x3,stride(步长)为1,核函数为大小为5x5x3,个数K=10,则输出(+pad=2)为32x32x10的矩阵,每个输出的值都是由5x5x3的核函数卷积过来的,每个值有需要有5x5x3=75个参数,则其中的参数个数:32*32*75*10=768000,参数过多容易出现过拟合且不容易进行迭代,所以有了
权重共享原则:每个值的参数都是一样的,都是75个,10层则只需要750个参数+10个b参数=760
- 每个神经元连接数据窗的权重是固定的
- 每个神经元只关注一个特性
- 一组固定的权重和不同窗口内数据做内积:卷积
3、激活函数
(1)Sigmoid函数:
- 以Sigmoid函数作为神经元的函数,且神经网络的层数很多时,根据链式法则,计算每一层参数对结果的影响,在x大于4或小于-4求导所得的值是接近1或0的,层层传递下来,所计算得的结果非常小,即w0对y的影响非常小,从而出现梯度消失
- 速度较慢
(2)RULE函数
- 易求导,且不会出现sigmoid的现象,解决了梯度消失的问题
- 当通过relu映射的值一直映射在左半部分时,会出现神经元挂掉的情况,loss不变
(3)tanh
某些情况下tanh激活函数会有意想不到的效果
4、池化
池化层(下采样):对输入卷积之后的特征再次提取,得到主要特征(深度不会改变)
MAX POOLING:对filters区域内选择最大(最明显)的数值
一搬选择2x2的filers,stride=2,得到原始大小的1/4的特征
5、全连接FC layer
在 CNN 中,全连接常出现在最后几层,用于对前面设计的特征做加权和。比如 mnist,前面的卷积和池化相当于做特征工程,后面的全连接相当于做特征加权。(卷积相当于全连接的有意弱化,按照局部视野的启发,把局部之外的弱影响直接抹为零影响;还做了一点强制,不同的局部所使用的参数居然一致。弱化使参数变少,节省计算量,又专攻局部不贪多求全;强制进一步减少参数。少即是多) 在 RNN 中,全连接用来把 embedding 空间拉到隐层空间,把隐层空间转回 label 空间等。
在CNN结构中,经多个卷积层和池化层后,连接着1个或1个以上的全连接层.与MLP类似,全连接层中的每个神经元与其前一层的所有神经元进行全连接.全连接层可以整合卷积层或者池化层中具有类别区分性的局部信息.为了提升 CNN网络性能,全连接层每个神经元的激励函数一般采用ReLU函数。最后一层全连接层的输出值被传递给一个输出,可以采用softmax逻辑回归(softmax regression)进行分类,该层也可 称为 softmax层(softmax layer).对于一个具体的分类任务,选择一个合适的损失函数是十分重要的,CNN几种常用的损失函数并分析了它们各自的特点.通 常,CNN的全连接层与MLP 结构一样,CNN的训练算法也多采用BP算法.
最后的两列小圆球就是两个全连接层,在最后一层卷积结束后,进行了最后一次池化,输出了20个12*12的图像,然后通过了一个全连接层变成了1*100的向量。
这是怎么做到的呢,其实就是有20*100个12*12的卷积核卷积出来的,对于输入的每一张图,用了一个和图像一样大小的核卷积,这样整幅图就变成了一个数了,如果厚度是20就是那20个核卷积完了之后相加求和。这样就能把一张图高度浓缩成一个数了。全连接的目的是什么呢?因为传统的网络我们的输出都是分类,也就是几个类别的概率甚至就是一个数–类别号,那么全连接层就是高度提纯的特征了,方便交给最后的分类器或者回归。
但是全连接的参数实在是太多了,你想这张图里就有20*12*12*100个参数,前面随便一层卷积,假设卷积核是7*7的,厚度是64,那也才7*7*64,所以现在的趋势是尽量避免全连接,目前主流的一个方法是全局平均值。
也就是最后那一层的feature map(最后一层卷积的输出结果),直接求平均值。有多少种分类就训练多少层,这十个数字就是对应的概率或者叫置信度。
6、结论
优点:
- 共享卷积核,优化计算量
- 无需手动选取特征,训练好权重即可得到特征
- 深层次的网络抽取图像,信息丰富,表达效果好
- 卷积层的主要优点是参数共享和稀疏连接,这使得卷积操作所需要学习的参数数量大大减少
缺点
- 需调参,大量样本,GPU的硬件依赖
- 物理含义不明确
7、Dropout
在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作,这样可以使模型泛化性更强,因为它不会太依赖某些局部的特征
上面公式中Bernoulli函数是为了生成概率r向量,也就是随机生成一个0、1的向量。
在训练时,每个神经单元以概率p被保留(dropout丢弃率为1-p);在测试阶段,每个神经单元都是存在的,权重参数w要乘以p,成为:pw。
测试时需要乘上p的原因:考虑第一隐藏层的一个神经元在dropout之前的输出是x,那么dropout之后的期望值是E=px+(1−p)0 ,在测试时该神经元总是激活,为了保持同样的输出期望值并使下一层也得到同样的结果,需要调整x→px. 其中p是Bernoulli分布(0-1分布)中值为1的概率
inverted dropout
在训练时由于舍弃了一些神经元,因此在测试时需要在激励的结果中乘上因子p进行缩放.但是这样需要需要对测试的代码进行更改并增加了测试时的计算量,非常影响测试性能。通常为了提高测试的性能(减少测试时的运算时间),可以将缩放的工作转移到训练阶段,而测试阶段与不使用dropout时相同,称为 inverted dropout :将前向传播dropout时保留下来的神经元的权重乘上1/p(看做惩罚项,使权重扩大为原来的1/p倍,这样测试时不用再缩小权重)
当模型使用了dropout layer,训练的时候只有占比为 1-p 的隐藏层单元参与训练,那么在预测的时候,如果所有的隐藏层单元都需要参与进来,则得到的结果相比训练时平均要大 1/1-p ,为了避免这种情况,就需要测试的时候将输出结果乘以 1/1-p 使下一层的输入规模保持不变。
dropout原因:
- Dropout存在两个版本:直接(不常用)和反转
- 不让神经网络记住太多东西
- 学习的过程中,保持泛化能力
- 每次都关掉一部分感知器,相当于得到一个新模型,最后做融合,类似随机森林
8、经典网络
AlexNet:
-
第一层:(1)使用了96个核函数大小为11x11,stride=4,pad=0(0填充)
分析:较大的核函数、步长,且没有pading,使得可滑动窗口变小,不利于提取特征,只是粗粒度的提取特征(2)使用了MaxPooling1
分析:特征压缩(3)NORM1(现已被证实了没有用)
-
第二层:进行了更细粒度的特征提取,使用了256个核函数,并再次pooling2
分析:前面一层经过了pooling,使得特征图变小,为了使特征能够更好的表达输入,所有需要增加特征图的个数(深度)->增加核函数个数即可增加深度
-
后面在进行3次提取特征(pading),大小不变,再次pooling3
-
最后:全连接操作:将之前提取的特征连接在一起,对这些特征进行分类,最后一层有多少个神经元,就分成多少类。
ResNet
层次很多,容易产生梯度消失,但是通过加法器将x传入若干层之后,解决了梯度消失的问题,但训练速度变慢
VGGNet:
- VGG相对于Alex模型,层数更多(19层),且核函数相对较小,为3x3,stride=1,pad=1,较小的核函数和步长能够提取更多的特征
- MaxPooling=2x2,stride=2,效果更好
- 层数并不是越多越好,越多的层数可能会降低准确率(2016CVPR-残差网络152层,使用了更少的参数)
下面是VGG-GUP所需要消耗的内存:
输入图片的内存(三通道):224*224*3
经过3*3*3的核函数(K=64,参数个数=3*3*3*64=1728),卷积之后得到224*224*64的特征图片
池化层无参数,直接滑动选择MAX
。。。
到了全连接层,前面一通操作,得到的是7*7*512的特征图片,全连接层的神经元需要与全部的特征图片相连,得到7*7*512*4096=102760448
.。。。
将内存*字节数4bytes=每张图片需要消耗的内存93M,然后根据
GPU所能容纳的内存>bitch数*93M