Natural Language Processing Lecture04

Natural Language Processing Lecture04

神经网络概述

一种模仿生物神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的数学模型或计算模型,用于对函数进行估计或近似。神经网络由大量的人工神经元联结进行计算。大多数情况下人工神经网络能在外界信息的基础上改变内部结构,是一种自适应系统。

目前较为流行的神经网络有三种结构:

从左到右依次是:全连接神经网络(FCN)、卷积神经网络(CNN)、循环神经网络(RNN)。

神经元

生物大脑中的基本单元——神经元,由三部分组成:

  • 细胞体
  • 轴突(输出)
  • 树突(输入)

所有神经元都是将电信号从一端传输到另一端,沿着轴突,将电信号从树突传送到树突。然后,这些信号从一个神经元传送到另一个神经元。

我们用一定的数学模型来模拟神经元对输入的响应到输出的过程。将一定的变量放到神经元里,经过一定的运算输出。

神经元里的计算模型

在人工神经网络中,每一个神经元都是一个逻辑运算单元。

  • \(x_i\) 是输入,θ 是权重,\(h_{\theta}(x)\) 是激活函数,这里是 sigmoid 函数。

接下来,我们给出一个典形的神经网络,一般输入层不算在神经网络层数中。

中间层是隐藏层,因为其输出结果在网络内部,并不显式输出。

  • \(a_i^j\):第 j 层的第 i 个单元

  • \(\theta ^j\) :第 j 层到 j + 1 层德1权重矩阵

    • 如果第 j 层有 \(s_j\) 个单元,第 j+1 层有 \(s_{j+1}\) 个单元,那么 \(\theta^j\) 的维度是 \(S_{j+1} \times(s_j+1)\)
    • 列数是下一层的单元个数
    • 行数是输入层的单元个数 + 1
    • 计算的时候是 \(\theta^Tx\)
  • \(\theta_{ij}^l\):

    • \(l\):输入层的层号
    • \(i\):第 \(l\) 层的 \(i\) 号单元
    • \(j\):第 \(l+1\) 层的 \(j\) 号单元

  • g 函数
    • 在神经元中,并不是所有的输入都有输出,输出有一个阈值限制
    • 在我们的数学模型中,就用激活函数来做这个阈值的映射

较为完整的前向传播过程:

逻辑回归

激活函数

当我们做预测问题时,输出值 y 是一个离散的变量:0 or 1,多元分类就是单位向量,元素取值还是 0 or 1。

我们使用线性回归函数 \(h_θ(x) = (θ^T x)\),为了达到分类假设,我们使用 g 函数,\(h_θ(x) = g(θ^T x)\)\(g(x)=\frac1{e^{-z}}\)。那么:

g 函数其实就是激活函数 sigmoid 函数,他的函数图形如下:

我们认为 \(h_θ(x)\) 的值就是当输入 x 时,y = 1 的概率。那么 \(h_\theta(x)=P(y=1|x;\theta)\),这样有以下两个事实:

  • \(P(y=1|x ; θ) + P(y=0|x ; θ) = 1\)
  • \(P(y=0|x ; θ) = 1 - P(y=1|x ; θ)\)

常用的激活函数:

  1. Sigmoid 函数

    \[S(x)=\frac{1}{1+e^{-x}}\]

    • 优点:便于求导
    • 三大缺点:
      • 容易出现 gradient vanishing
      • 函数输出并不是 zero-centered
      • 幂运算相对来讲比较耗时
    • Gradient Vanishing

      优化神经网络的方法是 Back Propagation,即导数的后向传递:先计算输出层对应的 loss,然后将 loss 以导数的形式不断向上一层网络传递,修正相应的参数,达到降低 loss 的目的。 Sigmoid 函数在深度网络中常常会导致导数逐渐变为 0,使得参数无法被更新,神经网络无法被优化。原因在于两点:(1) 在上图中容易看出,当 \(\sigma(x)\) 中 x 较大或较小时,导数接近 0,而后向传递的数学依据是微积分求导的链式法则,当前层的导数需要之前各层导数的乘积,几个小数的相乘,结果会很接近 0 (2) Sigmoid 导数的最大值是 0.25,这意味着导数在每一层至少会被压缩为原来的 1/4,通过两层后被变为1/16,…,通过 10 层后为 1/1048576。请注意这里是“至少”,导数达到最大值这种情况还是很少见的。

    • 输出并不是 zero-centered

      Sigmoid 函数的输出值恒大于 0,这会导致模型训练的收敛速度变慢。举例来讲,对\(\sigma(\Sigma_i w_ix_i+b)\),如果所有 \(x_i\) 均为正数或负数,那么其对 \(w_i\)的导数总是正数或负数,这会导致如下图红色箭头所示的阶梯式更新,这显然并非一个好的优化路径。深度学习往往需要大量时间来处理大量数据,模型的收敛速度是尤为重要的。所以,总体上来讲,训练深度学习网络尽量使用 zero-centered 数据(可以经过数据预处理实现) 和 zero-centered 输出。

    • 幂函数相对耗时

      相对于前两项,这其实并不是一个大问题,我们目前是具备相应计算能力的,但面对深度学习中庞大的计算量,最好是能省则省 :-)。之后我们会看到,在 ReLU 函数中,需要做的仅仅是一个 thresholding,相对于幂运算来讲会快很多。

  2. Tahn 函数

    \[tanh(x)=\frac{1-e^{-2x}}{1+e^{-2x}}=\frac{e^x-e^{-x}}{e^x+e^{-x}}\]

    tanh 读作 Hyperbolic Tangent,如上图所示,它解决了 zero-centered 的输出问题,然而,gradient vanishing 的问题和幂运算的问题仍然存在。

  3. ReLu 函数

    \[f(x)=max(0,x)\]

    ReLU 函数其实就是一个取最大值函数,注意这并不是全区间可导的,但是我们可以取 sub-gradient,如上图所示。ReLU 虽然简单,但却是近几年的重要成果,有以下几大优点:

    • 解决了gradient vanishing 问题 (在正区间)
    • 计算速度非常快,只需要判断输入是否大于 0
    • 收敛速度远快于 sigmoid 和 tanh

    ReLU 也有几个需要特别注意的问题:

    1. ReLU 的输出不是 zero-centered
    2. Dead ReLU Problem,指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新。有两个主要原因可能导致这种情况产生: (1) 非常不幸的参数初始化,这种情况比较少见 (2) learning rate 太高导致在训练过程中参数更新太大,不幸使网络进入这种状态。解决方法是可以采用 Xavier 初始化方法,以及避免将 learning rate 设置太大或使用adagrad 等自动调节 learning rate 的算法。

    尽管存在这两个问题,ReLU 目前仍是最常用的 activation function,在搭建人工神经网络的时候推荐优先尝试!

  4. Leaky ReLu 函数

    \[f(x)=max(0.01x,x)\]

    人们为了解决 Dead ReLU Problem,提出了将 ReLU 的前半段设为 0.01x 而非 0。另外一种直观的想法是基于参数的方法,即 Parametric ReLU: \(f(x)=max(\alpha x,x)\),其中 α 可由 back propagation 学出来。理论上来讲,Leaky ReLU 有 ReLU 的所有优点,外加不会有 Dead ReLU 问题,但是在实际操作当中,并没有完全证明 Leaky ReLU 总是好于 ReLU。

损失函数

我们定义如下的数据集,以及变量:

根据线性回归模型的损失函数:\(J(\theta)=\frac1m\sum_{i=1}^m\frac12(h_\theta(x^{(i)})-y^{(i)})^2\),我们重新定义损失函数为:\(J(\theta)=\frac1m\sum_{i=1}^mCost(h_{\theta}(x^{(i)}),y^{(i)})\)

新的 Cost 函数为: \[\begin{equation}Cost(h_\theta(x),y)=\left\{\begin{aligned}-log(h_\theta(x)) & & if \ y = 1\\-log(1-h_\theta(x)) & & if \ y = 0 \end{aligned}\right.\end{equation}\]

即:

化简后的 \(J(\theta)\) 为: \[J(\theta)=-\frac1m[\sum_{i=1}^m(y^{(i)}logh_\theta(x^{(i)})+(1-y^{(i)})log(1-h_\theta(x^{(i)})))]\]

接下来,通过梯度下降算法,更新权重,获取最小的 Loss 值即可。

反向传播算法

反向传播算法是减小损失函数的一个方法。

在神经网络中,我们定义的损失函数是整个网络的损失。所以在上文损失函数的基础上,我们需要加上每一层的损失函数,得到总的损失函数:

前一部分指的是每一个训练样本的输出向量的误差,后一部分是权重的损失值。

我们的目的是,寻求这样的参数 θ,来使得我们的损失函数最小化。

按照高等数学的理论,我们需要对 \(J(\theta)\) 求 θ 的偏微分: \(\frac{\partial}{\partial\theta^{l}_{ij}}J(\theta)\)

反向传播过程:

# NLP

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×