激活函数
深度学习的进展得益于人们对激活函数的更深理解
传统机器学习流行采用sigmoid激活函数,
这个函数可解释性好,数学性质好,但是在深度学习领域随着网络层的增加会导致梯度消失的问题。
TVM的激活函数类似 max(x-b), 实践上计算更快。
深度学习流行的relu, max(x) 形状和tvm类似,速度更快,也能解决深度消失的问题。实际应用为了保证负梯度的传播,还有在负梯度方向加一个线性梯度来解决
流行的激活函数有
Sigmoid(x)=1+e−x1
优点:
历史上很流行,可解释性好,
缺点:
在饱和区域丢失了梯度,输出不是以0为中心的,要么全正,要么全负,收敛会很慢,因为真正的梯度方向可能有正有负
Exp()计算有点贵
tanh(x)
该激活函数是以0为中心的,但是仍然会损失梯度
ReLU=max(0,x)
ReLU Rectified Linear Unit,
优点:
和生物的神经类似,计算效率高,收敛快,正方向梯度不饱和,精度更好
缺点:
不是以0为中心,可能会死
LeakyRelu(x)=max(0.1x,x)
负方向不会死
更一般的有Paramedic recifier PRelu
PRelu=max(ax,x)
是leakyrelu的一般版本
ELU(x)={xα(ex−1)x≥0x<0
Exponent LU, 对噪声更加鲁棒
Maxout=max(w1Tx+b1,w2Tx+b2)
优点:
非线性, ReLU和Leaky ReLU的通用版本
Linear Regime, 不饱和,不死
缺点:
参数和神经元数量多
反向传播算法
反向传播算法是为了计算倒数的方法,
链式法则里
比如函数
f(x,y,z)=q(x,y)*z
df/dx = df/dq * dq/dx
那么反向传播则是
已知dq/dx, 求 df/dx
即下游的梯度*本地的梯度
如果一个节点连多个节点,则上游的梯度为下游梯度之和
因此可以说正向传播的是计算,反向传播的是梯度
参数初始化
参数初始化最好是保持在一个类似正态分布的范围。现在流行用
Xavier initialization, [Glorot et al,. 2010]
批量归一化
batch normalization
在全连接,卷积后面可以跟一个batch norm层来使得特征图的分布更加规整
x=Var[x(k)]x(k)−E[x(k)]
流行的网络
Alex Net
[Krizhevsky et al.2010]
第一次用Relu, 开始用Norm Layers, 8层卷积
conv1–>maxpool–>norm1–>conv2–>norm2–>conv3–>conv4–>conv5–>maxpool–>FC–>FC–>FC
VGG
[Simonyan and Zisserman, 2014]
16层版本和19层版本
只有3x3核的卷积,2x2核的pool
GoogLeNet
[Szegedy et al., 2014]
在一些旁路增加小网络来解决梯度消失, 叫做注入技术
笔者认为,这是因为在一定抽象层次问题已经解决了,没必要更进一步抽象下去
增加一些1*1的conv来减少纬度
Resnet
[He et al., 2015]
Resnet引入了残差概念,每几层就来个residual connection, 类似googlenet的注入,来跳过一些层。实现了非常深的深度