激活函数
深度学习的进展得益于人们对激活函数的更深理解
传统机器学习流行采用sigmoid激活函数,
这个函数可解释性好,数学性质好,但是在深度学习领域随着网络层的增加会导致梯度消失的问题。
SVM的激活函数类似 max(x-b), 实践上计算更快。
深度学习流行的relu, max(x) 形状和tvm类似,速度更快,也能解决深度消失的问题。实际应用为了保证负梯度的传播,还有在负梯度方向加一个线性梯度来解决
流行的激活函数有
S
i
g
m
o
i
d
(
x
)
=
1
1
+
e
−
x
Sigmoid(x) = \frac{1}{1+e^{-x}}
Sigmoid(x)=1+e−x1
优点:
历史上很流行,可解释性好,
缺点:
在饱和区域丢失了梯度,输出不是以0为中心的,要么全正,要么全负,收敛会很慢,因为真正的梯度方向可能有正有负
Exp()计算有点贵
t
a
n
h
(
x
)
tanh(x)
tanh(x)
该激活函数是以0为中心的,但是仍然会损失梯度
R
e
L
U
=
max
(
0
,
x
)
ReLU=\max(0,x)
ReLU=max(0,x)
ReLU Rectified Linear Unit,
优点:
和生物的神经类似,计算效率高,收敛快,正方向梯度不饱和,精度更好
缺点:
不是以0为中心,可能会死
L
e
a
k
y
R
e
l
u
(
x
)
=
max
(
0.1
x
,
x
)
LeakyRelu(x)=\max(0.1x, x)
LeakyRelu(x)=max(0.1x,x)
负方向不会死
更一般的有Paramedic recifier PRelu
P
R
e
l
u
=
max
(
a
x
,
x
)
PRelu=\max(ax,x)
PRelu=max(ax,x)
是leakyrelu的一般版本
E
L
U
(
x
)
=
{
x
x
≥
0
α
(
e
x
−
1
)
x
<
0
ELU(x) =\begin{cases}x & x \ge 0\\ \alpha(e^x-1) & x < 0\end{cases}
ELU(x)={xα(ex−1)x≥0x<0
Exponent LU, 对噪声更加鲁棒
M
a
x
o
u
t
=
max
(
w
1
T
x
+
b
1
,
w
2
T
x
+
b
2
)
Maxout=\max(w_1^Tx+b_1,w_2^Tx+b_2)
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
^
=
x
(
k
)
−
E
[
x
(
k
)
]
V
a
r
[
x
(
k
)
]
\widehat{x} =\frac{x^{(k)}-E[x^{(k)}]}{\sqrt{Var[x^{(k)}]} }
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
norm layer用的LRN, 不过现代的深度学习已经抛弃了
VGG
[Simonyan and Zisserman, 2014]
16层版本和19层版本
只有3x3核的卷积,2x2核的pool
GoogLeNet
[Szegedy et al., 2014]
在一些旁路增加小网络来解决梯度消失
GoogLeNet的每层是一个inception module, 在最后用了avg pool来减少总的参数数量。 如果不用avg pool, 进入全连接的每个项都连神经元的话会带来海量的参数,用avg pool 最后仅仅获得了几个平均后的值来连神经元,预测准确度也没太大损失
笔者认为,这是因为在一定抽象层次问题已经解决了,没必要更进一步抽象下去
增加一些1*1的conv来减少纬度
Resnet
[He et al., 2015]
Resnet引入了残差概念,每几层就来个residual connection, 类似googlenet的注入,来跳过一些层。实现了非常深的深度