Commit e7ed4855 by 曹润柘

更新 chapter5.tex

parent 7b50e5a2
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
\parinterval 最初,神经网络设计的初衷是用计算模型来模拟生物大脑中神经元的运行机理,这种想法哪怕在现在看来也是十分超前的,甚至仍然影响着目前很多的研究方向。例如,目前很多机构关注的概念\raisebox{0.5mm}{------}``类脑计算''就是希望研究人脑的运行机制及相关的计算机实现方法。然而模拟大脑这件事并没有想象中的那么简单,众所周知,生物学中对人脑机制的研究是十分困难的,人们对人脑的运行机制尚不明确又何谈模拟呢?因而,神经网络技术的发展一直是在几乎没有任何参照的情况下摸索着进行的,神经网络发展到现在,其计算过程与人脑的运行机制已经大相径庭。 \parinterval 最初,神经网络设计的初衷是用计算模型来模拟生物大脑中神经元的运行机理,这种想法哪怕在现在看来也是十分超前的,甚至仍然影响着目前很多的研究方向。例如,目前很多机构关注的概念\raisebox{0.5mm}{------}``类脑计算''就是希望研究人脑的运行机制及相关的计算机实现方法。然而模拟大脑这件事并没有想象中的那么简单,众所周知,生物学中对人脑机制的研究是十分困难的,人们对人脑的运行机制尚不明确又何谈模拟呢?因而,神经网络技术的发展一直是在几乎没有任何参照的情况下摸索着进行的,神经网络发展到现在,其计算过程与人脑的运行机制已经大相径庭。
\parinterval 人工神经网络的第一个发展阶段是在二十世纪40年代到70年代,这个时期的人工神经网络还停留在利用线性模型模拟生物神经元的阶段,比如使用线性加权函数来描述输入$ \mathbf x $和输出$ y $之间的联系:$ f(\mathbf x,\mathbf w)=x_1 \cdot w_1 + \dots + x_n \cdot w_n $,举一个简单例子,输入$ \mathbf x $是这个地区的坐标和时间,然后输出$ y $是这个地区的温度,尽管真实的问题可能要复杂的多,但是线性模型确实有能力去拟合简单的函数关系。 \parinterval 人工神经网络的第一个发展阶段是在二十世纪40年代到70年代,这个时期的人工神经网络还停留在利用线性模型模拟生物神经元的阶段,比如使用线性加权函数来描述输入$ \mathbf x $和输出$ y $之间的联系:$ f(\mathbf x,\mathbf w)=x_1 \cdot w_1 + \dots + x_n \cdot w_n $,举一个简单例子,输入$ \mathbf x $是这个地区的坐标和时间,输出$ y $是这个地区的温度,尽管真实的问题可能要复杂的多,但是线性模型确实有能力去拟合简单的函数关系。
\parinterval 这种线性模型在现在看来可能比较``简陋'',但是这类模型对后来的随机下降等经典方法产生了深远影响。不过,显而易见的是,这种结构也存在着非常明显的缺陷,单层结构限制了它的学习能力,使它无法描述非线性问题,如著名的异或函数(XOR)学习问题,然而非线性才是现实世界的普遍特征,第一代人工神经网络对现实世界中的大部分事物规律都无法准确描述。此后,神经网络的研究陷入了很长一段时间的低迷期。 \parinterval 这种线性模型在现在看来可能比较``简陋'',但是这类模型对后来的随机下降等经典方法产生了深远影响。不过,显而易见的是,这种结构也存在着非常明显的缺陷,单层结构限制了它的学习能力,使它无法描述非线性问题,如著名的异或函数(XOR)学习问题,然而非线性才是现实世界的普遍特征,第一代人工神经网络对现实世界中的大部分事物规律都无法准确描述。此后,神经网络的研究陷入了很长一段时间的低迷期。
%--5.1.1.2神经网络的第二次高潮和第二次寒冬--------------------- %--5.1.1.2神经网络的第二次高潮和第二次寒冬---------------------
...@@ -620,7 +620,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=1 ...@@ -620,7 +620,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=1
\parinterval 那激活函数又是什么?神经元在接收到经过线性变换的结果后,通过激活函数的处理,得到最终的输出$ \mathbf y $。激活函数的目的是解决实际问题中的非线性变换,线性变换只能拟合直线,而激活函数的加入,使神经网络具有了拟合曲线的能力。 特别是在实际问题中,很多现象都无法用简单的线性关系描述,这时激活函数的非线性就为我们描述更加复杂的问题提供了工具。 \parinterval 那激活函数又是什么?神经元在接收到经过线性变换的结果后,通过激活函数的处理,得到最终的输出$ \mathbf y $。激活函数的目的是解决实际问题中的非线性变换,线性变换只能拟合直线,而激活函数的加入,使神经网络具有了拟合曲线的能力。 特别是在实际问题中,很多现象都无法用简单的线性关系描述,这时激活函数的非线性就为我们描述更加复杂的问题提供了工具。
\parinterval 神经网络方法的本质是拟合输入与输出的函数关系,正是激活函数赋予了神经网络拟合任何函数的能力。常见的非线性函数有Sigmoid、Relu、Tanh等。如图\ref{fig:activation}列举了几种激活函数的函数曲线。 \parinterval 神经网络方法的本质是拟合输入与输出的函数关系,正是激活函数赋予了神经网络拟合任何函数的能力。常见的非线性函数有sigmoid、relu、tanh等。如图\ref{fig:activation}列举了几种激活函数的函数曲线。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}\centering \begin{figure}\centering
...@@ -701,13 +701,13 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2=0\cdot 1+0\cdot 1+1\cdot 1=1 ...@@ -701,13 +701,13 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2=0\cdot 1+0\cdot 1+1\cdot 1=1
\parinterval 众所周知,单层神经网络无法解决线性不可分问题,比如经典的异或问题。但是具有一个隐藏层的两层神经网络在理论上就可以拟合所有的函数了。有些神奇?接下来我们分析一下为什么仅仅是多了一层,神经网络就能变得如此强大。在此之前,需要明确的一点是,``拟合''是把平面上一系列的点,用一条光滑的曲线连接起来,并用函数来表示这条拟合的曲线。在用神经网络解决问题时,我们是通过拟合训练数据中的``数据点''来获得输入与输出之间的函数关系,并利用其对未知数据做出判断。我们可以认为输入与输出之间存在一种函数关系,而神经网络的``拟合''能力并不是可以完全准确的计算某输入对应的原函数输出值,而是尽可能地逼近原函数输出值,与原函数输出值越逼近,则意味着拟合得越优秀。 \parinterval 众所周知,单层神经网络无法解决线性不可分问题,比如经典的异或问题。但是具有一个隐藏层的两层神经网络在理论上就可以拟合所有的函数了。有些神奇?接下来我们分析一下为什么仅仅是多了一层,神经网络就能变得如此强大。在此之前,需要明确的一点是,``拟合''是把平面上一系列的点,用一条光滑的曲线连接起来,并用函数来表示这条拟合的曲线。在用神经网络解决问题时,我们是通过拟合训练数据中的``数据点''来获得输入与输出之间的函数关系,并利用其对未知数据做出判断。我们可以认为输入与输出之间存在一种函数关系,而神经网络的``拟合''能力并不是可以完全准确的计算某输入对应的原函数输出值,而是尽可能地逼近原函数输出值,与原函数输出值越逼近,则意味着拟合得越优秀。
\parinterval 如图\ref{fig:two-layer-neural-network}是一个以Sigmoid作为隐藏层激活函数的两层神经网络。通过调整参数$ \mathbf w=(w_1,w_2) $$ \mathbf b=(b_1,b_2) $$ \mathbf w’=(w’_0,w’_1) $的值,我们可以不断地改变目标函数的形状。 \parinterval 如图\ref{fig:two-layer-neural-network}是一个以sigmoid作为隐藏层激活函数的两层神经网络。通过调整参数$ \mathbf w=(w_1,w_2) $$ \mathbf b=(b_1,b_2) $$ \mathbf w’=(w’_0,w’_1) $的值,我们可以不断地改变目标函数的形状。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-two-layer-neural-network} \input{./Chapter5/Figures/fig-two-layer-neural-network}
\caption{Sigmoid作为隐藏层激活函数的两层神经网络} \caption{sigmoid作为隐藏层激活函数的两层神经网络}
\label{fig:two-layer-neural-network} \label{fig:two-layer-neural-network}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
...@@ -878,7 +878,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=1 ...@@ -878,7 +878,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=1
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\parinterval 将矩阵乘法扩展到高阶张量中: \parinterval 将矩阵乘法扩展到高阶张量中:
\parinterval 一个张量$ \mathbf x $若要与矩阵$ \mathbf w $做矩阵乘法,则$ \mathbf x $的第一维度需要与$ \mathbf w $的行数大小相等,即:若张量$ \mathbf x $的形状为$ \cdot \times n $$ \mathbf w $须为$ n\times m $的矩阵。 \parinterval 一个张量$ \mathbf x $若要与矩阵$ \mathbf w $做矩阵乘法,则$ \mathbf x $的第一维度需要与$ \mathbf w $的行数大小相等,即:若张量$ \mathbf x $的形状为$ \cdot \times n $$ \mathbf w $须为$ n\times \cdot $的矩阵。
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\mathbf x(1:4,1:4,{\red{1:4}})\times {\mathbf w({\red{1:4}},1:2)}=\mathbf s(1:4,1:4,1:2) \mathbf x(1:4,1:4,{\red{1:4}})\times {\mathbf w({\red{1:4}},1:2)}=\mathbf s(1:4,1:4,1:2)
...@@ -915,14 +915,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=1 ...@@ -915,14 +915,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=1
%------------------------------------------- %-------------------------------------------
\vspace{0.5em} \vspace{0.5em}
\item 除了单位加之外,张量之间也可以减法、乘法,也可以对张量作激活函数。我们将其称作为函数的向量化(vectorization)。例如,对向量(1阶张量)作Relu激活,其中Relu激活函数的公式为: \item 除了单位加之外,张量之间也可以减法、乘法,也可以对张量作激活函数。我们将其称作为函数的向量化(vectorization)。例如,对向量(1阶张量)作relu激活,其中relu激活函数的公式为:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases} f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases}
\label{eqa1.26} \label{eqa1.26}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
例如$ {\rm{Relu}}\left( \begin{pmatrix} 2\\-.3\end{pmatrix}\right)=\begin{pmatrix} 2\\0\end{pmatrix} $ 例如$ {\rm{relu}}\left( \begin{pmatrix} 2\\-.3\end{pmatrix}\right)=\begin{pmatrix} 2\\0\end{pmatrix} $
\end{itemize} \end{itemize}
\vspace{0.5em} \vspace{0.5em}
%--5.3.2 张量的物理存储形式--------------------- %--5.3.2 张量的物理存储形式---------------------
...@@ -1027,7 +1027,7 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases} ...@@ -1027,7 +1027,7 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval NiuTensor支持张良的各种代数运算,各种单元算子,如$ + $$ - $$ \ast $$ / $、Log(取对数)、Exp(指数运算)、Power(幂方运算)、Absolute(绝对值)等,还有Sigmoid、Softmax等激活函数。如图\ref{fig:code-tensor-operation}是一段对张量进行1阶运算的程序示例。 \parinterval NiuTensor支持张良的各种代数运算,各种单元算子,如$ + $$ - $$ \ast $$ / $、Log(取对数)、Exp(指数运算)、Power(幂方运算)、Absolute(绝对值)等,还有sigmoid、softmax等激活函数。如图\ref{fig:code-tensor-operation}是一段对张量进行1阶运算的程序示例。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1073,10 +1073,10 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases} ...@@ -1073,10 +1073,10 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases}
\rule{0pt}{15pt} Concatenate(a,b,d) & 把两个张量$ \mathbf a $$ \mathbf b $沿d方向级联 \\ \rule{0pt}{15pt} Concatenate(a,b,d) & 把两个张量$ \mathbf a $$ \mathbf b $沿d方向级联 \\
\rule{0pt}{15pt} Merge(a,d) & 对张量$ \mathbf a $沿d方向合并 \\ \rule{0pt}{15pt} Merge(a,d) & 对张量$ \mathbf a $沿d方向合并 \\
\rule{0pt}{15pt} Split(a,d,n) & 对张量$ \mathbf a $沿d方向分裂成n份 \\ \rule{0pt}{15pt} Split(a,d,n) & 对张量$ \mathbf a $沿d方向分裂成n份 \\
\rule{0pt}{15pt} Sigmoid(a) &$ \mathbf a $进行Sigmoid变换 \\ \rule{0pt}{15pt} Sigmoid(a) &$ \mathbf a $进行sigmoid变换 \\
\rule{0pt}{15pt} Softmax(a) &$ \mathbf a $进行Softmax变换,沿最后一个方向 \\ \rule{0pt}{15pt} Softmax(a) &$ \mathbf a $进行softmax变换,沿最后一个方向 \\
\rule{0pt}{15pt} HardTanh(a) &$ \mathbf a $进行hard tanh变换(双曲正切的近似) \\ \rule{0pt}{15pt} HardTanh(a) &$ \mathbf a $进行hard tanh变换(双曲正切的近似) \\
\rule{0pt}{15pt} Relu(a) &$ \mathbf a $进行Relu变换 \\ \rule{0pt}{15pt} Relu(a) &$ \mathbf a $进行relu变换 \\
\end{tabular} \end{tabular}
\end{table} \end{table}
%表2-------------------------------------------------------------------- %表2--------------------------------------------------------------------
...@@ -1098,10 +1098,10 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases} ...@@ -1098,10 +1098,10 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 它可以被描述为公式\ref{eqa1.27},其中隐藏层的激活函数是Tanh函数,输出层的激活函数是Sigmoid函数: \parinterval 它可以被描述为公式\ref{eqa1.27},其中隐藏层的激活函数是tanh函数,输出层的激活函数是sigmoid函数:
%公式------------------------------------------ %公式------------------------------------------
\begin{eqnarray} \begin{eqnarray}
y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathbf w^2+\mathbf b^2 ) y={\rm{sigmoid}}({\rm{tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathbf w^2+\mathbf b^2 )
\label{eqa1.27} \label{eqa1.27}
\end{eqnarray} \end{eqnarray}
%公式------------------------------------------ %公式------------------------------------------
...@@ -1115,14 +1115,14 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb ...@@ -1115,14 +1115,14 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 前向计算实现如图\ref{fig:weather-forward}所示,图中对各张量和其他参数的形状做了详细说明,类似shape(3)这种形式代表维度为3的1阶张量,shape(3,2)代表2阶张量,其中第1阶有3个维度,第2阶有2个维度,也可以将其理解为$ 3\ast 2 $的矩阵。输入$ \mathbf x $是一个1阶张量,该阶有3个维度,分别对应天空状况、低空气温、水平气压三个方面。输入数据经过隐藏层的线性变换$ \mathbf x\cdot \mathbf w^1+\mathbf b^1 $Tanh激活函数后,得到新的张量$ \mathbf a $,张量$ \mathbf a $也是一个1阶张量,该阶有2个维度,分别对应着从输入数据中提取出的温度和风速两方面特征;神经网络在获取到天气情况的特征$ \mathbf a $后,继续对其进行线性变换$ \mathbf a\cdot \mathbf w^2+ b^2 $$ b^2 $是标量)和Sigmoid激活函数后,得到神经网络的最终输出$ y $,即神经网络此时预测的穿衣指数。 \parinterval 前向计算实现如图\ref{fig:weather-forward}所示,图中对各张量和其他参数的形状做了详细说明,类似shape(3)这种形式代表维度为3的1阶张量,shape(3,2)代表2阶张量,其中第1阶有3个维度,第2阶有2个维度,也可以将其理解为$ 3\ast 2 $的矩阵。输入$ \mathbf x $是一个1阶张量,该阶有3个维度,分别对应天空状况、低空气温、水平气压三个方面。输入数据经过隐藏层的线性变换$ \mathbf x\cdot \mathbf w^1+\mathbf b^1 $tanh激活函数后,得到新的张量$ \mathbf a $,张量$ \mathbf a $也是一个1阶张量,该阶有2个维度,分别对应着从输入数据中提取出的温度和风速两方面特征;神经网络在获取到天气情况的特征$ \mathbf a $后,继续对其进行线性变换$ \mathbf a\cdot \mathbf w^2+ b^2 $$ b^2 $是标量)和sigmoid激活函数后,得到神经网络的最终输出$ y $,即神经网络此时预测的穿衣指数。
%--5.3.5 神经网络实例--------------------- %--5.3.5 神经网络实例---------------------
\subsection{神经网络实例}\index{Chapter5.3.5} \subsection{神经网络实例}\index{Chapter5.3.5}
\parinterval 在了解了神经网络前向计算过程的基础上,我们进一步使用NiuTensor来演示搭建神经网络的过程。注意,搭建神经网络的过程本质上就是定义前向计算的过程。 \parinterval 在了解了神经网络前向计算过程的基础上,我们进一步使用NiuTensor来演示搭建神经网络的过程。注意,搭建神经网络的过程本质上就是定义前向计算的过程。
\parinterval 首先我们构造一个单层神经网络。如图\ref{fig:code-niutensor-one}所示,简单的定义输入、权重和偏置后,定义激活函数为Sigmoid函数,输入$ \mathbf x $经过线性变换和激活函数,得到输出。 \parinterval 首先我们构造一个单层神经网络。如图\ref{fig:code-niutensor-one}所示,简单的定义输入、权重和偏置后,定义激活函数为sigmoid函数,输入$ \mathbf x $经过线性变换和激活函数,得到输出。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1133,7 +1133,7 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb ...@@ -1133,7 +1133,7 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 如图\ref{fig:code-niutensor-three}是使用NiuTensor构造三层神经网络的程序示例,首先定义输入和各层的权重、偏置,随后定义神经网络中各层的实现细节,在第一层中,$ \mathbf x $作为输入,$ \mathbf h1 $作为输出,其中$ \mathbf h1={\rm{Sigmoid}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1) $。在第二层中,$ \mathbf h1 $作为输入,$ \mathbf h2 $作为输出,其中$ \mathbf h2={\rm{Tanh}}(\mathbf h1\cdot \mathbf w^2) $。在第三层中,$ \mathbf h2 $作为输入,$ \mathbf y $作为输出,其中$ \mathbf y={\rm{Relu}}(\mathbf h2\cdot \mathbf w^3) $ \parinterval 如图\ref{fig:code-niutensor-three}是使用NiuTensor构造三层神经网络的程序示例,首先定义输入和各层的权重、偏置,随后定义神经网络中各层的实现细节,在第一层中,$ \mathbf x $作为输入,$ \mathbf h1 $作为输出,其中$ \mathbf h1={\rm{sigmoid}}(\mathbf x\cdot \mathbf w1+\mathbf b1) $。在第二层中,$ \mathbf h1 $作为输入,$ \mathbf h2 $作为输出,其中$ \mathbf h2={\rm{tanh}}(\mathbf h1\cdot \mathbf w2) $。在第三层中,$ \mathbf h2 $作为输入,$ \mathbf y $作为输出,其中$ \mathbf y={\rm{relu}}(\mathbf h2\cdot \mathbf w3) $
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1158,7 +1158,7 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb ...@@ -1158,7 +1158,7 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb
%--5.4神经网络的参数训练----------------------------------------- %--5.4神经网络的参数训练-----------------------------------------
\section{神经网络的参数训练}\index{Chapter5.4} \section{神经网络的参数训练}\index{Chapter5.4}
\parinterval 简单来说,神经网络可以被看作是由变量和函数组成的表达式,例如:$ \mathbf y=\mathbf x+\mathbf b $$ \mathbf y={\rm{Relu}}(\mathbf x\cdot \mathbf w+\mathbf b) $$ \mathbf y={\rm{Sigmoid}}({\rm{Relu}}(\mathbf x\cdot \mathbf w_1+\mathbf b_1)\cdot \mathbf w_2+\mathbf b_2) $等等,其中的$ \mathbf x $$ \mathbf y $作为输入和输出变量, $ \mathbf w $$ \mathbf b $等其它变量作为\textbf{模型参数}(Model Parameters)。确定了函数表达式和模型参数,也就确定了神经网络模型。通常,表达式的形式需要系统开发者设计,而模型参数的数量非常巨大,因此需要自动学习,这个过程也称为模型学习或训练。为了实现这个目标,通常我们会准备一定量的带有标准答案的数据,称之为\textbf{有标注数据}(Annotated Data/Labeled Data)。这些数据会用于对模型参数的学习,这也对应了统计模型中的参数估计过程。在机器学习中,一般把这种使用有标注数据进行统计模型参数训练的过程称为\textbf{有指导的训练}\textbf{有监督的训练}(Supervised Training)。在本章中,如果没有特殊说明,模型训练都是指有监督的训练。那么神经网络内部是怎样利用有标注数据对参数进行训练的呢? \parinterval 简单来说,神经网络可以被看作是由变量和函数组成的表达式,例如:$ \mathbf y=\mathbf x+\mathbf b $$ \mathbf y={\rm{relu}}(\mathbf x\cdot \mathbf w+\mathbf b) $$ \mathbf y={\rm{sigmoid}}({\rm{relu}}(\mathbf x\cdot \mathbf w_1+\mathbf b_1)\cdot \mathbf w_2+\mathbf b_2) $等等,其中的$ \mathbf x $$ \mathbf y $作为输入和输出变量, $ \mathbf w $$ \mathbf b $等其它变量作为\textbf{模型参数}(Model Parameters)。确定了函数表达式和模型参数,也就确定了神经网络模型。通常,表达式的形式需要系统开发者设计,而模型参数的数量非常巨大,因此需要自动学习,这个过程也称为模型学习或训练。为了实现这个目标,通常我们会准备一定量的带有标准答案的数据,称之为\textbf{有标注数据}(Annotated Data/Labeled Data)。这些数据会用于对模型参数的学习,这也对应了统计模型中的参数估计过程。在机器学习中,一般把这种使用有标注数据进行统计模型参数训练的过程称为\textbf{有指导的训练}\textbf{有监督的训练}(Supervised Training)。在本章中,如果没有特殊说明,模型训练都是指有监督的训练。那么神经网络内部是怎样利用有标注数据对参数进行训练的呢?
\parinterval 为了回答这个问题,我们可以把模型参数的学习过程看作是一个优化问题,即找到一组参数,使得模型达到某种最优的状态。这个问题又可以被转化为两个新的问题: \parinterval 为了回答这个问题,我们可以把模型参数的学习过程看作是一个优化问题,即找到一组参数,使得模型达到某种最优的状态。这个问题又可以被转化为两个新的问题:
...@@ -1175,9 +1175,9 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb ...@@ -1175,9 +1175,9 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb
%--5.4.1 损失函数--------------------- %--5.4.1 损失函数---------------------
\subsection{损失函数}\index{Chapter5.4.1} \subsection{损失函数}\index{Chapter5.4.1}
\parinterval 在神经网络的有监督学习中,训练模型的数据是由输入和正确答案所组成的样本所构成。假设有多个输入样本$ \{\mathbf {x_1},\mathbf {x_2},\dots,\mathbf {x_n}\} $,每一个$ \mathbf {x_i} $都对应一个正确答案$ \mathbf {\widetilde y_i} $$ \{\mathbf {x_i},\mathbf {\widetilde y_i}\} $就构成一个优化神经网络的\textbf{训练数据集合}(training data set)。对于一个神经网络模型$ \mathbf y=f(\mathbf x) $,每个$ \mathbf {x_i} $也会有一个输出$ \mathbf {y_i} $,如果可以度量正确答案$ \mathbf {\widetilde y_i} $和神经网络输出$ \mathbf {y_i} $之间的偏差,进而通过调整网络参数减小这种偏差,就可以得到更好的模型。 \parinterval 在神经网络的有监督学习中,训练模型的数据是由输入和正确答案所组成的样本所构成。假设有多个输入样本$ \{\mathbf x_1,\mathbf x_2,\dots,\mathbf x_n\} $,每一个$ \mathbf x_i $都对应一个正确答案$ \mathbf {\widetilde y}_i $$ \{\mathbf x_i,\mathbf {\widetilde y}_i\} $就构成一个优化神经网络的\textbf{训练数据集合}(training data set)。对于一个神经网络模型$ \mathbf y=f(\mathbf x) $,每个$ \mathbf x_i $也会有一个输出$ \mathbf y_i $,如果可以度量正确答案$ \mathbf {\widetilde y}_i $和神经网络输出$ \mathbf y_i $之间的偏差,进而通过调整网络参数减小这种偏差,就可以得到更好的模型。
\parinterval 通常,可以通过设计\textbf{损失函数}(Loss Function)来度量正确答案$ \mathbf {\widetilde y_i} $和神经网络输出$ \mathbf {y_i} $之间的偏差。而这个损失函数往往充当训练的\textbf{目标函数}(Objective Function),神经网络训练就是通过不断调整神经网络内部的参数而使损失函数最小化。图\ref{fig:absolute-loss}展示了一个的绝对值损失函数的实例。 \parinterval 通常,可以通过设计\textbf{损失函数}(Loss Function)来度量正确答案$ \mathbf {\widetilde y}_i $和神经网络输出$ \mathbf y_i $之间的偏差。而这个损失函数往往充当训练的\textbf{目标函数}(Objective Function),神经网络训练就是通过不断调整神经网络内部的参数而使损失函数最小化。图\ref{fig:absolute-loss}展示了一个的绝对值损失函数的实例。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1188,7 +1188,7 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb ...@@ -1188,7 +1188,7 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 这里用$ Loss(\mathbf {\widetilde y_i},\mathbf {y_i}) $表示网络输出$ \mathbf {y_i} $相对于答案$ \mathbf {\widetilde y_i} $的损失,简记为$ L $。表\ref{tab3}是几种常见损失函数的定义。需要注意的是,没有一种损失函数可以适用于所有的问题。损失函数的选择取决于许多因素,包括:数据中是否有离群点、模型结构的选择、是否易于找到函数的导数以及预测结果的置信度等。对于相同的神经网络,不同的损失函数会对训练得到的模型产生不同的影响。对于新的问题,如果无法找到已有的、适合于该问题的损失函数,我们也可以自定义损失函数。因此设计新的损失函数也是神经网络中有趣的研究方向。 \parinterval 这里用$ Loss(\mathbf {\widetilde y}_i,\mathbf y_i) $表示网络输出$ \mathbf y_i $相对于答案$ \mathbf {\widetilde y}_i $的损失,简记为$ L $。表\ref{tab3}是几种常见损失函数的定义。需要注意的是,没有一种损失函数可以适用于所有的问题。损失函数的选择取决于许多因素,包括:数据中是否有离群点、模型结构的选择、是否易于找到函数的导数以及预测结果的置信度等。对于相同的神经网络,不同的损失函数会对训练得到的模型产生不同的影响。对于新的问题,如果无法找到已有的、适合于该问题的损失函数,我们也可以自定义损失函数。因此设计新的损失函数也是神经网络中有趣的研究方向。
%表3-------------------------------------------------------------------- %表3--------------------------------------------------------------------
\begin{table}[htp] \begin{table}[htp]
...@@ -1199,29 +1199,29 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb ...@@ -1199,29 +1199,29 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb
\begin{tabular}{l | l l} \begin{tabular}{l | l l}
\rule{0pt}{15pt} \textbf{名称} & \textbf{定义} & \textbf{应用} \\ \rule{0pt}{15pt} \textbf{名称} & \textbf{定义} & \textbf{应用} \\
\hline \hline
\rule{0pt}{15pt} 0-1损失 & $ \begin{cases} 0 & \mathbf {\widetilde y_i}=\mathbf {y_i} \\1 & \mathbf {\widetilde y_i}\not =\mathbf {y_i}\end{cases} $ & 感知机 \\ \rule{0pt}{15pt} 0-1损失 & $ L=\begin{cases} 0 & \mathbf {\widetilde y}_i=\mathbf y_i \\1 & \mathbf {\widetilde y}_i\not =\mathbf y_i\end{cases} $ & 感知机 \\
\rule{0pt}{15pt} Hinge损失 & $ L={\rm {max}}(0,1-\mathbf {\widetilde y_i}\cdot \mathbf {y_i}) $ & SVM \\ \rule{0pt}{15pt} Hinge损失 & $ L={\rm {max}}(0,1-\mathbf {\widetilde y}_i\cdot \mathbf y_i) $ & SVM \\
\rule{0pt}{15pt} 绝对值损失 & $ L=\vert \mathbf {\widetilde y_i}-\mathbf {y_i}\vert $ & 回归 \\ \rule{0pt}{15pt} 绝对值损失 & $ L=\vert \mathbf {\widetilde y}_i-\mathbf y_i\vert $ & 回归 \\
\rule{0pt}{15pt} Logistic损失 & $ L={\rm{log}}(1+\mathbf {\widetilde y_i}\cdot \mathbf {y_i}) $ & 回归 \\ \rule{0pt}{15pt} Logistic损失 & $ L={\rm{log}}(1+\mathbf {\widetilde y}_i\cdot \mathbf y_i) $ & 回归 \\
\rule{0pt}{15pt} 平方损失 & $ {(\mathbf {\widetilde y_i}-\mathbf {y_i})}^2 $ & 回归 \\ \rule{0pt}{15pt} 平方损失 & $ L={(\mathbf {\widetilde y}_i-\mathbf y_i)}^2 $ & 回归 \\
\rule{0pt}{15pt} 指数损失 & $ L={\rm{exp}}(-\mathbf {\widetilde y_i}\cdot \mathbf {y_i}) $ & AdaBoost \\ \rule{0pt}{15pt} 指数损失 & $ L={\rm{exp}}(-\mathbf {\widetilde y}_i\cdot \mathbf y_i) $ & AdaBoost \\
\rule{0pt}{15pt} 交叉熵损失 & $ L=-\sum_{k}{\mathbf {y_i}^{[k]}{\rm {log}}\mathbf {\widetilde y_i}^{[k]}} $ & 多分类 \\ \rule{0pt}{15pt} 交叉熵损失 & $ L=-\sum_{k}{\mathbf y_i^{[k]}{\rm {log}}\mathbf {\widetilde y}_i^{[k]}} $ & 多分类 \\
\end{tabular} \end{tabular}
\end{table} \end{table}
%表3-------------------------------------------------------------------- %表3--------------------------------------------------------------------
\parinterval 在实际系统开发中,损失函数中除了损失项(即用来度量正确答案$ \mathbf {\widetilde y_i} $和神经网络输出$ \mathbf {y_i} $之间的偏差的部分)之外,还可以包括正则项,比如L1正则和L2正则。设置正则项本质上是要加入一些偏置,使模型在优化的过程中偏向某个方向多一些。关于正则项的内容将在5.4.5节详细阐述。此外,在第七章的内容中还会看到,使用恰当的正则项可以大大提升基于神经网络的机器翻译系统性能。 \parinterval 在实际系统开发中,损失函数中除了损失项(即用来度量正确答案$ \mathbf {\widetilde y}_i $和神经网络输出$ \mathbf y_i $之间的偏差的部分)之外,还可以包括正则项,比如L1正则和L2正则。设置正则项本质上是要加入一些偏置,使模型在优化的过程中偏向某个方向多一些。关于正则项的内容将在5.4.5节详细阐述。此外,在第七章的内容中还会看到,使用恰当的正则项可以大大提升基于神经网络的机器翻译系统性能。
%--5.4.2 基于梯度的参数优化--------------------- %--5.4.2 基于梯度的参数优化---------------------
\subsection{基于梯度的参数优化}\index{Chapter5.4.2} \subsection{基于梯度的参数优化}\index{Chapter5.4.2}
\parinterval 对于第$ i $个样本$ (\mathbf {x_i},\mathbf {\widetilde y_i}) $,如果把损失函数$ Loss(\mathbf {\widetilde y_i},\mathbf {y_i}) $看作是参数$ \mathbf w $的函数\footnote{为了简化描述,我们用$ \mathbf w $表示神经网络中的所有参数}。因为输出$ \mathbf {y_i} $是由输入$ \mathbf {x_i} $和模型参数$ \mathbf w $决定,因此也把损失函数写为$ L(\mathbf {x_i},\mathbf {\widetilde y_i};\mathbf w) $。参数学习过程可以被描述为 \parinterval 对于第$ i $个样本$ (\mathbf x_i,\mathbf {\widetilde y}_i) $,如果把损失函数$ Loss(\mathbf {\widetilde y}_i,\mathbf y_i) $看作是参数$ \mathbf w $的函数\footnote{为了简化描述,我们用$ \mathbf w $表示神经网络中的所有参数}。因为输出$ \mathbf y_i $是由输入$ \mathbf x_i $和模型参数$ \mathbf w $决定,因此也把损失函数写为$ L(\mathbf x_i,\mathbf {\widetilde y}_i;\mathbf w) $。参数学习过程可以被描述为
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\hat{\mathbf w}=\mathop{\arg\min}_{\mathbf w}\frac{1}{n}\sum_{i=1}^{n}{L(\mathbf {x_i},\mathbf {\widetilde y_i};\mathbf w)} \hat{\mathbf w}=\mathop{\arg\min}_{\mathbf w}\frac{1}{n}\sum_{i=1}^{n}{L(\mathbf x_i,\mathbf {\widetilde y}_i;\mathbf w)}
\label{eqa1.28} \label{eqa1.28}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\parinterval 其中,$ \hat{\mathbf w} $表示在训练数据上使损失的平均值达到最小的参数,$ \frac{1}{n}\sum_{i=1}^{n}{L(\mathbf {x_i},\mathbf {\widetilde y_i};\mathbf w)} $\\被称作\textbf{代价函数}(Cost Function),它是损失函数均值期望的估计,记为$ J(\mathbf w) $ \parinterval 其中,$ \hat{\mathbf w} $表示在训练数据上使损失的平均值达到最小的参数,$ \frac{1}{n}\sum_{i=1}^{n}{L(\mathbf x_i,\mathbf {\widetilde y}_i;\mathbf w)} $\\被称作\textbf{代价函数}(Cost Function),它是损失函数均值期望的估计,记为$ J(\mathbf w) $
\parinterval 参数优化的核心问题是:找到使代价函数$ J(\mathbf w) $达到最小的$ \mathbf w $。然而$ J(\mathbf w) $可能会包含大量的参数,比如,基于神经网络的机器翻译模型的参数量可能会超过一亿个。因此,我们不可能用手动方法进行调参。为了实现高效的参数优化,比较常用的手段是使用梯度下降方法(Gradient Descent Method)。 \parinterval 参数优化的核心问题是:找到使代价函数$ J(\mathbf w) $达到最小的$ \mathbf w $。然而$ J(\mathbf w) $可能会包含大量的参数,比如,基于神经网络的机器翻译模型的参数量可能会超过一亿个。因此,我们不可能用手动方法进行调参。为了实现高效的参数优化,比较常用的手段是使用梯度下降方法(Gradient Descent Method)。
%--5.4.2.1梯度下降--------------------- %--5.4.2.1梯度下降---------------------
...@@ -1259,7 +1259,7 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb ...@@ -1259,7 +1259,7 @@ y={\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mathb
\parinterval 批量梯度下降是梯度下降方法中最原始的形式,这种梯度下降方法在每一次迭代时使用所有的样本进行参数更新。参数优化的目标函数是 \parinterval 批量梯度下降是梯度下降方法中最原始的形式,这种梯度下降方法在每一次迭代时使用所有的样本进行参数更新。参数优化的目标函数是
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
J(\mathbf w)=\frac{1}{n}\sum_{i=1}^{n}{L(\mathbf {x_i},\mathbf {\widetilde y_i};\mathbf w)} J(\mathbf w)=\frac{1}{n}\sum_{i=1}^{n}{L(\mathbf x_i,\mathbf {\widetilde y}_i;\mathbf w)}
\label{eqa1.30} \label{eqa1.30}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -1275,7 +1275,7 @@ J(\mathbf w)=\frac{1}{n}\sum_{i=1}^{n}{L(\mathbf {x_i},\mathbf {\widetilde y_i}; ...@@ -1275,7 +1275,7 @@ J(\mathbf w)=\frac{1}{n}\sum_{i=1}^{n}{L(\mathbf {x_i},\mathbf {\widetilde y_i};
\parinterval 随机梯度下降(简称SGD)不同于批量梯度下降,每次迭代只使用一个样本对参数进行更新。SGD的目标函数是 \parinterval 随机梯度下降(简称SGD)不同于批量梯度下降,每次迭代只使用一个样本对参数进行更新。SGD的目标函数是
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
J(\mathbf w)=L(\mathbf {x_i},\mathbf {\widetilde y_i};\mathbf w) J(\mathbf w)=L(\mathbf x_i,\mathbf {\widetilde y}_i;\mathbf w)
\label{eqa1.31} \label{eqa1.31}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -1291,7 +1291,7 @@ J(\mathbf w)=L(\mathbf {x_i},\mathbf {\widetilde y_i};\mathbf w) ...@@ -1291,7 +1291,7 @@ J(\mathbf w)=L(\mathbf {x_i},\mathbf {\widetilde y_i};\mathbf w)
\parinterval 为了综合批量梯度下降和随机梯度下降的优缺点,在实际应用中一般采用这两个算法的折中\raisebox{0.5mm}{------}小批量梯度下降。其思想是:每次迭代计算一小部分训练数据的损失函数,并对参数进行更新。这一小部分数据被称为一个批次(mini-batch或者batch)。小批量梯度下降的参数优化的目标函数如下: \parinterval 为了综合批量梯度下降和随机梯度下降的优缺点,在实际应用中一般采用这两个算法的折中\raisebox{0.5mm}{------}小批量梯度下降。其思想是:每次迭代计算一小部分训练数据的损失函数,并对参数进行更新。这一小部分数据被称为一个批次(mini-batch或者batch)。小批量梯度下降的参数优化的目标函数如下:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
J(\mathbf w)=\frac{1}{m}\sum_{j=i}^{j+m-1}{L(\mathbf {x_i},\mathbf {\widetilde y_i};\mathbf w)} J(\mathbf w)=\frac{1}{m}\sum_{j=i}^{j+m-1}{L(\mathbf x_i,\mathbf {\widetilde y}_i;\mathbf w)}
\label{eqa1.32} \label{eqa1.32}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -1413,7 +1413,7 @@ $+2x^2+x+1)$ & \ \ $(x^4+2x^3+2x^2+x+1)$ & $+6x+1$ \\ ...@@ -1413,7 +1413,7 @@ $+2x^2+x+1)$ & \ \ $(x^4+2x^3+2x^2+x+1)$ & $+6x+1$ \\
\noindent \textbf{a)Momentum } \noindent \textbf{a)Momentum }
\vspace{0.5em} \vspace{0.5em}
\parinterval Momentum梯度下降算法的参数更新公式见如下 \parinterval Momentum梯度下降算法的参数更新公式如下在\footnote{在梯度下降算法的几种改进方法的公式中,其更新对象是某个具体参数而非参数矩阵,因此不再使用加粗样式}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
v_t&=&\beta v_{t-1}+(1-\beta)\frac{\partial L}{\partial w_t}\label{eqa1.34}\\ v_t&=&\beta v_{t-1}+(1-\beta)\frac{\partial L}{\partial w_t}\label{eqa1.34}\\
...@@ -1512,37 +1512,37 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1512,37 +1512,37 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
%--5.4.4.1梯度消失现象及解决方法--------------------- %--5.4.4.1梯度消失现象及解决方法---------------------
\subsubsection{(一)梯度消失现象及解决方法}\index{Chapter5.4.4.1} \subsubsection{(一)梯度消失现象及解决方法}\index{Chapter5.4.4.1}
\parinterval 网络训练过程中,如果每层网络的梯度都小于1,反向传播过程中,各层梯度的偏导数会与后面层传递而来的梯度相乘得到本层的梯度,并向前一层传递。该过程循环进行,最后导致梯度指数级地减小,这就产生了梯度消失现象。这种情况会导致神经网络层数较浅的部分梯度为0,无法更新参数。一般来说,产生很小梯度的原因是我们使用了类似于Sigmoid这样的激活函数,当输入的值过大或者过小的时候这类函数曲线会趋于直线,梯度近似为零。针对这个问题,主要的解决办法是使用更加易于优化的激活函数,比如,使用Relu代替Sigmoid和Tanh作为激活函数。 \parinterval 网络训练过程中,如果每层网络的梯度都小于1,反向传播过程中,各层梯度的偏导数会与后面层传递而来的梯度相乘得到本层的梯度,并向前一层传递。该过程循环进行,最后导致梯度指数级地减小,这就产生了梯度消失现象。这种情况会导致神经网络层数较浅的部分梯度为0,无法更新参数。一般来说,产生很小梯度的原因是我们使用了类似于sigmoid这样的激活函数,当输入的值过大或者过小的时候这类函数曲线会趋于直线,梯度近似为零。针对这个问题,主要的解决办法是使用更加易于优化的激活函数,比如,使用relu代替sigmoid和tanh作为激活函数。
\parinterval 缓解梯度消失问题最直接的想法就是希望各层的偏导数大于或等于1。图\ref{fig:derivative1}展示了Sigmoid激活函数$ y=\frac{1}{1+e^{-x}}$的函数曲线和导函数曲线,如果使用Sigmoid作为损失函数,其梯度不可能超过0.25,这样经过链式求导之后,很容易发生梯度消失。 \parinterval 缓解梯度消失问题最直接的想法就是希望各层的偏导数大于或等于1。图\ref{fig:derivative1}展示了sigmoid激活函数$ y=\frac{1}{1+e^{-x}}$的函数曲线和导函数曲线,如果使用sigmoid作为损失函数,其梯度不可能超过0.25,这样经过链式求导之后,很容易发生梯度消失。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-derivative1} \input{./Chapter5/Figures/fig-derivative1}
\caption{Sigmoid激活函数的函数曲线和导函数曲线} \caption{sigmoid激活函数的函数曲线和导函数曲线}
\label{fig:derivative1} \label{fig:derivative1}
\end {figure} \end {figure}
%------------------------------------------- %-------------------------------------------
\parinterval 同理,Tanh作为激活函数也容易出现梯度消失现象,图\ref{fig:derivative2}展示了Tanh激活函数$ y=\frac{e^x-e^{-x}}{e^x+e^{-x}}$的函数曲线和导函数曲线,可以看出,Tanh激活函数比Sigmoid激活函数要好一些,但是Tanh激活函数的导数也小于1,因此无法避免梯度消失现象。 \parinterval 同理,tanh作为激活函数也容易出现梯度消失现象,图\ref{fig:derivative2}展示了tanh激活函数$ y=\frac{e^x-e^{-x}}{e^x+e^{-x}}$的函数曲线和导函数曲线,可以看出,tanh激活函数比sigmoid激活函数要好一些,但是tanh激活函数的导数也小于1,因此无法避免梯度消失现象。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-derivative2} \input{./Chapter5/Figures/fig-derivative2}
\caption{Tanh激活函数的函数曲线和导函数曲线} \caption{tanh激活函数的函数曲线和导函数曲线}
\label{fig:derivative2} \label{fig:derivative2}
\end {figure} \end {figure}
%------------------------------------------- %-------------------------------------------
\parinterval Relu激活函数的思想也很简单,如果激活函数的导数为1,那么就不存在梯度消失爆炸的问题了。图\ref{fig:derivative3}展示了Relu激活函数$ y={\rm{max}}(0,x)$的函数曲线和导函数曲线。可以很容易看出,Relu函数的导数在正数部分是恒等于1的,因此在深层网络中使用Relu激活函数就不会产生很小的梯度。 \parinterval relu激活函数的思想也很简单,如果激活函数的导数为1,那么就不存在梯度消失爆炸的问题了。图\ref{fig:derivative3}展示了relu激活函数$ y={\rm{max}}(0,x)$的函数曲线和导函数曲线。可以很容易看出,relu函数的导数在正数部分是恒等于1的,因此在深层网络中使用relu激活函数就不会产生很小的梯度。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-derivative3} \input{./Chapter5/Figures/fig-derivative3}
\caption{Relu激活函数的函数曲线和导函数曲线} \caption{relu激活函数的函数曲线和导函数曲线}
\label{fig:derivative3} \label{fig:derivative3}
\end {figure} \end {figure}
%------------------------------------------- %-------------------------------------------
...@@ -1714,7 +1714,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1714,7 +1714,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\begin{itemize} \begin{itemize}
\item $ \frac{\partial L}{\partial \mathbf h^K} $表示损失函数$ L $相对网络输出$ \mathbf h^K $表的梯度。比如,对于平方损失$ L=\frac{1}{2}{\Vert \widetilde {\mathbf y}-\mathbf h^K\Vert}^2 $,有$ \frac{\partial L}{\partial \mathbf h^K}= \widetilde{ \mathbf y} -\mathbf h^K $。计算结束后,将$ \frac{\partial L}{\partial \mathbf h^K} $向前传递。 \item $ \frac{\partial L}{\partial \mathbf h^K} $表示损失函数$ L $相对网络输出$ \mathbf h^K $表的梯度。比如,对于平方损失$ L=\frac{1}{2}{\Vert \widetilde {\mathbf y}-\mathbf h^K\Vert}^2 $,有$ \frac{\partial L}{\partial \mathbf h^K}= \widetilde{ \mathbf y} -\mathbf h^K $。计算结束后,将$ \frac{\partial L}{\partial \mathbf h^K} $向前传递。
\vspace{0.5em} \vspace{0.5em}
\item $ \frac{\partial f^T(\mathbf s^K)}{\partial \mathbf s^K} $表示激活函数相对于其输入$ \mathbf s^K $的梯度。比如,对于Sigmoid函数$ f(\mathbf s)=\frac{1}{1+e^{- \mathbf s}}$,有$ \frac{\partial f(\mathbf s)}{\partial \mathbf s}=f(\mathbf s) (1-f(\mathbf s))$ \item $ \frac{\partial f^T(\mathbf s^K)}{\partial \mathbf s^K} $表示激活函数相对于其输入$ \mathbf s^K $的梯度。比如,对于sigmoid函数$ f(\mathbf s)=\frac{1}{1+e^{- \mathbf s}}$,有$ \frac{\partial f(\mathbf s)}{\partial \mathbf s}=f(\mathbf s) (1-f(\mathbf s))$
\end{itemize} \end{itemize}
\end{spacing} \end{spacing}
\vspace{0.5em} \vspace{0.5em}
...@@ -1897,11 +1897,11 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1897,11 +1897,11 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\label{eqa1.60} \label{eqa1.60}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\noindent 这里的$ \mathbf C $可以被理解为一个查询表,根据$ w_i $中为1的那一维,在$ \mathbf C $中索引到相应的行进行输出(结果是一个行向量)。随后,把得到的$ \mathbf e_0 $$ \mathbf e_1 $$ \mathbf e_2 $三个向量级联在一起,经过两层网络,最后通过Softmax函数(橙色方框)得到输出: \noindent 这里的$ \mathbf C $可以被理解为一个查询表,根据$ w_i $中为1的那一维,在$ \mathbf C $中索引到相应的行进行输出(结果是一个行向量)。随后,把得到的$ \mathbf e_0 $$ \mathbf e_1 $$ \mathbf e_2 $三个向量级联在一起,经过两层网络,最后通过softmax函数(橙色方框)得到输出:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\mathbf y&=&{\rm{Softmax}}(\mathbf h_0\mathbf U)\label{eqa1.61}\\ \mathbf y&=&{\rm{softmax}}(\mathbf h_0\mathbf U)\label{eqa1.61}\\
\mathbf h_0&=&{\rm{Tanh}}([\mathbf e_{i-3},\mathbf e_{i-2},\mathbf e_{i-1}]\mathbf H+\mathbf d) \mathbf h_0&=&{\rm{tanh}}([\mathbf e_{i-3},\mathbf e_{i-2},\mathbf e_{i-1}]\mathbf H+\mathbf d)
\label{eqa1.62} \label{eqa1.62}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -1920,17 +1920,17 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1920,17 +1920,17 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval 在FNNLM中,所有的参数、输入、输出都是连续变量,因此FNNLM也是典型的一个连续空间模型。通过,使用交叉熵等损失函数,FNNLM很容易进行优化。比如,可以使梯度下降方法对FNNLM的模型参数进行训练。 \parinterval 在FNNLM中,所有的参数、输入、输出都是连续变量,因此FNNLM也是典型的一个连续空间模型。通过,使用交叉熵等损失函数,FNNLM很容易进行优化。比如,可以使梯度下降方法对FNNLM的模型参数进行训练。
\parinterval FNNLM的实现也非常简单,图\ref{fig:code-FNNLM}展示了基于NiuTensor的FNNLM的部分代码。需要注意的是,在程序实现时, Tanh函数一般会用HardTanh函数代替。因为 Tanh函数中的指数运算容易导致溢出: \parinterval FNNLM的实现也非常简单,图\ref{fig:code-FNNLM}展示了基于NiuTensor的FNNLM的部分代码。需要注意的是,在程序实现时, tanh函数一般会用hardtanh函数代替。因为 tanh函数中的指数运算容易导致溢出:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
{\rm{Tanh}}(z)=\frac{{\rm{exp}}(z)-{\rm{exp}}(-z)}{{\rm{exp}}(z)+\rm{exp}(-z)} {\rm{tanh}}(z)=\frac{{\rm{exp}}(z)-{\rm{exp}}(-z)}{{\rm{exp}}(z)+\rm{exp}(-z)}
\label{} \label{}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\noindentHardTanh函数不存在这个问题,因此具有数值计算的稳定性。HardTanh函数表达式如下: \noindenthardtanh函数不存在这个问题,因此具有数值计算的稳定性。hardtanh函数表达式如下:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
{\rm{HardTanh}}(z)=\begin{cases} -1 & z<-1\\z & -1\leqslant z\leqslant 1\\1 & z>1\end{cases} {\rm{hardtanh}}(z)=\begin{cases} -1 & z<-1\\z & -1\leqslant z\leqslant 1\\1 & z>1\end{cases}
\label{} \label{}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -1957,20 +1957,20 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1957,20 +1957,20 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval 在循环神经网络中,输入和输出都是一个序列,分别记为$ (\mathbf x_1,\dots,\mathbf x_m) $$ (\mathbf y_1,\dots,\\ \mathbf y_m) $。它们都可以被看作是时序序列,其中每个时刻$ t $都对应一个输入$ \mathbf x_t $和输出$ \mathbf y_t $。循环神经网络的核心是\textbf{循环单元}(RNN Cell),它读入前一个时刻循环单元的输出和当前时刻的输入,生成当前时刻循环单元的输出。图\ref{fig:rnn-LM}展示了一个简单的循环单元结构,对于时刻$ t $,循环单元的输出被定义为: \parinterval 在循环神经网络中,输入和输出都是一个序列,分别记为$ (\mathbf x_1,\dots,\mathbf x_m) $$ (\mathbf y_1,\dots,\\ \mathbf y_m) $。它们都可以被看作是时序序列,其中每个时刻$ t $都对应一个输入$ \mathbf x_t $和输出$ \mathbf y_t $。循环神经网络的核心是\textbf{循环单元}(RNN Cell),它读入前一个时刻循环单元的输出和当前时刻的输入,生成当前时刻循环单元的输出。图\ref{fig:rnn-LM}展示了一个简单的循环单元结构,对于时刻$ t $,循环单元的输出被定义为:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\mathbf h_t={\rm{Tanh}}(\mathbf x_t\mathbf U+\mathbf h_{t-1}\mathbf W) \mathbf h_t={\rm{tanh}}(\mathbf x_t\mathbf U+\mathbf h_{t-1}\mathbf W)
\label{eqa1.63} \label{eqa1.63}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\noindent 其中,$ \mathbf h_t $表示$ t $时刻循环单元的输出,$ \mathbf h_{t-1} $表示$ t-1 $时刻循环单元的输出,$ \mathbf U $$ \mathbf W $是模型的参数。可以看出,循环单元的结构其实很简单,只是一个对$ \mathbf h_{t-1} $$ \mathbf x_t $的线性变换再加上一个Tanh函数。通过读入上一时刻的输出,当前时刻可以访问以前的历史信息。这个过程可以循环执行,这样就完成了对所有历史信息的建模。$ \mathbf h_t $可以被看作是序列在$ t $时刻的一种表示,也可以被看作是网络的一个隐藏层。进一步,$ \mathbf h_t $可以被送入输出层,得到$ t $时刻的输出: \noindent 其中,$ \mathbf h_t $表示$ t $时刻循环单元的输出,$ \mathbf h_{t-1} $表示$ t-1 $时刻循环单元的输出,$ \mathbf U $$ \mathbf W $是模型的参数。可以看出,循环单元的结构其实很简单,只是一个对$ \mathbf h_{t-1} $$ \mathbf x_t $的线性变换再加上一个tanh函数。通过读入上一时刻的输出,当前时刻可以访问以前的历史信息。这个过程可以循环执行,这样就完成了对所有历史信息的建模。$ \mathbf h_t $可以被看作是序列在$ t $时刻的一种表示,也可以被看作是网络的一个隐藏层。进一步,$ \mathbf h_t $可以被送入输出层,得到$ t $时刻的输出:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\mathbf Y_t={\rm{Softmax}}(\mathbf h_t\mathbf V) \mathbf Y_t={\rm{softmax}}(\mathbf h_t\mathbf V)
\label{eqa1.64} \label{eqa1.64}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\noindent 其中,$ \mathbf V $是输出层的模型参数。 \noindent 其中,$ \mathbf V $是输出层的模型参数。
\parinterval\ref{fig:rnn-LM}展示了一个基于循环神经网络的语言模型结构。首先,所有输入的单词会被转换成分布式表示(红色部分),这个过程和FNNLM是一样的。之后,该模型堆叠了两层循环神经网络(绿色部分)。最后通过Softmax层(紫色部分)得到每个时刻的预测结果$ \mathbf y_t={\rm P}(w_t|w_1\dots w_{t-1}) $ \parinterval\ref{fig:rnn-LM}展示了一个基于循环神经网络的语言模型结构。首先,所有输入的单词会被转换成分布式表示(红色部分),这个过程和FNNLM是一样的。之后,该模型堆叠了两层循环神经网络(绿色部分)。最后通过softmax层(紫色部分)得到每个时刻的预测结果$ \mathbf y_t={\rm P}(w_t|w_1\dots w_{t-1}) $
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1989,7 +1989,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1989,7 +1989,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval 对于这个问题,研究者又提出了一种新的结构---自注意力机制(Self-Attention Mechanism)。自注意力是一种特殊的神经网络结构,它可以对序列上任意两个词的相互作用直接进行建模,这样也就避免了循环神经网络中随着距离变长信息传递步骤增多的缺陷。在自然语言处理领域,自注意力机制被成功的应用在机器翻译,形成了著名的Transformer模型\cite{vaswani2017attention}。在第六章我们会系统的介绍自注意力机制和Transformer模型。 \parinterval 对于这个问题,研究者又提出了一种新的结构---自注意力机制(Self-Attention Mechanism)。自注意力是一种特殊的神经网络结构,它可以对序列上任意两个词的相互作用直接进行建模,这样也就避免了循环神经网络中随着距离变长信息传递步骤增多的缺陷。在自然语言处理领域,自注意力机制被成功的应用在机器翻译,形成了著名的Transformer模型\cite{vaswani2017attention}。在第六章我们会系统的介绍自注意力机制和Transformer模型。
\parinterval 这里,先简单了解一下基于Transformer的语言模型结构(图\ref{fig:transformer-LM})。与FNNLM\\和RNNLM一样,Transformer首先对输入单词进行分布式表示,同时加上每个位置的编码构成了整个模型的输入(蓝色方框)。之后,利用自注意力机制对输入的向量进行处理(绿色方框)。自注意力的结果会被送入一个前馈神经网络,之后再送给Softmax输出层(橙色方框)。 \parinterval 这里,先简单了解一下基于Transformer的语言模型结构(图\ref{fig:transformer-LM})。与FNNLM\\和RNNLM一样,Transformer首先对输入单词进行分布式表示,同时加上每个位置的编码构成了整个模型的输入(蓝色方框)。之后,利用自注意力机制对输入的向量进行处理(绿色方框)。自注意力的结果会被送入一个前馈神经网络,之后再送给softmax输出层(橙色方框)。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
...@@ -2142,7 +2142,7 @@ Jobs was the CEO of {\red{\underline{apple}}}. ...@@ -2142,7 +2142,7 @@ Jobs was the CEO of {\red{\underline{apple}}}.
\parinterval GPT(Generative Pre-Training)也是一种基于语言建模的句子表示模型\cite{radford2018improving}。该工作的贡献在于利用Transformer结构代替了LSTM。而且该模型基于Pre-training + Fine-tuning的框架,预训练的结果做为下游系统的句子表示模块的参数初始值,因此可以更好的适应目标任务。 \parinterval GPT(Generative Pre-Training)也是一种基于语言建模的句子表示模型\cite{radford2018improving}。该工作的贡献在于利用Transformer结构代替了LSTM。而且该模型基于Pre-training + Fine-tuning的框架,预训练的结果做为下游系统的句子表示模块的参数初始值,因此可以更好的适应目标任务。
\parinterval GPT模型仍然使用标准的语言建模的思路,即通过前$ n-1 $个词预测第$ n $个词。但是在网络结构上,GPT模型使用了Transformer(图\ref{fig:gpt}),而且模型参数会在目标任务上进行有监督的微调。与ELMO模型的做法不同,GPT不需要对目标任务构建新的模型结构,而是直接在Transformer语言表示模型的最后一层加上Softmax层作为任务的输出层。实验结果证明,GPT模型的性能较ELMO模型更为优越,在12个NLP任务中取得了9个任务当时最好的结果。 \parinterval GPT模型仍然使用标准的语言建模的思路,即通过前$ n-1 $个词预测第$ n $个词。但是在网络结构上,GPT模型使用了Transformer(图\ref{fig:gpt}),而且模型参数会在目标任务上进行有监督的微调。与ELMO模型的做法不同,GPT不需要对目标任务构建新的模型结构,而是直接在Transformer语言表示模型的最后一层加上softmax层作为任务的输出层。实验结果证明,GPT模型的性能较ELMO模型更为优越,在12个NLP任务中取得了9个任务当时最好的结果。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论