【面筋】神经网络推导
文章目录
激活函数
为什么要激活函数?而且还是非线性的激活函数?没了激活函数会怎样?
1)深度神经网络可以看做一个特征映射函数,使用激活函数是为了提供非线性映射,从而把特征转换到高纬空间
2)为啥一定是非线性激活函数,如果使用线性函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合,加深神经网络的层数就没有什么意义了。不加激活函数和加线性激活函数本质上没有区别;
关于这部分理论,可以用通用近似原理来证明: 人工神经网络最有价值的地方可能就在于,它可以在理论上证明:“一个包含足够多隐含层神经元的多层前馈网络,能以任意精度逼近任意预定的连续函数”。这个定理即为通用近似原理(Universal Approximation Theorem) ;
常用的激活函数
-
Sigmoid函数:
σ ( x ) = 1 1 + e − x \sigma(x)=\frac{1}{1+\mathrm{e}^{-x}} σ(x)=1+e−x1
优点:平滑易求导;输出范围[0,1], 输出值可以作为概率,具备可解释性缺点:导函数 0 ≤ σ ( x ) ′ = σ ( x ) ( 1 − σ ( x ) ) ≤ 1 4 0\leq\sigma(x)^{\prime}=\sigma(x)(1-\sigma(x))\leq \frac{1}{4} 0≤σ(x)′=σ(x)(1−σ(x))≤41,反向传播易导致梯度消失;含有指数运算较为耗时;输出值不以0为中心,可能导致模型收敛速度慢;
-
Tanh函数:
tanh ( x ) = 2 σ ( 2 x ) − 1 = e x − e − x e x + e − x \tanh(x)=2 \sigma(2 x)-1=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}} tanh(x)=2σ(2x)−1=ex+e−xex−e−x优点:平滑易求导;输出值以0为中心,模型收敛快
缺点:导函数 0 ≤ tanh ( x ) ′ = 1 − tanh ( x ) 2 ≤ 1 0\leq\tanh(x)^{\prime}=1-\tanh(x)^2\leq 1 0≤tanh(x)′=1−tanh(x)2≤1,反向传播易导致梯度消失;含有指数运算较为耗时;
-
ReLU函数:
max ( 0 , x ) \max(0,x) max(0,x)优点:在正区间上解决了梯度消失的问题;计算简单,因为只需判断是否大于0;收敛速度比上面两个激活函数要快
缺点:输出值为0的概率太大,容易导致神经元死亡,无法重新激活
改进方法:初始化权重时别把神经元弄死;学习率不要设置太高以防权重更新幅度太大把神经元弄死;采用动态调整学习率的优化算法;采用Leaky ReLU/PReLU函数替代
-
Leaky ReLU/PReLU函数:
m a x ( a x , x ) max(ax,x) max(ax,x)优点:修正了ReLU函数的缺点,如果 α \alpha α是固定值则为Leaky ReLU,如果 α \alpha α需要自己学出来则为PReLU;
手推证明:sigmoid会导致其下层所有神经元的权重更新方向一致;
1)假设两个神经元,其参数为 w 1 , w 2 w_1, w_2 w1,w2, 可以计算得到神经元输出,
h t = w 1 y 1 t − 1 + w 2 y 2 t − 1 h^t=w_1y_1^{t-1}+w_2y_2^{t-1} ht=w1y1t−1+w2y2t−1
2)通过激活函数得到该层的输出;
y t = f ( h t ) y^t=f(h^t) yt=f(ht)
3)计算两个神经元的参数 w 1 , w 2 w_1,w_2 w1,w2的梯度:
∂ L o s s ∂ w 1 = ∂ L o s s ∂ y t ⋅ ∂ y t ∂ h t ⋅ ∂ h t ∂ w 1 = ∂ L o s s ∂ y t ⋅ ∂ y t ∂ h t ⋅ y 1 t − 1 \cfrac{\partial Loss}{\partial w_1}=\cfrac{\partial Loss}{\partial y^t}\cdot\cfrac{\partial y^t}{\partial h^t}\cdot\cfrac{\partial h^t}{\partial w_1}=\cfrac{\partial Loss}{\partial y^t}\cdot\cfrac{\partial y^t}{\partial h^t}\cdot y_1^{t-1} ∂w1∂Loss=∂yt∂Loss⋅∂ht∂yt⋅∂w1∂ht=∂yt∂Loss⋅∂ht∂yt⋅y1t−1
∂ L o s s ∂ w 2 = ∂ L o s s ∂ y t ⋅ ∂ y t ∂ h t ⋅ ∂ h t ∂ w 2 = ∂ L o s s ∂ y t ⋅ ∂ y t ∂ h t ⋅ y 2 t − 1 \cfrac{\partial Loss}{\partial w_2}=\cfrac{\partial Loss}{\partial y^t}\cdot\cfrac{\partial y^t}{\partial h^t}\cdot\cfrac{\partial h^t}{\partial w_2}=\cfrac{\partial Loss}{\partial y^t}\cdot\cfrac{\partial y^t}{\partial h^t}\cdot y_2^{t-1} ∂w2∂Loss=∂yt∂Loss⋅∂ht∂yt⋅∂w2∂ht=∂yt∂Loss⋅∂ht∂yt⋅y2t−1
4)分析结果:其中, y 1 t − 1 y_1^{t-1} y1t−1和 y 2 t − 1 y_2^{t-1} y2t−1都是上层神经元的输出,如果上层神经元采用的是Sigmoid函数激活的话,那么 y 1 t − 1 y_1^{t-1} y1t−1和 y 2 t − 1 y_2^{t-1} y2t−1均恒大于0,此时 w 1 , w 2 w_1,w_2 w1,w2的梯度正负号恒一致,从而也就导致权重更新方向一致。
不过这是只计算单个样本损失就更新梯度的情形,通常训练都是采用mini-batch梯度下降,所以会同时算多个样本的损失,然后累加所有样本损失给出的梯度更新值以后作为最终梯度更新值,此时更新时不一定方向是一致的,比如:
y 1 t : Δ w 1 = + 6 , Δ w 2 = + 0.5 y_1^t:\Delta w_1=+6,\Delta w_2=+0.5 y1t:Δw1=+6,Δw2=+0.5
y 2 t : Δ w 1 = − 0.2 , Δ w 2 = − 3 y_2^t:\Delta w_1=-0.2,\Delta w_2=-3 y2t:Δw1=−0.2,Δw2=−3
那么 w 1 w_1 w1和 w 2 w_2 w2总的梯度更新幅度为
Δ w 1 = + 5.8 , Δ w 2 = − 2.5 \Delta w_1=+5.8,\Delta w_2=-2.5 Δw1=+5.8,Δw2=−2.5
显然两者的更新方向此时不再一致。
手推证明:ReLU神经元死亡将导致权重无法更新;
1)假设两个神经元;得到输出的就算公式;
h t = w 1 y 1 t − 1 + w 2 y 2 t − 1 h^t=w_1y_1^{t-1}+w_2y_2^{t-1} ht=w1y1t−1+w2y2t−1
y t = ReLU ( h t ) y^t=\text{ReLU}(h^t) yt=ReLU(ht)
2)计算两个神经元参数的梯度,如果此时第 t t t层神经元死亡的话,也即 y t y^t yt恒等于0,那么
∂ L o s s ∂ w 1 = ∂ L o s s ∂ y t ⋅ ∂ y t ∂ h t ⋅ ∂ h t ∂ w 1 = ∂ L o s s ∂ y t ⋅ 0 ⋅ y 1 t − 1 = 0 \cfrac{\partial Loss}{\partial w_1}=\cfrac{\partial Loss}{\partial y^t}\cdot\cfrac{\partial y^t}{\partial h^t}\cdot\cfrac{\partial h^t}{\partial w_1}=\cfrac{\partial Loss}{\partial y^t}\cdot 0 \cdot y_1^{t-1}=0 ∂w1∂Loss=∂yt∂Loss⋅∂ht∂yt⋅∂w1∂ht=∂yt∂Loss⋅0⋅y1t−1=0
∂ L o s s ∂ w 2 = ∂ L o s s ∂ y t ⋅ ∂ y t ∂ h t ⋅ ∂ h t ∂ w 2 = ∂ L o s s ∂ y t ⋅ 0 ⋅ y 2 t − 1 = 0 \cfrac{\partial Loss}{\partial w_2}=\cfrac{\partial Loss}{\partial y^t}\cdot\cfrac{\partial y^t}{\partial h^t}\cdot\cfrac{\partial h^t}{\partial w_2}=\cfrac{\partial Loss}{\partial y^t}\cdot 0 \cdot y_2^{t-1}=0 ∂w2∂Loss=∂yt∂Loss⋅∂ht∂yt⋅∂w2∂ht=∂yt∂Loss⋅0⋅y2t−1=0
显然,此时第 t t t层神经元的权重永远无法更新,从而也就导致永远无法激活
优化算法
整体叙述框架参见:https://zhuanlan.zhihu.com/p/32230623 ,具体内容参见:https://blog.csdn.net/u010089444/article/details/76725843 和 https://ruder.io/optimizing-gradient-descent/index.html
参数更新框架:
基本框架:定义当前时刻待优化参数为 θ t ∈ R d \theta_t\in R^{d} θt∈Rd,损失函数为 J ( θ ) J(\theta) J(θ),学习率为 η \eta η,参数更新框架为:
- 计算损失函数关于当前参数的梯度: g t = ∇ J ( θ t ) g_t=\nabla J(\theta_t) gt=∇J(θt);
- 根据历史梯度计算一阶动量(一次项)和二阶动量(二次项): m t = ϕ ( g 1 , g 2 , . . . , g t ) , V t = ψ ( g 1 , g 2 , . . . , g t ) m_t=\phi(g_1,g_2,...,g_t),V_t=\psi(g_1,g_2,...,g_t) mt=ϕ(g1,g2,...,gt),Vt=ψ(g1,g2,...,gt);
- 计算当前时刻的下降梯度: Δ θ t = − η ⋅ m t V t \Delta\theta_t=-\eta\cdot\cfrac{m_t}{\sqrt{V_t}} Δθt=−η⋅Vtmt
- 根据下降梯度更新参数: θ t + 1 = θ t + Δ θ t \theta_{t+1}=\theta_t+\Delta\theta_t θt+1=θt+Δθt
SGD
- SGD:由于SGD没有动量的概念,也即没有考虑历史梯度,所以当前时刻的动量即为当前时刻的梯度 m t = g t m_t=g_t mt=gt,且二阶动量 V t = E V_t=E Vt=E,所以SGD的参数更新公式为
Δ θ t = − η ⋅ g t \Delta\theta_t=-\eta\cdot g_t Δθt=−η⋅gt
θ t + 1 = θ t − η ⋅ g t \theta_{t+1}=\theta_t-\eta\cdot g_t θt+1=θt−η⋅gt
缺点:下降速度慢,而且可能会在沟壑(还有鞍点)的两边持续震荡,停留在一个局部最优点。
SGD-M
- SGD with Momentum:为了抑制SGD的震荡,SGDM认为梯度下降过程可以加入惯性。下坡的时候,如果发现是陡坡,那就利用惯性跑的快一些。SGDM全称是SGD with momentum,在SGD基础上引入了一阶动量。而所谓的一阶动量就是该时刻梯度的指数加权移动平均值: η ⋅ m t : = β ⋅ m t − 1 + η ⋅ g t \eta\cdot m_t:=\beta\cdot m_{t-1}+\eta\cdot g_t η⋅mt:=β⋅mt−1+η⋅gt(其中当前时刻的梯度 g t g_t gt并不严格按照指数加权移动平均值的定义采用权重 1 − β 1-\beta 1−β,而是使用我们自定义的学习率 η \eta η),那么为什么要用移动平均而不用历史所有梯度的平均?因为移动平均存储量小,且能近似表示历史所有梯度的平均。由于此时仍然没有二阶动量,所以 V t = E V_t=E Vt=E,那么SGDM的参数更新公式为
Δ θ t = − η ⋅ m t = − ( β m t − 1 + η g t ) \Delta\theta_t=-\eta\cdot m_t=-\left(\beta m_{t-1}+\eta g_t\right) Δθt=−η⋅mt=−(βmt−1+ηgt)
θ t + 1 = θ t − ( β m t − 1 + η g t ) \theta_{t+1}=\theta_t-\left(\beta m_{t-1}+\eta g_t\right) θt+1=θt−(βmt−1+ηgt)
所以,当前时刻参数更新的方向不光取决于当前时刻的梯度,还取决于之前时刻的梯度,特别地,当 β = 0.9 \beta=0.9 β=0.9时, m t m_t mt近似表示的是前10个时刻梯度的指数加权移动平均值,而且离得越近的时刻的梯度权重也越大。
优点:利用历史梯度作为惯性克服了SGD可能会在沟壑的两边持续震荡,停留在一个局部最优点的缺点,同时还加速了收敛。
缺点:对于比较深的沟壑有时用Momentum也没法跳出- 指数加权移动平均值(exponentially weighted moving average,EWMA):假设 v t − 1 v_{t-1} vt−1是 t − 1 t-1 t−1时刻的指数加权移动平均值, θ t \theta_t θt是 t t t时刻的观测值,那么 t t t时刻的指数加权移动平均值为
v t = β v t − 1 + ( 1 − β ) θ t = ( 1 − β ) θ t + ∑ i = 1 t − 1 ( 1 − β ) β i θ t − i \begin{aligned} v_t&=\beta v_{t-1}+(1-\beta)\theta_t \\ &=(1-\beta)\theta_t+\sum_{i=1}^{t-1}(1-\beta)\beta^i\theta_{t-i} \end{aligned} vt=βvt−1+(1−β)θt=(1−β)θt+i=1∑t−1(1−β)βiθt−i
其中 0 ≤ β < 1 , v 0 = 0 0 \leq \beta < 1,v_0=0 0≤β<1,v0=0。显然,由上式可知, t t t时刻的指数加权移动平均值其实可以看做前 t t t时刻所有观测值的加权平均值,除了第 t t t时刻的观测值权重为 1 − β 1-\beta 1−β外,其他时刻的观测值权重为 ( 1 − β ) β i (1-\beta)\beta^i (1−β)βi。由于通常对于那些权重小于 1 e \frac{1}{e} e1的观测值可以忽略不计,所以忽略掉那些观测值以后,上式就可以看做在求加权移动平均值。那么哪些项的权重会小于 1 e \frac{1}{e} e1呢?由于
lim n → + ∞ ( 1 − 1 n ) n = 1 e ≈ 0.3679 \lim_{n \rightarrow +\infty} \left(1-\frac{1}{n}\right)^n = \frac{1}{e} \approx 0.3679 n→+∞lim(1−n1)n=e1≈0.3679
若令 n = 1 1 − β n=\frac{1}{1-\beta} n=1−β1,则
lim n → + ∞ ( 1 − 1 n ) n = lim β → 1 ( β ) 1 1 − β = 1 e ≈ 0.3679 \lim_{n \rightarrow +\infty} \left(1-\frac{1}{n}\right)^n =\lim_{\beta \rightarrow 1} \left(\beta\right)^{\frac{1}{1-\beta}}=\frac{1}{e} \approx 0.3679 n→+∞lim(1−n1)n=β→1lim(β)1−β1=e1≈0.3679
所以,当 β → 1 \beta\rightarrow 1 β→1时,那些 i ≥ 1 1 − β i\geq\frac{1}{1-\beta} i≥1−β1的 θ t − i \theta_{t-i} θt−i的权重 ( 1 − β ) β i (1-\beta)\beta^i (1−β)βi一定小于 1 e \frac{1}{e} e1。代入计算可知,那些权重小于 1 e \frac{1}{e} e1的观测值就是近 1 1 − β \frac{1}{1-\beta} 1−β1个时刻之前的观测值。例如当 t = 20 , β = 0.9 t=20,\beta=0.9 t=20,β=0.9时, θ 1 , θ 2 , . . , θ 9 , θ 10 \theta_1,\theta_2,..,\theta_9,\theta_{10} θ1,θ2,..,θ9,θ10的权重都是小于 1 e \frac{1}{e} e1的,因此可以忽略不计,那么此时就相当于在求 θ 1 1 , θ 1 2 , . . , θ 1 9 , θ 20 \theta_11,\theta_12,..,\theta_19,\theta_{20} θ11,θ12,
- 指数加权移动平均值(exponentially weighted moving average,EWMA):假设 v t − 1 v_{t-1} vt−1是 t − 1 t-1 t−1时刻的指数加权移动平均值, θ t \theta_t θt是 t t t时刻的观测值,那么 t t t时刻的指数加权移动平均值为