Commit f1db191d by xiaotong

minor updates of sections 3, 5 and 6

parent be196d93
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
\node [anchor=north west] (line1) at (0,0) {\small\sffamily\bfseries{IBM模型1的训练(EM算法)}}; \node [anchor=north west] (line1) at (0,0) {\small\sffamily\bfseries{IBM模型1的训练(EM算法)}};
\node [anchor=north west] (line2) at ([yshift=-0.3em]line1.south west) {输入: 平行语料${(\mathbf{s}^{[1]},\mathbf{t}^{[1]}),...,(\mathbf{s}^{[N]},\mathbf{t}^{[N]})}$}; \node [anchor=north west] (line2) at ([yshift=-0.3em]line1.south west) {输入: 平行语料${(\mathbf{s}^{[1]},\mathbf{t}^{[1]}),...,(\mathbf{s}^{[N]},\mathbf{t}^{[N]})}$};
\node [anchor=north west] (line3) at ([yshift=-0.1em]line2.south west) {输出: 参数$f(\cdot|\cdot)$的最优值}; \node [anchor=north west] (line3) at ([yshift=-0.1em]line2.south west) {输出: 参数$f(\cdot|\cdot)$的最优值};
\node [anchor=north west] (line4) at ([yshift=-0.1em]line3.south west) {1: \textbf{Function} \textsc{TrainItWithEM}($\{(\mathbf{s}^{[1]},\mathbf{t}^{[1]}),...,(\mathbf{s}^{[N]},\mathbf{t}^{[N]})\}$) }; \node [anchor=north west] (line4) at ([yshift=-0.1em]line3.south west) {1: \textbf{Function} \textsc{EM}($\{(\mathbf{s}^{[1]},\mathbf{t}^{[1]}),...,(\mathbf{s}^{[N]},\mathbf{t}^{[N]})\}$) };
\node [anchor=north west] (line5) at ([yshift=-0.1em]line4.south west) {2: \ \ Initialize $f(\cdot|\cdot)$ \hspace{5em} $\rhd$ 比如给$f(\cdot|\cdot)$一个均匀分布}; \node [anchor=north west] (line5) at ([yshift=-0.1em]line4.south west) {2: \ \ Initialize $f(\cdot|\cdot)$ \hspace{5em} $\rhd$ 比如给$f(\cdot|\cdot)$一个均匀分布};
\node [anchor=north west] (line6) at ([yshift=-0.1em]line5.south west) {3: \ \ Loop until $f(\cdot|\cdot)$ converges}; \node [anchor=north west] (line6) at ([yshift=-0.1em]line5.south west) {3: \ \ Loop until $f(\cdot|\cdot)$ converges};
\node [anchor=north west] (line7) at ([yshift=-0.1em]line6.south west) {4: \ \ \ \ \textbf{foreach} $k = 1$ to $N$ \textbf{do}}; \node [anchor=north west] (line7) at ([yshift=-0.1em]line6.south west) {4: \ \ \ \ \textbf{foreach} $k = 1$ to $N$ \textbf{do}};
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
\draw [-,ublue] (n10.west) -- (n10.east); \draw [-,ublue] (n10.west) -- (n10.east);
\draw [-,ublue] (n11.west) -- (n11.east); \draw [-,ublue] (n11.west) -- (n11.east);
\node [anchor=north] (x1) at ([yshift=-6em]n11.south) {$x_1$}; \node [anchor=north] (x1) at ([yshift=-6em]n11.south) {$x_1$};
\node [anchor=north] (labela) at ([xshift=3.5em,yshift=-0.5em]x1.south) {\footnotesize{(a)}}; \node [anchor=north] (labela) at ([xshift=3.5em,yshift=-0.5em]x1.south) {\footnotesize{(a) 拟合一小段函数}};
\node [anchor=north] (b) at ([yshift=-6em]n10.south) {$b$}; \node [anchor=north] (b) at ([yshift=-6em]n10.south) {$b$};
{ {
\draw [->,thick,red] (b.north) -- ([yshift=-0.1em]n10.south); \draw [->,thick,red] (b.north) -- ([yshift=-0.1em]n10.south);
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
\draw [-,ublue] (n10.west) -- (n10.east); \draw [-,ublue] (n10.west) -- (n10.east);
\draw [-,ublue] (n11.west) -- (n11.east); \draw [-,ublue] (n11.west) -- (n11.east);
\node [anchor=north] (x1) at ([yshift=-6em]n11.south) {$x_1$}; \node [anchor=north] (x1) at ([yshift=-6em]n11.south) {$x_1$};
\node [anchor=north] (labelb) at ([xshift=6em,yshift=-0.5em]x1.south) {\footnotesize{(b)}}; \node [anchor=north] (labelb) at ([xshift=6em,yshift=-0.5em]x1.south) {\footnotesize{(b) 拟合更大一段函数}};
\node [anchor=north] (b) at ([yshift=-6em]n10.south) {$b$}; \node [anchor=north] (b) at ([yshift=-6em]n10.south) {$b$};
{ {
\draw [->,thick,red] (b.north) -- ([yshift=-0.1em]n10.south); \draw [->,thick,red] (b.north) -- ([yshift=-0.1em]n10.south);
......
...@@ -156,7 +156,7 @@ ...@@ -156,7 +156,7 @@
\parinterval 线性代数作为一个数学分支,广泛应用于科学和工程中,神经网络的数学描述中也大量使用了线性代数工具。因此,这里我们对线性代数的一些概念进行简要介绍,以方便后续对神经网络的数学建模。 \parinterval 线性代数作为一个数学分支,广泛应用于科学和工程中,神经网络的数学描述中也大量使用了线性代数工具。因此,这里我们对线性代数的一些概念进行简要介绍,以方便后续对神经网络的数学建模。
%--5.2.1.1标量、向量和矩阵--------------------- %--5.2.1.1标量、向量和矩阵---------------------
\subsubsection{(一)标量、向量和矩阵}\index{Chapter5.2.1.1} \subsubsection{标量、向量和矩阵}\index{Chapter5.2.1.1}
\parinterval {\small\sffamily\bfseries{标量}}(Scalar):标量亦称``无向量'',是一种只具有数值大小而没有方向的量,通俗地说,一个标量就是一个单独的数,这里我们特指实数\footnote{严格意义上,标量可以是复数等其它形式,这里为了方便讨论,我们仅以实数为对象。}。我们一般用小写斜体表示标量。比如,对于$ a=5 $$ a $就是一个标量。 \parinterval {\small\sffamily\bfseries{标量}}(Scalar):标量亦称``无向量'',是一种只具有数值大小而没有方向的量,通俗地说,一个标量就是一个单独的数,这里我们特指实数\footnote{严格意义上,标量可以是复数等其它形式,这里为了方便讨论,我们仅以实数为对象。}。我们一般用小写斜体表示标量。比如,对于$ a=5 $$ a $就是一个标量。
...@@ -188,18 +188,18 @@ ...@@ -188,18 +188,18 @@
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
%--5.2.1.2矩阵的转置--------------------- %--5.2.1.2矩阵的转置---------------------
\subsubsection{(二)矩阵的转置}\index{Chapter5.2.1.2} \subsubsection{矩阵的转置}\index{Chapter5.2.1.2}
\parinterval {\small\sffamily\bfseries{转置}}transpose)是矩阵的重要操作之一。矩阵的转置可以看作是将矩阵以对角线为镜像进行翻转:假设$ \mathbf a $$ m $$ n $列的矩阵,第$ i $行第$ j $ 列的元素是$ a_{ij} $,即:$ \mathbf a={(a_{ij})}_{m\times n} $,把$ m\times n $矩阵$ \mathbf a $的行换成同序数的列得到一个$ n\times m $矩阵,则得到$ \mathbf a $的转置矩阵,记为$ \mathbf a^{\rm T} $,其中$ a_{ji}^{\rm T}=a_{ij} $。例如: \parinterval {\small\sffamily\bfseries{转置}}Transpose)是矩阵的重要操作之一。矩阵的转置可以看作是将矩阵以对角线为镜像进行翻转:假设$ \mathbf a $$ m $$ n $列的矩阵,第$ i $行第$ j $ 列的元素是$ a_{ij} $,即:$ \mathbf a={(a_{ij})}_{m\times n} $,把$ m\times n $矩阵$ \mathbf a $的行换成同序数的列得到一个$ n\times m $矩阵,则得到$ \mathbf a $的转置矩阵,记为$ \mathbf a^{\rm T} $,其中$ a_{ji}^{\rm T}=a_{ij} $。例如:
\begin{eqnarray} \begin{eqnarray}
\mathbf a & = & \begin{pmatrix} 1 & 3 & 2 & 6\\5 & 4 & 8 & 2\end{pmatrix} \\ \mathbf a & = & \begin{pmatrix} 1 & 3 & 2 & 6\\5 & 4 & 8 & 2\end{pmatrix} \\
{\mathbf a}^{\rm T} & = &\begin{pmatrix} 1 & 5\\3 & 4\\2 & 8\\6 & 2\end{pmatrix} {\mathbf a}^{\rm T} & = &\begin{pmatrix} 1 & 5\\3 & 4\\2 & 8\\6 & 2\end{pmatrix}
\end{eqnarray} \end{eqnarray}
\parinterval 向量可以看作只有一行(列)的矩阵。对应地,向量的转置可以看作是只有一列(行)的矩阵。标量可以看作是只有一个元素的矩阵。因此,标量的转置等于它本身,即$ a^{\rm T}=a $ \parinterval 向量可以看作只有一行(列)的矩阵。对应地,向量的转置可以看作是只有一列(行)的矩阵。标量可以看作是只有一个元素的矩阵。因此,标量的转置等于它本身,即$ a^{\rm T}=a $
%--5.2.1.3矩阵加法和数乘--------------------- %--5.2.1.3矩阵加法和数乘---------------------
\subsubsection{(三)矩阵加法和数乘}\index{Chapter5.2.1.3} \subsubsection{矩阵加法和数乘}\index{Chapter5.2.1.3}
\parinterval 矩阵加法又被称作{\small\sffamily\bfseries{按元素加法}}element-wise addition)。它是指两个矩阵把其相对应元素加在一起的运算,通常的矩阵加法被定义在两个形状相同的矩阵上。两个$ m\times n $矩阵$ \mathbf a $$ \mathbf b $的和,标记为$ \mathbf a + \mathbf b $,它也是个$ m\times n $矩阵,其内的各元素为其相对应元素相加后的值。如果矩阵$ \mathbf c = \mathbf a + \mathbf b $,则$ c_{ij} = a_{ij} + b_{ij} $。公式\ref{eqa1.4}展示了矩阵之间进行加法的计算过程。 \parinterval 矩阵加法又被称作{\small\sffamily\bfseries{按元素加法}}Element-wise Addition)。它是指两个矩阵把其相对应元素加在一起的运算,通常的矩阵加法被定义在两个形状相同的矩阵上。两个$ m\times n $矩阵$ \mathbf a $$ \mathbf b $的和,标记为$ \mathbf a + \mathbf b $,它也是个$ m\times n $矩阵,其内的各元素为其相对应元素相加后的值。如果矩阵$ \mathbf c = \mathbf a + \mathbf b $,则$ c_{ij} = a_{ij} + b_{ij} $。公式\ref{eqa1.4}展示了矩阵之间进行加法的计算过程。
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\begin{pmatrix} \begin{pmatrix}
...@@ -258,7 +258,7 @@ ...@@ -258,7 +258,7 @@
\parinterval (3)结合律:$ (kl)\mathbf a=k(l\mathbf a) $ \parinterval (3)结合律:$ (kl)\mathbf a=k(l\mathbf a) $
%--5.2.1.4矩阵乘法和矩阵点乘--------------------- %--5.2.1.4矩阵乘法和矩阵点乘---------------------
\subsubsection{(四)矩阵乘法和矩阵点乘}\index{Chapter5.2.1.4} \subsubsection{矩阵乘法和矩阵点乘}\index{Chapter5.2.1.4}
\parinterval 矩阵乘法是矩阵运算中最重要的操作之一,为了与矩阵点乘区分,我们通常也把矩阵乘法叫做矩阵的叉乘。假设$ \mathbf a $$ m\times p $的矩阵,$ \mathbf b $$ p\times n $的矩阵,对$ \mathbf a $$ \mathbf b $作矩阵乘积的结果是一个$ m\times n $的矩阵$ \mathbf c $,其中矩阵$ \mathbf c $中第$ i $行、第$ j $列的元素可以表示为: \parinterval 矩阵乘法是矩阵运算中最重要的操作之一,为了与矩阵点乘区分,我们通常也把矩阵乘法叫做矩阵的叉乘。假设$ \mathbf a $$ m\times p $的矩阵,$ \mathbf b $$ p\times n $的矩阵,对$ \mathbf a $$ \mathbf b $作矩阵乘积的结果是一个$ m\times n $的矩阵$ \mathbf c $,其中矩阵$ \mathbf c $中第$ i $行、第$ j $列的元素可以表示为:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -311,9 +311,9 @@ ...@@ -311,9 +311,9 @@
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
%--5.2.1.5线性映射--------------------- %--5.2.1.5线性映射---------------------
\subsubsection{(五)线性映射}\index{Chapter5.2.1.5} \subsubsection{线性映射}\index{Chapter5.2.1.5}
\parinterval {\small\sffamily\bfseries{线性映射}}linear mapping)或{\small\sffamily\bfseries{线性变换}}(linear transformation)是从一个向量空间V到另一个向量空间W的映射函数$ f:v\rightarrow w$,且该映射函数保持加法运算和数量乘法运算,即对于空间V中任何两个向量$ \mathbf u $$ \mathbf v $以及任何标量$ c $ \parinterval {\small\sffamily\bfseries{线性映射}}Linear Mapping)或{\small\sffamily\bfseries{线性变换}}(Linear Transformation)是从一个向量空间V到另一个向量空间W的映射函数$ f:v\rightarrow w$,且该映射函数保持加法运算和数量乘法运算,即对于空间V中任何两个向量$ \mathbf u $$ \mathbf v $以及任何标量$ c $
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
f(\mathbf u+\mathbf v)&=&f(\mathbf u)+f(\mathbf v)\label{eqa1.9}\\ f(\mathbf u+\mathbf v)&=&f(\mathbf u)+f(\mathbf v)\label{eqa1.9}\\
...@@ -336,8 +336,10 @@ f(c\mathbf v)&=&cf(\mathbf v) ...@@ -336,8 +336,10 @@ f(c\mathbf v)&=&cf(\mathbf v)
\end{pmatrix} \end{pmatrix}
\label{eqa1.12} \label{eqa1.12}
\end{eqnarray} \end{eqnarray}
\begin{eqnarray} \begin{eqnarray}
\mathbf y&=&\mathbf a\mathbf x\;\;=\;\; \mathbf y& = &\mathbf a\mathbf x \nonumber \\
& = &
\begin{pmatrix} \begin{pmatrix}
a_{11}x_{1}+a_{12}x_{2}+\dots+a_{1n}x_{n}\\ a_{11}x_{1}+a_{12}x_{2}+\dots+a_{1n}x_{n}\\
a_{21}x_{1}+a_{22}x_{2}+\dots+a_{2n}x_{n}\\ a_{21}x_{1}+a_{22}x_{2}+\dots+a_{2n}x_{n}\\
...@@ -346,9 +348,11 @@ f(c\mathbf v)&=&cf(\mathbf v) ...@@ -346,9 +348,11 @@ f(c\mathbf v)&=&cf(\mathbf v)
\label{eqa1.13}\end{pmatrix} \label{eqa1.13}\end{pmatrix}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\parinterval 上例中矩阵$ \mathbf a $定义了一个从$ R^n $$ R^m $的线性映射:向量$ \mathbf x\in R^n $$ \mathbf y\in R^m $别为两个空间中的列向量,即大小为$ n\times 1 $$ m\times 1 $的矩阵。 \parinterval 上例中矩阵$ \mathbf a $定义了一个从$ R^n $$ R^m $的线性映射:向量$ \mathbf x\in R^n $$ \mathbf y\in R^m $别为两个空间中的列向量,即大小为$ n\times 1 $$ m\times 1 $的矩阵。
%--5.2.1.6范数--------------------- %--5.2.1.6范数---------------------
\subsubsection{(六)范数}\index{Chapter5.2.1.6} \subsubsection{范数}\index{Chapter5.2.1.6}
\parinterval 工程领域,我们经常会使用被称为范数(norm)的函数衡量向量大小,范数为向量空间内的所有向量赋予非零的正长度或大小。对于一个n维向量$ \mathbf x $,一个常见的范数函数为$ l_p $范数,通常表示为$ {\Vert{\mathbf x}\Vert}_p $ ,其中$p\geqslant 0$,是一个标量形式的参数。常用的$ p $的取值有$ 1 $$ 2 $$ \infty $等。范数的计算公式为: \parinterval 工程领域,我们经常会使用被称为范数(norm)的函数衡量向量大小,范数为向量空间内的所有向量赋予非零的正长度或大小。对于一个n维向量$ \mathbf x $,一个常见的范数函数为$ l_p $范数,通常表示为$ {\Vert{\mathbf x}\Vert}_p $ ,其中$p\geqslant 0$,是一个标量形式的参数。常用的$ p $的取值有$ 1 $$ 2 $$ \infty $等。范数的计算公式为:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
...@@ -366,7 +370,8 @@ l_p(\mathbf x)&=&{\Vert{\mathbf x}\Vert}_p\;\;=\;\;{\left (\sum_{i=1}^{n}{{\vert ...@@ -366,7 +370,8 @@ l_p(\mathbf x)&=&{\Vert{\mathbf x}\Vert}_p\;\;=\;\;{\left (\sum_{i=1}^{n}{{\vert
\parinterval $ l_2 $范数为向量的各个元素平方和的二分之一次方: \parinterval $ l_2 $范数为向量的各个元素平方和的二分之一次方:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
{\Vert{\mathbf x}\Vert}_2&=&\sqrt{\sum_{i=1}^{n}{{x_{i}}^2}}\;\;=\;\;\sqrt{{\mathbf x}^{\rm T}\mathbf x} {\Vert{\mathbf x}\Vert}_2&=&\sqrt{\sum_{i=1}^{n}{{x_{i}}^2}} \nonumber \\
&=&\sqrt{{\mathbf x}^{\rm T}\mathbf x}
\label{eqa1.16} \label{eqa1.16}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -451,7 +456,8 @@ y=\begin{cases} 0 & \sum_{i}{x_i\cdot w_i}-\sigma <0\\1 & \sum_{i}{x_i\cdot w_i} ...@@ -451,7 +456,8 @@ y=\begin{cases} 0 & \sum_{i}{x_i\cdot w_i}-\sigma <0\\1 & \sum_{i}{x_i\cdot w_i}
\parinterval 在这种情况下应该如何做出决定呢?比如,女朋友很希望和你一起去看音乐会,但是剧场很远而且票价500元,如果这些因素对你都是同等重要的(即$ w_0=w_1=w_2 $,假设这三个权重都设置为1)那么我们会得到一个综合得分: \parinterval 在这种情况下应该如何做出决定呢?比如,女朋友很希望和你一起去看音乐会,但是剧场很远而且票价500元,如果这些因素对你都是同等重要的(即$ w_0=w_1=w_2 $,假设这三个权重都设置为1)那么我们会得到一个综合得分:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
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 x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumber \\
& = & 1
\label{eqa1.20} \label{eqa1.20}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -473,7 +479,9 @@ 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 ...@@ -473,7 +479,9 @@ 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 在上面的例子中,如果你是守财奴,则会对票价看得更重一些,这样你会用不均匀的权重计算每个因素的影响,比如:$ w_0=0.5 $$ w_1=2 $$ w_2=0.5 $,此时感知机模型如图\ref{fig:perceptron-to-predict-2}所示。在这种情况下,女友很希望和你一起去看音乐会,但是剧场很远而且票价有500元,会导致你不去看音乐会,因为 \parinterval 在上面的例子中,如果你是守财奴,则会对票价看得更重一些,这样你会用不均匀的权重计算每个因素的影响,比如:$ w_0=0.5 $$ w_1=2 $$ w_2=0.5 $,此时感知机模型如图\ref{fig:perceptron-to-predict-2}所示。在这种情况下,女友很希望和你一起去看音乐会,但是剧场很远而且票价有500元,会导致你不去看音乐会,因为
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\sum_{i}{x_i\cdot w_i}=0\cdot 0.5+0\cdot 2+1\cdot 0.5=0.5<\sigma =1 \sum_{i}{x_i\cdot w_i} & = & 0\cdot 0.5+0\cdot 2+1\cdot 0.5 \nonumber \\
& = & 0.5 \nonumber \\
& < & \sigma = 1
\label{eqa1.21} \label{eqa1.21}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -513,7 +521,9 @@ 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 ...@@ -513,7 +521,9 @@ 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 使用修改后的模型做决策:女朋友很希望和你一起,但是剧场有20km远而且票价有500元。于是有$ x_0=10/20 $$ x_1=150/500 $$ x_2=1 $ \parinterval 使用修改后的模型做决策:女朋友很希望和你一起,但是剧场有20km远而且票价有500元。于是有$ x_0=10/20 $$ x_1=150/500 $$ x_2=1 $
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\sum_{i}{x_i\cdot w_i}=0.5\cdot 0.5+0.3\cdot 2+1\cdot 0.5=1.35>\sigma =1 \sum_{i}{x_i\cdot w_i} & = & 0.5\cdot 0.5+0.3\cdot 2+1\cdot 0.5 \nonumber \\
& = & 1.35 \nonumber \\
& > & \sigma =1
\label{eqa1.22} \label{eqa1.22}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -554,7 +564,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 ...@@ -554,7 +564,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 感知机也被称作一种最简单的单层神经网络。一个非常自然的问题是:能否把多个这样的网络叠加在一起,获得建模更复杂问题的能力?如果可以,那么在多层神经网络的每一层,神经元之间是怎么组织、工作的呢?单层网络又是通过什么方式构造成多层的呢?
%--5.2.3.1线性变换和激活函数--------------------- %--5.2.3.1线性变换和激活函数---------------------
\subsubsection{(一)线性变换和激活函数}\index{Chapter5.2.3.1} \subsubsection{线性变换和激活函数}\index{Chapter5.2.3.1}
\parinterval 为了建立多层神经网络,这里我们首先需要把前面提到的简单的神经元进行扩展,把多个神经元组成一``层''神经元。比如,很多实际问题中我们希望同时有多个输出,这时可以把多个相同的神经元并列起来,每个神经元都会有一个单独的输出,这就构成一``层'',形成了单层神经网络。单层神经网络中的每一个神经元都对应着一组权重和一个输出,我们可以把单层神经网络中的不同输出看作一个事物不同角度的描述。举个简单的例子,预报天气时,往往需要预测温度、湿度和风力,这就意味着如果使用单层神经网络进行预测,需要设置3个神经元。如图\ref{fig:corresponence-between-matrix-element-and-output},权重矩阵$ \mathbf w=\begin{pmatrix} w_{00} & w_{01} & w_{02}\\ w_{10} & w_{11} & w_{12}\end{pmatrix} $中第一列元素$ \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:single-layer-of-neural-network-for-weather-prediction}所示(在本例中,假设输入$ \mathbf x=(x_0,x_1) $)。 \parinterval 为了建立多层神经网络,这里我们首先需要把前面提到的简单的神经元进行扩展,把多个神经元组成一``层''神经元。比如,很多实际问题中我们希望同时有多个输出,这时可以把多个相同的神经元并列起来,每个神经元都会有一个单独的输出,这就构成一``层'',形成了单层神经网络。单层神经网络中的每一个神经元都对应着一组权重和一个输出,我们可以把单层神经网络中的不同输出看作一个事物不同角度的描述。举个简单的例子,预报天气时,往往需要预测温度、湿度和风力,这就意味着如果使用单层神经网络进行预测,需要设置3个神经元。如图\ref{fig:corresponence-between-matrix-element-and-output},权重矩阵$ \mathbf w=\begin{pmatrix} w_{00} & w_{01} & w_{02}\\ w_{10} & w_{11} & w_{12}\end{pmatrix} $中第一列元素$ \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:single-layer-of-neural-network-for-weather-prediction}所示(在本例中,假设输入$ \mathbf x=(x_0,x_1) $)。
%---------------------------------------------- %----------------------------------------------
...@@ -583,9 +593,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=1 ...@@ -583,9 +593,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=1
\parinterval 那么,线性变换的本质是什么? \parinterval 那么,线性变换的本质是什么?
\parinterval 从代数角度看,对于线性空间$ \rm V $,任意$ a,b\in {\rm V} $和数域中的任意$ \alpha $,线性变换$ T(\cdot) $需满足:$ T(a+b)=T(a)+T(b) $$ T(\alpha a)=\alpha T(a) $ \begin{itemize}
\item 从代数角度看,对于线性空间$ \rm V $,任意$ a,b\in {\rm V} $和数域中的任意$ \alpha $,线性变换$ T(\cdot) $需满足:$ T(a+b)=T(a)+T(b) $$ T(\alpha a)=\alpha T(a) $
\item 从几何角度上看,公式中的$ \mathbf x\cdot \mathbf w+\mathbf b $$ \mathbf x $右乘$ \mathbf w $相当于对$ \mathbf x $进行旋转变换,如图\ref{fig:rotation}所示,对三个点$ (0,0) $$ (0,1) $$ (1,0) $及其围成的矩形区域右乘$ \mathbf w=\begin{pmatrix} 1 & 0 & 0\\ 0 & -1 & 0\\ 0 & 0 & 1\end{pmatrix} $\\后,矩形区域由第一象限旋转90度到了第四象限。
\end{itemize}
\parinterval 从几何角度上看,公式中的$ \mathbf x\cdot \mathbf w+\mathbf b $$ \mathbf x $右乘$ \mathbf w $相当于对$ \mathbf x $进行旋转变换,如图\ref{fig:rotation}所示,对三个点$ (0,0) $$ (0,1) $$ (1,0) $及其围成的矩形区域右乘$ \mathbf w=\begin{pmatrix} 1 & 0 & 0\\ 0 & -1 & 0\\ 0 & 0 & 1\end{pmatrix} $\\后,矩形区域由第一象限旋转90度到了第四象限。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
...@@ -634,20 +646,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=1 ...@@ -634,20 +646,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=1
\subfigure[Sigmoid]{ \subfigure[Sigmoid]{
\centering \centering
\begin{minipage}{.23\textwidth} \begin{minipage}{.23\textwidth}
\input{./Chapter5/Figures/fig-sigmoid} \input{./Chapter5/Figures/fig-Sigmoid}
\end{minipage}% \end{minipage}%
} }
\qquad \qquad
\subfigure[Tanh]{ \subfigure[Tanh]{
\centering \centering
\begin{minipage}{.23\textwidth} \begin{minipage}{.23\textwidth}
\input{./Chapter5/Figures/fig-tanh} \input{./Chapter5/Figures/fig-Tanh}
\end{minipage} \end{minipage}
}\\ \vspace{-0.5em} }\\ \vspace{-0.5em}
\subfigure[relu]{ \subfigure[Relu]{
\centering \centering
\begin{minipage}{.23\textwidth} \begin{minipage}{.23\textwidth}
\input{./Chapter5/Figures/fig-relu} \input{./Chapter5/Figures/fig-Relu}
\end{minipage}% \end{minipage}%
} }
\qquad \qquad
...@@ -670,7 +682,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 ...@@ -670,7 +682,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
%------------------------------------------- %-------------------------------------------
%--5.2.3.2单层神经网络->多层神经网络--------------------- %--5.2.3.2单层神经网络->多层神经网络---------------------
\subsubsection{(二)单层神经网络$\rightarrow$多层神经网络}\index{Chapter5.2.3.2} \subsubsection{单层神经网络$\rightarrow$多层神经网络}\index{Chapter5.2.3.2}
\parinterval 单层神经网络由线性变换和激活函数两部分构成,但在实际问题中,单层网络并不足以拟合所有函数关系,因此很自然的想到将单层网络扩展到多层神经网络即深层神经网络。将一层神经网络的最终输出向量作为另一层神经网络的输入向量,通过这种方式我们可以将多层神经网络连接在一起,如图\ref{fig:more-layers}所示. \parinterval 单层神经网络由线性变换和激活函数两部分构成,但在实际问题中,单层网络并不足以拟合所有函数关系,因此很自然的想到将单层网络扩展到多层神经网络即深层神经网络。将一层神经网络的最终输出向量作为另一层神经网络的输入向量,通过这种方式我们可以将多层神经网络连接在一起,如图\ref{fig:more-layers}所示.
%---------------------------------------------- %----------------------------------------------
...@@ -701,13 +713,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 +713,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}
%------------------------------------------- %-------------------------------------------
...@@ -802,26 +814,26 @@ 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 ...@@ -802,26 +814,26 @@ 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
\subsection{ 张量及其计算}\index{Chapter5.3.1} \subsection{ 张量及其计算}\index{Chapter5.3.1}
%--5.3.1.1张量--------------------- %--5.3.1.1张量---------------------
\subsubsection{(一)张量}\index{Chapter5.3.1.1} \subsubsection{张量}\index{Chapter5.3.1.1}
\parinterval 对于神经网络中的某层神经元$ \mathbf y=f(\mathbf x\cdot \mathbf w+\mathbf b) $,其中$ \mathbf w $是权重矩阵,例如$ \begin{pmatrix} 1 & 2\\ 3 & 4\end{pmatrix} $$ \mathbf b $ 是偏移向量,例如$ (1,3) $。在这里,输入$ \mathbf x $和输出$ \mathbf y $,可以不是简单的向量或是矩阵形式,而是深度学习中更加通用的数学量\ \dash \ 张量,比如下式中的几种情况都可以看作是深度学习中定义数据的张量: \parinterval 对于神经网络中的某层神经元$ \mathbf y=f(\mathbf x\cdot \mathbf w+\mathbf b) $,其中$ \mathbf w $是权重矩阵,例如$ \begin{pmatrix} 1 & 2\\ 3 & 4\end{pmatrix} $$ \mathbf b $ 是偏移向量,例如$ (1,3) $。在这里,输入$ \mathbf x $和输出$ \mathbf y $,可以不是简单的向量或是矩阵形式,而是深度学习中更加通用的数学量\ \dash \ {\small\bfnew{张量}}(Tensor),比如下式中的几种情况都可以看作是深度学习中定义数据的张量:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\mathbf x&=&\begin{pmatrix} -1 & 3\end{pmatrix}\qquad \mathbf x&=&\begin{pmatrix} -1 & 3\end{pmatrix}\qquad
\mathbf x\;\;=\;\;\begin{pmatrix} -1 & 3\\ 0.2 & 2\end{pmatrix}\qquad \mathbf x\;\;=\;\;\begin{pmatrix} -1 & 3\\ 0.2 & 2\end{pmatrix}\qquad
\mathbf x\;\;=\;\;\begin{pmatrix}{\begin{pmatrix} -1 & 3\\ 0.2 & 2\end{pmatrix}}\\{\begin{pmatrix} -1 & 3\\ 0.2 & 2\end{pmatrix}}\end{pmatrix} \mathbf x\;\;=\;\;\begin{pmatrix}{\begin{pmatrix} -1 & 3\\ 0.2 & 2\end{pmatrix}}\\{\begin{pmatrix} -1 & 3\\ 0.2 & 2\end{pmatrix}}\end{pmatrix} \nonumber
\label{} \label{}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\parinterval 简单来说,张量可以为我们描述数据提供更多方便,是一种通用的工具。比如,输入的量有三个维度在变化,用矩阵不容易描述,但是用张量却很容易。 \parinterval 简单来说,张量可以为我们描述数据提供更多方便,是一种通用的工具。比如,输入的量有三个维度在变化,用矩阵不容易描述,但是用张量却很容易。
\parinterval 从计算机实现的角度来看,现在所有深度学习框架都把张量定义为``多维数组''。张量有一个非常重要的属性\ \dash \ 阶(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:tensor-sample},这是一个3维数组或3阶张量,其中,每个4*4的方形代表一个2阶张量,这样的方形有4个,最终形成3阶张量。 \parinterval 从计算机实现的角度来看,现在所有深度学习框架都把张量定义为``多维数组''。张量有一个非常重要的属性\ \dash \ 阶(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:tensor-sample},这是一个3维数组或3阶张量,其中,每个$4 \times 4$的方形代表一个2阶张量,这样的方形有4个,最终形成3阶张量。
%---------------------------------------------- %----------------------------------------------
% 图 % 图
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-tensor-sample} \input{./Chapter5/Figures/fig-tensor-sample}
\caption{3阶张量示例(4*4*4} \caption{3阶张量示例($4 \times 4 \times 4$}
\label{fig:tensor-sample} \label{fig:tensor-sample}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
...@@ -857,7 +869,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 ...@@ -857,7 +869,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 上面讲了很多和神经网络不太相关的内容,目的是要明确张量的原始定义,以避免对这个概念的误解。但是,在本书中,我们仍然遵循深度学习中常用的概念,把张量理解为多维数组。使用张量,我们可以更容易的表示更高阶的数学形式。在保证数学表达的简洁性的同时,使程序实现接口更加统一。
%--5.3.1.2张量的矩阵乘法--------------------- %--5.3.1.2张量的矩阵乘法---------------------
\subsubsection{(二)张量的矩阵乘法}\index{Chapter5.3.1.2} \subsubsection{张量的矩阵乘法}\index{Chapter5.3.1.2}
\parinterval 对于一层神经网络,$ \mathbf y=f(\mathbf x\cdot \mathbf w+\mathbf b) $中的$ \mathbf x\cdot \mathbf w $表示对输入$ \mathbf x $进行线性变换,其中$ \mathbf x $是输入张量,$ \mathbf w $是权重矩阵。$ \mathbf x\cdot \mathbf w $表示的是矩阵乘法,需要注意的是这里是矩阵乘法而不是张量乘法。 \parinterval 对于一层神经网络,$ \mathbf y=f(\mathbf x\cdot \mathbf w+\mathbf b) $中的$ \mathbf x\cdot \mathbf w $表示对输入$ \mathbf x $进行线性变换,其中$ \mathbf x $是输入张量,$ \mathbf w $是权重矩阵。$ \mathbf x\cdot \mathbf w $表示的是矩阵乘法,需要注意的是这里是矩阵乘法而不是张量乘法。
...@@ -872,7 +884,8 @@ 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 ...@@ -872,7 +884,8 @@ 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
\noindent 例如$ \mathbf a= \begin{pmatrix} a_{11} & a_{12} & a_{13}\\a_{21} & a_{22} & a_{23}\end{pmatrix} $$ \mathbf b= \begin{pmatrix} b_{11} & b_{12}\\b_{21} & b_{22}\\b_{31} & b_{32}\end{pmatrix} $,则 \noindent 例如$ \mathbf a= \begin{pmatrix} a_{11} & a_{12} & a_{13}\\a_{21} & a_{22} & a_{23}\end{pmatrix} $$ \mathbf b= \begin{pmatrix} b_{11} & b_{12}\\b_{21} & b_{22}\\b_{31} & b_{32}\end{pmatrix} $,则
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\mathbf c&=&\mathbf a\mathbf b\;\;=\;\;\begin{pmatrix} a_{11}b_{11}+a_{12}b_{21}+a_{13}b_{31} & a_{11}b_{12}+a_{12}b_{22}+a_{13}b_{32}\\a_{21}b_{11}+a_{22}b_{21}+a_{23}b_{31} & a_{21}b_{12}+a_{22}b_{22}+a_{23}b_{32}\end{pmatrix} \mathbf c & = & \mathbf a\mathbf b \nonumber \\
& = & \begin{pmatrix} a_{11}b_{11}+a_{12}b_{21}+a_{13}b_{31} & a_{11}b_{12}+a_{12}b_{22}+a_{13}b_{32}\\a_{21}b_{11}+a_{22}b_{21}+a_{23}b_{31} & a_{21}b_{12}+a_{22}b_{22}+a_{23}b_{32}\end{pmatrix}
\label{} \label{}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -897,7 +910,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 ...@@ -897,7 +910,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
%------------------------------------------- %-------------------------------------------
%--5.3.1.3张量的单元操作--------------------- %--5.3.1.3张量的单元操作---------------------
\subsubsection{(三)张量的单元操作}\index{Chapter5.3.1.3} \subsubsection{张量的单元操作}\index{Chapter5.3.1.3}
\parinterval 对于神经网络中的某层神经元$ \mathbf y=f(\mathbf x\cdot \mathbf w+\mathbf b) $,也包含有其它张量单元操作:1)加法:$ \mathbf s+\mathbf b $,其中张量$ \mathbf s=\mathbf x\cdot \mathbf w $;2)激活函数:$ f(\cdot) $。具体来说: \parinterval 对于神经网络中的某层神经元$ \mathbf y=f(\mathbf x\cdot \mathbf w+\mathbf b) $,也包含有其它张量单元操作:1)加法:$ \mathbf s+\mathbf b $,其中张量$ \mathbf s=\mathbf x\cdot \mathbf w $;2)激活函数:$ f(\cdot) $。具体来说:
...@@ -915,14 +928,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 +928,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 张量的物理存储形式---------------------
...@@ -952,7 +965,7 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases} ...@@ -952,7 +965,7 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases}
%--5.3.3 使用开源框架实现张量计算---以NiuTensor为例--------------------- %--5.3.3 使用开源框架实现张量计算---以NiuTensor为例---------------------
\subsection{使用开源框架实现张量计算}\index{Chapter5.3.3} \subsection{使用开源框架实现张量计算}\index{Chapter5.3.3}
\parinterval 实现神经网络的开源系统有很多,比如,一个简单好用的Python工具包\ \dash \ Numpy(https://numpy.org/)。Numpy提供了张量表示和使用的范式,可以很方便地定义、使用多维数组。 \parinterval 实现神经网络的开源系统有很多,比如,一个简单好用的Python工具包\ \dash \ Numpy(\url{https://numpy.org/})。Numpy提供了张量表示和使用的范式,可以很方便地定义、使用多维数组。
\parinterval 此外,如今深度学习框架已经非常成熟。比如, Tensorflow和Pytorch就是非常受欢迎的深度学习工具包,除此之外还有很多其它优秀的框架:CNTK、MXNet、\\PaddlePaddle、Keras、Chainer、dl4j、NiuTensor等。开发者可以根据自身的喜好和开发项目的要求选择所采用的框架。 \parinterval 此外,如今深度学习框架已经非常成熟。比如, Tensorflow和Pytorch就是非常受欢迎的深度学习工具包,除此之外还有很多其它优秀的框架:CNTK、MXNet、\\PaddlePaddle、Keras、Chainer、dl4j、NiuTensor等。开发者可以根据自身的喜好和开发项目的要求选择所采用的框架。
...@@ -1075,8 +1088,8 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases} ...@@ -1075,8 +1088,8 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases}
\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 +1111,10 @@ f(x)=\begin{cases} 0 & x\leqslant0 \\x & x>0\end{cases} ...@@ -1098,10 +1111,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 +1128,14 @@ y&=&{\rm{sigmoid}}({\rm{tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat ...@@ -1115,14 +1128,14 @@ y&=&{\rm{sigmoid}}({\rm{tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat
\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 +1146,7 @@ y&=&{\rm{sigmoid}}({\rm{tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat ...@@ -1133,7 +1146,7 @@ y&=&{\rm{sigmoid}}({\rm{tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\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) $ \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 +1171,7 @@ y&=&{\rm{sigmoid}}({\rm{tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat ...@@ -1158,7 +1171,7 @@ y&=&{\rm{sigmoid}}({\rm{tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat
%--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 $等其它变量作为{\small\sffamily\bfseries{模型参数}}(Model Parameters)。确定了函数表达式和模型参数,也就确定了神经网络模型。通常,表达式的形式需要系统开发者设计,而模型参数的数量非常巨大,因此需要自动学习,这个过程也称为模型学习或训练。为了实现这个目标,通常我们会准备一定量的带有标准答案的数据,称之为{\small\sffamily\bfseries{有标注数据}}(Annotated Data/Labeled Data)。这些数据会用于对模型参数的学习,这也对应了统计模型中的参数估计过程。在机器学习中,一般把这种使用有标注数据进行统计模型参数训练的过程称为{\small\sffamily\bfseries{有指导的训练}}{\small\sffamily\bfseries{有监督的训练}}(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 $等其它变量作为{\small\sffamily\bfseries{模型参数}}(Model Parameters)。确定了函数表达式和模型参数,也就确定了神经网络模型。通常,表达式的形式需要系统开发者设计,而模型参数的数量非常巨大,因此需要自动学习,这个过程也称为模型学习或训练。为了实现这个目标,通常我们会准备一定量的带有标准答案的数据,称之为{\small\sffamily\bfseries{有标注数据}}(Annotated Data/Labeled Data)。这些数据会用于对模型参数的学习,这也对应了统计模型中的参数估计过程。在机器学习中,一般把这种使用有标注数据进行统计模型参数训练的过程称为{\small\sffamily\bfseries{有指导的训练}}{\small\sffamily\bfseries{有监督的训练}}(Supervised Training)。在本章中,如果没有特殊说明,模型训练都是指有监督的训练。那么神经网络内部是怎样利用有标注数据对参数进行训练的呢?
\parinterval 为了回答这个问题,我们可以把模型参数的学习过程看作是一个优化问题,即找到一组参数,使得模型达到某种最优的状态。这个问题又可以被转化为两个新的问题: \parinterval 为了回答这个问题,我们可以把模型参数的学习过程看作是一个优化问题,即找到一组参数,使得模型达到某种最优的状态。这个问题又可以被转化为两个新的问题:
...@@ -1502,7 +1515,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1502,7 +1515,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\end {figure} \end {figure}
%------------------------------------------- %-------------------------------------------
\parinterval\ref{fig:parallel}对比了同步更新和异步更新的区别,在这个例子中,使用4台设备对一个两层神经网络中的参数进行更新,其中使用了一个参数服务器(parameter server,图中的G4)来保存最新的参数,不同设备(worker,图中的G1、G2、G3)可以通过同步或者异步的方式访问参数服务器。图中的$ \mathbf w_o $$ \mathbf w_h $分别代表输出层和隐藏层的全部参数,操作push(P)设备向参数服务器传送梯度,操作fetch(F)表示参数服务器向设备传送更新后的参数。 \parinterval\ref{fig:parallel}对比了同步更新和异步更新的区别,在这个例子中,使用4台设备对一个两层神经网络中的参数进行更新,其中使用了一个参数服务器(Parameter Server,图中的G4)来保存最新的参数,不同设备(Worker,图中的G1、G2、G3)可以通过同步或者异步的方式访问参数服务器。图中的$ \mathbf w_o $$ \mathbf w_h $分别代表输出层和隐藏层的全部参数,操作push(P)设备向参数服务器传送梯度,操作fetch(F)表示参数服务器向设备传送更新后的参数。
\parinterval 此外,在使用多个设备进行并行训练的时候,由于设备间带宽的限制,大量的数据传输会有较高的延时。对于复杂神经网络来说,设备间参数和梯度传递的时间消耗也会成为一个不得不考虑的因素。有时候,设备间数据传输的时间甚至比模型计算的时间都长,大大降低了并行度\cite{xiao2017fast}。对于这种问题,可以考虑对数据进行压缩或者减少传输的次数缓解问题。 \parinterval 此外,在使用多个设备进行并行训练的时候,由于设备间带宽的限制,大量的数据传输会有较高的延时。对于复杂神经网络来说,设备间参数和梯度传递的时间消耗也会成为一个不得不考虑的因素。有时候,设备间数据传输的时间甚至比模型计算的时间都长,大大降低了并行度\cite{xiao2017fast}。对于这种问题,可以考虑对数据进行压缩或者减少传输的次数缓解问题。
%--5.4.4 梯度消失、梯度爆炸和稳定性训练--------------------- %--5.4.4 梯度消失、梯度爆炸和稳定性训练---------------------
...@@ -1512,37 +1525,37 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1512,37 +1525,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 +1727,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1714,7 +1727,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}
...@@ -1920,17 +1933,17 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1920,17 +1933,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}}(x)&=&\frac{{\rm{exp}}(x)-{\rm{exp}}(-x)}{{\rm{exp}}(x)+\rm{exp}(-x)} {\rm{Tanh}}(x)&=&\frac{{\rm{exp}}(x)-{\rm{exp}}(-x)}{{\rm{exp}}(x)+{\rm{exp}}(-x)}
\label{} \label{}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\noindent 而hardtanh函数不存在这个问题,因此具有数值计算的稳定性。hardtanh函数表达式如下: \noindent 而hardTanh函数不存在这个问题,因此具有数值计算的稳定性。hardTanh函数表达式如下:
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
\begin{eqnarray} \begin{eqnarray}
{\rm{hardtanh}}(x)&=&\begin{cases} -1 & x<-1\\x & -1\leqslant x\leqslant 1\\1 & x>1\end{cases} {\rm{hardTanh}}(x)&=&\begin{cases} -1 & x<-1\\x & -1\leqslant x\leqslant 1\\1 & x>1\end{cases}
\label{} \label{}
\end{eqnarray} \end{eqnarray}
%公式-------------------------------------------------------------------- %公式--------------------------------------------------------------------
...@@ -1957,11 +1970,11 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1957,11 +1970,11 @@ 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 $。循环神经网络的核心是{\small\sffamily\bfseries{循环单元}}(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 $。循环神经网络的核心是{\small\sffamily\bfseries{循环单元}}(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)
......
...@@ -379,7 +379,7 @@ NMT & $ 21.7^{\ast}$ & $18.7^{\ast}$ & -1 ...@@ -379,7 +379,7 @@ NMT & $ 21.7^{\ast}$ & $18.7^{\ast}$ & -1
\parinterval 显然,根据上下文中提到的``没吃饭''、``很饿'',最佳的答案是``吃 饭''或者``吃 东西''。也就是,对序列中某个位置的答案进行预测时我们需要记忆当前时刻之前的序列信息,因此,循环神经网络(Recurrent Neural Network, RNN)应运而生。实际上循环神经网络有着极为广泛的应用,例如语音识别、语言建模以及我们要介绍的神经机器翻译。 \parinterval 显然,根据上下文中提到的``没吃饭''、``很饿'',最佳的答案是``吃 饭''或者``吃 东西''。也就是,对序列中某个位置的答案进行预测时我们需要记忆当前时刻之前的序列信息,因此,循环神经网络(Recurrent Neural Network, RNN)应运而生。实际上循环神经网络有着极为广泛的应用,例如语音识别、语言建模以及我们要介绍的神经机器翻译。
\parinterval 第五章已经对循环神经网络的基本知识进行过介绍。这里再简单回顾一下。简单来说,循环神经网络由循环单元组成。对于序列中的任意时刻,都有一个循环单元与之对应,它会融合当前时刻的输入和上一时刻循环单元的输出,生成当前时刻的输出。这样每个时刻的信息都会被传递到下一时刻,这也间接达到了记录历史信息的目的。比如,对于序列$\mathbf{x}=\{x_1, x_2,…, x_m\}$,循环神经网络的会按顺序输出一个序列$\mathbf{h}=\{ \mathbf{h}_1, \mathbf{h}_2,…, \mathbf{h}_m \}$,其中$\mathbf{h}_i$表示$i$时刻循环神经网络的输出(通常为一个向量)。 \parinterval 第五章已经对循环神经网络的基本知识进行过介绍。这里再简单回顾一下。简单来说,循环神经网络由循环单元组成。对于序列中的任意时刻,都有一个循环单元与之对应,它会融合当前时刻的输入和上一时刻循环单元的输出,生成当前时刻的输出。这样每个时刻的信息都会被传递到下一时刻,这也间接达到了记录历史信息的目的。比如,对于序列$\mathbf{x}=\{x_1, x_2,..., x_m\}$,循环神经网络的会按顺序输出一个序列$\mathbf{h}=\{ \mathbf{h}_1, \mathbf{h}_2,..., \mathbf{h}_m \}$,其中$\mathbf{h}_i$表示$i$时刻循环神经网络的输出(通常为一个向量)。
\parinterval\ref{fig:6-8}展示了一个循环神经网络处理序列问题的实例。当前时刻循环单元的输入由上一个时刻的输入和当前时刻的输入组成,因此也可以理解为,网络当前时刻计算得到的输出是由之前的序列共同决定的,即网络在不断的传递信息的过程中记忆了历史信息。以最后一个时刻的循环单元为例,它在对``开始''这个单词的信息进行处理时,参考了之前所有词(``<eos> 让 我们'')的信息。 \parinterval\ref{fig:6-8}展示了一个循环神经网络处理序列问题的实例。当前时刻循环单元的输入由上一个时刻的输入和当前时刻的输入组成,因此也可以理解为,网络当前时刻计算得到的输出是由之前的序列共同决定的,即网络在不断的传递信息的过程中记忆了历史信息。以最后一个时刻的循环单元为例,它在对``开始''这个单词的信息进行处理时,参考了之前所有词(``<eos> 让 我们'')的信息。
...@@ -411,14 +411,14 @@ NMT & $ 21.7^{\ast}$ & $18.7^{\ast}$ & -1 ...@@ -411,14 +411,14 @@ NMT & $ 21.7^{\ast}$ & $18.7^{\ast}$ & -1
\label{eqC6.1} \label{eqC6.1}
\end{eqnarray} \end{eqnarray}
\noindent 在这里,我们用$\mathbf{x}=\{ x_1,x_2,…, x_m \}$表示输入的源语言单词序列,$\mathbf{y}=\{ y_1,y_2,…, y_n \}$ 表示生成的目标语单词序列。由于神经机器翻译在生成译文时采用的是自左向右逐词生成的方式,并在翻译每个单词时会考虑已经生成的翻译结果,因此对$\textrm{P} (\mathbf{y} | \mathbf{x})$的求解可以转换为: \noindent 在这里,我们用$\mathbf{x}=\{ x_1,x_2,..., x_m \}$表示输入的源语言单词序列,$\mathbf{y}=\{ y_1,y_2,..., y_n \}$ 表示生成的目标语单词序列。由于神经机器翻译在生成译文时采用的是自左向右逐词生成的方式,并在翻译每个单词时会考虑已经生成的翻译结果,因此对$\textrm{P} (\mathbf{y} | \mathbf{x})$的求解可以转换为:
%----------------- %-----------------
\begin{eqnarray} \begin{eqnarray}
\textrm{P} (\mathbf{y} | \mathbf{x}) = \prod_{j=1}^{n} \textrm{P} ( y_j | \mathbf{y}_{<j }, \mathbf{x} ) \textrm{P} (\mathbf{y} | \mathbf{x}) = \prod_{j=1}^{n} \textrm{P} ( y_j | \mathbf{y}_{<j }, \mathbf{x} )
\label{eqC6.2} \label{eqC6.2}
\end{eqnarray} \end{eqnarray}
\noindent 其中,$ \mathbf{y}_{<j }$表示目标语第$j$个位置之前已经生成的译文单词序列。$\textrm{P} ( y_j | \mathbf{y}_{<j }, \mathbf{x})$可以被解释为,根据源语句子$\mathbf{x} $和已生成的目标语言译文片段$\mathbf{y}_{<j }=\{ y_1, y_2,, y_{j-1} \}$,生成第$j$个目标语言单词$y_j$的概率。举个简单的例子,已知源文为$\mathbf{x} =$\{\textrm{我,很好}\},则译文$\mathbf{y}=$\{I’m,fine\}的概率为: \noindent 其中,$ \mathbf{y}_{<j }$表示目标语第$j$个位置之前已经生成的译文单词序列。$\textrm{P} ( y_j | \mathbf{y}_{<j }, \mathbf{x})$可以被解释为,根据源语句子$\mathbf{x} $和已生成的目标语言译文片段$\mathbf{y}_{<j }=\{ y_1, y_2,..., y_{j-1} \}$,生成第$j$个目标语言单词$y_j$的概率。举个简单的例子,已知源文为$\mathbf{x} =$\{\textrm{我,很好}\},则译文$\mathbf{y}=$\{I’m,fine\}的概率为:
%------------- %-------------
\begin{eqnarray} \begin{eqnarray}
\textrm{P} ( \{{\textrm{I'm,fine}}\}|\{\textrm{我,很好}\}) = \textrm{P} (\textrm{I'm}| \{\textrm{我,很好}\} ) \cdot \textrm{P} (\textrm{fine}|\textrm{I'm},\{\textrm{我,很好}\}) \textrm{P} ( \{{\textrm{I'm,fine}}\}|\{\textrm{我,很好}\}) = \textrm{P} (\textrm{I'm}| \{\textrm{我,很好}\} ) \cdot \textrm{P} (\textrm{fine}|\textrm{I'm},\{\textrm{我,很好}\})
...@@ -556,7 +556,7 @@ $\textrm{P}({y_j | \mathbf{s}_{j-1} ,y_{j-1},\mathbf{C}})$由Softmax实现,Sof ...@@ -556,7 +556,7 @@ $\textrm{P}({y_j | \mathbf{s}_{j-1} ,y_{j-1},\mathbf{C}})$由Softmax实现,Sof
\parinterval 循环神经网络的核心是设计循环单元的结构。至今,研究人员已经提出了很多优秀的循环单元结构,这里将介绍其中三种基本结构:RNN,LSTM和GRU。LSTM\\和GRU是RNN的变体,在自然语言处理任务中得到了广泛的应用。 \parinterval 循环神经网络的核心是设计循环单元的结构。至今,研究人员已经提出了很多优秀的循环单元结构,这里将介绍其中三种基本结构:RNN,LSTM和GRU。LSTM\\和GRU是RNN的变体,在自然语言处理任务中得到了广泛的应用。
%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%
\subsubsection{循环神经单元(RNN)}\index{Chapter6.3.3.1} \subsubsection{循环神经单元(RNN)}\index{Chapter6.3.3.1}
\parinterval RNN(Recurrent Neural Network)是最原始的循环神经网络结构。在RNN中,对于序列$\mathbf{x}=\{ \mathbf{x}_1, \mathbf{x}_2,,\mathbf{x}_m \}$,每个时刻$t$都对应一个循环单元,它的输出是一个向量$\mathbf{h}_t$,可以被描述为: \parinterval RNN(Recurrent Neural Network)是最原始的循环神经网络结构。在RNN中,对于序列$\mathbf{x}=\{ \mathbf{x}_1, \mathbf{x}_2,...,\mathbf{x}_m \}$,每个时刻$t$都对应一个循环单元,它的输出是一个向量$\mathbf{h}_t$,可以被描述为:
\begin{eqnarray} \begin{eqnarray}
\mathbf{h}_t=f(\mathbf{x}_t \mathbf{U}+\mathbf{h}_{t-1} \mathbf{W}+\mathbf{b}) \mathbf{h}_t=f(\mathbf{x}_t \mathbf{U}+\mathbf{h}_{t-1} \mathbf{W}+\mathbf{b})
\label{eqC6.11} \label{eqC6.11}
...@@ -781,13 +781,13 @@ $\textrm{P}({y_j | \mathbf{s}_{j-1} ,y_{j-1},\mathbf{C}})$由Softmax实现,Sof ...@@ -781,13 +781,13 @@ $\textrm{P}({y_j | \mathbf{s}_{j-1} ,y_{j-1},\mathbf{C}})$由Softmax实现,Sof
\parinterval 那么注意力机制是如何针对不同单词生成不同的上下文向量的呢?这里,我们可以将注意力机制看做是一种对接收到的信息的加权处理。对于更重要的信息赋予更高的权重即更高的关注度,对于贡献度较低的信息分配较低的权重,弱化其对结果的影响。这样,$\mathbf{C}_j$可以包含更多对当前目标语言位置有贡献的源语言片段的信息。 \parinterval 那么注意力机制是如何针对不同单词生成不同的上下文向量的呢?这里,我们可以将注意力机制看做是一种对接收到的信息的加权处理。对于更重要的信息赋予更高的权重即更高的关注度,对于贡献度较低的信息分配较低的权重,弱化其对结果的影响。这样,$\mathbf{C}_j$可以包含更多对当前目标语言位置有贡献的源语言片段的信息。
\parinterval 根据这种思想,上下文向量$\mathbf{C}_j$被定义为对不同时间步编码器输出的状态序列$\{ \mathbf{h}_1, \mathbf{h}_2,,\mathbf{h}_m \}$进行加权求和,如下: \parinterval 根据这种思想,上下文向量$\mathbf{C}_j$被定义为对不同时间步编码器输出的状态序列$\{ \mathbf{h}_1, \mathbf{h}_2,...,\mathbf{h}_m \}$进行加权求和,如下:
\begin{eqnarray} \begin{eqnarray}
\mathbf{C}_j=\sum_{i} \alpha_{i,j} \mathbf{h}_i \mathbf{C}_j=\sum_{i} \alpha_{i,j} \mathbf{h}_i
\label{eqC6.22} \label{eqC6.22}
\end{eqnarray} \end{eqnarray}
\noindent 其中,$\alpha_{i,j}${\small\sffamily\bfseries{注意力权重}},它表示目标语第$j$个位置与源语第$i$个位置之间的相关性大小。这里,我们将每个时间步编码器的输出$\mathbf{h}_i$看作源语言位置$i$的表示结果。进行翻译时,解码端可以根据当前的位置$j$,通过控制不同$\mathbf{h}_i$的权重得到$\mathbf{C}_j$,使得对目标语位置$j$贡献大的$\mathbf{h}_i$$\mathbf{C}_j$的影响增大。也就是说,$\mathbf{C}_j$实际上就是\{${\mathbf{h}_1, \mathbf{h}_2,,\mathbf{h}_m}$\}的一种组合,只不过不同的$\mathbf{h}_i$会根据对目标端的贡献给予不同的权重。图\ref{fig:6-22}展示了上下文向量$\mathbf{C}_j$的计算过程。 \noindent 其中,$\alpha_{i,j}${\small\sffamily\bfseries{注意力权重}},它表示目标语第$j$个位置与源语第$i$个位置之间的相关性大小。这里,我们将每个时间步编码器的输出$\mathbf{h}_i$看作源语言位置$i$的表示结果。进行翻译时,解码端可以根据当前的位置$j$,通过控制不同$\mathbf{h}_i$的权重得到$\mathbf{C}_j$,使得对目标语位置$j$贡献大的$\mathbf{h}_i$$\mathbf{C}_j$的影响增大。也就是说,$\mathbf{C}_j$实际上就是\{${\mathbf{h}_1, \mathbf{h}_2,...,\mathbf{h}_m}$\}的一种组合,只不过不同的$\mathbf{h}_i$会根据对目标端的贡献给予不同的权重。图\ref{fig:6-22}展示了上下文向量$\mathbf{C}_j$的计算过程。
%---------------------------------------------- %----------------------------------------------
% 图3.10 % 图3.10
...@@ -937,7 +937,7 @@ $\textrm{a}(\cdot)$可以被看作是目标语表示和源语言表示的一种` ...@@ -937,7 +937,7 @@ $\textrm{a}(\cdot)$可以被看作是目标语表示和源语言表示的一种`
\parinterval 将公式\ref{eqC6.29}应用于神经机器翻译有几个基本问题需要考虑:1)损失函数的选择;2)参数初始化的策略,也就是如何设置$\mathbf{w}_0$;3)优化策略和学习率调整策略;4)训练加速。下面我们对这些问题进行讨论。 \parinterval 将公式\ref{eqC6.29}应用于神经机器翻译有几个基本问题需要考虑:1)损失函数的选择;2)参数初始化的策略,也就是如何设置$\mathbf{w}_0$;3)优化策略和学习率调整策略;4)训练加速。下面我们对这些问题进行讨论。
%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%
\subsubsection{损失函数}\index{Chapter6.3.5.1} \subsubsection{损失函数}\index{Chapter6.3.5.1}
\parinterval 因为神经机器翻译在每个目标语位置都会输出一个概率分布,表示这个位置上不同单词出现的可能性,因此我们需要知道当前位置输出的分布相比于标准答案的``损失''。对于这个问题,常用的是交叉熵损失函数\footnote{\ \ 百度百科:\url{https://baike.baidu.com/item/\%E4\%BA\%A4\%E5\%8F\%89\%E7\%86\%B5/8983241?fr=aladdin}}。令$\mathbf{y}$表示机器翻译模型输出的分布,$\hat{\mathbf{y}}$表示标准答案,则交叉熵损失可以被定义为$L_{\textrm{ce}}(\mathbf{y},\hat{\mathbf{y}}) = - \sum_{k=1}^{|V|} \mathbf{y}[k] \textrm{log} (\hat{\mathbf{y}}[k])$,其中$\mathbf{y}[k]$$\hat{\mathbf{y}}[k]$分别表示向量$\mathbf{y}$$\hat{\mathbf{y}}$的第$k$维,$|V|$表示输出向量得维度(等于词表大小)。对于一个模型输出的概率分布$\mathbf{Y} = \{ \mathbf{y}_1,\mathbf{y}_2,…, \mathbf{y}_n \}$和标准答案分布$\hat{\mathbf{Y}}=\{ \hat{\mathbf{y}}_1, \hat{\mathbf{y}}_2,…,\hat{\mathbf{y}}_n \}$,损失函数可以被定义为 \parinterval 因为神经机器翻译在每个目标语位置都会输出一个概率分布,表示这个位置上不同单词出现的可能性,因此我们需要知道当前位置输出的分布相比于标准答案的``损失''。对于这个问题,常用的是交叉熵损失函数\footnote{\ \ 百度百科:\url{https://baike.baidu.com/item/\%E4\%BA\%A4\%E5\%8F\%89\%E7\%86\%B5/8983241?fr=aladdin}}。令$\mathbf{y}$表示机器翻译模型输出的分布,$\hat{\mathbf{y}}$表示标准答案,则交叉熵损失可以被定义为$L_{\textrm{ce}}(\mathbf{y},\hat{\mathbf{y}}) = - \sum_{k=1}^{|V|} \mathbf{y}[k] \textrm{log} (\hat{\mathbf{y}}[k])$,其中$\mathbf{y}[k]$$\hat{\mathbf{y}}[k]$分别表示向量$\mathbf{y}$$\hat{\mathbf{y}}$的第$k$维,$|V|$表示输出向量得维度(等于词表大小)。对于一个模型输出的概率分布$\mathbf{Y} = \{ \mathbf{y}_1,\mathbf{y}_2,..., \mathbf{y}_n \}$和标准答案分布$\hat{\mathbf{Y}}=\{ \hat{\mathbf{y}}_1, \hat{\mathbf{y}}_2,...,\hat{\mathbf{y}}_n \}$,损失函数可以被定义为
%------------- %-------------
\begin{eqnarray} \begin{eqnarray}
L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{\mathbf{y}}_j) L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{\mathbf{y}}_j)
...@@ -991,7 +991,7 @@ L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{ ...@@ -991,7 +991,7 @@ L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{
\subsubsection{梯度裁剪}\index{Chapter6.3.5.4} \subsubsection{梯度裁剪}\index{Chapter6.3.5.4}
\parinterval 需要注意的是,训练循环神经网络时,反向传播使得网络层之间的梯度重复相乘,在网络层数过深时,如果连乘因子小于1可能造成梯度指数级的减少,甚至趋近于0,导致网络无法优化,也就是梯度消失问题。当连乘因子大于1时,可能会导致梯度的乘积变得异常大,造成梯度爆炸的问题。在这种情况下需要使用``梯度裁剪''来防止梯度$\pi$超过阈值。具体公式如下: \parinterval 需要注意的是,训练循环神经网络时,反向传播使得网络层之间的梯度重复相乘,在网络层数过深时,如果连乘因子小于1可能造成梯度指数级的减少,甚至趋近于0,导致网络无法优化,也就是梯度消失问题。当连乘因子大于1时,可能会导致梯度的乘积变得异常大,造成梯度爆炸的问题。在这种情况下需要使用``梯度裁剪''来防止梯度$\pi$超过阈值。具体公式如下:
\begin{eqnarray} \begin{eqnarray}
\mathbf{w}' = \mathbf{w} \cdot \frac{threshold} {\textrm{max}(threshold,\| \mathbf{w} \|_2)} \mathbf{w}' = \mathbf{w} \cdot \frac{\gamma} {\textrm{max}(\gamma,\| \mathbf{w} \|_2)}
\label{eqC6.32} \label{eqC6.32}
\end{eqnarray} \end{eqnarray}
...@@ -1140,11 +1140,11 @@ L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{ ...@@ -1140,11 +1140,11 @@ L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{
\parinterval 贪婪搜索的优点在于速度快。在对翻译速度有较高要求的场景中,贪婪搜索是一种十分有效的加速系统的方法。而且贪婪搜索的原理非常简单,易于快速原型。不过,由于每一步只保留一个最好的局部结果,贪婪搜索往往会带来翻译品质上的损失。 \parinterval 贪婪搜索的优点在于速度快。在对翻译速度有较高要求的场景中,贪婪搜索是一种十分有效的加速系统的方法。而且贪婪搜索的原理非常简单,易于快速原型。不过,由于每一步只保留一个最好的局部结果,贪婪搜索往往会带来翻译品质上的损失。
%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%
\subsubsection{束搜索}\index{Chapter6.3.6.2} \subsubsection{束搜索}\index{Chapter6.3.6.2}
\parinterval 束搜索是一种启发式图搜索算法。相比于全搜索,它可以减少搜索所占用的空间和时间,在每一步扩展的时候,剪掉一些质量比较差的结点,保留下一些质量较高的结点。具体到机器翻译任务,对于每一个目标语位置,束搜索选择了概率最大的前$K$个单词进行扩展(其中$K$叫做束宽度,或简称为束宽)。如图\ref{fig:6-33}所示,当$K=3$时,若令\{$y_1, y_2,, y_n$\}表示生成的目标语序列,则束搜索的具体过程为:在预测第一个位置时,我们通过模型得到$y_1$的概率分布,选取概率最大的前3个单词作为候选结果(假设分别为``have'', ``has'', ``it'')。在预测第二个位置的单词时,模型针对已经得到的三个候选结果(``have'', ``has'', ``it'')计算第二个单词的概率分布。例如,我们可以在将``have''作为第二步的输入,计算$y_2$的概率分布。此时,译文序列的概率为 \parinterval 束搜索是一种启发式图搜索算法。相比于全搜索,它可以减少搜索所占用的空间和时间,在每一步扩展的时候,剪掉一些质量比较差的结点,保留下一些质量较高的结点。具体到机器翻译任务,对于每一个目标语位置,束搜索选择了概率最大的前$K$个单词进行扩展(其中$K$叫做束宽度,或简称为束宽)。如图\ref{fig:6-33}所示,当$K=3$时,若令\{$y_1, y_2,..., y_n$\}表示生成的目标语序列,则束搜索的具体过程为:在预测第一个位置时,我们通过模型得到$y_1$的概率分布,选取概率最大的前3个单词作为候选结果(假设分别为``have'', ``has'', ``it'')。在预测第二个位置的单词时,模型针对已经得到的三个候选结果(``have'', ``has'', ``it'')计算第二个单词的概率分布。例如,我们可以在将``have''作为第二步的输入,计算$y_2$的概率分布。此时,译文序列的概率为
%-------------------------------------------- %--------------------------------------------
\begin{eqnarray} \begin{eqnarray}
\textrm{P} (y_2,y_1 | \mathbf{x}) & = & \textrm{P} (y_2, \textrm{``have''} | \mathbf{x}) \nonumber \\ \textrm{P} (y_2,y_1 | \mathbf{x}) & = & \textrm{P} (y_2, \textrm{``have''} | \mathbf{x}) \nonumber \\
& = & \textrm{P}(y_2 | \textrm{``have''} , \mathbf{x}) \textrm{P} (\textrm{``have''} | \mathbf{x}) & = & \textrm{P}(y_2 | \textrm{``have''} , \mathbf{x}) \cdot \textrm{P} (\textrm{``have''} | \mathbf{x})
\label{eqC6.36} \label{eqC6.36}
\end{eqnarray} \end{eqnarray}
...@@ -1269,7 +1269,7 @@ L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{ ...@@ -1269,7 +1269,7 @@ L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{
\label{tab:performence form different models} \label{tab:performence form different models}
\begin{tabular}{l l l l} \begin{tabular}{l l l l}
\multicolumn{1}{l|}{\multirow{2}{*}{\#}} & \multicolumn{2}{c}{BLEU} & \multirow{2}{*}{\parbox{6em}{Training Cost(FLOPs)}} \\ \multicolumn{1}{l|}{\multirow{2}{*}{\#}} & \multicolumn{2}{c}{BLEU} & \multirow{2}{*}{\parbox{6em}{Training Cost (FLOPs)}} \\
\multicolumn{1}{l|}{} & EN-DE & EN-FR & \\ \hline \multicolumn{1}{l|}{} & EN-DE & EN-FR & \\ \hline
\multicolumn{1}{l|}{GNMT+RL} & 24.6 & 39.92 & 1.4$\times 10^{20}$ \\ \multicolumn{1}{l|}{GNMT+RL} & 24.6 & 39.92 & 1.4$\times 10^{20}$ \\
\multicolumn{1}{l|}{ConvS2S} & 25.16 & 40.46 & 1.5$\times 10^{20}$ \\ \multicolumn{1}{l|}{ConvS2S} & 25.16 & 40.46 & 1.5$\times 10^{20}$ \\
...@@ -1284,7 +1284,7 @@ L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{ ...@@ -1284,7 +1284,7 @@ L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{自注意力模型}\index{Chapter6.4.1} \subsection{自注意力模型}\index{Chapter6.4.1}
\label{sec:6.4.1} \label{sec:6.4.1}
\parinterval 首先,让我们再回顾一下循环神经网络处理文字序列的过程。如图\ref{fig:6-34}所示,对于单词序列$\{ w_1,,w_m \}$,处理第$m$个单词$w_m$时(绿色方框部分),需要输入前一时刻的信息(即处理单词$w_{m-1}$),而$w_{m-1}$又依赖于$w_{m-2}$,以此类推。也就是说,如果想建立$w_m$$w_1$之间的关系,需要$m-1$次信息传递。对于长序列来说,词汇之间信息传递距离过长会导致信息在传递过程中丢失,同时这种按顺序建模的方式也使得系统对序列的处理十分缓慢。 \parinterval 首先,让我们再回顾一下循环神经网络处理文字序列的过程。如图\ref{fig:6-34}所示,对于单词序列$\{ w_1,...,w_m \}$,处理第$m$个单词$w_m$时(绿色方框部分),需要输入前一时刻的信息(即处理单词$w_{m-1}$),而$w_{m-1}$又依赖于$w_{m-2}$,以此类推。也就是说,如果想建立$w_m$$w_1$之间的关系,需要$m-1$次信息传递。对于长序列来说,词汇之间信息传递距离过长会导致信息在传递过程中丢失,同时这种按顺序建模的方式也使得系统对序列的处理十分缓慢。
%---------------------------------------------- %----------------------------------------------
% 图3.10 % 图3.10
...@@ -1340,16 +1340,16 @@ L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{ ...@@ -1340,16 +1340,16 @@ L(\mathbf{Y},\hat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\hat{
\parinterval\ref{fig:6-38}展示了经典的Transformer结构。解码器由若干层组成(绿色虚线框就代表一层)。每一层(layer)的输入都是一个向量序列,输出是同样大小的向量序列,而Transformer层的作用是对输入进行进一步的抽象,得到新的表示结果。不过这里的层并不是指单一的神经网络结构,它里面由若干不同的模块组成,包括: \parinterval\ref{fig:6-38}展示了经典的Transformer结构。解码器由若干层组成(绿色虚线框就代表一层)。每一层(layer)的输入都是一个向量序列,输出是同样大小的向量序列,而Transformer层的作用是对输入进行进一步的抽象,得到新的表示结果。不过这里的层并不是指单一的神经网络结构,它里面由若干不同的模块组成,包括:
\begin{itemize} \begin{itemize}
\item {\small\sffamily\bfseries{自注意力子层}}self-attention sub-layer):使用自注意力机制对输入的序列进行新的表示 \item {\small\sffamily\bfseries{自注意力子层}}Self-attention Sub-layer):使用自注意力机制对输入的序列进行新的表示
\item {\small\sffamily\bfseries{前馈神经网络子层}}feed forward sub-layer):使用全连接的前馈神经网络对输入向量序列进行进一步变换 \item {\small\sffamily\bfseries{前馈神经网络子层}}Feed-forward Sub-layer):使用全连接的前馈神经网络对输入向量序列进行进一步变换
\item {\small\sffamily\bfseries{残差连接}}residual connection,标记为``Add''):对于自注意力子层和前馈神经网络子层,都有一个从输入直接到输出的额外连接,也就是一个跨子层的直连。残差连接可以使深层网络的信息传递更为有效。 \item {\small\sffamily\bfseries{残差连接}}Residual Connection,标记为``Add''):对于自注意力子层和前馈神经网络子层,都有一个从输入直接到输出的额外连接,也就是一个跨子层的直连。残差连接可以使深层网络的信息传递更为有效。
\item {\small\sffamily\bfseries{层正则化}}layer normalization):自注意力子层和前馈神经网络子层进行最终输出之前,会对输出的向量进行层正则化,规范结果向量取值范围,这样易于后面进一步的处理。 \item {\small\sffamily\bfseries{层正则化}}Layer Normalization):自注意力子层和前馈神经网络子层进行最终输出之前,会对输出的向量进行层正则化,规范结果向量取值范围,这样易于后面进一步的处理。
\end{itemize} \end{itemize}
\parinterval 以上操作就构成了Transformer的一层,各个模块执行的顺序可以简单描述为:Self-Attention -> Residual Connection -> Layer Normalization -> Feed Forward Network -> Residual Connection -> Layer Normalization。编码器可以包含多个这样的层,比如,我们可以构建一个六层编码器,每层都只执行上面的操作。最上层的结果作为整个编码的结果,会被传入解码器。 \parinterval 以上操作就构成了Transformer的一层,各个模块执行的顺序可以简单描述为:Self-Attention $\to$ Residual Connection $\to$ Layer Normalization $\to$ Feed Forward Network $\to$ Residual Connection $\to$ Layer Normalization。编码器可以包含多个这样的层,比如,我们可以构建一个六层编码器,每层都只执行上面的操作。最上层的结果作为整个编码的结果,会被传入解码器。
\parinterval 解码器的结构与编码器十分类似。它也是由若干层组成,每一层包含编码器中的所有结构,即:自注意力子层、前馈神经网络子层、残差连接和层正则化模块。此外,为了捕捉源语言的信息,解码器又引入了一个额外的{\small\sffamily\bfseries{编码-解码注意力子层}}(encoder-decoder attention sub-layer)。这个新的子层,可以帮助模型使用源语言句子的表示信息生成目标语不同位置的表示。编码-解码注意力子层仍然基于自注意力机制,因此它和自注意力子层的结构是相同的,只是$\mathrm{query}$$\mathrm{key}$$\mathrm{value}$的定义不同。比如,在解码端,自注意力子层的$\mathrm{query}$$\mathrm{key}$$\mathrm{value}$是相同的,它们都等于解码端每个位置的表示。而在编码-解码注意力子层中,$\mathrm{query}$是解码端每个位置的表示,而$\mathrm{key}$$\mathrm{value}$是相同的,等于编码端每个位置的表示。图\ref{fig:6-37}给出了这两种不同注意力子层输入的区别。 \parinterval 解码器的结构与编码器十分类似。它也是由若干层组成,每一层包含编码器中的所有结构,即:自注意力子层、前馈神经网络子层、残差连接和层正则化模块。此外,为了捕捉源语言的信息,解码器又引入了一个额外的{\small\sffamily\bfseries{编码-解码注意力子层}}(encoder-decoder attention sub-layer)。这个新的子层,可以帮助模型使用源语言句子的表示信息生成目标语不同位置的表示。编码-解码注意力子层仍然基于自注意力机制,因此它和自注意力子层的结构是相同的,只是$\mathrm{query}$$\mathrm{key}$$\mathrm{value}$的定义不同。比如,在解码端,自注意力子层的$\mathrm{query}$$\mathrm{key}$$\mathrm{value}$是相同的,它们都等于解码端每个位置的表示。而在编码-解码注意力子层中,$\mathrm{query}$是解码端每个位置的表示,而$\mathrm{key}$$\mathrm{value}$是相同的,等于编码端每个位置的表示。图\ref{fig:6-37}给出了这两种不同注意力子层输入的区别。
......
...@@ -31,13 +31,13 @@ ...@@ -31,13 +31,13 @@
\node [anchor=west,inner sep=2pt] (s4) at ([xshift=0.3em]s3.east) {\scriptsize{...}}; \node [anchor=west,inner sep=2pt] (s4) at ([xshift=0.3em]s3.east) {\scriptsize{...}};
} }
{ {
\node [rnnnode,anchor=south,fill=blue!20] (o1) at ([yshift=1em]s1.north) {\scriptsize{softmax}}; \node [rnnnode,anchor=south,fill=blue!20] (o1) at ([yshift=1em]s1.north) {\scriptsize{Softmax}};
} }
{ {
\node [rnnnode,anchor=south,fill=blue!20] (o2) at ([yshift=1em]s2.north) {\scriptsize{softmax ($\times 3$)}}; \node [rnnnode,anchor=south,fill=blue!20] (o2) at ([yshift=1em]s2.north) {\scriptsize{Softmax ($\times 3$)}};
} }
{ {
\node [rnnnode,anchor=south,fill=blue!20] (o3) at ([yshift=1em]s3.north) {\scriptsize{softmax ($\times 3$)}}; \node [rnnnode,anchor=south,fill=blue!20] (o3) at ([yshift=1em]s3.north) {\scriptsize{Softmax ($\times 3$)}};
\node [anchor=west,inner sep=2pt] (o4) at ([xshift=0.3em]o3.east) {\scriptsize{...}}; \node [anchor=west,inner sep=2pt] (o4) at ([xshift=0.3em]o3.east) {\scriptsize{...}};
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
\node [wnode,anchor=north] (wt1) at ([yshift=-0.8em]t1.south) {\scriptsize{$\langle$eos$\rangle$}}; \node [wnode,anchor=north] (wt1) at ([yshift=-0.8em]t1.south) {\scriptsize{$\langle$eos$\rangle$}};
{ {
\node [rnnnode,anchor=south,fill=blue!20] (o1) at ([yshift=1em]s1.north) {\scriptsize{softmax}}; \node [rnnnode,anchor=south,fill=blue!20] (o1) at ([yshift=1em]s1.north) {\scriptsize{Softmax}};
} }
{ {
......
\begin{tikzpicture} \begin{tikzpicture}
\begin{scope} \begin{scope}
\tikzstyle{rnnnode} = [minimum height=1.1em,minimum width=2.1em,inner sep=2pt,rounded corners=1pt,draw,fill=red!20]; \tikzstyle{rnnnode} = [minimum height=1.1em,minimum width=2.1em,inner sep=2pt,rounded corners=1pt,draw,fill=red!20];
...@@ -50,15 +45,15 @@ ...@@ -50,15 +45,15 @@
\node [anchor=west,inner sep=2pt] (s5) at ([xshift=0.3em]s4.east) {\tiny{...}}; \node [anchor=west,inner sep=2pt] (s5) at ([xshift=0.3em]s4.east) {\tiny{...}};
} }
{ {
\node [rnnnode,anchor=south,fill=blue!20] (o1) at ([yshift=1em]s1.north) {\tiny{softmax}}; \node [rnnnode,anchor=south,fill=blue!20] (o1) at ([yshift=1em]s1.north) {\tiny{Softmax}};
\node [anchor=east] (decoder) at ([xshift=-0.5em]o1.north west) {\scriptsize{\textbf{解码器}}}; \node [anchor=east] (decoder) at ([xshift=-0.5em]o1.north west) {\scriptsize{\textbf{解码器}}};
} }
{ {
\node [rnnnode,anchor=south,fill=blue!20] (o2) at ([yshift=1em]s2.north) {\tiny{softmax}}; \node [rnnnode,anchor=south,fill=blue!20] (o2) at ([yshift=1em]s2.north) {\tiny{Softmax}};
} }
{ {
\node [rnnnode,anchor=south,fill=blue!20] (o3) at ([yshift=1em]s3.north) {\tiny{softmax}}; \node [rnnnode,anchor=south,fill=blue!20] (o3) at ([yshift=1em]s3.north) {\tiny{Softmax}};
\node [rnnnode,anchor=south,fill=blue!20] (o4) at ([yshift=1em]s4.north) {\tiny{softmax}}; \node [rnnnode,anchor=south,fill=blue!20] (o4) at ([yshift=1em]s4.north) {\tiny{Softmax}};
\node [anchor=west,inner sep=2pt] (o5) at ([xshift=0.3em]o4.east) {\tiny{...}}; \node [anchor=west,inner sep=2pt] (o5) at ([xshift=0.3em]o4.east) {\tiny{...}};
} }
{ {
...@@ -145,7 +140,7 @@ ...@@ -145,7 +140,7 @@
\draw [->] ([yshift=-0.3em]s1.west) .. controls +(west:2) and +(-50:0.3) .. (c2.-40); \draw [->] ([yshift=-0.3em]s1.west) .. controls +(west:2) and +(-50:0.3) .. (c2.-40);
} }
{ {
\draw [->] (c2.0) -- ([xshift=1.358in]c2.0) -- ([yshift=0.3em,xshift=-1.2em]s2.west) -- ([yshift=0.3em,xshift=-0.1em]s2.west); \draw [->] (c2.0) -- ([xshift=1.2in]c2.0) -- ([yshift=0.3em,xshift=-1.2em]s2.west) -- ([yshift=0.3em,xshift=-0.1em]s2.west);
} }
{ {
......
...@@ -20,10 +20,10 @@ legend pos=outer north east, ...@@ -20,10 +20,10 @@ legend pos=outer north east,
legend style={yshift=-4.5em,xshift=-6em,legend cell align=left,legend plot pos=right}, legend style={yshift=-4.5em,xshift=-6em,legend cell align=left,legend plot pos=right},
ymin=6, ymin=6,
ymax=28] ymax=28]
\addplot [sharp plot,very thick,black!70,mark=diamond*] coordinates{(1-15,11.3) (16-25,16.4) (26-35,17) (>35,19.8)}; \addplot [sharp plot,very thick,ublue,mark=diamond*] coordinates{(1-15,11.3) (16-25,16.4) (26-35,17) (>35,19.8)};
\addplot [sharp plot,very thick,teal,mark=triangle*] coordinates{(1-15,14.4) (16-25,22.6) (26-35,23.8) (>35,25.9)}; \addplot [sharp plot,very thick,red,mark=triangle*] coordinates{(1-15,14.4) (16-25,22.6) (26-35,23.8) (>35,25.9)};
\addplot [sharp plot,very thick,darkgray!60,mark=square*] coordinates{(1-15,14.9) (16-25,23.7) (26-35,24.7) (>35,26.4)}; \addplot [sharp plot,very thick,ugreen,mark=square*] coordinates{(1-15,14.9) (16-25,23.7) (26-35,24.7) (>35,26.4)};
\addplot [sharp plot,very thick,ublue,mark=*] coordinates{(1-15,17.5) (16-25,24) (26-35,25) (>35,27)}; \addplot [sharp plot,very thick,orange,mark=*] coordinates{(1-15,17.5) (16-25,24) (26-35,25) (>35,27)};
\legend{\tiny{NMT},\tiny{SPB},\tiny{HPB},\tiny{PBSY}} \legend{\tiny{NMT},\tiny{SPB},\tiny{HPB},\tiny{PBSY}}
\end{axis} \end{axis}
\end{tikzpicture} \end{tikzpicture}
......
...@@ -160,21 +160,21 @@ ...@@ -160,21 +160,21 @@
\indexentry{Chapter5.2.1.5|hyperpage}{214} \indexentry{Chapter5.2.1.5|hyperpage}{214}
\indexentry{Chapter5.2.1.6|hyperpage}{215} \indexentry{Chapter5.2.1.6|hyperpage}{215}
\indexentry{Chapter5.2.2|hyperpage}{216} \indexentry{Chapter5.2.2|hyperpage}{216}
\indexentry{Chapter5.2.2.1|hyperpage}{217} \indexentry{Chapter5.2.2.1|hyperpage}{216}
\indexentry{Chapter5.2.2.2|hyperpage}{217} \indexentry{Chapter5.2.2.2|hyperpage}{218}
\indexentry{Chapter5.2.2.3|hyperpage}{218} \indexentry{Chapter5.2.2.3|hyperpage}{218}
\indexentry{Chapter5.2.2.4|hyperpage}{219} \indexentry{Chapter5.2.2.4|hyperpage}{219}
\indexentry{Chapter5.2.3|hyperpage}{220} \indexentry{Chapter5.2.3|hyperpage}{220}
\indexentry{Chapter5.2.3.1|hyperpage}{220} \indexentry{Chapter5.2.3.1|hyperpage}{220}
\indexentry{Chapter5.2.3.2|hyperpage}{222} \indexentry{Chapter5.2.3.2|hyperpage}{222}
\indexentry{Chapter5.2.4|hyperpage}{224} \indexentry{Chapter5.2.4|hyperpage}{222}
\indexentry{Chapter5.3|hyperpage}{227} \indexentry{Chapter5.3|hyperpage}{228}
\indexentry{Chapter5.3.1|hyperpage}{227} \indexentry{Chapter5.3.1|hyperpage}{228}
\indexentry{Chapter5.3.1.1|hyperpage}{227} \indexentry{Chapter5.3.1.1|hyperpage}{228}
\indexentry{Chapter5.3.1.2|hyperpage}{229} \indexentry{Chapter5.3.1.2|hyperpage}{230}
\indexentry{Chapter5.3.1.3|hyperpage}{230} \indexentry{Chapter5.3.1.3|hyperpage}{231}
\indexentry{Chapter5.3.2|hyperpage}{231} \indexentry{Chapter5.3.2|hyperpage}{232}
\indexentry{Chapter5.3.3|hyperpage}{232} \indexentry{Chapter5.3.3|hyperpage}{233}
\indexentry{Chapter5.3.4|hyperpage}{236} \indexentry{Chapter5.3.4|hyperpage}{236}
\indexentry{Chapter5.3.5|hyperpage}{237} \indexentry{Chapter5.3.5|hyperpage}{237}
\indexentry{Chapter5.4|hyperpage}{238} \indexentry{Chapter5.4|hyperpage}{238}
......
...@@ -345,23 +345,23 @@ ...@@ -345,23 +345,23 @@
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsection}{\numberline {5.2.1}线性代数基础}{210}{subsection.5.2.1} \contentsline {subsection}{\numberline {5.2.1}线性代数基础}{210}{subsection.5.2.1}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(一)标量、向量和矩阵}{211}{section*.222} \contentsline {subsubsection}{标量、向量和矩阵}{211}{section*.222}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(二)矩阵的转置}{212}{section*.223} \contentsline {subsubsection}{矩阵的转置}{212}{section*.223}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(三)矩阵加法和数乘}{212}{section*.224} \contentsline {subsubsection}{矩阵加法和数乘}{212}{section*.224}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(四)矩阵乘法和矩阵点乘}{213}{section*.225} \contentsline {subsubsection}{矩阵乘法和矩阵点乘}{213}{section*.225}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(五)线性映射}{214}{section*.226} \contentsline {subsubsection}{线性映射}{214}{section*.226}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(六)范数}{215}{section*.227} \contentsline {subsubsection}{范数}{215}{section*.227}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsection}{\numberline {5.2.2}人工神经元和感知机}{216}{subsection.5.2.2} \contentsline {subsection}{\numberline {5.2.2}人工神经元和感知机}{216}{subsection.5.2.2}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(一)感知机\ \raisebox {0.5mm}{------}\ 最简单的人工神经元模型}{217}{section*.230} \contentsline {subsubsection}{(一)感知机\ \raisebox {0.5mm}{------}\ 最简单的人工神经元模型}{216}{section*.230}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(二)神经元内部权重}{217}{section*.233} \contentsline {subsubsection}{(二)神经元内部权重}{218}{section*.233}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(三)神经元的输入\ \raisebox {0.5mm}{------}\ 离散 vs 连续}{218}{section*.235} \contentsline {subsubsection}{(三)神经元的输入\ \raisebox {0.5mm}{------}\ 离散 vs 连续}{218}{section*.235}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
...@@ -369,25 +369,25 @@ ...@@ -369,25 +369,25 @@
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsection}{\numberline {5.2.3}多层神经网络}{220}{subsection.5.2.3} \contentsline {subsection}{\numberline {5.2.3}多层神经网络}{220}{subsection.5.2.3}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(一)线性变换和激活函数}{220}{section*.239} \contentsline {subsubsection}{线性变换和激活函数}{220}{section*.239}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(二)单层神经网络$\rightarrow $多层神经网络}{222}{section*.246} \contentsline {subsubsection}{单层神经网络$\rightarrow $多层神经网络}{222}{section*.246}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsection}{\numberline {5.2.4}函数拟合能力}{224}{subsection.5.2.4} \contentsline {subsection}{\numberline {5.2.4}函数拟合能力}{222}{subsection.5.2.4}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {section}{\numberline {5.3}神经网络的张量实现}{227}{section.5.3} \contentsline {section}{\numberline {5.3}神经网络的张量实现}{228}{section.5.3}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsection}{\numberline {5.3.1} 张量及其计算}{227}{subsection.5.3.1} \contentsline {subsection}{\numberline {5.3.1} 张量及其计算}{228}{subsection.5.3.1}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(一)张量}{227}{section*.256} \contentsline {subsubsection}{张量}{228}{section*.256}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(二)张量的矩阵乘法}{229}{section*.259} \contentsline {subsubsection}{张量的矩阵乘法}{230}{section*.259}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsubsection}{(三)张量的单元操作}{230}{section*.261} \contentsline {subsubsection}{张量的单元操作}{231}{section*.261}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsection}{\numberline {5.3.2}张量的物理存储形式}{231}{subsection.5.3.2} \contentsline {subsection}{\numberline {5.3.2}张量的物理存储形式}{232}{subsection.5.3.2}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsection}{\numberline {5.3.3}使用开源框架实现张量计算}{232}{subsection.5.3.3} \contentsline {subsection}{\numberline {5.3.3}使用开源框架实现张量计算}{233}{subsection.5.3.3}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
\contentsline {subsection}{\numberline {5.3.4}神经网络中的前向传播}{236}{subsection.5.3.4} \contentsline {subsection}{\numberline {5.3.4}神经网络中的前向传播}{236}{subsection.5.3.4}
\defcounter {refsection}{0}\relax \defcounter {refsection}{0}\relax
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论