CS224D 课程学习笔记 L06

Lecture 6. Neural Tips and Tricks


Lecture 6主要介绍了深度学习应用的一些小技巧,例如多任务训练、梯度检测、正则化、多种激活函数、参数初始化、学习速率等。

文章目录

    • Lecture 6. Neural Tips and Tricks
      • 多任务学习(也叫权重共享)
      • 梯度检测
      • 正则化
      • 非线性神经元
        • Sigmoid
        • Tanh
        • Hard Tanh
        • Soft sign
        • ReLu
        • Leaky ReLu
        • MaxOut Network
      • 参数初始化
      • 学习速率
      • AdaGrad
      • 其他方法

多任务学习(也叫权重共享)

对比上节课我们学到的神经网络,多任务学习就是在输出层用softmax分类器取代标量得分。训练方法依然采用后向传播。

神经网络和传统机器学习方法的不同在于,深度学习需要同时学习词向量和权重。

主要思想:我们在训练多种不同NLP任务(例如NER和POS),可以共享两个任务的词向量和隐藏层的权重,只有输出层的softmax权重不同。损失函数是不同任务损失函数相加,例如:

δ t o t a l = δ P O S + δ N E R \delta^{total} = \delta^{POS} + \delta^{NER} δtotal=δPOS+δNER

参考论文《NLP(almost from scratch, Collobert et al.2011)》

成功的神经网络的通用步骤是这样的:

  1. 选择合适的网络框架
    1. 框架:单个词、固定窗口、词袋、循环神经网络、递归神经网络、CNN等;
    2. 非线性神经单元
  2. 用梯度检测器检查实现代码是否存在bug
  3. 参数初始化
  4. 优化技巧
  5. 检查模型是否强大到过拟合
    1. 如果没有过拟合,改变模型框架或者模型调大
    2. 如果过拟合,请用正则化

下面我们根据这些步骤分别介绍使用技巧。

梯度检测

梯度检测我们在第一次作业中用过,从导数的本质上求得参数的梯度,和我们用后向传播计算得到的梯度对比。公式如下:

f ′ ( θ ) ≈ J ( θ ( i + ) ) − J ( θ ( i − ) ) 2 ϵ f\prime (\theta) \approx \frac{J(\theta^{(i+)}) - J(\theta^{(i-)})}{2\epsilon} f(θ)2ϵJ(θ(i+))J(θ(i))

其中, θ ( i + ) = θ + ϵ × e i \theta^{(i+)} = \theta + \epsilon \times e_i θ(i+)=θ+ϵ×ei

简单的代码实现为:

old_value = x[ix]
x[ix] = old_value + h 
fxh = f(x) 
x[ix] = old_value
grad[ix] = (fxh - fx) / h

如果梯度检测失败了应该怎么做?修改代码确定没有bug!

正则化

正则化前面课程提到的次数也很多,和大多数分类器一样,神经网络也需要避免过拟合,使得验证集和测试集能够获得良好的表现。正则化后的损失函数为:

J R = J + λ ∑ i = 1 L ∣ ∣ W ( i ) ∣ ∣ F J_R = J + \lambda\sum_{i=1}^L||W^{(i)}||_F JR=J+λi=1LW(i)F

上式中, ∣ ∣ W ( i ) ∣ ∣ F ||W^{(i)}||_F W(i)F是矩阵 W ( i ) W^{(i)} W(i) F F F范数, λ \lambda λ是正则化选项的相对权重。

非线性神经元

目前为止我们讨论的非线性神经元有sigmoid,然而在很多应用中有更好的激活函数。常用的有:

Sigmoid

公式:

σ ( z ) = 1 1 + e x p ( − z ) ∈ ( 0 , 1 ) \sigma(z) = \frac{1}{1+exp(-z)} \in (0,1) σ(z)=1+exp(z)1(0,1)

梯度:

σ ′ ( z ) = σ ( z ) ( 1 − σ ( z ) ) \sigma\prime(z) = \sigma(z)(1-\sigma(z)) σ(z)=σ(z)(1σ(z))

Tanh

与sigmoid相比,tanh函数收敛更快,输出范围为-1到1。

公式:

t a n h ( z ) = e x p ( z ) − e x p ( − z ) e x p ( z ) + e x p ( − z ) = 2 σ ( 2 z ) − 1 ∈ ( − 1 , 1 ) tanh(z) = \frac{exp(z)-exp(-z)}{exp(z) + exp(-z)} = 2\sigma(2z) -1 \in (-1,1) tanh(z)=exp(z)+exp(z)exp(z)exp(z)=2σ(2z)1(1,1)

梯度:

t a n h ′ ( z ) = 1 − t a n h 2 ( z ) tanh\prime(z) = 1 - tanh^2(z) tanh(z)=1tanh2(z)

Hard Tanh

hard tanh比tanh更容易计算。

公式:

h a r d t a n h ( z ) = { − 1 : z < − 1 z : − 1 ≤ z ≤ 1 1 : z > 1 hardtanh(z) = \begin{cases} -1 &:&z<-1\\z&:&-1\leq z\leq 1\\1&:&z>1\\\end{cases} hardtanh(z)=1z1:::z<11z1z>1

梯度:

h a r d t a n h ′ ( z ) = { 1 : − 1 ≤ z ≤ 1 0 : o t h e r w i s e hardtanh\prime(z) = \begin{cases}1 &:&-1\leq z \leq 1\\0&:&otherwise\end{cases} hardtanh(z)={10::1z1otherwise

Soft sign

公式:

s o f t s i g n ( z ) = z 1 + ∣ z ∣ softsign(z) = \frac{z}{1+|z|} softsign(z)=1+zz

梯度:

s o f t s i g n ′ ( z ) = s g n ( z ) ( 1 + z ) 2 softsign\prime(z) = \frac{sgn(z)}{(1+z)^2} softsign(z)=(1+z)2sgn(z)

​ 其中 s g n ( z ) sgn(z) sgn(z)是符号函数,根据z的不同返回不同, s g n ( z ) = { 1 z > 0 0 z = 0 − 1 z < 0 sgn(z) = \begin{cases}1 &z>0&\\0 &z=0&\\-1 &z<0&\end{cases} sgn(z)=101z>0z=0z<0

ReLu

ReLu,Rectify Linear Unit,是一种比较流行的激活函数,因为它的上限不饱和,在计算视觉应用方面获得成功。

公式:

r e c t ( z ) = m a x ( z , 0 ) rect(z) = max(z, 0) rect(z)=max(z,0)

梯度:

r e c t ′ ( z ) = { 1 : z > 0 0 : o t h e r w i s e rect\prime(z) = \begin{cases}1 &:&z>0\\0 &:&otherwise\end{cases} rect(z)={10::z>0otherwise

Leaky ReLu

传统ReLu激活单元对非正的z不具备传播误差的功能,leaky ReLu改进了这一缺陷,使得晓得误差能够被后向传播。

公式:

l e a k y ( z ) = m a x ( z , k ⋅ z ) leaky(z) = max(z, k\cdot z) leaky(z)=max(z,kz) 其中 0 < k < 1 0<k<1 0<k<1

梯度:

l e a k y ′ ( z ) = { 1 : z > 0 k : o t h e r w i s e leaky\prime (z) = \begin{cases}1 &:&z>0\\k &:&otherwise\\\end{cases} leaky(z)={1k::z>0otherwise

MaxOut Network

最近出现的一个非线性网络,公式:

f i ( z ) = m a x j ∈ [ 1 , k ] z i j f_i(z) = max_{j\in[1,k]}z_{ij} fi(z)=maxj[1,k]zij

z i j = x T W ⋅ ⋅ i j + b i j z_{ij} = x^TW_{\cdot \cdot ij} + b_{ij} zij=xTWij+bij

这种方法在一些图片数据集上取得了不错的效果。

参数初始化

论文《Understanding the difficulty of training deep feedfor-ward neural networks (2010), Xavier et al》中研究了权重和偏置的初始值不同对训练的影响,结果表明,当权重矩阵 W ∈ R n ( l + 1 ) × n ( l ) W\in R^{n^{(l+1)}\times n^{(l)}} WRn(l+1)×n(l)采用以下范围的均匀分布来随机初始化时,对sigmoid和tanh激活函数会得到更低的误差率和更快的收敛速度:

U [ − 6 n ( l ) + n ( l + 1 ) , 6 n ( l ) + n ( l + 1 ) ] U[-\sqrt{\frac{6}{n^{(l)} + n^{(l+1)}}}, \sqrt{\frac{6}{n^{(l)} + n^{(l+1)}}}] U[n(l)+n(l+1)6 ,n(l)+n(l+1)6 ]

其中, n ( l ) n^{(l)} n(l)表示输入单元的个数, n l + 1 n^{l+1} nl+1表示输出单元的个数。

目的:维护层层之间激活方差和后向传播的梯度方差。

学习速率

模型中梯度更新的速度使用学习速率这个变量来控制,在下面公式中, α \alpha α表示学习速率:

θ n e w = θ o l d − α Δ θ J t ( θ ) \theta^{new} = \theta^{old} - \alpha \Delta_{\theta}J_t(\theta) θnew=θoldαΔθJt(θ)

梯度更新的速度并不是越快越好, a l p h a alpha alpha太大,可能会导致无法收敛到最优解。在非凸模型中(我们遇到的大部分模型都是非凸的),很大的学习速率导致损失函数的发散几率更高。

关于学习速率的设置有很多变种,详细信息可以看讲义。

AdaGrad

AdaGrad可以说是标准的SGD,但是只有一点不同:它的每个参数的学习速率是不同的。每个参数的学习速率依赖于历史更新信息,换句话说,没有更新过的参数的学习速率可能更高,用公式表示:

θ t , i = θ t − 1 , i − α ∑ τ = 1 t g τ , i 2 g t , i \theta_{t,i} = \theta_{t-1,i} - \frac{\alpha}{\sqrt{\sum_{\tau = 1}^tg_{\tau,i}^2}}g_{t,i} θt,i=θt1,iτ=1tgτ,i2 αgt,i

​ 其中, g t , i = ∂ ∂ θ i t J t ( θ ) g_{t,i} = \frac{\partial}{\partial \theta_i^t}J_t(\theta) gt,i=θitJt(θ)

简单的代码实现:

cache += dx**2
x += - learning_rate * dx / np.sqrt(cache + 1e-8)

其他方法

你可能感兴趣的:(机器学习算法,深度学习算法,Stanford,CS224(d/n),Deep,Learning,for,NLP,Notes)