Commit 929453c8 by 曹润柘

合并分支 'master' 到 'caorunzhe'

Master

查看合并请求 !254
parents 34827943 f9eaf253
......@@ -10,8 +10,8 @@
\node [anchor=west,inner sep=2pt] (eq1) at (0,0) {$f(s_u|t_v)$};
\node [anchor=west] (eq2) at (eq1.east) {$=$\ };
\draw [-] ([xshift=0.3em]eq2.east) -- ([xshift=11.6em]eq2.east);
\node [anchor=south west] (eq3) at ([xshift=1em]eq2.east) {$\sum_{i=1}^{K} c_{\mathbb{E}}(s_u|t_v;s^{[i]},t^{[i]})$};
\node [anchor=north west] (eq4) at (eq2.east) {$\sum_{s_u} \sum_{i=1}^{K} c_{\mathbb{E}}(s_u|t_v;s^{[i]},t^{[i]})$};
\node [anchor=south west] (eq3) at ([xshift=1em]eq2.east) {$\sum_{k=1}^{K} c_{\mathbb{E}}(s_u|t_v;s^{[k]},t^{[k]})$};
\node [anchor=north west] (eq4) at (eq2.east) {$\sum_{s_u} \sum_{k=1}^{K} c_{\mathbb{E}}(s_u|t_v;s^{[k]},t^{[k]})$};
{
\node [anchor=south] (label1) at ([yshift=-6em,xshift=3em]eq1.north west) {利用这个公式计算};
......
......@@ -275,11 +275,11 @@ $\seq{t}$ = machine\; \underline{translation}\; is\; a\; process\; of\; generati
\parinterval 如果有更多的句子,上面的方法同样适用。假设,有$K$个互译句对$\{(\seq{s}^{[1]},\seq{t}^{[1]})$,...,\\$(\seq{s}^{[K]},\seq{t}^{[K]})\}$。仍然可以使用基于相对频次的方法估计翻译概率$\funp{P}(x,y)$,具体方法如下:
\begin{eqnarray}
\funp{P}(x,y) = \frac{{\sum_{i=1}^{K} c(x,y;\seq{s}^{[i]},\seq{t}^{[i]})}}{\sum_{i=1}^{K}{{\sum_{x',y'} c(x',y';\seq{s}^{[i]},\seq{t}^{[i]})}}}
\funp{P}(x,y) = \frac{{\sum_{k=1}^{K} c(x,y;\seq{s}^{[k]},\seq{t}^{[k]})}}{\sum_{k=1}^{K}{{\sum_{x',y'} c(x',y';\seq{s}^{[k]},\seq{t}^{[k]})}}}
\label{eq:5-4}
\end{eqnarray}
\parinterval 与公式\ref{eq:5-1}相比,公式\ref{eq:5-4}的分子、分母都多了一项累加符号$\sum_{i=1}^{K} \cdot$,它表示遍历语料库中所有的句对。换句话说,当计算词的共现次数时,需要对每个句对上的计数结果进行累加。从统计学习的角度,使用更大规模的数据进行参数估计可以提高结果的可靠性。计算单词的翻译概率也是一样,在小规模的数据上看,很多翻译现象的特征并不突出,但是当使用的数据量增加到一定程度,翻译的规律会很明显的体现出来。
\parinterval 与公式\ref{eq:5-1}相比,公式\ref{eq:5-4}的分子、分母都多了一项累加符号$\sum_{k=1}^{K} \cdot$,它表示遍历语料库中所有的句对。换句话说,当计算词的共现次数时,需要对每个句对上的计数结果进行累加。从统计学习的角度,使用更大规模的数据进行参数估计可以提高结果的可靠性。计算单词的翻译概率也是一样,在小规模的数据上看,很多翻译现象的特征并不突出,但是当使用的数据量增加到一定程度,翻译的规律会很明显的体现出来。
\parinterval 举个例子,实例\ref{eg:5-2}展示了一个由两个句对构成的平行语料库。
......@@ -1045,7 +1045,17 @@ f(s_u|t_v)=\frac{c_{\mathbb{E}}(s_u|t_v;\seq{s},\seq{t})} { \sum\limits_{s_u} c
\label{eq:5-45}
\end{eqnarray}
\vspace{-0.5em}
\parinterval 进一步,假设有$K$个互译的句对(称作平行语料):
$\{(\seq{s}^{[1]},\seq{t}^{[1]}),...,(\seq{s}^{[K]},\seq{t}^{[K]})\}$$f(s_u|t_v)$的期望频次为:
\begin{eqnarray}
c_{\mathbb{E}}(s_u|t_v)=\sum\limits_{k=1}^{K} c_{\mathbb{E}}(s_u|t_v;s^{[k]},t^{[k]})
\label{eq:5-46}
\end{eqnarray}
\parinterval 于是有$f(s_u|t_v)$的计算公式和迭代过程图\ref{fig:5-27}所示。完整的EM算法如图\ref{fig:5-28}所示。其中E-Step对应4-5行,目的是计算$c_{\mathbb{E}}(\cdot)$;M-Step对应6-9行,目的是计算$f(\cdot|\cdot)$
%----------------------------------------------
\begin{figure}[htp]
\centering
......@@ -1054,7 +1064,7 @@ f(s_u|t_v)=\frac{c_{\mathbb{E}}(s_u|t_v;\seq{s},\seq{t})} { \sum\limits_{s_u} c
\label{fig:5-27}
\end{figure}
%----------------------------------------------
\vspace{-1em}
%----------------------------------------------
\begin{figure}[htp]
\centering
......@@ -1064,15 +1074,6 @@ f(s_u|t_v)=\frac{c_{\mathbb{E}}(s_u|t_v;\seq{s},\seq{t})} { \sum\limits_{s_u} c
\end{figure}
%----------------------------------------------
\parinterval 进一步,假设有$K$个互译的句对(称作平行语料):
$\{(\seq{s}^{[1]},\seq{t}^{[1]}),...,(\seq{s}^{[K]},\seq{t}^{[K]})\}$$f(s_u|t_v)$的期望频次为:
\begin{eqnarray}
c_{\mathbb{E}}(s_u|t_v)=\sum\limits_{i=1}^{K} c_{\mathbb{E}}(s_u|t_v;s^{[i]},t^{[i]})
\label{eq:5-46}
\end{eqnarray}
\parinterval 于是有$f(s_u|t_v)$的计算公式和迭代过程图\ref{fig:5-27}所示。完整的EM算法如图\ref{fig:5-28}所示。其中E-Step对应4-5行,目的是计算$c_{\mathbb{E}}(\cdot)$;M-Step对应6-9行,目的是计算$f(\cdot|\cdot)$
\parinterval 至此,本章完成了对IBM模型1训练方法的介绍。其可以通过图\ref{fig:5-27}所示的算法进行实现。算法最终的形式并不复杂,因为只需要遍历每个句对,之后计算$f(\cdot|\cdot)$的期望频次,最后估计新的$f(\cdot|\cdot)$,这个过程迭代直至$f(\cdot|\cdot)$收敛至稳定状态。
\vspace{-1.5em}
......
......@@ -102,14 +102,14 @@
\vspace{0.5em}
\end{itemize}
\parinterval 另外,从应用的角度,数据量的快速提升和模型容量的增加也为深度学习的成功提供了条件,数据量的增加使得深度学习有了用武之地,例如,2000年以来,无论在学术研究还是在工业实践中,双语数据的使用数量都在逐年上升(如图\ref{fig:5-1}所示)。现在的深度学习模型参数量都十分巨大,因此需要大规模数据才能保证模型学习的充分性,而大数据时代的到来为训练这样的模型提供了数据基础。
\parinterval 另外,从应用的角度,数据量的快速提升和模型容量的增加也为深度学习的成功提供了条件,数据量的增加使得深度学习有了用武之地,例如,2000年以来,无论在学术研究还是在工业实践中,双语数据的使用数量都在逐年上升(如图\ref{fig:9-1}所示)。现在的深度学习模型参数量都十分巨大,因此需要大规模数据才能保证模型学习的充分性,而大数据时代的到来为训练这样的模型提供了数据基础。
%----------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-the-amount-of-data-in-a-bilingual-corpus}
\caption{机器翻译系统所使用的双语数据量变化趋势}
\label{fig:5-1}
\label{fig:9-1}
\end{figure}
%----------------------------------------------------------------------
......@@ -127,7 +127,7 @@
\subsubsection{1. 端到端学习和表示学习}
\parinterval 端到端学习使机器学习不再依赖传统的特征工程方法,因此也不需要繁琐的数据预处理、特征选择、降维等过程,而是直接利用人工神经网络自动从输入数据中提取、组合更复杂的特征,大大提升了模型能力和工程效率。以图\ref{fig:5-2}中的图像分类为例,在传统方法中,图像分类需要很多阶段的处理。首先,需要提取一些手工设计的图像特征,在将其降维之后,需要利用SVM等分类算法对其进行分类。与这种多阶段的流水线似的处理流程相比,端到端深度学习只训练一个神经网络,输入就是图片的像素表示,输出直接是分类类别。
\parinterval 端到端学习使机器学习不再依赖传统的特征工程方法,因此也不需要繁琐的数据预处理、特征选择、降维等过程,而是直接利用人工神经网络自动从输入数据中提取、组合更复杂的特征,大大提升了模型能力和工程效率。以图\ref{fig:9-2}中的图像分类为例,在传统方法中,图像分类需要很多阶段的处理。首先,需要提取一些手工设计的图像特征,在将其降维之后,需要利用SVM等分类算法对其进行分类。与这种多阶段的流水线似的处理流程相比,端到端深度学习只训练一个神经网络,输入就是图片的像素表示,输出直接是分类类别。
%------------------------------------------------------------------------------
\begin{figure}[htp]
......@@ -147,7 +147,7 @@
\end{minipage}%
}
\caption{特征工程{\small\sffamily\bfseries{vs}}端到端学习\red{(图要换)}}
\label{fig:5-2}
\label{fig:9-2}
\end {figure}
%------------------------------------------------------------------------------
......@@ -503,25 +503,25 @@ l_p(\mathbf x) & = & {\Vert{\mathbf x}\Vert}_p \nonumber \\
%----------------------------------------------------------------------------------------
\subsection{人工神经元和感知机}
\parinterval 生物学中,神经元是神经系统的基本组成单元。图\ref{fig:5-3}展示了一个生物神经元实例。
\parinterval 生物学中,神经元是神经系统的基本组成单元。图\ref{fig:9-3}展示了一个生物神经元实例。
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[width=8cm]{./Chapter9/Figures/biological-neuron.jpg}
\caption{生物神经元\red{(图要换)}}
\label{fig:5-3}
\label{fig:9-3}
\end{figure}
%-------------------------------------------
\parinterval 同样,人工神经元是人工神经网络的基本单元。在人们的想象中,人工神经元应该与生物神经元类似。但事实上,二者在形态上是有明显差别的。如图\ref{fig:5-4} 是一个典型的人工神经元,其本质是一个形似$ y=f(\mathbf x\cdot \mathbf w+b) $的函数。显而易见,一个神经元主要由$ \mathbf x $$ \mathbf w $$ b $$ f $四个部分构成。其中$ \mathbf x $是一个形如$ (x_0,x_1,\dots,x_n) $ 的实数向量,在一个神经元中担任``输入''的角色。$ \mathbf w $是一个权重矩阵,其中的每一个元素都对应着一个输入和一个输出,代表着``某输入对某输出的贡献程度'',通常也被理解为神经元连接的{\small\sffamily\bfseries{权重}}\index{权重}(weight)\index{weight}$ b $被称作偏置,是一个实数。$ f $被称作激活函数,用于对输入向量各项加权和后进行某种变换。可见,一个人工神经元的功能是将输入向量与权重矩阵右乘(做内积)后,加上偏置量,经过一个激活函数得到一个标量结果。
\parinterval 同样,人工神经元是人工神经网络的基本单元。在人们的想象中,人工神经元应该与生物神经元类似。但事实上,二者在形态上是有明显差别的。如图\ref{fig:9-4} 是一个典型的人工神经元,其本质是一个形似$ y=f(\mathbf x\cdot \mathbf w+b) $的函数。显而易见,一个神经元主要由$ \mathbf x $$ \mathbf w $$ b $$ f $四个部分构成。其中$ \mathbf x $是一个形如$ (x_0,x_1,\dots,x_n) $ 的实数向量,在一个神经元中担任``输入''的角色。$ \mathbf w $是一个权重矩阵,其中的每一个元素都对应着一个输入和一个输出,代表着``某输入对某输出的贡献程度'',通常也被理解为神经元连接的{\small\sffamily\bfseries{权重}}\index{权重}(weight)\index{weight}$ b $被称作偏置,是一个实数。$ f $被称作激活函数,用于对输入向量各项加权和后进行某种变换。可见,一个人工神经元的功能是将输入向量与权重矩阵右乘(做内积)后,加上偏置量,经过一个激活函数得到一个标量结果。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-artificial-neuron}
\caption{人工神经元}
\label{fig:5-4}
\label{fig:9-4}
\end{figure}
%----------------------------------------------
......@@ -533,7 +533,7 @@ l_p(\mathbf x) & = & {\Vert{\mathbf x}\Vert}_p \nonumber \\
\subsubsection{1. 感知机\ \dash \ 最简单的人工神经元模型}
\vspace{0.5em}
\parinterval 感知机是人工神经元的一种实例,在上世纪50-60年代被提出后,对神经网络研究产生了深远的影响。感知机模型如图\ref {fig:5-5}所示,其输入是一个$n$维二值向量$ \mathbf x=(x_0,x_1,\dots,x_n) $,其中$ x_i=0 $$ 1 $。权重$ \mathbf w=(w_0,w_1,\dots,w_n) $,每个输入变量对应一个权重$ w_i $(实数)。偏置$ b $是一个实数变量($ -\sigma $)。输出也是一个二值结果,即$ y=0 $$ 1 $$ y $值的判定由输入的加权和是否大于(或小于)一个阈值$ \sigma $决定(公式\ref{eq:5-19}):
\parinterval 感知机是人工神经元的一种实例,在上世纪50-60年代被提出后,对神经网络研究产生了深远的影响。感知机模型如图\ref {fig:9-5}所示,其输入是一个$n$维二值向量$ \mathbf x=(x_0,x_1,\dots,x_n) $,其中$ x_i=0 $$ 1 $。权重$ \mathbf w=(w_0,w_1,\dots,w_n) $,每个输入变量对应一个权重$ w_i $(实数)。偏置$ b $是一个实数变量($ -\sigma $)。输出也是一个二值结果,即$ y=0 $$ 1 $$ y $值的判定由输入的加权和是否大于(或小于)一个阈值$ \sigma $决定(公式\ref{eq:5-19}):
\begin{eqnarray}
y=\begin{cases} 0 & \sum_{i}{x_i\cdot w_i}-\sigma <0\\1 & \sum_{i}{x_i\cdot w_i}-\sigma \geqslant 0\end{cases}
\label{eq:5-19}
......@@ -544,7 +544,7 @@ y=\begin{cases} 0 & \sum_{i}{x_i\cdot w_i}-\sigma <0\\1 & \sum_{i}{x_i\cdot w_i}
\centering
\input{./Chapter9/Figures/fig-perceptron-mode}
\caption{感知机模型}
\label{fig:5-5}
\label{fig:9-5}
\end{figure}
%-------------------------------------------
......@@ -567,14 +567,14 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\label{eq:5-20}
\end{eqnarray}
\parinterval 如果你不是十分纠结的人,能够接受不完美的事情,你可能会把$ \sigma $设置为1,于是$ \sum{w_i\cdot x_i}-\sigma \ge 0 $,那么你会去音乐会。可以看出,上面的例子的本质就是一个如图\ref{fig:5-6}的感知机:
\parinterval 如果你不是十分纠结的人,能够接受不完美的事情,你可能会把$ \sigma $设置为1,于是$ \sum{w_i\cdot x_i}-\sigma \ge 0 $,那么你会去音乐会。可以看出,上面的例子的本质就是一个如图\ref{fig:9-6}的感知机:
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-perceptron-to-predict-1}
\caption{预测是否去剧场的感知机(权重相同)}
\label{fig:5-6}
\label{fig:9-6}
\end{figure}
%-------------------------------------------
......@@ -585,7 +585,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\vspace{-1em}
\subsubsection{2. 神经元内部权重}
\parinterval 在上面的例子中,连接权重代表着每个输入因素对最终输出结果的重要程度,为了得到令人满意的决策,需要不断调整权重。如果你是守财奴,则会对票价看得更重一些,这样你会用不均匀的权重计算每个因素的影响,比如:$ w_0=0.5 $$ w_1=2 $$ w_2=0.5 $,此时感知机模型如图\ref{fig:5-7}所示。在这种情况下,女友很希望和你一起去看音乐会,但是剧场很远而且票价500元,会导致你不去看音乐会,因为
\parinterval 在上面的例子中,连接权重代表着每个输入因素对最终输出结果的重要程度,为了得到令人满意的决策,需要不断调整权重。如果你是守财奴,则会对票价看得更重一些,这样你会用不均匀的权重计算每个因素的影响,比如:$ w_0=0.5 $$ w_1=2 $$ w_2=0.5 $,此时感知机模型如图\ref{fig:9-7}所示。在这种情况下,女友很希望和你一起去看音乐会,但是剧场很远而且票价500元,会导致你不去看音乐会,因为
\begin{eqnarray}
\sum_{i}{x_i\cdot w_i} & = & 0\cdot 0.5+0\cdot 2+1\cdot 0.5 \nonumber \\
& = & 0.5 \nonumber \\
......@@ -598,7 +598,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\centering
\input{./Chapter9/Figures/fig-perceptron-to-predict-2}
\caption{预测是否去剧场的感知机(改变权重)}
\label{fig:5-7}
\label{fig:9-7}
\end{figure}
%-------------------------------------------
......@@ -618,14 +618,14 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\parinterval $ x_2 $:女朋友是否喜欢
\parinterval 在新修改的模型中,$ x_0 $$ x_1 $变成了连续变量,$ x_2 $仍然是离散变量,如图\ref{fig:5-8}
\parinterval 在新修改的模型中,$ x_0 $$ x_1 $变成了连续变量,$ x_2 $仍然是离散变量,如图\ref{fig:9-8}
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-different-forms-of-neuronal-input}
\caption{神经元输入的不同形式}
\label{fig:5-8}
\label{fig:9-8}
\end{figure}
%-------------------------------------------
......@@ -645,14 +645,14 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\subsubsection{4. 神经元内部的参数学习}
\parinterval 一次成功的音乐会之后,你似乎掌握了一个真理:其他什么都不重要,女友的喜好最重要,所以你又将决策模型的权重做出了调整:最简单的方式就是$ w_0=w_1=0 $,同时令$ w_2>0 $,相当于只考虑$ x_2 $的影响而忽略其他因素,于是你得到了如图\ref {fig:5-9}所示的决策模型:
\parinterval 一次成功的音乐会之后,你似乎掌握了一个真理:其他什么都不重要,女友的喜好最重要,所以你又将决策模型的权重做出了调整:最简单的方式就是$ w_0=w_1=0 $,同时令$ w_2>0 $,相当于只考虑$ x_2 $的影响而忽略其他因素,于是你得到了如图\ref {fig:9-9}所示的决策模型:
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-perceptron-to-predict-3}
\caption{预测是否去剧场的决策模型(只考虑女友喜好)}
\label{fig:5-9}
\label{fig:9-9}
\end{figure}
%-------------------------------------------
......@@ -691,7 +691,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\parinterval 为了建立多层神经网络,首先需要把前面提到的简单的神经元进行扩展,把多个神经元组成一``层''神经元。比如,很多实际问题需要同时有多个输出,这时可以把多个相同的神经元并列起来,每个神经元都会有一个单独的输出,这就构成一``层'',形成了单层神经网络。单层神经网络中的每一个神经元都对应着一组权重和一个输出,可以把单层神经网络中的不同输出看作一个事物不同角度的描述。
\parinterval 举个简单的例子,预报天气时,往往需要预测温度、湿度和风力,这就意味着如果使用单层神经网络进行预测,需要设置3个神经元。如图\ref{fig:5-10},权重矩阵为:
\parinterval 举个简单的例子,预报天气时,往往需要预测温度、湿度和风力,这就意味着如果使用单层神经网络进行预测,需要设置3个神经元。如图\ref{fig:9-10},权重矩阵为:
\begin{eqnarray}
\mathbf w=\begin{pmatrix} w_{00} & w_{01} & w_{02}\\ w_{10} & w_{11} & w_{12}\end{pmatrix}
......@@ -702,18 +702,18 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\centering
\input{./Chapter9/Figures/fig-corresponence-between-matrix-element-and-output}
\caption{权重矩阵中的元素与输出的对应关系}
\label{fig:5-10}
\label{fig:9-10}
\end{figure}
%-------------------------------------------
\noindent 它的第一列元素$ \begin{pmatrix} w_{00}\\ w_{10}\end{pmatrix} $是输入相对第一个输出$ y_0 $ 的权重,参数向量$ \mathbf b=(b_0,b_1,b_2) $的第一个元素$ b_0 $是对应于第一个输出$ y_0 $ 的偏置量;类似的,可以得到$ y_1 $$ y_2 $。预测天气的单层模型如图\ref{fig:5-11}所示(在本例中,假设输入$ \mathbf x=(x_0,x_1) $)。
\noindent 它的第一列元素$ \begin{pmatrix} w_{00}\\ w_{10}\end{pmatrix} $是输入相对第一个输出$ y_0 $ 的权重,参数向量$ \mathbf b=(b_0,b_1,b_2) $的第一个元素$ b_0 $是对应于第一个输出$ y_0 $ 的偏置量;类似的,可以得到$ y_1 $$ y_2 $。预测天气的单层模型如图\ref{fig:9-11}所示(在本例中,假设输入$ \mathbf x=(x_0,x_1) $)。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-single-layer-of-neural-network-for-weather-prediction}
\caption{预测天气的单层神经网络}
\label{fig:5-11}
\label{fig:9-11}
\end{figure}
%-------------------------------------------
......@@ -731,7 +731,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\mathbf w=\begin{pmatrix} 1 & 0 & 0\\ 0 & -1 & 0\\ 0 & 0 & 1\end{pmatrix}
\end{eqnarray}
这样,矩形区域由第一象限旋转90度到了第四象限,如图\ref{fig:5-13}第一步所示。公式$ \mathbf x\cdot \mathbf w+\mathbf b $中的公式中的$ \mathbf b $相当于对其进行平移变换。其过程如图\ref{fig:5-13} 第二步所示,偏置矩阵$ \mathbf b=\begin{pmatrix} 0.5 & 0 & 0\\ 0 & 0 & 0\\ 0 & 0 & 0\end{pmatrix} $将矩形区域沿x轴向右平移了一段距离。
这样,矩形区域由第一象限旋转90度到了第四象限,如图\ref{fig:9-13}第一步所示。公式$ \mathbf x\cdot \mathbf w+\mathbf b $中的公式中的$ \mathbf b $相当于对其进行平移变换。其过程如图\ref{fig:9-13} 第二步所示,偏置矩阵$ \mathbf b=\begin{pmatrix} 0.5 & 0 & 0\\ 0 & 0 & 0\\ 0 & 0 & 0\end{pmatrix} $将矩形区域沿x轴向右平移了一段距离。
\vspace{0.5em}
\end{itemize}
......@@ -740,11 +740,11 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\centering
\input{./Chapter9/Figures/fig-translation}
\caption{线性变换示意图}
\label{fig:5-13}
\label{fig:9-13}
\end{figure}
%-------------------------------------------
\parinterval 也就是说,线性变换提供了对输入数据进行空间中旋转、平移的能力。当然,线性变换也适用于更加复杂的情况,这也为神经网络提供了拟合不同函数的能力。比如,可以利用线性变换将三维图形投影到二维平面上,或者将二维平面上的图形映射到三维空间。如图\ref{fig:5-14},通过一个简单的线性变换,可以将三维图形投影到二维平面上。
\parinterval 也就是说,线性变换提供了对输入数据进行空间中旋转、平移的能力。当然,线性变换也适用于更加复杂的情况,这也为神经网络提供了拟合不同函数的能力。比如,可以利用线性变换将三维图形投影到二维平面上,或者将二维平面上的图形映射到三维空间。如图\ref{fig:9-14},通过一个简单的线性变换,可以将三维图形投影到二维平面上。
\vspace{-0.5em}
%----------------------------------------------
......@@ -752,12 +752,12 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\centering
\input{./Chapter9/Figures/fig-linear-transformation}
\caption{线性变换3维$ \rightarrow $2维数学示意}
\label{fig:5-14}
\label{fig:9-14}
\end{figure}
%-------------------------------------------
\vspace{-0.5em}
\parinterval 那激活函数又是什么?神经元在接收到经过线性变换的结果后,通过激活函数的处理,得到最终的输出$ \mathbf y $。激活函数的目的是解决实际问题中的非线性变换,线性变换只能拟合直线,而激活函数的加入,使神经网络具有了拟合曲线的能力。 特别是在实际问题中,很多现象都无法用简单的线性关系描述,这时可以使用非线性激活函数来描述更加复杂的问题。常见的非线性函数有Sigmoid、ReLU、Tanh等。如图\ref{fig:5-15}列举了几种激活函数的形式。\\
\parinterval 那激活函数又是什么?神经元在接收到经过线性变换的结果后,通过激活函数的处理,得到最终的输出$ \mathbf y $。激活函数的目的是解决实际问题中的非线性变换,线性变换只能拟合直线,而激活函数的加入,使神经网络具有了拟合曲线的能力。 特别是在实际问题中,很多现象都无法用简单的线性关系描述,这时可以使用非线性激活函数来描述更加复杂的问题。常见的非线性函数有Sigmoid、ReLU、Tanh等。如图\ref{fig:9-15}列举了几种激活函数的形式。\\
%----------------------------------------------
\begin{figure}\centering
......@@ -802,7 +802,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\end{minipage}
}
\caption{几种常见的激活函数}
\label{fig:5-15}
\label{fig:9-15}
\end {figure}
%-------------------------------------------
......@@ -820,11 +820,11 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\centering
\input{./Chapter9/Figures/fig-four-layers-of-neural-network}
\caption{具有四层神经元的(三层)神经网络}
\label{fig:5-17}
\label{fig:9-17}
\end{figure}
%-------------------------------------------
\parinterval 在多层神经网络中,通常包括输入层、输出层和至少一个隐藏层。如图\ref{fig:5-17}是一个由四层神经网络构成的模型,包括输入层、输出层和两个隐藏层。\\
\parinterval 在多层神经网络中,通常包括输入层、输出层和至少一个隐藏层。如图\ref{fig:9-17}是一个由四层神经网络构成的模型,包括输入层、输出层和两个隐藏层。\\
%----------------------------------------------------------------------------------------
% NEW SUB-SECTION
......@@ -837,7 +837,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\parinterval 众所周知,单层神经网络无法解决线性不可分问题,比如经典的异或问题。但是具有一个隐藏层的两层神经网络在理论上就可以拟合所有的函数了。接下来我们分析一下为什么仅仅是多了一层,神经网络就能变得如此强大。对于二维空间(平面),``拟合''是指:把平面上一系列的点,用一条光滑的曲线连接起来,并用函数来表示这条拟合的曲线。这个概念可以推广到更高维空间上。在用神经网络解决问题时,可以通过拟合训练数据中的`` 数据点''来获得输入与输出之间的函数关系,并利用其对未知数据做出判断。可以假设输入与输出之间存在一种函数关系,而神经网络的``拟合''能力是要尽可能地逼近原函数输出值,与原函数输出值越逼近,则意味着拟合得越好。
\parinterval 如图\ref{fig:5-18}是一个以Sigmoid作为隐藏层激活函数的两层神经网络。通过调整参数$ \mathbf w=(w_1,w_2) $$ \mathbf b=(b_1,b_2) $$ \mathbf w^{'}=(w'_{1},w'_{2}) $ 的值,可以不断地改变目标函数的形状。
\parinterval 如图\ref{fig:9-18}是一个以Sigmoid作为隐藏层激活函数的两层神经网络。通过调整参数$ \mathbf w=(w_1,w_2) $$ \mathbf b=(b_1,b_2) $$ \mathbf w^{'}=(w'_{1},w'_{2}) $ 的值,可以不断地改变目标函数的形状。
%----------------------------------------------
......@@ -845,52 +845,52 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\centering
\input{./Chapter9/Figures/fig-two-layer-neural-network}
\caption{以Sigmoid作为隐藏层激活函数的两层神经网络}
\label{fig:5-18}
\label{fig:9-18}
\end{figure}
%-------------------------------------------
\parinterval 设置$ w'_1=1 $$ w_1=1 $$ b_1=0 $,其他参数设置为0。可以得到如图\ref{fig:5-19}(a)所示的目标函数,此时目标函数还是比较平缓的。通过调大$ w_1 $,可以将图\ref{fig:5-19}(a) 中函数的坡度调得更陡:当$ w_1=10 $时,如图\ref{fig:5-19}(b)所示,目标函数的坡度与图\ref{fig:5-19}(a)相比变得更陡了;当$ w_1=100 $时,如图\ref{fig:5-19}(c)所示,目标函数的坡度变得更陡、更尖锐,已经逼近一个阶梯函数。
\parinterval 设置$ w'_1=1 $$ w_1=1 $$ b_1=0 $,其他参数设置为0。可以得到如图\ref{fig:9-19}(a)所示的目标函数,此时目标函数还是比较平缓的。通过调大$ w_1 $,可以将图\ref{fig:9-19}(a) 中函数的坡度调得更陡:当$ w_1=10 $时,如图\ref{fig:9-19}(b)所示,目标函数的坡度与图\ref{fig:9-19}(a)相比变得更陡了;当$ w_1=100 $时,如图\ref{fig:9-19}(c)所示,目标函数的坡度变得更陡、更尖锐,已经逼近一个阶梯函数。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-weight}
\caption{通过调整权重$ w_1 $改变目标函数平滑程度}
\label{fig:5-19}
\label{fig:9-19}
\end {figure}
%-------------------------------------------
\parinterval 设置$ w'_1=1 $$ w_1=100 $$ b_1=0 $,其他参数设置为0。可以得到如图\ref{fig:5-20}(a)所示的目标函数,此时目标函数是一个阶梯函数,其``阶梯''恰好与y轴重合。通过改变$ b_1 $,可以将整个函数沿x轴向左右平移:当$ b_1=-2 $时,如图\ref{fig:5-20}(b)所示,与图\ref{fig:5-20}(a)相比目标函数的形状没有发生改变,但其位置沿x轴向右平移;当$ b_1=-4 $时,如图\ref{fig:5-20}(c)所示,目标函数的位置继续沿x轴向右平移。
\parinterval 设置$ w'_1=1 $$ w_1=100 $$ b_1=0 $,其他参数设置为0。可以得到如图\ref{fig:9-20}(a)所示的目标函数,此时目标函数是一个阶梯函数,其``阶梯''恰好与y轴重合。通过改变$ b_1 $,可以将整个函数沿x轴向左右平移:当$ b_1=-2 $时,如图\ref{fig:9-20}(b)所示,与图\ref{fig:9-20}(a)相比目标函数的形状没有发生改变,但其位置沿x轴向右平移;当$ b_1=-4 $时,如图\ref{fig:9-20}(c)所示,目标函数的位置继续沿x轴向右平移。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-bias}
\caption{通过调整偏置量$ b_1 $改变目标函数位置}
\label{fig:5-20}
\label{fig:9-20}
\end {figure}
%-------------------------------------------
\parinterval 设置$ w'_1=1 $$ w_1=100 $$ b_1=-4 $,其他参数设置为0。可以得到如图\ref{fig:5-21}\\(a)所示的目标函数,此时目标函数是一个阶梯函数,该阶梯函数取得最大值的分段处为$ y=1 $。 通过改变$ w'_1 $,可以将目标函数``拉高''或是``压扁''。如图\ref{fig:5-21}(b)和(c)所示,目标函数变得 ``扁''了。最终,该阶梯函数取得最大值的分段处约为$ y=0.7 $
\parinterval 设置$ w'_1=1 $$ w_1=100 $$ b_1=-4 $,其他参数设置为0。可以得到如图\ref{fig:9-21}\\(a)所示的目标函数,此时目标函数是一个阶梯函数,该阶梯函数取得最大值的分段处为$ y=1 $。 通过改变$ w'_1 $,可以将目标函数``拉高''或是``压扁''。如图\ref{fig:9-21}(b)和(c)所示,目标函数变得 ``扁''了。最终,该阶梯函数取得最大值的分段处约为$ y=0.7 $
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-w1}
\caption{通过改变权重$ w'_1 $将目标函数``拉高''或``压扁''}
\label{fig:5-21}
\label{fig:9-21}
\end {figure}
%-------------------------------------------
\parinterval 设置$ w'_1=0.7 $$ w_1=100 $$ b_1=-4 $,其他参数设置为0。可以得到如图\ref{fig:5-22}\\(a)所示的目标函数,此时目标函数是一个阶梯函数。若是将其他参数设置为$ w'_2=0.7 $$ w_2=100 $$ b_2=16 $,由图\ref{fig:5-22}(b)可以看出,原来目标函数的``阶梯''由一级变成了两级,由此可以推测,将第二组参数进行设置,可以使目标函数分段数增多;若将第二组参数中的$ w'_2 $由原来的$ 0.7 $设置为$ -0.7 $,可得到如图\ref{fig:5-22}(c)所示的目标函数,与图\ref{fig:5-22}(b)相比,原目标函数的``第二级阶梯''向下翻转,由此可见$ w' $的符号决定了目标函数的翻转方向。
\parinterval 设置$ w'_1=0.7 $$ w_1=100 $$ b_1=-4 $,其他参数设置为0。可以得到如图\ref{fig:9-22}\\(a)所示的目标函数,此时目标函数是一个阶梯函数。若是将其他参数设置为$ w'_2=0.7 $$ w_2=100 $$ b_2=16 $,由图\ref{fig:9-22}(b)可以看出,原来目标函数的``阶梯''由一级变成了两级,由此可以推测,将第二组参数进行设置,可以使目标函数分段数增多;若将第二组参数中的$ w'_2 $由原来的$ 0.7 $设置为$ -0.7 $,可得到如图\ref{fig:9-22}(c)所示的目标函数,与图\ref{fig:9-22}(b)相比,原目标函数的``第二级阶梯''向下翻转,由此可见$ w' $的符号决定了目标函数的翻转方向。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-w2}
\caption{通过设置第二组参数($b_2$$w'_2$)将目标函数分段数增加}
\label{fig:5-22}
\label{fig:9-22}
\end {figure}
%-------------------------------------------
......@@ -901,20 +901,20 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\centering
\input{./Chapter9/Figures/fig-piecewise}
\caption{将目标函数作分段处理}
\label{fig:5-23}
\label{fig:9-23}
\end {figure}
%-------------------------------------------
\parinterval 以如图\ref{fig:5-23}(a)所示的目标函数为例,为了拟合该函数,可以将其看成分成无数小段的分段函数,如图\ref{fig:5-23}(b)所示。
\parinterval 以如图\ref{fig:9-23}(a)所示的目标函数为例,为了拟合该函数,可以将其看成分成无数小段的分段函数,如图\ref{fig:9-23}(b)所示。
\parinterval 如图\ref{fig:5-24}(a)所示,上例中两层神经网络的函数便可以拟合出目标函数的一小段。为了使两层神经网络可以拟合出目标函数更多的一小段,需要增加隐层神经元的个数。如图\ref{fig:5-24}(b),将原本的两层神经网络神经元个数增多一倍,由2个神经元扩展到4个神经元,其函数的分段数也增加一倍,而此时的函数恰好可以拟合目标函数中的两个小段。以此类推,理论上,该两层神经网络便可以通过不断地增加隐层神经元数量去拟合任意函数。
\parinterval 如图\ref{fig:9-24}(a)所示,上例中两层神经网络的函数便可以拟合出目标函数的一小段。为了使两层神经网络可以拟合出目标函数更多的一小段,需要增加隐层神经元的个数。如图\ref{fig:9-24}(b),将原本的两层神经网络神经元个数增多一倍,由2个神经元扩展到4个神经元,其函数的分段数也增加一倍,而此时的函数恰好可以拟合目标函数中的两个小段。以此类推,理论上,该两层神经网络便可以通过不断地增加隐层神经元数量去拟合任意函数。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-fit}
\caption{扩展隐层神经元个数去拟合目标函数更多的``一小段''}
\label{fig:5-24}
\label{fig:9-24}
\end {figure}
%-------------------------------------------
......@@ -964,14 +964,14 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\parinterval 简单来说,张量是一种通用的工具,用于描述由多个数据构成的量。比如,输入的量有三个维度在变化,用矩阵不容易描述,但是用张量却很容易。
\parinterval 从计算机实现的角度来看,现在所有深度学习框架都把张量定义为``多维数组''。张量有一个非常重要的属性\ \dash \ {\small\bfnew{}}\index{}(Rank)\index{Rank}。可以将多维数组中``维''的属性与张量的``阶''的属性作类比,这两个属性都表示多维数组(张量)有多少个独立的方向。例如,3是一个标量(Scalar),相当于一个0维数组或0阶张量;$ {(\begin{array}{cccc} 2 & -3 & 0.8 & 0.2\end{array})}^{\rm T} $ 是一个向量(Vector),相当于一个1维数组或1阶张量;$ \begin{pmatrix} -1 & 3 & 7\\ 0.2 & 2 & 9\end{pmatrix} $是一个矩阵(Matrix),相当于一个2维数组或2阶张量;如图\ref{fig:5-25},这是一个3 维数组或3阶张量,其中,每个$4 \times 4$的方形代表一个2阶张量,这样的方形有4个,最终形成3阶张量。
\parinterval 从计算机实现的角度来看,现在所有深度学习框架都把张量定义为``多维数组''。张量有一个非常重要的属性\ \dash \ {\small\bfnew{}}\index{}(Rank)\index{Rank}。可以将多维数组中``维''的属性与张量的``阶''的属性作类比,这两个属性都表示多维数组(张量)有多少个独立的方向。例如,3是一个标量(Scalar),相当于一个0维数组或0阶张量;$ {(\begin{array}{cccc} 2 & -3 & 0.8 & 0.2\end{array})}^{\rm T} $ 是一个向量(Vector),相当于一个1维数组或1阶张量;$ \begin{pmatrix} -1 & 3 & 7\\ 0.2 & 2 & 9\end{pmatrix} $是一个矩阵(Matrix),相当于一个2维数组或2阶张量;如图\ref{fig:9-25},这是一个3 维数组或3阶张量,其中,每个$4 \times 4$的方形代表一个2阶张量,这样的方形有4个,最终形成3阶张量。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-tensor-sample}
\caption{3阶张量示例($4 \times 4 \times 4$}
\label{fig:5-25}
\label{fig:9-25}
\end{figure}
%-------------------------------------------
......@@ -1004,14 +1004,14 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\label{eq:5-25}
\end{eqnarray}
\noindent 其中,张量$ \mathbf x $沿第1阶所在的方向与矩阵$ \mathbf w $进行矩阵运算(张量$ \mathbf x $第1阶的每个维度都可以看做一个$ 4\times 4 $的矩阵)。图\ref{fig:5-27}演示了这个计算过程。张量$ \mathbf x $中编号为\ding{172}的子张量(可看作矩阵)与矩阵$ \mathbf w $进行矩阵乘法,其结果对应张量$ \mathbf s $中编号为\ding{172}的子张量。这个过程会循环四次,因为有四个这样的矩阵(子张量)。最终,图\ref{fig:5-27}给出了结果张量的形式($ 4 \times 4 \times 2 $)。
\noindent 其中,张量$ \mathbf x $沿第1阶所在的方向与矩阵$ \mathbf w $进行矩阵运算(张量$ \mathbf x $第1阶的每个维度都可以看做一个$ 4\times 4 $的矩阵)。图\ref{fig:9-27}演示了这个计算过程。张量$ \mathbf x $中编号为\ding{172}的子张量(可看作矩阵)与矩阵$ \mathbf w $进行矩阵乘法,其结果对应张量$ \mathbf s $中编号为\ding{172}的子张量。这个过程会循环四次,因为有四个这样的矩阵(子张量)。最终,图\ref{fig:9-27}给出了结果张量的形式($ 4 \times 4 \times 2 $)。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-tensor-mul}
\caption{张量与矩阵的矩阵乘法}
\label{fig:5-27}
\label{fig:9-27}
\end {figure}
%-------------------------------------------
......@@ -1026,14 +1026,14 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\begin{itemize}
\vspace{0.5em}
\item $ \mathbf s+\mathbf b $中的单元加就是对张量中的每个位置都进行加法。在上例中$ \mathbf s $是形状为$ (1:4,1:4,1:2) $的3阶张量,而$ \mathbf b $是含有4个元素的向量,在形状不同的情况下是怎样进行单元加的呢?在这里需要引入{\small\sffamily\bfseries{广播机制}}\index{广播机制}:如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失或长度为1的维度上进行,它是深度学习框架中常用的计算方式。来看一个具体的例子,如图\ref{fig:5-28}所示,$ \mathbf s $是一个$ 2\times 4 $的矩阵而$ \mathbf b $是一个长度为4的向量,这两者进行单元加运算时,广播机制会将$ \mathbf b $沿第一个维度复制后,再与$ \mathbf s $做加法运算。
\item $ \mathbf s+\mathbf b $中的单元加就是对张量中的每个位置都进行加法。在上例中$ \mathbf s $是形状为$ (1:4,1:4,1:2) $的3阶张量,而$ \mathbf b $是含有4个元素的向量,在形状不同的情况下是怎样进行单元加的呢?在这里需要引入{\small\sffamily\bfseries{广播机制}}\index{广播机制}:如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失或长度为1的维度上进行,它是深度学习框架中常用的计算方式。来看一个具体的例子,如图\ref{fig:9-28}所示,$ \mathbf s $是一个$ 2\times 4 $的矩阵而$ \mathbf b $是一个长度为4的向量,这两者进行单元加运算时,广播机制会将$ \mathbf b $沿第一个维度复制后,再与$ \mathbf s $做加法运算。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-broadcast}
\caption{广播机制}
\label{fig:5-28}
\label{fig:9-28}
\end {figure}
%-------------------------------------------
\vspace{0.5em}
......@@ -1057,11 +1057,11 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\begin{itemize}
\vspace{0.5em}
\item 张量$ \mathbf T(1:3) $表示一个含有三个元素的向量(1阶张量),其物理存储如图\ref{fig:5-29}(a)所示。
\item 张量$ \mathbf T(1:3) $表示一个含有三个元素的向量(1阶张量),其物理存储如图\ref{fig:9-29}(a)所示。
\vspace{0.5em}
\item 张量$ \mathbf T(1:2,1:3) $表示一个$ 2\times 3 $的矩阵(2阶张量),其物理存储如图\ref{fig:5-29}(b)所示。
\item 张量$ \mathbf T(1:2,1:3) $表示一个$ 2\times 3 $的矩阵(2阶张量),其物理存储如图\ref{fig:9-29}(b)所示。
\vspace{0.5em}
\item 张量$ \mathbf T(1:2,1:2,1:3) $表示一个大小$ 2\times 2\times 3 $的3阶张量,其物理存储如图\ref{fig:5-29}(c)所示。
\item 张量$ \mathbf T(1:2,1:2,1:3) $表示一个大小$ 2\times 2\times 3 $的3阶张量,其物理存储如图\ref{fig:9-29}(c)所示。
\vspace{0.5em}
\end{itemize}
......@@ -1070,7 +1070,7 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\centering
\input{./Chapter9/Figures/fig-save}
\caption{1阶(a)、2阶(b)、3阶张量(c)的物理存储}
\label{fig:5-29}
\label{fig:9-29}
\end{figure}
%-------------------------------------------
......@@ -1084,25 +1084,25 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\parinterval 实现神经网络的开源系统有很多,比如,使用经典的Python工具包Numpy。也可以使用成熟的深度学习框架,比如,Tensorflow和Pytorch就是非常受欢迎的深度学习工具包,除此之外还有很多其他优秀的框架:CNTK、MXNet、PaddlePaddle、\\Keras、Chainer、dl4j、NiuTensor等。开发者可以根据自身的喜好和开发项目的要求选择所采用的框架。
\parinterval 本节将使用NiuTensor来描述张量计算。NiuTensor是一个面向自然语言处理任务的张量库,它支持丰富的张量计算接口。如图\ref{fig:5-30}是一个使用NiuTensor声明、定义张量的C++代码:
\parinterval 本节将使用NiuTensor来描述张量计算。NiuTensor是一个面向自然语言处理任务的张量库,它支持丰富的张量计算接口。如图\ref{fig:9-30}是一个使用NiuTensor声明、定义张量的C++代码:
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-code-tensor-define}
\caption{使用NiuTensor声明定义张量}
\label{fig:5-30}
\label{fig:9-30}
\end{figure}
%-------------------------------------------
\parinterval 这段程序定义了一个形状为$ 2\times 2 $${\rm{dimsize}}=2,2 $),数据类型是单精度浮点($ \rm{dtype=X\_FLOAT} $),非稀疏($ \rm{dense}=1.00 $)的2阶($ \rm{order}=2 $)张量。运行这个程序会显示张量每个元素的值,如图\ref{fig:5-31}所示。
\parinterval 这段程序定义了一个形状为$ 2\times 2 $${\rm{dimsize}}=2,2 $),数据类型是单精度浮点($ \rm{dtype=X\_FLOAT} $),非稀疏($ \rm{dense}=1.00 $)的2阶($ \rm{order}=2 $)张量。运行这个程序会显示张量每个元素的值,如图\ref{fig:9-31}所示。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-code-out}
\caption{程序运行结果}
\label{fig:5-31}
\label{fig:9-31}
\end{figure}
%-------------------------------------------
......@@ -1120,29 +1120,29 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\vspace{0.5em}
\end{itemize}
\parinterval 定义XTensor的程序示例如图\ref{fig:5-32}(a)所示:
\parinterval 定义XTensor的程序示例如图\ref{fig:9-32}(a)所示:
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-code-tensor-define-2}
\caption{ NiuTensor定义张量程序示例}
\label{fig:5-32}
\label{fig:9-32}
\end{figure}
%-------------------------------------------
\parinterval 除此之外,NiuTensor还提供更简便的张量定义方式,如图\ref{fig:5-32}(b)所示。也可以在GPU上定义张量,如图\ref{fig:5-32}(c)所示。NiuTensor支持张量的各种代数运算,各种单元算子,如$ + $$ - $$ \ast $$ / $、Log(取对数)、Exp(指数运算)、Power(幂方运算)、Absolute(绝对值)等,还有Sigmoid、Softmax等激活函数。图\ref{fig:5-35}(a)是一段对张量进行1阶运算的程序示例。
\parinterval 除此之外,NiuTensor还提供更简便的张量定义方式,如图\ref{fig:9-32}(b)所示。也可以在GPU上定义张量,如图\ref{fig:9-32}(c)所示。NiuTensor支持张量的各种代数运算,各种单元算子,如$ + $$ - $$ \ast $$ / $、Log(取对数)、Exp(指数运算)、Power(幂方运算)、Absolute(绝对值)等,还有Sigmoid、Softmax等激活函数。图\ref{fig:9-35}(a)是一段对张量进行1阶运算的程序示例。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-code-tensor-operation}
\caption{ 张量代数运算程序示例}
\label{fig:5-35}
\label{fig:9-35}
\end{figure}
%-------------------------------------------
\parinterval 除了上述单元算子外,NiuTensor还支持张量之间的高阶运算,其中最常用的是矩阵乘法,图\ref{fig:5-35}(b)是张量之间进行矩阵乘法的程序示例。表\ref{tab:5-2}展示了一些NiuTensor支持的其他函数操作。
\parinterval 除了上述单元算子外,NiuTensor还支持张量之间的高阶运算,其中最常用的是矩阵乘法,图\ref{fig:9-35}(b)是张量之间进行矩阵乘法的程序示例。表\ref{tab:5-2}展示了一些NiuTensor支持的其他函数操作。
%--------------------------------------------------------------------
\begin{table}[htp]
......@@ -1182,14 +1182,14 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\parinterval 有了张量这个工具,可以很容易地实现任意的神经网络。反过来,神经网络都可以被看作是张量的函数。一种经典的神经网络计算模型是:给定输入张量,通过各个神经网络层所对应的张量计算之后,最后得到输出张量。这个过程也被称作{\small\sffamily\bfseries{前向传播}}\index{前向传播}(Forward Prorogation\index{Forward Prorogation}),它常常被应用在使用神经网络对新的样本进行推断中。
\parinterval 来看一个具体的例子,如图\ref{fig:5-37}(a)是一个根据天气情况判断穿衣指数(穿衣指数是人们穿衣薄厚的依据)的过程,将当天的天空状况、低空气温、水平气压作为输入,通过一层神经元在输入数据中提取温度、风速两方面的特征,并根据这两方面的特征判断穿衣指数。需要注意的是,在实际的神经网络中,并不能准确地知道神经元究竟可以提取到哪方面的特征,以上表述是为了让读者更好地理解神经网络的建模过程和前向传播过程。这里将上述过程建模为如图\ref{fig:5-37}(b)所示的两层神经网络。
\parinterval 来看一个具体的例子,如图\ref{fig:9-37}(a)是一个根据天气情况判断穿衣指数(穿衣指数是人们穿衣薄厚的依据)的过程,将当天的天空状况、低空气温、水平气压作为输入,通过一层神经元在输入数据中提取温度、风速两方面的特征,并根据这两方面的特征判断穿衣指数。需要注意的是,在实际的神经网络中,并不能准确地知道神经元究竟可以提取到哪方面的特征,以上表述是为了让读者更好地理解神经网络的建模过程和前向传播过程。这里将上述过程建模为如图\ref{fig:9-37}(b)所示的两层神经网络。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-weather}
\caption{判断穿衣指数问题的神经网络过程\red{(图需要改)}}
\label{fig:5-37}
\label{fig:9-37}
\end{figure}
%-------------------------------------------
......@@ -1199,17 +1199,17 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^{[1]}+\mathbf b^{[1]})\c
\label{eq:5-27}
\end{eqnarray}
\parinterval 前向计算实现如图\ref{fig:5-38}所示,图中对各张量和其他参数的形状做了详细说明。输入$ \mathbf x=(x_1,x_2,x_3) $是一个$1\times 3$的张量,其三个维度分别对应天空状况、低空气温、水平气压三个方面的数据。输入数据经过隐藏层的线性变换$ \mathbf x\cdot \mathbf w^{[1]}+\mathbf b^{[1]}$和Tanh函数的激活,得到新的张量$ \mathbf a=(a_1,a_2) $,其中$a_1$$a_2$分别对应着从输入数据中提取出的温度和风速两方面特征;神经网络在获取到天气情况的特征$ \mathbf a $后,继续对其进行线性变换$ \mathbf a\cdot \mathbf w^{[2]}+ b^{[2]} $和Sigmoid函数的激活操作,得到神经网络的最终输出$ y $,即神经网络此时预测的穿衣指数。
\parinterval 前向计算实现如图\ref{fig:9-38}所示,图中对各张量和其他参数的形状做了详细说明。输入$ \mathbf x=(x_1,x_2,x_3) $是一个$1\times 3$的张量,其三个维度分别对应天空状况、低空气温、水平气压三个方面的数据。输入数据经过隐藏层的线性变换$ \mathbf x\cdot \mathbf w^{[1]}+\mathbf b^{[1]}$和Tanh函数的激活,得到新的张量$ \mathbf a=(a_1,a_2) $,其中$a_1$$a_2$分别对应着从输入数据中提取出的温度和风速两方面特征;神经网络在获取到天气情况的特征$ \mathbf a $后,继续对其进行线性变换$ \mathbf a\cdot \mathbf w^{[2]}+ b^{[2]} $和Sigmoid函数的激活操作,得到神经网络的最终输出$ y $,即神经网络此时预测的穿衣指数。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-weather-forward}
\caption{前向计算示例(计算图)\red{(图需要改)}}
\label{fig:5-38}
\label{fig:9-38}
\end{figure}
%-------------------------------------------
\parinterval\ref{fig:5-38}实际上是神经网络的一种{\small\bfnew{计算图}}\index{计算图}(Computation Graph)\index{Computation Graph}表示。现在很多深度学习框架都是把神经网络转化为计算图,这样可以把复杂的运算分解为简单的运算,称为{\small\bfnew{算子}}\index{算子}(Calculus\index{Calculus})。通过对计算图中节点的遍历,可以方便地完成神经网络的计算。比如,可以对图中节点进行拓扑排序(由输入到输出),之后依次访问每个节点,同时完成相应的计算,这也就实现了一个前向计算的过程。
\parinterval\ref{fig:9-38}实际上是神经网络的一种{\small\bfnew{计算图}}\index{计算图}(Computation Graph)\index{Computation Graph}表示。现在很多深度学习框架都是把神经网络转化为计算图,这样可以把复杂的运算分解为简单的运算,称为{\small\bfnew{算子}}\index{算子}(Calculus\index{Calculus})。通过对计算图中节点的遍历,可以方便地完成神经网络的计算。比如,可以对图中节点进行拓扑排序(由输入到输出),之后依次访问每个节点,同时完成相应的计算,这也就实现了一个前向计算的过程。
\parinterval 使用计算图的另一个优点在于,这种方式易于参数梯度的计算。在后面的内容中会看到,计算神经网络中参数的梯度是模型训练的重要步骤。在计算图中,可以使用{\small\bfnew{反向传播}}\index{反向传播} (Backward Prorogation\index{Backward Prorogation})的方式逐层计算不同节点上的梯度信息。在\ref{sec5:para-training} 节会看到使用计算图这种结构可以非常方便、高效地计算反向传播中所需的梯度信息。
......@@ -1248,11 +1248,11 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^{[1]}+\mathbf b^{[1]})\c
\centering
\input{./Chapter9/Figures/fig-absolute-loss}
\caption{正确答案与神经网络输出之间的偏差}
\label{fig:5-42}
\label{fig:9-42}
\end{figure}
%-------------------------------------------
\parinterval 通常,可以通过设计{\small\sffamily\bfseries{损失函数}}\index{损失函数}(Loss Function)\index{Loss Function}来度量正确答案$ \mathbf {\widetilde y}_i $和神经网络输出$ \mathbf y_i $之间的偏差。而这个损失函数往往充当训练的{\small\sffamily\bfseries{目标函数}}\index{目标函数}(Objective Function)\index{Objective Function},神经网络训练就是通过不断调整神经网络内部的参数而使损失函数最小化。图\ref{fig:5-42}展示了一个绝对值损失函数的实例。
\parinterval 通常,可以通过设计{\small\sffamily\bfseries{损失函数}}\index{损失函数}(Loss Function)\index{Loss Function}来度量正确答案$ \mathbf {\widetilde y}_i $和神经网络输出$ \mathbf y_i $之间的偏差。而这个损失函数往往充当训练的{\small\sffamily\bfseries{目标函数}}\index{目标函数}(Objective Function)\index{Objective Function},神经网络训练就是通过不断调整神经网络内部的参数而使损失函数最小化。图\ref{fig:9-42}展示了一个绝对值损失函数的实例。
\parinterval 这里用$ Loss(\mathbf {\widetilde y}_i,\mathbf y_i) $表示网络输出$ \mathbf y_i $相对于答案$ \mathbf {\widetilde y}_i $的损失,简记为$ L $。表\ref{tab:5-3}是几种常见损失函数的定义。需要注意的是,没有一种损失函数可以适用于所有的问题。损失函数的选择取决于许多因素,包括:数据中是否有离群点、模型结构的选择、是否易于找到函数的导数以及预测结果的置信度等。对于相同的神经网络,不同的损失函数会对训练得到的模型产生不同的影响。对于新的问题,如果无法找到已有的、适合于该问题的损失函数,研究人员也可以自定义损失函数。因此设计新的损失函数也是神经网络中有趣的研究方向。
......@@ -1301,14 +1301,14 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^{[1]}+\mathbf b^{[1]})\c
\subsubsection{1. 梯度下降}
\parinterval 梯度下降法是一种常用的优化方法,非常适用于目标函数可微分的问题。它的基本思想是:给定函数上的第一个点,找到使函数值变化最大的方向,然后前进一``步'',这样模型就可以朝着更大(或更小)的函数值以最快的速度移动\footnote{梯度下降的一种实现是{\scriptsize\bfnew{最速下降}}(Steepest Descent)。该方法的每一步移动都选取合适的步长,进而使目标函数能得到最大程度的增长(或下降)。}。具体来说,梯度下降通过迭代更新参数$ \mathbf w $,不断沿着梯度的反方向让参数$ \mathbf w $朝着损失函数更小的方向移动:如果$ J(\mathbf w) $$ \mathbf w $可微分,则$ \frac{\partial J(\mathbf w)}{\partial \mathbf w} $将指向$ J(\mathbf w) $$ \mathbf w $处变化最大的方向,这里将其称之为梯度方向。$ \mathbf w $沿着梯度方向更新,新的$ \mathbf w $可以使函数更接近极值,其过程如图\ref{fig:5-43}所示。
\parinterval 梯度下降法是一种常用的优化方法,非常适用于目标函数可微分的问题。它的基本思想是:给定函数上的第一个点,找到使函数值变化最大的方向,然后前进一``步'',这样模型就可以朝着更大(或更小)的函数值以最快的速度移动\footnote{梯度下降的一种实现是{\scriptsize\bfnew{最速下降}}(Steepest Descent)。该方法的每一步移动都选取合适的步长,进而使目标函数能得到最大程度的增长(或下降)。}。具体来说,梯度下降通过迭代更新参数$ \mathbf w $,不断沿着梯度的反方向让参数$ \mathbf w $朝着损失函数更小的方向移动:如果$ J(\mathbf w) $$ \mathbf w $可微分,则$ \frac{\partial J(\mathbf w)}{\partial \mathbf w} $将指向$ J(\mathbf w) $$ \mathbf w $处变化最大的方向,这里将其称之为梯度方向。$ \mathbf w $沿着梯度方向更新,新的$ \mathbf w $可以使函数更接近极值,其过程如图\ref{fig:9-43}所示。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-gradient-descent}
\caption{函数上一个点沿着不同方向移动的示例}
\label{fig:5-43}
\label{fig:9-43}
\end{figure}
%-------------------------------------------
......@@ -1461,14 +1461,14 @@ $+2x^2+x+1)$ & \ \ $(x^4+2x^3+2x^2+x+1)$ & $+6x+1$ \\
\noindent 这里,$\bar{h_i}$表示损失函数$L$相对于$h_i$的梯度信息,它会被保存在节点$i$处。为了计算$\bar{h_i}$,需要从网络的输出反向计算每一个节点处的梯度。具体实现时,这个过程由一个包括前向计算和反向计算的两阶段方法实现。
\parinterval 首先,从神经网络的输入,逐层计算每层网络的输出值。如图\ref{fig:5-44},第$ i $ 层的输出$ \mathbf h_i $ 作为第$ i+1 $ 层的输入,数据流在神经网络内部逐层传递。
\parinterval 首先,从神经网络的输入,逐层计算每层网络的输出值。如图\ref{fig:9-44},第$ i $ 层的输出$ \mathbf h_i $ 作为第$ i+1 $ 层的输入,数据流在神经网络内部逐层传递。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-forward-propagation}
\caption{前向计算示意图}
\label{fig:5-44}
\label{fig:9-44}
\end{figure}
%-------------------------------------------
......@@ -1482,14 +1482,14 @@ $+2x^2+x+1)$ & \ \ $(x^4+2x^3+2x^2+x+1)$ & $+6x+1$ \\
\vspace{0.5em}
\end{itemize}
\parinterval 对于反向计算的实现,一般从神经网络的输出开始,逆向逐层计算每层网络输入所对应的微分结果。如图\ref{fig:5-45},在第$ i $层计算此处的梯度$ \frac{\partial L}{\partial \mathbf h_i} $,并将微分值向前一层传递,根据链式法则继续计算梯度。
\parinterval 对于反向计算的实现,一般从神经网络的输出开始,逆向逐层计算每层网络输入所对应的微分结果。如图\ref{fig:9-45},在第$ i $层计算此处的梯度$ \frac{\partial L}{\partial \mathbf h_i} $,并将微分值向前一层传递,根据链式法则继续计算梯度。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-back-propagation}
\caption{反向计算示意图}
\label{fig:5-45}
\label{fig:9-45}
\end{figure}
%-------------------------------------------
......@@ -1528,14 +1528,14 @@ w_{t+1}&=&w_t-\alpha v_t
\parinterval 该算法引入了一个``动量''的理念\cite{qian1999momentum},它是基于梯度的移动指数加权平均。公式中的$ v_t $是损失函数在前$ t-1 $次更新中累积的梯度动量,$ \beta $是梯度累积的一个指数,这里一般设置值为0.9。所以Momentum梯度下降算法的主要思想就是对网络的参数进行平滑处理,让梯度的摆动幅度变得更小。
\parinterval 这里的``梯度''不再只是现在的损失函数的梯度,而是之前的梯度的加权和。在原始的梯度下降算法中,如果在某个参数状态下,梯度方向变化特别大,甚至与上一次参数更新中梯度方向成90度夹角,下一次参数更新中梯度方向可能又是一次90度的改变,这时参数优化路径将会成``锯齿''状(如图\ref{fig:5-46}所示),优化效率极慢。而Momentum梯度下降算法不会让梯度发生90度的变化,而是让梯度慢慢发生改变:如果当前的梯度方向与之前的梯度方向相同,在原梯度方向上加速更新参数;如果当前的梯度方向与之前的梯度方向相反,并不会产生一个急转弯,而是尽量把优化路径平滑地进行改变。这样做的优点也非常明显,一方面杜绝了``锯齿''状优化路径的出现,另一方面将优化幅度变得更加平滑,不会导致频频跳过最优点。
\parinterval 这里的``梯度''不再只是现在的损失函数的梯度,而是之前的梯度的加权和。在原始的梯度下降算法中,如果在某个参数状态下,梯度方向变化特别大,甚至与上一次参数更新中梯度方向成90度夹角,下一次参数更新中梯度方向可能又是一次90度的改变,这时参数优化路径将会成``锯齿''状(如图\ref{fig:9-46}所示),优化效率极慢。而Momentum梯度下降算法不会让梯度发生90度的变化,而是让梯度慢慢发生改变:如果当前的梯度方向与之前的梯度方向相同,在原梯度方向上加速更新参数;如果当前的梯度方向与之前的梯度方向相反,并不会产生一个急转弯,而是尽量把优化路径平滑地进行改变。这样做的优点也非常明显,一方面杜绝了``锯齿''状优化路径的出现,另一方面将优化幅度变得更加平滑,不会导致频频跳过最优点。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-sawtooth}
\caption{Momentum梯度下降 vs 普通梯度下降}
\label{fig:5-46}
\label{fig:9-46}
\end{figure}
%-------------------------------------------
......@@ -1616,7 +1616,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\vspace{0.5em}
\end{itemize}
\parinterval\ref{fig:5-47}对比了同步更新和异步更新的区别,在这个例子中,使用4台设备对一个两层神经网络中的参数进行更新,其中使用了一个{\small\bfnew{参数服务器}}\index{参数服务器}(Parameter Server\index{Parameter Server})来保存最新的参数,不同设备(Worker,图中的G1、G2、G3)可以通过同步或者异步的方式访问参数服务器。图中的$ \mathbf w_o $$ \mathbf w_h $分别代表输出层和隐藏层的全部参数,操作push(P) 表示设备向参数服务器传送梯度,操作fetch(F)表示参数服务器向设备传送更新后的参数。
\parinterval\ref{fig:9-47}对比了同步更新和异步更新的区别,在这个例子中,使用4台设备对一个两层神经网络中的参数进行更新,其中使用了一个{\small\bfnew{参数服务器}}\index{参数服务器}(Parameter Server\index{Parameter Server})来保存最新的参数,不同设备(Worker,图中的G1、G2、G3)可以通过同步或者异步的方式访问参数服务器。图中的$ \mathbf w_o $$ \mathbf w_h $分别代表输出层和隐藏层的全部参数,操作push(P) 表示设备向参数服务器传送梯度,操作fetch(F)表示参数服务器向设备传送更新后的参数。
\parinterval 此外,在使用多个设备进行并行训练的时候,由于设备间带宽的限制,大量的数据传输会有较高的延时。对于复杂神经网络来说,设备间参数和梯度传递的时间消耗也会成为一个不得不考虑的因素。有时候,设备间数据传输的时间甚至比模型计算的时间都长,大大降低了并行度\cite{xiao2017fast}。对于这种问题,可以考虑对数据进行压缩或者减少传输的次数来缓解问题。
......@@ -1625,7 +1625,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\centering
\input{./Chapter9/Figures/fig-parallel}
\caption{同步更新与异步更新对比\red{(图要改成中文)}}
\label{fig:5-47}
\label{fig:9-47}
\end {figure}
%-------------------------------------------
......@@ -1675,7 +1675,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\item {\small\bfnew{层归一化}}\index{层归一化}(Layer Normalization)\index{Layer Normalization}。类似的,层归一化更多是针对自然语言处理这种序列处理任务\cite{Ba2016LayerN},它和批量归一化的原理是一样的,只是归一化操作是在序列上同一层网络的输出结果上进行的,也就是归一化操作沿着序列方向进行。这种方法可以很好的避免序列上不同位置神经网络输出结果的不可比性。同时由于归一化后所有的结果都转化到一个可比的范围,使得隐层状态可以在不同层之间进行自由组合。
\item {\small\bfnew{残差网络}}\index{残差网络}(Residual Networks)\index{Residual Networks}。最初,残差网络是为了解决神经网络持续加深时的模型退化问题\cite{DBLP:journals/corr/HeZRS15},但是残差结构对解决梯度消失和梯度爆炸问题也有所帮助。有了残差结构,可以很轻松的构建几十甚至上百层的神经网络,而不用担心层数过深造成的梯度消失问题。残差网络的结构如图\ref{fig:5-51}所示。图\ref{fig:5-51}中右侧的曲线叫做{\small\bfnew{跳接}}\index{跳接}(Shortcut Connection)\index{Shortcut Connection},通过跳接在激活函数前,将上一层(或几层)之前的输出与本层计算的输出相加,将求和的结果输入到激活函数中作为本层的输出。假设残差结构的输入为$ \mathbf x_l $,输出为$ \mathbf x_{l+1} $,则有
\item {\small\bfnew{残差网络}}\index{残差网络}(Residual Networks)\index{Residual Networks}。最初,残差网络是为了解决神经网络持续加深时的模型退化问题\cite{DBLP:journals/corr/HeZRS15},但是残差结构对解决梯度消失和梯度爆炸问题也有所帮助。有了残差结构,可以很轻松的构建几十甚至上百层的神经网络,而不用担心层数过深造成的梯度消失问题。残差网络的结构如图\ref{fig:9-51}所示。图\ref{fig:9-51}中右侧的曲线叫做{\small\bfnew{跳接}}\index{跳接}(Shortcut Connection)\index{Shortcut Connection},通过跳接在激活函数前,将上一层(或几层)之前的输出与本层计算的输出相加,将求和的结果输入到激活函数中作为本层的输出。假设残差结构的输入为$ \mathbf x_l $,输出为$ \mathbf x_{l+1} $,则有
\begin{eqnarray}
\mathbf x_{l+1}&=&F(\mathbf x_l)+\mathbf x_l
......@@ -1688,7 +1688,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\centering
\input{./Chapter9/Figures/fig-residual-structure}
\caption{残差网络的结构}
\label{fig:5-51}
\label{fig:9-51}
\end{figure}
%-------------------------------------------
......@@ -1726,14 +1726,14 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval 为了获取梯度,最常用的做法是使用自动微分技术,通常通过{\small\sffamily\bfseries{反向传播}}\index{反向传播}(Back Propagation)\index{Back Propagation}来实现。该方法分为两个计算过程:前向计算和反向计算。前向计算的目的是从输入开始,逐层计算,得到网络的输出,并记录计算图中每个节点的局部输出。反向计算过程从输出端反向计算梯度,这个过程可以被看作是一种梯度的``传播'',最终计算图中所有节点都会得到相应的梯度结果。
\parinterval 这里,首先对反向传播算法中涉及到的符号进行统一说明。图\ref{fig:5-52}是一个多层神经网络,其中层$ k-1 $、层$ k $、层$ k+1 $均为神经网络中的隐藏层,层$ K $为神经网络中的输出层。为了化简问题,这里每层网络没有使用偏置项。
\parinterval 这里,首先对反向传播算法中涉及到的符号进行统一说明。图\ref{fig:9-52}是一个多层神经网络,其中层$ k-1 $、层$ k $、层$ k+1 $均为神经网络中的隐藏层,层$ K $为神经网络中的输出层。为了化简问题,这里每层网络没有使用偏置项。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-multilayer-neural-network-example}
\caption{多层神经网络实例}
\label{fig:5-52}
\label{fig:9-52}
\end{figure}
%-------------------------------------------
......@@ -1787,14 +1787,14 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\label{eq:5-48}
\end{eqnarray}
\noindent 也就是,输出层(第$ K $层)的输入$ \mathbf h^{K-1} $先经过线性变换右乘$ \mathbf w^K $转换为中间状态$ \mathbf s^K $,之后$ \mathbf s^K $再经过激活函数$ f^K(\cdot) $变为$ \mathbf h^K $$ \mathbf h^K $即为第$ K $层(输出层)的输出。最后,$ \mathbf h^K $和标准答案一起计算得到损失函数的值,记为$ L $。以上过程如图\ref{fig:5-53}所示。这里将输出层的前向计算过程细化为两个阶段:线性变换阶段和激活函数+损失函数阶段。
\noindent 也就是,输出层(第$ K $层)的输入$ \mathbf h^{K-1} $先经过线性变换右乘$ \mathbf w^K $转换为中间状态$ \mathbf s^K $,之后$ \mathbf s^K $再经过激活函数$ f^K(\cdot) $变为$ \mathbf h^K $$ \mathbf h^K $即为第$ K $层(输出层)的输出。最后,$ \mathbf h^K $和标准答案一起计算得到损失函数的值,记为$ L $。以上过程如图\ref{fig:9-53}所示。这里将输出层的前向计算过程细化为两个阶段:线性变换阶段和激活函数+损失函数阶段。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-forward-propagation-output}
\caption{输出层的前向计算过程}
\label{fig:5-53}
\label{fig:9-53}
\end{figure}
%-------------------------------------------
......@@ -1811,14 +1811,14 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\vspace{0.5em}
\end{itemize}
\parinterval 对于前两个步骤,如图\ref{fig:5-54}所示:
\parinterval 对于前两个步骤,如图\ref{fig:9-54}所示:
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-back-propagation-output1}
\caption{从损失到中间状态的反向传播(输出层)}
\label{fig:5-54}
\label{fig:9-54}
\end{figure}
%-------------------------------------------
......@@ -1844,14 +1844,14 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval 这个过程可以得到$ \mathbf s^K $节点处的梯度$ {\pi}^K= \frac{\partial L}{\partial \mathbf s^K} $,在后续的过程中可以直接使用其作为前一层提供的梯度计算结果,而不需要从$ \mathbf h^K $节点处重新计算。这也体现了自动微分与符号微分的差别,对于计算图的每一个阶段,并不需要得到完成的微分表达式,而是通过前一层提供的梯度,直接计算当前的梯度即可,这样避免了大量的重复计算。
\parinterval 在得到$ {\pi}^K= \frac{\partial L}{\partial \mathbf s^K} $之后,下一步的目标是:1)计算损失函数$ L $相对于第$ K-1 $层与输出层之间连接权重$ \mathbf w^K $的梯度;2)计算损失函数$ L $相对于神经网络网络第$ K-1 $层输出结果$ \mathbf h^{K-1} $的梯度。这部分内容如图\ref{fig:5-55}所示。
\parinterval 在得到$ {\pi}^K= \frac{\partial L}{\partial \mathbf s^K} $之后,下一步的目标是:1)计算损失函数$ L $相对于第$ K-1 $层与输出层之间连接权重$ \mathbf w^K $的梯度;2)计算损失函数$ L $相对于神经网络网络第$ K-1 $层输出结果$ \mathbf h^{K-1} $的梯度。这部分内容如图\ref{fig:9-55}所示。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-back-propagation-output2}
\caption{从中间状态到输入的反向传播(输出层)}
\label{fig:5-55}
\label{fig:9-55}
\end{figure}
%-------------------------------------------
......@@ -1890,14 +1890,14 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\label{eq:5-53}
\end{eqnarray}
\noindent 其中,$ \mathbf h^k $$ \mathbf s^k $$ \mathbf h^{k-1} $$\mathbf w^k $和分别表示隐藏层的输出、中间状态、隐藏层的输入和参数矩阵。隐藏层的前向计算过程如图\ref{fig:5-56}所示,第$ k-1 $ 层神经元的输出$ \mathbf h^{k-1} $经过线性变换和激活函数后,将计算结果$ \mathbf h^k $向后一层传递。
\noindent 其中,$ \mathbf h^k $$ \mathbf s^k $$ \mathbf h^{k-1} $$\mathbf w^k $和分别表示隐藏层的输出、中间状态、隐藏层的输入和参数矩阵。隐藏层的前向计算过程如图\ref{fig:9-56}所示,第$ k-1 $ 层神经元的输出$ \mathbf h^{k-1} $经过线性变换和激活函数后,将计算结果$ \mathbf h^k $向后一层传递。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-forward-propagation-hid}
\caption{隐藏层的前向计算过程}
\label{fig:5-56}
\label{fig:9-56}
\end{figure}
%-------------------------------------------
......@@ -1925,14 +1925,14 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\label{eq:5-56}
\end{eqnarray}
\parinterval $ \frac{\partial L}{\partial \mathbf h^{k-1}} $需要继续向第$ k-1 $隐藏层传递。$ \frac{\partial L}{\partial \mathbf w^k} $会作为参数的梯度用于参数更新。图\ref{fig:5-57}展示了隐藏层反向传播的计算过程。
\parinterval $ \frac{\partial L}{\partial \mathbf h^{k-1}} $需要继续向第$ k-1 $隐藏层传递。$ \frac{\partial L}{\partial \mathbf w^k} $会作为参数的梯度用于参数更新。图\ref{fig:9-57}展示了隐藏层反向传播的计算过程。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-back-propagation-hid}
\caption{隐藏层的反向传播}
\label{fig:5-57}
\label{fig:9-57}
\end{figure}
%-------------------------------------------
......@@ -1944,26 +1944,26 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\subsubsection{3. 实例}
\parinterval 为了进一步理解反向传播的过程,图\ref{fig:5-58}展示了一个简单的神经网络的反向传播程序示例。
\parinterval 为了进一步理解反向传播的过程,图\ref{fig:9-58}展示了一个简单的神经网络的反向传播程序示例。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-code-back-propagation-1}
\caption{手动编写反向传播代码(NiuTensor)}
\label{fig:5-58}
\label{fig:9-58}
\end{figure}
%-------------------------------------------
\parinterval 此外,很多张量计算工具都提供了封装好的反向传播函数。如图\ref{fig:5-59}所示,在完成神经网络的搭建后,无论前向计算过程是怎样的,直接利用Backward 函数就可以实现整个神经网络的反向传播,系统开发人员可以完全不用关心其求解过程。
\parinterval 此外,很多张量计算工具都提供了封装好的反向传播函数。如图\ref{fig:9-59}所示,在完成神经网络的搭建后,无论前向计算过程是怎样的,直接利用Backward 函数就可以实现整个神经网络的反向传播,系统开发人员可以完全不用关心其求解过程。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-code-back-propagation-2}
\caption{反向传播的自动微分实现(NiuTensor)}
\label{fig:5-59}
\label{fig:9-59}
\end{figure}
%-------------------------------------------
......@@ -2027,11 +2027,11 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\centering
\input{./Chapter9/Figures/fig-4-gram}
\caption{4-gram前馈神经网络语言架构}
\label{fig:5-60}
\label{fig:9-60}
\end{figure}
%-------------------------------------------
\parinterval 为了有一个直观的认识,这里以4-gram的FNNLM语言模型为例,即根据前三个单词$ w_{i-3} $$ w_{i-2} $$ w_{i-1} $预测当前单词$ w_i $的概率。模型结构如图\ref{fig:5-60}所示。从结构上看,FNNLM是一个典型的多层神经网络结构。主要有三层:
\parinterval 为了有一个直观的认识,这里以4-gram的FNNLM语言模型为例,即根据前三个单词$ w_{i-3} $$ w_{i-2} $$ w_{i-1} $预测当前单词$ w_i $的概率。模型结构如图\ref{fig:9-60}所示。从结构上看,FNNLM是一个典型的多层神经网络结构。主要有三层:
\begin{itemize}
\vspace{0.3em}
......@@ -2103,14 +2103,14 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval 在FNNLM中,所有的参数、输入、输出都是连续变量,因此FNNLM也是典型的一个连续空间模型。通过使用交叉熵等损失函数,FNNLM很容易进行优化。比如,可以使用梯度下降方法对FNNLM的模型参数进行训练。
\parinterval FNNLM的实现也非常简单,图\ref{fig:5-61}展示了基于FNNLM一个简单实现。虽然FNNLM模型形式简单,却为处理自然语言提供了一个全新的视角。首先,该模型重新定义了``词是什么''\ \dash \ 它并非词典的一项,而是可以用一个连续实数向量进行表示的可计算的``量''。此外,由于$n$-gram不再是离散的符号序列,模型不需要记录$n$-gram,所以很好的缓解了上面所提到的数据稀疏问题,模型体积也大大减小。
\parinterval FNNLM的实现也非常简单,图\ref{fig:9-61}展示了基于FNNLM一个简单实现。虽然FNNLM模型形式简单,却为处理自然语言提供了一个全新的视角。首先,该模型重新定义了``词是什么''\ \dash \ 它并非词典的一项,而是可以用一个连续实数向量进行表示的可计算的``量''。此外,由于$n$-gram不再是离散的符号序列,模型不需要记录$n$-gram,所以很好的缓解了上面所提到的数据稀疏问题,模型体积也大大减小。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-code-fnnlm}
\caption{FNNLM模型代码示例(NiuTensor)}
\label{fig:5-61}
\label{fig:9-61}
\end{figure}
%-------------------------------------------
......@@ -2132,7 +2132,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval 对于长距离依赖问题,可以通过{\small\sffamily\bfseries{循环神经网络}}\index{循环神经网络}(Recurrent Neural Network\index{Recurrent Neural Network},或RNN)进行求解。通过引入循环单元这种特殊的结构,循环神经网络可以对任意长度的历史进行建模,因此在一定程度上解决了传统$n$-gram语言模型有限历史的问题。正是基于这个优点,{\small\sffamily\bfseries{循环神经网络语言模型}}\index{循环神经网络语言模型}(RNNLM)\index{RNNLM}应运而生\cite{mikolov2010recurrent}
\parinterval 在循环神经网络中,输入和输出都是一个序列,分别记为$ (\mathbf x_1,\dots,\mathbf x_m) $$ (\mathbf y_1,\dots,\\ \mathbf y_m) $。它们都可以被看作是时序序列,其中每个时刻$ t $都对应一个输入$ \mathbf x_t $和输出$ \mathbf y_t $。循环神经网络的核心是{\small\sffamily\bfseries{循环单元}}\index{循环单元}(RNN Cell)\index{RNN Cell},它读入前一个时刻循环单元的输出和当前时刻的输入,生成当前时刻循环单元的输出。图\ref{fig:5-62}展示了一个简单的循环单元结构,对于时刻$ t $,循环单元的输出被定义为:
\parinterval 在循环神经网络中,输入和输出都是一个序列,分别记为$ (\mathbf x_1,\dots,\mathbf x_m) $$ (\mathbf y_1,\dots,\\ \mathbf y_m) $。它们都可以被看作是时序序列,其中每个时刻$ t $都对应一个输入$ \mathbf x_t $和输出$ \mathbf y_t $。循环神经网络的核心是{\small\sffamily\bfseries{循环单元}}\index{循环单元}(RNN Cell)\index{RNN Cell},它读入前一个时刻循环单元的输出和当前时刻的输入,生成当前时刻循环单元的输出。图\ref{fig:9-62}展示了一个简单的循环单元结构,对于时刻$ t $,循环单元的输出被定义为:
\begin{eqnarray}
\mathbf h_t&=&{\rm{Tanh}}(\mathbf x_t\mathbf U+\mathbf h_{t-1}\mathbf W)
\label{eq:5-63}
......@@ -2146,14 +2146,14 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\noindent 其中,$ \mathbf V $是输出层的模型参数。
\parinterval\ref{fig:5-62}展示了一个基于循环神经网络的语言模型结构。首先,所有输入的单词会被转换成分布式表示(红色部分),这个过程和FNNLM是一样的。之后,该模型堆叠了两层循环神经网络(绿色部分)。最后通过Softmax层(紫色部分)得到每个时刻的预测结果$ \mathbf y_t={\rm P}(w_t|w_1\dots w_{t-1}) $
\parinterval\ref{fig:9-62}展示了一个基于循环神经网络的语言模型结构。首先,所有输入的单词会被转换成分布式表示(红色部分),这个过程和FNNLM是一样的。之后,该模型堆叠了两层循环神经网络(绿色部分)。最后通过Softmax层(紫色部分)得到每个时刻的预测结果$ \mathbf y_t={\rm P}(w_t|w_1\dots w_{t-1}) $
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-rnn-lm}
\caption{基于循环神经网络的语言模型结构}
\label{fig:5-62}
\label{fig:9-62}
\end{figure}
%-------------------------------------------
......@@ -2185,14 +2185,14 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\subsubsection{1. One-hot编码}
\parinterval {\small\sffamily\bfseries{One-hot编码}}\index{One-hot编码}(也称{\small\sffamily\bfseries{独热编码}}\index{独热编码})是传统的单词表示方法。One-hot编码把单词表示为词汇表大小的0-1向量,其中只有该词所对应的那一项是1,而其余所有项都是零。举个简单的例子,假如有一个词典,里面包含10k个单词,并进行编号。那么每个单词都可以表示为一个10k维的One-hot向量,它仅在对应编号那个维度为1,其他维度都为0,如图\ref{fig:5-64}所示。
\parinterval {\small\sffamily\bfseries{One-hot编码}}\index{One-hot编码}(也称{\small\sffamily\bfseries{独热编码}}\index{独热编码})是传统的单词表示方法。One-hot编码把单词表示为词汇表大小的0-1向量,其中只有该词所对应的那一项是1,而其余所有项都是零。举个简单的例子,假如有一个词典,里面包含10k个单词,并进行编号。那么每个单词都可以表示为一个10k维的One-hot向量,它仅在对应编号那个维度为1,其他维度都为0,如图\ref{fig:9-64}所示。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-one-hot}
\caption{单词的One-hot表示 }
\label{fig:5-64}
\label{fig:9-64}
\end{figure}
%-------------------------------------------
......@@ -2206,14 +2206,14 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval 神经语言模型中使用的是一种{\small\sffamily\bfseries{分布式表示}}\index{分布式表示}(Distributed Representation)\index{Distributed Representation}。在神经语言模型里,每个单词不再是完全正交的0-1向量,而是在多维实数空间中的一个点,具体表现为一个实数向量。很多时候,也会把单词的这种分布式表示叫做{\small\sffamily\bfseries{词嵌入}}\index{词嵌入}(Word Embedding)\index{Word Embedding}
\parinterval 单词的分布式表示可以被看作是欧式空间中的一个点,因此单词之间的关系也可以通过空间的几何性质进行刻画。如图\ref{fig:5-65}所示,可以在一个512维空间上表示不同的单词。在这种表示下,``桌子''与``椅子''之间是具有一定的联系的。
\parinterval 单词的分布式表示可以被看作是欧式空间中的一个点,因此单词之间的关系也可以通过空间的几何性质进行刻画。如图\ref{fig:9-65}所示,可以在一个512维空间上表示不同的单词。在这种表示下,``桌子''与``椅子''之间是具有一定的联系的。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-embedding}
\caption{单词的分布式表示(词嵌入) }
\label{fig:5-65}
\label{fig:9-65}
\end{figure}
%-------------------------------------------
......@@ -2228,25 +2228,25 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\qquad 屋里 要 摆放 一个{ \blue{椅子}} \hspace{0.5em}\quad\quad 没见过,但是仍然是合理预测
\end{example}
\parinterval 关于单词的分布式表示还有一个经典的例子:通过词嵌入可以得到如下关系:$\textrm{``国王''}=\textrm{``女王''}-\textrm{``女人''} +\textrm{``男人''}$。从这个例子可以看出,词嵌入也具有一些代数性质,比如,词的分布式表示可以通过加、减等代数运算相互转换。图\ref{fig:5-66}展示了词嵌入在一个二维平面上的投影,不难发现,含义相近的单词分布比较临近。
\parinterval 关于单词的分布式表示还有一个经典的例子:通过词嵌入可以得到如下关系:$\textrm{``国王''}=\textrm{``女王''}-\textrm{``女人''} +\textrm{``男人''}$。从这个例子可以看出,词嵌入也具有一些代数性质,比如,词的分布式表示可以通过加、减等代数运算相互转换。图\ref{fig:9-66}展示了词嵌入在一个二维平面上的投影,不难发现,含义相近的单词分布比较临近。
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[width=6cm]{./Chapter9/Figures/word-graph.jpg}
\caption{分布式表示的可视化}
\label{fig:5-66}
\label{fig:9-66}
\end{figure}
%-------------------------------------------
\parinterval 语言模型的词嵌入是通过词嵌入矩阵进行存储的,矩阵中的每一行对应了一个词的分布式表示结果。图\ref{fig:5-67}展示了一个词嵌入矩阵的实例。
\parinterval 语言模型的词嵌入是通过词嵌入矩阵进行存储的,矩阵中的每一行对应了一个词的分布式表示结果。图\ref{fig:9-67}展示了一个词嵌入矩阵的实例。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-embedding-matrix}
\caption{词嵌入矩阵$mathbf C$}
\label{fig:5-67}
\label{fig:9-67}
\end{figure}
%-------------------------------------------
......@@ -2270,27 +2270,27 @@ Jobs was the CEO of {\red{\underline{apple}}}.
\parinterval 回忆一下神经语言模型的结构,它需要在每个位置预测单词生成的概率。这个概率是由若干层神经网络进行计算后,通过输出层得到的。实际上,在送入输出层之前,系统已经得到了这个位置的一个向量(隐藏层的输出),因此可以把它看作是含有一部分上下文信息的表示结果。
\parinterval 以RNN为例,图\ref{fig:5-68}展示了一个由四个词组成的句子,这里使用了一个两层循环神经网络对其进行建模。可以看到,对于第三个位置,RNN已经积累了从第1个单词到第3个单词的信息,因此可以看作是单词1-3(``乔布斯\ 就职\ 于'')的一种表示;另一方面,第4个单词的词嵌入可以看作是``苹果''自身的表示。这样,可以把第3 个位置RNN的输出和第4个位置的词嵌入进行合并,就得到了第4个位置上含有上下文信息的表示结果。从另一个角度说,这里得到了``苹果''的一种新的表示,它不仅包含苹果这个词自身的信息,也包含它前文的信息。
\parinterval 以RNN为例,图\ref{fig:9-68}展示了一个由四个词组成的句子,这里使用了一个两层循环神经网络对其进行建模。可以看到,对于第三个位置,RNN已经积累了从第1个单词到第3个单词的信息,因此可以看作是单词1-3(``乔布斯\ 就职\ 于'')的一种表示;另一方面,第4个单词的词嵌入可以看作是``苹果''自身的表示。这样,可以把第3 个位置RNN的输出和第4个位置的词嵌入进行合并,就得到了第4个位置上含有上下文信息的表示结果。从另一个角度说,这里得到了``苹果''的一种新的表示,它不仅包含苹果这个词自身的信息,也包含它前文的信息。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-rnn-model}
\caption{基于RNN的表示模型(词+上下文)}
\label{fig:5-68}
\label{fig:9-68}
\end{figure}
%-------------------------------------------
\parinterval 在自然语言处理中,{\small\sffamily\bfseries{句子表示模型}}\index{句子表示模型}是指把输入的句子进行分布式表示。不过表示的形式不一定是一个单独的向量。现在广泛使用的句子表示模型可以被描述为:给定一个输入的句子$ \{ w_1,\dots ,w_m\} $,得到一个表示序列$ \{ \mathbf h_1,\dots ,\mathbf h_m\} $,其中$ h_i $是句子在第$ i $个位置的表示结果。$ \{ \mathbf h_1,\dots ,\mathbf h_m\} $就被看作是{\small\sffamily\bfseries{句子的表示}}\index{句子的表示},它可以被送入下游模块。比如,在机器翻译任务中,可以用这种模型表示源语言句子,然后通过这种表示结果进行目标语译文的生成;在序列标注(如词性标注)任务中,可以对输入的句子进行表示,然后在这个表示之上构建标签预测模块。很多自然语言处理任务都可以用句子表示模型进行建模,因此句子的表示模型也是应用最广泛的深度学习模型之一。而学习这种表示的过程也被称作{\small\sffamily\bfseries{表示学习}}\index{表示学习}(Representation Learning)\index{Representation Learning}
\parinterval 句子表示模型有两种训练方法。最简单的方法是把它作为目标系统中的一个模块进行训练,比如把句子表示模型作为机器翻译系统的一部分。也就是,并不单独训练句子表示模型,而是把它作为一个内部模块放到其他系统中。另一种方法是把句子表示作为独立的模块,用外部系统进行训练,之后把训练好的表示模型放入目标系统中,再进行微调。这种方法构成了一种新的范式:预训练+微调(pre-training + fine-tuning)。图\ref{fig:5-69}对比了这两种不同的方法。
\parinterval 句子表示模型有两种训练方法。最简单的方法是把它作为目标系统中的一个模块进行训练,比如把句子表示模型作为机器翻译系统的一部分。也就是,并不单独训练句子表示模型,而是把它作为一个内部模块放到其他系统中。另一种方法是把句子表示作为独立的模块,用外部系统进行训练,之后把训练好的表示模型放入目标系统中,再进行微调。这种方法构成了一种新的范式:预训练+微调(pre-training + fine-tuning)。图\ref{fig:9-69}对比了这两种不同的方法。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter9/Figures/fig-model-training}
\caption{表示模型的训练方法(与目标任务联合训练 vs 用外部任务预训练)}
\label{fig:5-69}
\label{fig:9-69}
\end{figure}
%-------------------------------------------
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论