线性分类模型一般是一个广义线性函数,即一个或多个【线性判别函数】加上一个【非线性激活函数】,所谓“线性”是指决策边界由一个多个超平面组成。通过引入S型的对数几率函数 y = 1 1 + e − z y=\dfrac{1}{1+e^{-z}} y=1+e−z1该激活函数作用是因此引入非线性:
逻辑回归即线性回归+sigmoid函数,是最基础也是最重要的模型:
(1)非线性
(2)可微性:因为在反向传播更新梯度时,需要计算损失函数对权重的偏导数,传统的激活函数sigmoid满足出处可微,而ReLU函数仅在有限个点处不可微。对于随机梯度下降(Stochastic Gradient Descent,SGD)算法,几乎不可能收敛到梯度接近0的位置,所以优先的不可微点对于优化结果影响不大。
(3)单调性:保证单层网络为凸函数;单调性说明其导数符号不变,使得梯度方向不会经常改变(从而让训练更容易收敛)
(4)f(x)≈x
(5)输出值范围:
(6)计算简单、归一化
relu是针对sigmoid和tanh饱和区间的问题而提出的激活函数,其函数形式和求导结果都很简单:
δ ( x ) = max ( 0 , x ) δ ′ ( x ) = { 0 x < = 0 1 x > 0 \begin{gathered} \delta(x)=\max (0, x) \\ \delta^{\prime}(x)= \begin{cases}0 & \mathrm{x}<=0 \\ 1 & \mathrm{x}>0\end{cases} \end{gathered} δ(x)=max(0,x)δ′(x)={01x<=0x>0
优点:
(1)ReLU函数的线性特点使得其收敛速度比Sigmoid、tanh更快,而且没有梯度饱和、梯度消失的情况出现。
(2)计算更加高效,相比于sigmoid、tanh函数,ReLU只需要一个阈值就可以得到激活值(不需要指数运算),不需要对输入归一化来防止达到饱和。
缺点:
(1)ReLU的输出不是0均值
(2)Dead ReLU Problem(神经元坏死现象):ReLU在负数区域被kill的现象叫做dead relu。ReLU在训练的时很“脆弱”。在x<0时,梯度为0。这个神经元及之后的神经元梯度永远为0,不再对任何数据有所响应,导致相应参数永远不会被更新
取值范围为(0, 1),可用来做二分类任务。 S ( x ) = 1 1 + e − z = e x e x + 1 S(x)=\frac{1}{1+e^{-z}}=\frac{e^x}{e^x+1} S(x)=1+e−z1=ex+1ex
Sigmoid优点:输出范围有限,所以数据在传递过程中不易发散;还有容易求导。
Sigmoid缺点:梯度下降非常明显,且两头过于平坦,容易在反向传播时,出现梯度消失的情况,输出的至于不对称(并非像tanh函数那样是-1~1)
对sigmoid函数进行求导: σ ′ ( x ) = ( 1 1 + e − x ) ′ = e − x ( 1 + e − x ) 2 = e − x + 1 − 1 ( 1 + e − x ) 2 = 1 1 + e − x − 1 ( 1 + e − x ) 2 = 1 1 + e − x ( 1 − 1 1 + e − x ) = σ ( x ) ( 1 − σ ′ ( x ) ) \begin{aligned} \sigma^{\prime}(x) & \\ & =\left(\frac{1}{1+e^{-x}}\right)^{\prime} \\ & =\frac{e^{-x}}{\left(1+e^{-x}\right)^2} \\ & =\frac{e^{-x}+1-1}{\left(1+e^{-x}\right)^2} \\ & =\frac{1}{1+e^{-x}}-\frac{1}{\left(1+e^{-x}\right)^2} \\ & =\frac{1}{1+e^{-x}}\left(1-\frac{1}{1+e^{-x}}\right) \\ & =\sigma(x)\left(1-\sigma^{\prime}(x)\right) \end{aligned} σ′(x)=(1+e−x1)′=(1+e−x)2e−x=(1+e−x)2e−x+1−1=1+e−x1−(1+e−x)21=1+e−x1(1−1+e−x1)=σ(x)(1−σ′(x))
双曲正切函数,取值范围为[-1, 1] Tanh ( x ) = e x − e − x e x + e − x \operatorname{Tanh}(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}} Tanh(x)=ex+e−xex−e−x
优点:相对于sigmoid,tanh是0均值的
缺点:仍存在梯度饱和,和由于是指数形式,计算复杂度高的问题
对tanh函数进行求导:
tanh ′ ( x ) = ( e x − e − x e x + e − x ) ′ = ( e x − e − x ) ′ ( e x + e − x ) − ( e x − e − x ) ( e x + e − x ) ′ ( e x + e − x ) 2 = ( e x + e − x ) 2 − ( e x − e − x ) 2 ( e x + e − x ) 2 = 1 − ( e x − e − x e x + e − x ) 2 = 1 − tanh 2 ( x ) \begin{aligned} \tanh ^{\prime}(x) & \\ & =\left(\frac{e^x-e^{-x}}{e^x+e^{-x}}\right)^{\prime} \\ & =\frac{\left(e^x-e^{-x}\right)^{\prime}\left(e^x+e^{-x}\right)-\left(e^x-e^{-x}\right)\left(e^x+e^{-x}\right)^{\prime}}{\left(e^x+e^{-x}\right)^2} \\ & =\frac{\left(e^x+e^{-x}\right)^2-\left(e^x-e^{-x}\right)^2}{\left(e^x+e^{-x}\right)^2} \\ & =1-\left(\frac{e^x-e^{-x}}{e^x+e^{-x}}\right)^2 \\ & =1-\tanh ^2(x) \end{aligned} tanh′(x)=(ex+e−xex−e−x)′=(ex+e−x)2(ex−e−x)′(ex+e−x)−(ex−e−x)(ex+e−x)′=(ex+e−x)2(ex+e−x)2−(ex−e−x)2=1−(ex+e−xex−e−x)2=1−tanh2(x)
softmax通常来讲是激活函数,但是softmax函数要与交叉熵损失函数一起使用来避免数值溢出的问题。所以,在常见的深度学习框架中(比如torch和paddle中),在网络构造中通常是看不见softmax函数的,而在我们调用交叉熵损失函数时(entropy),框架会在entropy之前自动为我们添加softmax函数。
nn.CrossEntropyLoss
时,网络最后不需要进行softmax,该函数会进行log_softmax
的操作:
torch.LongTensor()
,不然会报错1
生成独热编码向量。(1)交叉熵手写版本
import numpy as np
y = np.array([1, 0, 0])
z = np.array([0.2, 0.1, -0.1])
y_predict = np.exp(z) / np.exp(z).sum()
loss = (- y * np.log(y_predict)).sum()
print(loss)
# 0.9729189131256584
(2)交叉熵pytorch栗子
交叉熵损失和NLL损失的区别(读文档):
可以。当采用ReLU作为RNN中隐藏层的激活函数时,只有当W的取值在单位矩阵附近时才能取到较好的效果(因此要将W初始化为单位矩阵),实验证明这样做后能在一些应用与LSTM取得相似的结果,且学习速度更快。
[1] Activation Functions in Neural Networks
[2] 夯实基础知识——常见激活函数总结