有空还是多看看CS231n,里面学生问的问题其实跟面试官问的问题大差不差,挺有意思的
Neural Network
常用的激活函数
CNN
卷积和池化
cnn中卷积层的前几层一般代表了一些低阶的图像特征(边缘),中间层可以得到一些边角和斑点的特征
S
i
z
e
o
u
t
p
u
t
=
(
S
i
z
e
i
n
p
u
t
−
S
i
z
e
k
e
r
n
e
l
+
2
×
p
a
d
d
i
n
g
)
/
s
t
r
i
d
e
+
1
Size_{output}=(Size_{input}-Size_{kernel}+2 \times padding)/stride+1
Sizeoutput=(Sizeinput−Sizekernel+2×padding)/stride+1
池化:
1、特征不变性,汇合操作使模型更加关注是否存在某些特征而不是特征具体的位置,可以看做是一种很强的先验,是特征学习包含某种程度自由度,能容忍一些特征微小的位移。
2、特征降维。类似于做了维度约减,使模型可以抽取更广泛围的特征,减小了下一层输入大小,进而减小计算量和参数个数。
3、在一定程度防止过拟合,更方便优化。
最大池化:图像中的部分在该卷积核下的激发程度,我们更愿意找出在该部分下被激发最大的块
所以说最大池化用的最多
池化的作用:降采样
池化层没有参数…不要被诈了
激活函数的选择
sigmoid/tanh:当输入值很大或者很小的时候,使用链式求导法则会出现梯度=0的情况,称作梯度消失,此外sigmoid还有一个问题在于他全是正的,这样就造成了如果输入的x全是正数的画,每次更新得到的 ω \omega ω要么都增大,要么都减小,这对于参数更新不利,这也是为什么每次在设置初始值的时候,要使得x有正有负,符合均值为0的Gauss分布
relu:正数时不会出现梯度消失的现象,而且相对于sigmoid更容易收敛,relu缺点在于当x为负值会出现梯度消失的现象,神经元死亡,不会更新,当使用学习率不会动态更新的优化算法更新的时候,随着学习的深入,当值为负的时候,就会出现梯度小时
ELU:与leaky relu相比没有在负区间倾斜
激活函数的选择:
- 通常用relu
- 可以试试leaky relu/Maxout/ELU
- 试试tanh,随便试试
- 不要用sigmoid
归一化
当输入项全是正的时候,就会导致参数值同时上升或者同时下降,不利于收敛,因此考虑使用0-1归一化
还有一种解释,看一下上图,如果说没有做归一化,虽然直线也能够正确分类,但是稍微转动一点点就不可以了,做了归一化,稍微转动一点点也可以,我们可以说做了归一化的数据使得他对分类器得扰动更加鲁棒
对于图像,很少做PCA操作,因为不想破坏图像本身的一种空间结构,直接用cnn就行,但是之前要做一个白化的操作
权值
权值很小造成的问题
当我们用relu的时候,每一层的输出都是relu(wx+b),当w很小的时候,当层数加深,wx趋近于0,relu(wx+b)迅速缩小(这里我们假设这个b也是无限小,实际上b也不会很大),导致最后的输出基本都是0,这是我们不想看到的
权重很大造成的问题
当使用tanh作为激活函数的时候,大的权重会使得wx+b总是很大或者很小,然后tanh一下就趋近于1,同时梯度为0,权重更新变慢
权值初始化:一般使用Xavier初始值
BN
Batchnorm的实质是对于神经网络的每一层,将他强行拉回到标准的正态分布,然后再给他施加两个参数 γ \gamma γ和 β \beta β,使得加深网络的这几层是有意义的,总的来说,是让网络自己调整他所输入的均值和方差
为什么需要BN,因为如果说不调整均值和方差的话,其实每一层的权值w和b都是在调整x分布的均值和方差,随着网络的加深,均值越来越偏移0的时候(对于relu),就会使得越来越多的输入项可能出现死亡,因此我们需要用BN将其每次拉回到标准(正态(没必要非要是,这个跟输入的x分布有关))分布,然后给定参数使网络自己调节输入的均值和方差
训练
如果有上图的学习曲线,估摸着是初始值没有调好
Dropout
随机的将一部分神经元置为0,dropout可以看作是对一个完整的cnn网络取一个子模型,每次训练不会训练全部的权重,只会训练部分的权重,再测试环境下,丢弃dropout层,使用全部的权重,类似于一种集成学习来抑制过拟合
在测试环境下,对于每个神经元的权重都需要乘上p,p代表dropout训练过程中单个神经元被丢弃的概率
迁移学习
当数据集和现有数据集的分布基本一致(主要是任务基本一致,但是有所不同,比如说人家是图像分类,你也是图像分类,而且分的都是动物,人家是边缘识别,你也是边缘识别)这种情况考虑采用迁移学习,预训练网络后freeze深度的几层,对全连接层进行重新训练
重要的CNN架构
AlexNet:
1 使用relu而不是sigmoid 2 添加了dropout层 3 提出了数据增强(对原图片进行随机裁剪256x256裁剪为227x227)
VGG
1.使用pre-training,等网络稳定了再逐渐加深,这也就是为什么会有VGG13 VGG16 VGG19这么一说
GoogleNet:
- 去掉了部分全连接层FC,用average-pooling代替
- 加入了inception
- 中间层加入了辅助计算的loss单元,最终的loss为 f i n a l L o s s + m i d L o s s 1 ∗ 0.3 + m i d L o s s 2 ∗ 0.3 finalLoss+midLoss1*0.3+midLoss2*0.3 finalLoss+midLoss1∗0.3+midLoss2∗0.3,目的是让计算损失时低层的层也有很好的区分能力(说白了就是为了缓解梯度消失,使底层权重也能够在优化算法中得到改变,而不是使得反响传播到这里就基本上为0了)
Inception v1:
对于某一层的输入,用不同大小的卷积核去处理,然后把他们融合再一起,对于1x1的卷积核,padding=0,对于3x3的卷积核,padding=1,5x5的padding=2,这样才能保证输出的时候W,H是相等的,然后在D上给摞起来,用了三个Conv层加一个Maxpooling层
同时为了降维,在输入之前
Inception v2:
使用VGG的思想,将5*5的卷积核替换为2层3x3的卷积核
Inception v3
加入Batchnorm
Resnet
随着神经网络深度的增加,会出现神经网络的退化(在训练集和测试集的精度都下降,这是由于深度神经网络的优化变得困难)以及过拟合问题(在测试集精度下降)
F是求和前网络映射,H是从输入到求和后的网络映射。比如把5映射到5.1,那么引入残差前是F’(5)=5.1,引入残差后是H(5)=5.1, H(5)=F(5)+5, F(5)=0.1。这里的F’和F都表示网络参数映射,引入残差后的映射对输出的变化更敏感。比如s输出从5.1变到5.2,映射F’的输出增加了1/51=2%,而对于残差结构输出从5.1到5.2,映射F是从0.1到0.2,增加了100%。明显后者输出变化对权重的调整作用更大,所以效果更好。残差的思想都是去掉相同的主体部分,从而突出微小的变化,看到残差网络我第一反应就是差分放大器…
从以往的学习输出变成了学习残差,最终的输出是delta(x)+x,为什么学习残差在之前也讲了,因为残差的思想是去掉相同的主体部分,突出微小的变化,使得在优化过程中参数能够有较大的变化,优化得以进行。
这里面需要注意的问题就是要保证F(x)和x的维度相同,可以采用以下两种方案
- zero_padding来调整W,H的维度
- 1*1的卷积核来调整D的维度
DenseNet
几个重要的问题
-
卷积核的尺寸对图像扫描的影响
小的卷积核可使我们采用更深的深度来训练神经网络,可以给神经网络带来更多的非线性
一个5*5的卷积核的感受野相当于2层3x3的卷积核,但是相对于一个 5 × 5 5 \times 5 5×5,2层3x3可以带来更多的非线性
-
1*1卷积核的意义
实现跨通道卷积的整合
通道数的升降
-
权值初始化为0
把初始值设为一样的画,他们将会有相同的输入输出(因为他们的激活函数时一样的),导致梯度也一样,导致更新时也一样,就没有意义了,没有打破参数对称的问题
-
用0来填充padding是否是变相的增加特征
我们只能保证尽可能的他与原来的是一样的,从图像分类的角度来讲,我们将未知区域认为是白色在实践中是合理的,当然除了用0填充外仍有其他的方式,只是0填充从直观上来讲是一个较为可靠的方式
-
padding层的作用
保证输出图像尺寸不变,同时保证边角区域与中间一样应用于卷积核,如果不做padding的画则图像尺寸则会逐层缩减,会丢掉边缘处图像的信息
-
既然池化和滑动步长都是降采样的作用,为什么采取前者而不是后者
事实上已经有了滑动步长来取代池化的过程
-
把学习率设置非常小,为什么在训练初期训练集精确率有着较大的提升?
可能的原因是由于目标函数的梯度在该点很大,且不断减小(类比一个a>0的二次函数),虽然初期学习率设置非常小,但是由于梯度非常大,导致精确率的提升也很大