Commit efd5fe21 by 孟霞

chapter5 of first

parent 0feec455
...@@ -25,10 +25,10 @@ ...@@ -25,10 +25,10 @@
\node [rectangle,inner sep=0.2em,fill=red!20] [fit = (neuron01) (neuron05)] (layer01) {}; \node [rectangle,inner sep=0.2em,fill=red!20] [fit = (neuron01) (neuron05)] (layer01) {};
\end{pgfonlayer} \end{pgfonlayer}
\node [anchor=west] (layer00label) at ([xshift=1.25em]x5.east) {\footnotesize{\red{{输入层}}}}; \node [anchor=west] (layer00label) at ([xshift=1.3em]x5.east) {\footnotesize{第0层}};
\node [anchor=west] (layer00label2) at (layer00label.east) {\footnotesize{\red{(输入层)}}};
{ {
\node [anchor=west] (layer01label) at ([xshift=1em]layer01.east) {\footnotesize{}}; \node [anchor=west] (layer01label) at ([xshift=1em]layer01.east) {\footnotesize{1}};
} }
{ {
\node [anchor=west] (layer01label2) at (layer01label.east) {\footnotesize{\red{({隐层})}}}; \node [anchor=west] (layer01label2) at (layer01label.east) {\footnotesize{\red{({隐层})}}};
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
} }
\end{pgfonlayer} \end{pgfonlayer}
\node [anchor=west] (layer02label) at ([xshift=4.4em]layer02.east) {\footnotesize{}}; \node [anchor=west] (layer02label) at ([xshift=4.4em]layer02.east) {\footnotesize{2}};
{ {
\node [anchor=west] (layer02label2) at (layer02label.east) {\footnotesize{\red{({隐层})}}}; \node [anchor=west] (layer02label2) at (layer02label.east) {\footnotesize{\red{({隐层})}}};
} }
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
} }
\end{pgfonlayer} \end{pgfonlayer}
\node [anchor=west] (layer03label) at ([xshift=1em]layer03.east) {\footnotesize{}}; \node [anchor=west] (layer03label) at ([xshift=1em]layer03.east) {\footnotesize{3}};
{ {
\node [anchor=west] (layer03label2) at (layer03label.east) {\footnotesize{\red{({输出层})}}}; \node [anchor=west] (layer03label2) at (layer03label.east) {\footnotesize{\red{({输出层})}}};
} }
......
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
\tikzstyle{parametershard} = [draw,thick,minimum width=4em,align=left,rounded corners=2pt] \tikzstyle{parametershard} = [draw,thick,minimum width=4em,align=left,rounded corners=2pt]
{ {
\node[parametershard,anchor=west,fill=yellow!10] (param1) at (0,0) {$W_o$, $b_o$}; \node[parametershard,anchor=west,fill=yellow!10] (param1) at (0,0) {$W_o$};
\node (param2) at ([xshift=1em]param1.east) {}; \node (param2) at ([xshift=1em]param1.east) {};
\node[parametershard,anchor=west,fill=red!10] (param3) at ([xshift=1em]param2.east) {$W_h$, $b_h$}; \node[parametershard,anchor=west,fill=red!10] (param3) at ([xshift=1em]param2.east) {$W_h$};
\node[anchor=south,inner sep=1pt] (serverlabel) at ([yshift=0.2em]param2.north) {\footnotesize{\textbf{parameter server}: $\mathbf w_{new} = \mathbf w - \alpha\cdot \frac{\partial L}{\partial \mathbf w}$}}; \node[anchor=south,inner sep=1pt] (serverlabel) at ([yshift=0.2em]param2.north) {\footnotesize{\textbf{parameter server}: $\mathbf w_{new} = \mathbf w - \alpha\cdot \frac{\partial L}{\partial \mathbf w}$}};
} }
...@@ -88,9 +88,9 @@ ...@@ -88,9 +88,9 @@
\tikzstyle{parametershard} = [draw,thick,minimum width=4em,align=left,rounded corners=2pt] \tikzstyle{parametershard} = [draw,thick,minimum width=4em,align=left,rounded corners=2pt]
{ {
\node[parametershard,anchor=west,fill=yellow!10] (param1) at (0,0) {$W_o$, $b_o$}; \node[parametershard,anchor=west,fill=yellow!10] (param1) at (0,0) {$W_o$};
\node (param2) at ([xshift=1em]param1.east) {}; \node (param2) at ([xshift=1em]param1.east) {};
\node[parametershard,anchor=west,fill=red!10] (param3) at ([xshift=1em]param2.east) {$W_h$, $b_h$}; \node[parametershard,anchor=west,fill=red!10] (param3) at ([xshift=1em]param2.east) {$W_h$};
\node[anchor=south,inner sep=1pt] (serverlabel) at ([yshift=0.2em]param2.north) {\footnotesize{\textbf{parameter server}: $\mathbf w_{new} = \mathbf w - \alpha\cdot \frac{\partial L}{\partial \mathbf w}$}}; \node[anchor=south,inner sep=1pt] (serverlabel) at ([yshift=0.2em]param2.north) {\footnotesize{\textbf{parameter server}: $\mathbf w_{new} = \mathbf w - \alpha\cdot \frac{\partial L}{\partial \mathbf w}$}};
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
\begin{tikzpicture} \begin{tikzpicture}
%% a two-layer neural network %% a two-layer neural network
\begin{scope} \begin{scope}[xshift=2in]
\tikzstyle{neuronnode} = [minimum size=1.7em,circle,draw,ublue,very thick,inner sep=1pt, fill=white,align=center,drop shadow={shadow xshift=0.1em,shadow yshift=-0.1em}] \tikzstyle{neuronnode} = [minimum size=1.7em,circle,draw,ublue,very thick,inner sep=1pt, fill=white,align=center,drop shadow={shadow xshift=0.1em,shadow yshift=-0.1em}]
%% output illustration %% output illustration
\begin{scope}[xshift=2.8in,yshift=0.1in] \begin{scope}[xshift=2.8in,yshift=0.1in]
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
\draw [->,thick] (-2.2,0) -- (2.2,0); \draw [->,thick] (-2.2,0) -- (2.2,0);
\draw [->,thick] (0,0) -- (0,2); \draw [->,thick] (0,0) -- (0,2);
\draw [-] (-0.05,1) -- (0.05,1); \draw [-] (-0.05,1) -- (0.05,1);
\node [anchor=north,inner sep=1pt] (labela) at (0,-0.2) {\footnotesize{(a)}}; \node [anchor=north,inner sep=1pt] (labelb) at (0,-0.2) {\footnotesize{(b)}};
} }
{ {
\draw [->,thick] (-2.2,0) -- (2.2,0); \draw [->,thick] (-2.2,0) -- (2.2,0);
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
\end{scope} \end{scope}
%% a two-layer neural network %% a two-layer neural network
\begin{scope}[xshift=2in] \begin{scope}[xshift=0in]
\tikzstyle{neuronnode} = [minimum size=1.7em,circle,draw,ublue,very thick,inner sep=1pt, fill=white,align=center,drop shadow={shadow xshift=0.1em,shadow yshift=-0.1em}] \tikzstyle{neuronnode} = [minimum size=1.7em,circle,draw,ublue,very thick,inner sep=1pt, fill=white,align=center,drop shadow={shadow xshift=0.1em,shadow yshift=-0.1em}]
%% output illustration %% output illustration
\begin{scope}[xshift=2.8in,yshift=0.1in] \begin{scope}[xshift=2.8in,yshift=0.1in]
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
\draw [-] (-0.05,1) -- (0.05,1); \draw [-] (-0.05,1) -- (0.05,1);
\node [anchor=east,inner sep=1pt] (label1) at (0,1) {\tiny{1}}; \node [anchor=east,inner sep=1pt] (label1) at (0,1) {\tiny{1}};
\node [anchor=south east,inner sep=1pt] (label2) at (0,0) {\tiny{0}}; \node [anchor=south east,inner sep=1pt] (label2) at (0,0) {\tiny{0}};
\node [anchor=north,inner sep=1pt] (labelb) at (0,-0.2) {\footnotesize{(b)}}; \node [anchor=north,inner sep=1pt] (labela) at (0,-0.2) {\footnotesize{(a)}};
} }
{ {
\draw [->,thick] (-2.2,0) -- (2.2,0); \draw [->,thick] (-2.2,0) -- (2.2,0);
......
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
\node [anchor=north,minimum width=4.0em,minimum height=1.5em] (part5) at ([yshift=-1.4em]part4.south) {\footnotesize {$\mathbf a$}}; \node [anchor=north,minimum width=4.0em,minimum height=1.5em] (part5) at ([yshift=-1.4em]part4.south) {\footnotesize {$\mathbf a$}};
\draw [-,thick](part4.south)--([yshift=-0.1em]part5.north); \draw [-,thick](part4.south)--([yshift=-0.1em]part5.north);
%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%
\node [anchor=west,minimum width=2.0em,minimum height=1.5em,draw,fill=red!20] (part5-3) at ([xshift=0.0em,yshift=0.1em]part5.east) {\footnotesize {$\mathbf w^2$}}; \node [anchor=west,minimum width=2.0em,minimum height=1.5em,draw,fill=red!20] (part5-3) at ([xshift=0.0em,yshift=0.1em]part5.east) {\footnotesize {$\mathbf w^{[2]}$}};
\node [anchor=west,minimum width=2.0em,minimum height=1.5em,draw,fill=orange!40] (part5-4) at ([xshift=2.0em,yshift=0.0em]part5-3.east) {\footnotesize {$\mathbf b^2$}}; \node [anchor=west,minimum width=2.0em,minimum height=1.5em,draw,fill=orange!40] (part5-4) at ([xshift=2.0em,yshift=0.0em]part5-3.east) {\footnotesize {$ b^{[2]}$}};
\draw[-,thick](part4.south)--(part5-3.north); \draw[-,thick](part4.south)--(part5-3.north);
\draw[-,thick](part3.south)--(part5-4.north); \draw[-,thick](part3.south)--(part5-4.north);
\node [anchor=south,minimum width=1.5em,minimum height=1.5em] (part5-3-1) at ([xshift=1.1em,yshift=-0.45em]part5-3.north) {\scriptsize {$1\times 2$}}; \node [anchor=south,minimum width=1.5em,minimum height=1.5em] (part5-3-1) at ([xshift=1.1em,yshift=-0.45em]part5-3.north) {\scriptsize {$1\times 2$}};
...@@ -41,8 +41,8 @@ ...@@ -41,8 +41,8 @@
\node [anchor=north,minimum width=4.0em,minimum height=1.5em] (part9) at ([yshift=-1.4em]part8.south) {\footnotesize {$\mathbf x$}}; \node [anchor=north,minimum width=4.0em,minimum height=1.5em] (part9) at ([yshift=-1.4em]part8.south) {\footnotesize {$\mathbf x$}};
\draw [-,thick](part8.south)--([yshift=-0.1em]part9.north); \draw [-,thick](part8.south)--([yshift=-0.1em]part9.north);
%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%
\node [anchor=west,minimum width=2.0em,minimum height=1.5em,draw,fill=red!20] (part9-3) at ([xshift=0.0em,yshift=0.1em]part9.east) {\footnotesize {$\mathbf w^1$}}; \node [anchor=west,minimum width=2.0em,minimum height=1.5em,draw,fill=red!20] (part9-3) at ([xshift=0.0em,yshift=0.1em]part9.east) {\footnotesize {$\mathbf w^{[1]}$}};
\node [anchor=west,minimum width=2.0em,minimum height=1.5em,draw,fill=orange!40] (part9-4) at ([xshift=2.0em,yshift=0.0em]part9-3.east) {\footnotesize {$\mathbf b^1$}}; \node [anchor=west,minimum width=2.0em,minimum height=1.5em,draw,fill=orange!40] (part9-4) at ([xshift=2.0em,yshift=0.0em]part9-3.east) {\footnotesize {$\mathbf b^{[1]}$}};
\draw[-,thick](part8.south)--(part9-3.north); \draw[-,thick](part8.south)--(part9-3.north);
\draw[-,thick](part7.south)--(part9-4.north); \draw[-,thick](part7.south)--(part9-4.north);
\node [anchor=south,minimum width=1.5em,minimum height=1.5em] (part9-3-1) at ([xshift=1.1em,yshift=-0.45em]part9-3.north) {\scriptsize {$3\times 2$}}; \node [anchor=south,minimum width=1.5em,minimum height=1.5em] (part9-3-1) at ([xshift=1.1em,yshift=-0.45em]part9-3.north) {\scriptsize {$3\times 2$}};
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
\node [anchor=north,draw=ublue,minimum width=3.55em,fill=yellow!20] (part1-2) at ([yshift=-2.0em]part1-1.south) {\scriptsize {低空气温}}; \node [anchor=north,draw=ublue,minimum width=3.55em,fill=yellow!20] (part1-2) at ([yshift=-2.0em]part1-1.south) {\scriptsize {低空气温}};
\node [anchor=north,draw=ublue,minimum width=3.55em,fill=yellow!20] (part1-3) at ([yshift=-2.0em]part1-2.south) {\scriptsize {水平气压}}; \node [anchor=north,draw=ublue,minimum width=3.55em,fill=yellow!20] (part1-3) at ([yshift=-2.0em]part1-2.south) {\scriptsize {水平气压}};
\node [rectangle,rounded corners,draw=black!50,densely dashed,inner sep=0.4em] [fit = (part1-1) (part1-2) (part1-3) (inputlabel)] (inputshadow) {}; \node [rectangle,rounded corners,draw=black!50,densely dashed,inner sep=0.4em] [fit = (part1-1) (part1-2) (part1-3) (inputlabel)] (inputshadow) {};
\node [anchor=north,draw=ublue,minimum width=3.55em,fill=yellow!20] (part1-4) at ([yshift=-2.0em]part1-3.south) {\scriptsize {1}}; \node [anchor=north,draw=ublue,minimum width=3.55em,fill=yellow!20] (part1-4) at ([yshift=-2.0em]part1-3.south) {\scriptsize {1}};
\node [anchor=north,minimum width=2.5em] (part1-5) at ([yshift=-0.5em]part1-4.south) {\scriptsize {输入层}}; \node [anchor=north,minimum width=2.5em] (part1-5) at ([yshift=-0.5em]part1-4.south) {\scriptsize {输入层}};
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
\node [anchor=north] (hidlabel) at ([yshift=3.1em]part2-1.north) {\scriptsize{特征}}; \node [anchor=north] (hidlabel) at ([yshift=3.1em]part2-1.north) {\scriptsize{特征}};
\node [circle,anchor=west,draw=ublue,minimum width=2.5em,fill=blue!20] (part2-2) at ([xshift=2.0em,yshift=-1.7em]part1-2.east) {\scriptsize {风速}}; \node [circle,anchor=west,draw=ublue,minimum width=2.5em,fill=blue!20] (part2-2) at ([xshift=2.0em,yshift=-1.7em]part1-2.east) {\scriptsize {风速}};
\node [rectangle,rounded corners,draw=black!50,densely dashed,inner sep=0.4em] [fit = (part2-1) (part2-2) (hidlabel) ] (inputshadow) {}; \node [rectangle,rounded corners,draw=black!50,densely dashed,inner sep=0.4em] [fit = (part2-1) (part2-2) (hidlabel) ] (inputshadow) {};
\node [circle,anchor=west,draw=ublue,minimum width=2.5em,fill=blue!20,inner sep=2pt] (part2-3) at ([xshift=2.0em,yshift=-1.7em]part1-3.east) {\scriptsize {2}}; \node [circle,anchor=west,draw=ublue,minimum width=2.5em,fill=blue!20,inner sep=2pt] (part2-3) at ([xshift=2.0em,yshift=-1.7em]part1-3.east) {\scriptsize {2}};
\node [anchor=north,minimum width=3.0em] (part2-4) at ([xshift=0.0em,yshift=-1.6em]part2-3.south) {\scriptsize{隐藏层}}; \node [anchor=north,minimum width=3.0em] (part2-4) at ([xshift=0.0em,yshift=-1.6em]part2-3.south) {\scriptsize{隐藏层}};
\node [anchor=north] (labela) at ([xshift=0.0em,yshift=-4em]part2-3.south) {\footnotesize {(a)}}; \node [anchor=north] (labela) at ([xshift=0.0em,yshift=-4em]part2-3.south) {\footnotesize {(a)}};
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
y y
\node [rectangle,rounded corners,draw=black!50,densely dashed,inner sep=0.4em] [fit = (part1-1) (part1-2) (part1-3) (inputlabel)] (inputshadow) {}; \node [rectangle,rounded corners,draw=black!50,densely dashed,inner sep=0.4em] [fit = (part1-1) (part1-2) (part1-3) (inputlabel)] (inputshadow) {};
\node [anchor=north,draw=ublue,minimum width=3.55em,fill=yellow!20] (part1-4) at ([yshift=-2.0em]part1-3.south) {\footnotesize {$\mathbf b^1 $}}; \node [anchor=north,draw=ublue,minimum width=3.55em,fill=yellow!20] (part1-4) at ([yshift=-2.0em]part1-3.south) {\footnotesize {$\mathbf b^{[1]} $}};
\node [anchor=north,minimum width=2.5em] (part1-5) at ([yshift=-0.5em]part1-4.south) {\scriptsize {输入层}}; \node [anchor=north,minimum width=2.5em] (part1-5) at ([yshift=-0.5em]part1-4.south) {\scriptsize {输入层}};
...@@ -65,7 +65,7 @@ y ...@@ -65,7 +65,7 @@ y
\node [circle,anchor=west,draw=ublue,minimum width=2.5em,fill=blue!20] (part2-2) at ([xshift=2.0em,yshift=-1.7em]part1-2.east) {\large{$a_2$}}; \node [circle,anchor=west,draw=ublue,minimum width=2.5em,fill=blue!20] (part2-2) at ([xshift=2.0em,yshift=-1.7em]part1-2.east) {\large{$a_2$}};
\node [rectangle,rounded corners,draw=black!50,densely dashed,inner sep=0.4em] [fit = (part2-1) (part2-2) (hidlabel) ] (inputshadow) {}; \node [rectangle,rounded corners,draw=black!50,densely dashed,inner sep=0.4em] [fit = (part2-1) (part2-2) (hidlabel) ] (inputshadow) {};
\node [circle,anchor=west,draw=ublue,minimum width=2.5em,fill=blue!20,inner sep=2pt] (part2-3) at ([xshift=2.0em,yshift=-1.7em]part1-3.east) {\large {$b^2 $}}; \node [circle,anchor=west,draw=ublue,minimum width=2.5em,fill=blue!20,inner sep=2pt] (part2-3) at ([xshift=2.0em,yshift=-1.7em]part1-3.east) {\large {$b^{[2]} $}};
\node [anchor=north,minimum width=3.0em] (part2-4) at ([xshift=0.0em,yshift=-1.6em]part2-3.south) {\scriptsize{隐藏层}}; \node [anchor=north,minimum width=3.0em] (part2-4) at ([xshift=0.0em,yshift=-1.6em]part2-3.south) {\scriptsize{隐藏层}};
\node [anchor=north] (labelb) at ([xshift=0.0em,yshift=-4em]part2-3.south) {\footnotesize {(b)}}; \node [anchor=north] (labelb) at ([xshift=0.0em,yshift=-4em]part2-3.south) {\footnotesize {(b)}};
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
\chapter{人工神经网络和神经语言建模} \chapter{人工神经网络和神经语言建模}
\parinterval {\small\sffamily\bfseries{人工神经网络}}\index{人工神经网络}(Artificial Neural Networks)\index{Artificial Neural Networks}{\small\sffamily\bfseries{神经网络}}\index{神经网络}(Neural Networks)\index{Neural Networks}是描述客观世界的一种数学模型。这种模型的行为和生物学上的神经系统有一些相似之处,但是人们更多的是把它作为一种计算工具,而非一个生物学模型。近些年,随着机器学习领域的快速发展,人工神经网络被更多的使用在对图像和自然语言处理问题的建模上。特别是,研究人员发现深层神经网络可以被成功训练后,学术界也逐渐形成了一种新的机器学习范式\ \dash \ 深度学习。可以说,深度学习是近几年最受瞩目的研究领域,其应用也十分广泛。比如,图像识别的很多重要进展都来自深度学习模型的使用。包括机器翻译在内的很多自然语言处理任务中,深度学习也已经成为了一种标准模型。基于深度学习的表示学习方法也为自然语言处理开辟了新的思路。 \parinterval {\small\sffamily\bfseries{人工神经网络}}\index{人工神经网络}(Artificial Neural Networks)\index{Artificial Neural Networks}{\small\sffamily\bfseries{神经网络}}\index{神经网络}(Neural Networks)\index{Neural Networks}是描述客观世界的一种数学模型。这种模型和生物学上的神经系统在行为上有一些相似之处,但是人们更多的是把它作为一种计算工具,而非一个生物学模型。近些年,随着机器学习领域的快速发展,人工神经网络被更多的使用在对图像和自然语言处理问题的建模上。特别是,研究人员发现深层神经网络可以被成功训练后,学术界也逐渐形成了一种新的机器学习范式\ \dash \ 深度学习。可以说,深度学习是近几年最受瞩目的研究领域之一,其应用也十分广泛。比如,图像识别的很多重要进展都来自深度学习模型的使用。包括机器翻译在内的很多自然语言处理任务中,深度学习也已经成为了一种标准模型。基于深度学习的表示学习方法也为自然语言处理开辟了新的思路。
\parinterval 本章将对深度学习的概念和技术进行介绍,目的是为第六章和第七章神经机器翻译的内容进行铺垫。此外,本章也会对深度学习在语言建模方面的应用进行介绍。这样,读者可以更容易地理解如何使用深度学习方法描述自然语言处理问题。同时,进一步了解一些相关的学术前沿,如预训练模型。 \parinterval 本章将对深度学习的概念和技术进行介绍,目的是为第六章和第七章神经机器翻译的内容进行铺垫。此外,本章也会对深度学习在语言建模方面的应用进行介绍。这样,读者可以更容易地理解如何使用深度学习方法描述自然语言处理问题。同时,进一步了解一些相关的学术前沿,如预训练模型。
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
\parinterval {\small\sffamily\bfseries{深度学习}}\index{深度学习}(Deep Learning)\index{Deep Learning}是机器学习研究中一个非常重要的分支,其概念来源于对人工神经网络的研究:通过人工神经元之间的连接建立一种数学模型,使计算机可以像人一样进行分析、学习和推理。 \parinterval {\small\sffamily\bfseries{深度学习}}\index{深度学习}(Deep Learning)\index{Deep Learning}是机器学习研究中一个非常重要的分支,其概念来源于对人工神经网络的研究:通过人工神经元之间的连接建立一种数学模型,使计算机可以像人一样进行分析、学习和推理。
\parinterval 近几年来,随着深度学习技术的广泛传播与使用,``人工智能''这个名词在有些场合下甚至与``深度学习''划上了等号。这种理解非常片面,比较准确地说,``深度学习''是实现``人工智能''的一种技术手段。但从这种现象中也可以看出,深度学习的火爆情况可见一斑。深度学习的技术浪潮以惊人的速度席卷世界,也改变了很多领域的现状,在数据挖掘、自然语言处理、语音识别、图像识别等各个领域随处可见深度学习的身影。自然语言处理领域中,深度学习在很多任务中已经处于``统治''地位。特别是,基于深度学习的表示学习方法已经成为自然语言处理的新范式,在机器翻译任务中更是衍生出了``神经机器翻译''这样全新的模型。 \parinterval 近几年来,随着深度学习技术的广泛传播与使用,``人工智能''这个名词在有些场合下甚至与``深度学习''划上了等号。这种理解非常片面,比较准确地说,``深度学习''是实现``人工智能''的一种技术手段。但从这种现象中,深度学习的火爆情况可见一斑。深度学习的技术浪潮以惊人的速度席卷世界,也改变了很多领域的现状,在数据挖掘、自然语言处理、语音识别、图像识别等各个领域随处可见深度学习的身影。自然语言处理领域中,深度学习在很多任务中已经处于``统治''地位。特别是,基于深度学习的表示学习方法已经成为自然语言处理的新范式,在机器翻译任务中更是衍生出了``神经机器翻译''这样全新的模型。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
\subsubsection{早期的人工神经网络和第一次寒冬} \subsubsection{早期的人工神经网络和第一次寒冬}
\parinterval 最初,神经网络设计的初衷是用计算模型来模拟生物大脑中神经元的运行机理,这种想法哪怕现在看来也是十分超前的。例如,目前很多机构关注的概念\ \dash \ ``类脑计算''就是希望研究人脑的运行机制及相关的计算机实现方法。然而模拟大脑这件事并没有想象中的那么简单,众所周知,生物学中对人脑机制的研究是十分困难的,我们对人脑的运行机制尚不明确又何谈模拟呢?因而,神经网络技术一直在摸索着前行,发展到现在,其计算过程与人脑的运行机制已经大相径庭。 \parinterval 最初,神经网络设计的初衷是用计算模型来模拟生物大脑中神经元的运行机理,这种想法哪怕现在看来也是十分超前的。例如,目前很多机构关注的概念\ \dash \ ``类脑计算''就是希望研究人脑的运行机制及相关的计算机实现方法。然而模拟大脑这件事并没有想象中的那么简单,众所周知,生物学中对人脑机制的研究是十分困难的,我们对人脑的运行机制尚不明确又何谈模拟呢?因而,神经网络技术一直在摸索着前行,发展到现在,其计算过程与人脑的运行机制已经大相径庭。
\parinterval 人工神经网络的第一个发展阶段是在二十世纪40年代到70年代,这个时期的人工神经网络还停留在利用线性模型模拟生物神经元的阶段,比如使用线性加权函数来描述输入$ \mathbf x $和输出$ y $ 之间的联系:$y=x_1 \cdot w_1 + \dots + x_n \cdot w_n $。举一个简单例子,输入$ \mathbf x $是某个地区的坐标和时间,输出$ y $是该地区的温度,尽管真实的问题可能要复杂的多,但是线性模型确实有能力去拟合简单的函数关系。 \parinterval 人工神经网络的第一个发展阶段是在二十世纪40年代到70年代,这个时期的人工神经网络还停留在利用线性模型模拟生物神经元的阶段,比如使用线性加权函数来描述输入$ \mathbf x $和输出$ y $ 之间的联系:$y=x_1 \cdot w_1 + \dots + x_n \cdot w_n $。举一个简单例子,输入$ \mathbf x $是某个地区的坐标和时间,输出$ y $是该地区的温度,尽管真实的问题可能要复杂的多,但是线性模型确实有能力去拟合简单的函数关系。
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
\subsubsection{神经网络的第二次高潮和第二次寒冬} \subsubsection{神经网络的第二次高潮和第二次寒冬}
\parinterval 虽然第一代神经网络受到了打击,但是20世纪80年代开始,第二代人工神经网络开始萌发新的生机。在这个发展阶段,生物属性已经不再是神经网络的唯一灵感来源,在{\small\bfnew{连接主义}}\index{连接主义}(Connectionism)\index{Connectionism}{\small\bfnew{分布式表示}}\index{分布式表示}(Distributed representation)\index{Distributed representation}两种思潮的影响下,神经网络方法再次走入了人们的视线。 \parinterval 虽然第一代神经网络受到了打击,但是20世纪80年代,第二代人工神经网络开始萌发新的生机。在这个发展阶段,生物属性已经不再是神经网络的唯一灵感来源,在{\small\bfnew{连接主义}}\index{连接主义}(Connectionism)\index{Connectionism}{\small\bfnew{分布式表示}}\index{分布式表示}(Distributed representation)\index{Distributed representation}两种思潮的影响下,神经网络方法再次走入了人们的视线。
\vspace{0.3em} \vspace{0.3em}
\parinterval (1)符号主义与连接主义 \parinterval (1)符号主义与连接主义
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
\parinterval (2)分布式表示 \parinterval (2)分布式表示
\vspace{0.3em} \vspace{0.3em}
\parinterval 分布式表示的主要思想是``一个复杂系统的任何部分的输入都应该是多个特征共同表示的结果'',这种思想在自然语言处理领域的影响尤其深刻,它改变了刻画世界的角度,将世界万物从离散空间映射到多维连续空间。例如,在现实世界中,``张三''这个代号就代表着一个人。如果想要知道这个人亲属都有谁,因为有``A和B如果姓氏相同,在一个家谱中,那么A和B是本家''这个先验知识在,在知道代号``张三''的情况下,可以得知``张三''的亲属是谁。但是如果不依靠这个先验知识,就无法得知``张三''的亲属是谁。但在分布式表示中,可以用一个实数向量,如$ (0.1,0.3,0.4) $来表示``张三''这个人,这个人的所有特征信息都包含在这个实数向量中,通过在向量空间中的一些操作(如计算距离等),哪怕没有任何先验知识的存在,也完全可以找到这个人的所有亲属。在自然语言处理中,一个单词也用一个实数向量(词向量或词嵌入)表示,通过这种方式将语义空间重新刻画,将这个离散空间转化成了一个连续空间,这时单词就不再是一个简单的词条,而是由成百上千个特征共同描述出来,而每个特征都描述这个词的某个`` 方面''。 \parinterval 分布式表示的主要思想是``一个复杂系统的任何部分的输入都应该是多个特征共同表示的结果'',这种思想在自然语言处理领域的影响尤其深刻,它改变了刻画世界的角度,将世界万物从离散空间映射到多维连续空间。例如,在现实世界中,``张三''这个代号就代表着一个人。如果想要知道这个人亲属都有谁,因为有``A和B如果姓氏相同,在一个家谱中,那么A和B是本家''这个先验知识在,在知道代号``张三''的情况下,可以得知``张三''的亲属是谁。但是如果不依靠这个先验知识,就无法得知``张三''的亲属是谁。但在分布式表示中,可以用一个实数向量,如$ (0.1,0.3,0.4) $来表示``张三''这个人,这个人的所有特征信息都包含在这个实数向量中,通过在向量空间中的一些操作(如计算距离等),哪怕没有任何先验知识的存在,也完全可以找到这个人的所有亲属。在自然语言处理中,一个单词也用一个实数向量(词向量或词嵌入)表示,通过这种方式将语义空间重新刻画,将这个离散空间转化成了一个连续空间,这时单词就不再是一个简单的词条,而是由成百上千个特征共同描述出来的,其中每个特征分别代表这个词的某个`` 方面''。
\parinterval 随着第二代人工神经网络的``脱胎换骨'',学者们又对神经网络方法燃起了希望之火,这也导致有些时候过分夸大了神经网络的能力。20世纪90年代后期,由于在语音识别、自然语言处理等应用中,人们对神经网络方法期望过高,但是结果并没有达到预期,这也让很多人丧失了对神经网络方法的信任。相反,核方法、图模型等机器学习方法取得了很好的效果,这导致神经网络研究又一次进入低谷。 \parinterval 随着第二代人工神经网络的``脱胎换骨'',学者们又对神经网络方法燃起了希望之火,这也导致有些时候过分夸大了神经网络的能力。20世纪90年代后期,由于在语音识别、自然语言处理等应用中,人们对神经网络方法期望过高,但是结果并没有达到预期,这也让很多人丧失了对神经网络方法的信任。相反,核方法、图模型等机器学习方法取得了很好的效果,这导致神经网络研究又一次进入低谷。
...@@ -82,13 +82,13 @@ ...@@ -82,13 +82,13 @@
\subsubsection{深度学习和神经网络方法的崛起} \subsubsection{深度学习和神经网络方法的崛起}
\parinterval 21世纪初,随着深度学习浪潮席卷世界,人工神经网络又一次出现在人们的视野中。深度学习的流行源于2006年Hinton等人成功训练了一个深度信念网络(Deep Belief Network),在深度神经网络方法完全不受重视的情况下,大家突然发现深度神经网络完全是一个魔鬼般的存在,可以解决很多当时其他方法无法解决的问题。神经网络方法终于在一次又一次的否定后,迎来了它的春天。随之针对神经网络和深度学习的一系列研究前赴后继地展开了,延续至今。 \parinterval 21世纪初,随着深度学习浪潮席卷世界,人工神经网络又一次出现在人们的视野中。深度学习的流行源于2006年Hinton等人成功训练了一个深度信念网络(Deep Belief Network),在深度神经网络方法完全不受重视的情况下,大家突然发现深度神经网络完全是一个魔鬼般的存在,可以解决很多当时其他方法无法解决的问题。神经网络方法终于在一次又一次的否定后,迎来了它的春天。随之针对神经网络和深度学习的一系列研究前赴后继地展开了,延续至今。
\parinterval 回过头来看,现代深度学习的成功主要有三方面的原因: \parinterval 回过头来看,现代深度学习的成功主要有三方面的原因:
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\item 第一,模型和算法的不断完善和改进。这个方面的进步是现代深度学习能够获得成功的最主要原因; \item 第一,模型和算法的不断完善和改进。这是现代深度学习能够获得成功的最主要原因;
\vspace{0.5em} \vspace{0.5em}
\item 第二,并行计算能力的提升使大规模的实践成为了可能。早期的计算机设备根本无法支撑深度神经网络训练所需要的计算量,导致实践变得十分困难。而设备的进步、计算能力的提升则彻底改变了这种窘境; \item 第二,并行计算能力的提升使大规模的实践成为了可能。早期的计算机设备根本无法支撑深度神经网络训练所需要的计算量,导致实践变得十分困难。而设备的进步、计算能力的提升则彻底改变了这种窘境;
\vspace{0.5em} \vspace{0.5em}
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
\vspace{0.5em} \vspace{0.5em}
\end{itemize} \end{itemize}
\parinterval 另外,从应用的角度,数据量的快速提升和模型容量的增加也为深度学习的成功提供了条件,数据量的增加使得深度学习有了用武之地,例如,2000年以来,双文本数据量无论在学术研究还是在工业实践中的使用数量都在逐年上升(如图\ref{fig:5-1}所示)。现在的统计模型参数量往往很大,因此需要大规模数据才能保证模型学习的充分性,而大数据时代的到来为训练这样的模型提供了数据基础。 \parinterval 另外,从应用的角度,数据量的快速提升和模型容量的增加也为深度学习的成功提供了条件,数据量的增加使得深度学习有了用武之地,例如,2000年以来,双文本数据量无论在学术研究还是在工业实践中的使用数量都在逐年上升(如图\ref{fig:5-1}所示)。现在的深度学习模型参数量往往很大,因此需要大规模数据才能保证模型学习的充分性,而大数据时代的到来为训练这样的模型提供了数据基础。
%---------------------------------------------------------------------- %----------------------------------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -194,7 +194,7 @@ ...@@ -194,7 +194,7 @@
\sectionnewpage \sectionnewpage
\section{神经网络基础} \section{神经网络基础}
\parinterval 神经网络是一种由大量的节点(或称神经元)之间相互连接构成的计算模型。那么什么是神经元?神经元之间又是如何连接的?神经网络的数学描述又是什么样的?这一节将围绕这些问题对神经网络的基础知识进行系统的介绍。 \parinterval 神经网络是一种由大量的节点(或称神经元)之间相互连接构成的计算模型。那么什么是神经元?神经元之间又是如何连接的?神经网络的数学描述又是什么样的?这一节将围绕这些问题对神经网络的基础知识进行系统的介绍。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
...@@ -330,7 +330,7 @@ ...@@ -330,7 +330,7 @@
\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 $列的元素可以表示为:
\begin{eqnarray} \begin{eqnarray}
{(\mathbf a\mathbf b)}_{ij} &=& \prod_{k=1}^p a_{ik}b_{kj} {(\mathbf a\mathbf b)}_{ij} &=& \sum_{k=1}^p a_{ik}b_{kj}
\label{eq:5-6} \label{eq:5-6}
\end{eqnarray} \end{eqnarray}
...@@ -398,7 +398,7 @@ f(c\mathbf v)&=&cf(\mathbf v) ...@@ -398,7 +398,7 @@ f(c\mathbf v)&=&cf(\mathbf v)
\label{eq:5-10} \label{eq:5-10}
\end{eqnarray} \end{eqnarray}
\parinterval 利用矩阵$ \mathbf a\in R^{m\times n} $,可以实现两个有限维欧氏空间的映射函数$f:R^n\rightarrow R^m$。例如$ n $维列向量$ \mathbf x $$ m\times n $的矩阵$ \mathbf a $,向量$ \mathbf x $左乘矩阵$ \mathbf a $,可将向量$ \mathbf x $映射为$ m $列向量,对于: \parinterval 利用矩阵$ \mathbf a\in R^{m\times n} $,可以实现两个有限维欧氏空间的映射函数$f:R^n\rightarrow R^m$。例如$ n $维列向量$ \mathbf x ^{\rm T}$$ m\times n $的矩阵$ \mathbf a $,向量$ \mathbf x ^{\rm T}$左乘矩阵$ \mathbf a $,可将向量$ \mathbf x ^{\rm T}$映射为$ m $列向量,对于:
\begin{eqnarray} \begin{eqnarray}
\mathbf x^{\textrm{T}} & = & {\begin{pmatrix} x_1, & x_2, & \dots &, x_n \end{pmatrix}}^{\rm T} \mathbf x^{\textrm{T}} & = & {\begin{pmatrix} x_1, & x_2, & \dots &, x_n \end{pmatrix}}^{\rm T}
\label{eq:5-11} \label{eq:5-11}
...@@ -477,7 +477,7 @@ l_p(\mathbf x) & = & {\Vert{\mathbf x}\Vert}_p \nonumber \\ ...@@ -477,7 +477,7 @@ l_p(\mathbf x) & = & {\Vert{\mathbf x}\Vert}_p \nonumber \\
\parinterval 在深度学习中,有时候希望衡量矩阵的大小,这时可以考虑使用 {\small\bfnew{Frobenius 范数}}\index{Frobenius 范数}(Frobenius Norm)\index{Frobenius Norm}。计算方式为: \parinterval 在深度学习中,有时候希望衡量矩阵的大小,这时可以考虑使用 {\small\bfnew{Frobenius 范数}}\index{Frobenius 范数}(Frobenius Norm)\index{Frobenius Norm}。计算方式为:
\begin{eqnarray} \begin{eqnarray}
{\Vert{\mathbf A}\Vert}_F&=&\sqrt{\sum_{i,j} A_{i,j}^2} {\Vert{\mathbf a}\Vert}_F&=&\sqrt{\sum_{i,j} a_{i,j}^2}
\label{eq:5-18} \label{eq:5-18}
\end{eqnarray} \end{eqnarray}
...@@ -554,7 +554,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -554,7 +554,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-perceptron-to-predict-1} \input{./Chapter5/Figures/fig-perceptron-to-predict-1}
\caption{预测是否去剧场的感知机:权重相同} \caption{预测是否去剧场的感知机(权重相同)}
\label{fig:5-6} \label{fig:5-6}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
...@@ -565,7 +565,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -565,7 +565,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\subsubsection{神经元内部权重} \subsubsection{神经元内部权重}
\parinterval 在上面的例子中,连接权重代表着每个输入因素对最终输出结果的重要程度,为了得到令人满意的决策,需要不断调整权重。如果你是守财奴,则会对票价看得更重一些,这样你会用不均匀的权重计算每个因素的影响,比如:$ w_0=0.5 $$ w_1=2 $$ w_2=0.5 $,此时感知机模型如图\ref{fig:5-7}所示。在这种情况下,女友很希望和你一起去看音乐会,但是剧场很远而且票价500元,会导致你不去看音乐会,因为 \parinterval 在上面的例子中,连接权重代表着每个输入因素对最终输出结果的重要程度,为了得到令人满意的决策,需要不断调整权重。如果你是守财奴,则会对票价看得更重一些,这样你会用不均匀的权重计算每个因素的影响,比如:$ w_0=0.5 $$ w_1=2 $$ w_2=0.5 $,此时感知机模型如图\ref{fig:5-7}所示。在这种情况下,女友很希望和你一起去看音乐会,但是剧场很远而且票价500元,会导致你不去看音乐会,因为
\begin{eqnarray} \begin{eqnarray}
\sum_{i}{x_i\cdot w_i} & = & 0\cdot 0.5+0\cdot 2+1\cdot 0.5 \nonumber \\ \sum_{i}{x_i\cdot w_i} & = & 0\cdot 0.5+0\cdot 2+1\cdot 0.5 \nonumber \\
& = & 0.5 \nonumber \\ & = & 0.5 \nonumber \\
...@@ -577,12 +577,12 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -577,12 +577,12 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-perceptron-to-predict-2} \input{./Chapter5/Figures/fig-perceptron-to-predict-2}
\caption{预测是否去剧场的感知机:改变权重} \caption{预测是否去剧场的感知机(改变权重)}
\label{fig:5-7} \label{fig:5-7}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 当然,结果是女友对这个结果非常不满意,让你跪键盘上反思一下自己。 \parinterval 当然,结果是女友对这个决定非常不满意,让你跪键盘上反思一下自己。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION % NEW SUBSUB-SECTION
...@@ -631,7 +631,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -631,7 +631,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-perceptron-to-predict-3} \input{./Chapter5/Figures/fig-perceptron-to-predict-3}
\caption{预测是否去剧场的决策模型:只考虑女友喜好} \caption{预测是否去剧场的决策模型(只考虑女友喜好)}
\label{fig:5-9} \label{fig:5-9}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
...@@ -644,9 +644,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 \nonumbe ...@@ -644,9 +644,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 \nonumbe
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\item 对问题建模,即定义输入$ \{x_i\} $的形式 \item 对问题建模,即定义输入$ \{x_i\} $的形式
\vspace{0.5em} \vspace{0.5em}
\item 设计有效的决策模型,即定义$ y $ \item 设计有效的决策模型,即定义$ y $
\vspace{0.5em} \vspace{0.5em}
\item 决定模型所涉及的参数(如权重$ \{w_i\} $)的最优值。 \item 决定模型所涉及的参数(如权重$ \{w_i\} $)的最优值。
\vspace{0.5em} \vspace{0.5em}
...@@ -696,7 +696,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -696,7 +696,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 在神经网络中,对于输入向量$ \mathbf x\in R^m $,一层神经网络首先将其经过线性变换映射到$ R^n $,再经过激活函数变成$ \mathbf y\in R^n $。还是上面天气预测的例子,每个神经元获得相同的输入,权重矩阵$ \mathbf w $是一个$ 2\times 3 $矩阵,矩阵中每个元素$ w_{ij} $代表第$ j $个神经元中$ x_{i} $对应的权重值,假设编号为0的神经元负责预测温度,则$ w_{0j} $含义为预测温度时,输入$ x_{i} $对其影响程度。此外所有神经元的偏置$ b_{0} $$ b_{1} $$ b_{2} $组成了最终的偏置向量$ \mathbf b $。在该例中则有,权重矩阵$ \mathbf w=\begin{pmatrix} w_{00} & w_{01} & w_{02}\\ w_{10} & w_{11} & w_{12}\end{pmatrix} $,偏置向量$ \mathbf b=(b_0,b_1,b_2) $ \parinterval 在神经网络中,对于输入向量$ \mathbf x\in R^m $,一层神经网络首先将其经过线性变换映射到$ R^n $,再经过激活函数变成$ \mathbf y\in R^n $。还是上面天气预测的例子,每个神经元获得相同的输入,权重矩阵$ \mathbf w $是一个$ 2\times 3 $矩阵,矩阵中每个元素$ w_{ij} $代表第$ j $个神经元中$ x_{i} $对应的权重值,假设编号为0的神经元负责预测温度,则$ w_{i0} $含义为预测温度时,输入$ x_{i} $对其影响程度。此外所有神经元的偏置$ b_{0} $$ b_{1} $$ b_{2} $组成了最终的偏置向量$ \mathbf b $。在该例中则有,权重矩阵$ \mathbf w=\begin{pmatrix} w_{00} & w_{01} & w_{02}\\ w_{10} & w_{11} & w_{12}\end{pmatrix} $,偏置向量$ \mathbf b=(b_0,b_1,b_2) $
\parinterval 那么,线性变换的本质是什么? \parinterval 那么,线性变换的本质是什么?
...@@ -732,7 +732,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -732,7 +732,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 也就是说,线性变换提供了对输入数据进行空间中旋转、平移的能力。当然,线性变换也适用于更加复杂的情况,这也为神经网络提供了拟合不同函数的能力。比如,可以利用线性变换将三维图形投影到二维平面上,或者将二维平面上的图形映射到三维平面。如图\ref{fig:5-14},通过一个简单的线性变换,可以将三维图形投影到二维平面上。 \parinterval 也就是说,线性变换提供了对输入数据进行空间中旋转、平移的能力。当然,线性变换也适用于更加复杂的情况,这也为神经网络提供了拟合不同函数的能力。比如,可以利用线性变换将三维图形投影到二维平面上,或者将二维平面上的图形映射到三维空间。如图\ref{fig:5-14},通过一个简单的线性变换,可以将三维图形投影到二维平面上。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -815,7 +815,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -815,7 +815,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-four-layers-of-neural-network} \input{./Chapter5/Figures/fig-four-layers-of-neural-network}
\caption{具有三层神经元的四层神经网络} \caption{具有四层神经元的三层神经网络}
\label{fig:5-17} \label{fig:5-17}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
...@@ -858,7 +858,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -858,7 +858,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-bias} \input{./Chapter5/Figures/fig-bias}
\caption{通过改变偏$ b_1 $改变目标函数位置} \caption{通过改变偏$ b_1 $改变目标函数位置}
\label{fig:5-20} \label{fig:5-20}
\end {figure} \end {figure}
%------------------------------------------- %-------------------------------------------
...@@ -869,12 +869,12 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -869,12 +869,12 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter5/Figures/fig-w1} \input{./Chapter5/Figures/fig-w1}
\caption{通过改变偏移量$ w'_1 $将目标函数``拉高''或``压扁''} \caption{通过改变权重$ w'_1 $将目标函数``拉高''或``压扁''}
\label{fig:5-21} \label{fig:5-21}
\end {figure} \end {figure}
%------------------------------------------- %-------------------------------------------
\parinterval 设置$ w'_1=0.7 $$ w_1=100 $$ b_1=-4 $,其他参数设置为0。可以得到如图\ref{fig:5-22}\\(a)所示的目标函数,此时目标函数是一个阶梯函数。若是将其他参数设置为$ w'_2=0.7 $$ w_2=100 $$ b_2=16 $,由图\ref{fig:5-22}(b)可以看出,原来目标函数的``阶梯''由一级变成了两级,由此可以推测,由于将第二组参数进行设置,使目标函数分段数增多;若将第二组参数中的$ w'_2 $由原来的$ 0.7 $设置为$ -0.7 $,可得到如图\ref{fig:5-22}(c)所示的目标函数,与图\ref{fig:5-22}(b)相比,原目标函数的``第二级阶梯''向下翻转,由此可见$ w' $的符号决定了目标函数的翻转方向。 \parinterval 设置$ w'_1=0.7 $$ w_1=100 $$ b_1=-4 $,其他参数设置为0。可以得到如图\ref{fig:5-22}\\(a)所示的目标函数,此时目标函数是一个阶梯函数。若是将其他参数设置为$ w'_2=0.7 $$ w_2=100 $$ b_2=16 $,由图\ref{fig:5-22}(b)可以看出,原来目标函数的``阶梯''由一级变成了两级,由此可以推测,将第二组参数进行设置,可以使目标函数分段数增多;若将第二组参数中的$ w'_2 $由原来的$ 0.7 $设置为$ -0.7 $,可得到如图\ref{fig:5-22}(c)所示的目标函数,与图\ref{fig:5-22}(b)相比,原目标函数的``第二级阶梯''向下翻转,由此可见$ w' $的符号决定了目标函数的翻转方向。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -945,7 +945,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -945,7 +945,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\subsubsection{张量} \subsubsection{张量}
\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{张量}}\index{张量}(Tensor)\index{Tensor},比如下式中的几种情况都可以看作是深度学习中定义数据的张量: \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{张量}}\index{张量}(Tensor)\index{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
...@@ -977,9 +977,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 \nonumbe ...@@ -977,9 +977,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 \nonumbe
\label{eq:5-66} \label{eq:5-66}
\end{eqnarray} \end{eqnarray}
\noindent 其中,$ c $为任意实数。这个性质非常重要,根据这个性质可以推导出张量的其他定义。 \noindent 其中,$ u $$ v_i $的同型向量,$ c $为任意实数。这个性质非常重要,根据这个性质可以推导出张量的其他定义。
\parinterval 从我们的物理世界看,如果一个物理量在物体的某个位置上只是一个单值,那么它是一个标量,例如密度;如果一个物理量在同一个位置、从多个方向上看,有不同的值,那么这个物理量就是一个张量比如物理学中常用的应力的描述就是一个典型的张量。举一个简单的例子:$ \mathbf T(\mathbf v,\mathbf u) $是一个三维空间$(\textrm{x},\textrm{y},\textrm{z})$上的2阶张量,其中$ \mathbf v $$ \mathbf u $ 是两个向量,如图\ref{fig:5-26}所示,向量$ \mathbf v $在某个两两垂直的三维坐标系中可以表示为$ {(\begin{array}{ccc} a & b & c\end{array})}^{\rm T} $,同理向量$ \mathbf u $在某个两两垂直的三维坐标系中可以表示为$ {(\begin{array}{ccc} a' & b' & c' \end{array})}^{\rm T} $。但在三维空间$(\textrm{x},\textrm{y},\textrm{z})$中,向量$ \mathbf v $和向量$ \mathbf u $分别被表示为$ {(\begin{array}{ccc} v_x & v_y & v_z\end{array})}^{\rm T} $$ {(\begin{array}{ccc} u_x & u_y & u_z\end{array})}^{\rm T} $ \parinterval 从我们的物理世界看,如果一个物理量在物体的某个位置上只是一个单值,那么它是一个标量,例如密度;如果一个物理量在同一个位置、从多个方向上看,有不同的值,那么这个物理量就是一个张量比如物理学中常用的应力的描述就是一个典型的张量。举一个简单的例子:$ \mathbf T(\mathbf v,\mathbf u) $是一个三维空间$(\textrm{x},\textrm{y},\textrm{z})$上的2阶张量,其中$ \mathbf v $$ \mathbf u $ 是两个向量,如图\ref{fig:5-26}所示,向量$ \mathbf v $在某个两两垂直的三维坐标系中可以表示为$ {(\begin{array}{ccc} a & b & c\end{array})}^{\rm T} $,同理向量$ \mathbf u $在某个两两垂直的三维坐标系中可以表示为$ {(\begin{array}{ccc} a' & b' & c' \end{array})}^{\rm T} $。但在三维空间$(\textrm{x},\textrm{y},\textrm{z})$中,向量$ \mathbf v $和向量$ \mathbf u $分别被表示为$ {(\begin{array}{ccc} v_x & v_y & v_z\end{array})}^{\rm T} $$ {(\begin{array}{ccc} u_x & u_y & u_z\end{array})}^{\rm T} $
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1001,7 +1001,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -1001,7 +1001,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\parinterval 其中,$ \begin{pmatrix} v_x\\v_y\\v_z\end{pmatrix} $是向量$ \mathbf v $在基向量$(\textrm{x},\textrm{y},\textrm{z})$上的投影,$ \begin{pmatrix} u_x\\u_y\\u_z\end{pmatrix} $是向量$ \mathbf u $在基向量$(\textrm{x},\textrm{y},\textrm{z})$上的投影,$ \begin{pmatrix}T_{xx} & T_{xy} & T_{xz}\\T_{yx} & T_{yy} & T_{yz}\\T_{zx} & T_{zy} & T_{zz}\end{pmatrix} $是张量$ \mathbf T $$3 \times 3$个方向上的分量,恰巧用``矩阵''表示,记为$ [\mathbf T] $ \parinterval 其中,$ \begin{pmatrix} v_x\\v_y\\v_z\end{pmatrix} $是向量$ \mathbf v $在基向量$(\textrm{x},\textrm{y},\textrm{z})$上的投影,$ \begin{pmatrix} u_x\\u_y\\u_z\end{pmatrix} $是向量$ \mathbf u $在基向量$(\textrm{x},\textrm{y},\textrm{z})$上的投影,$ \begin{pmatrix}T_{xx} & T_{xy} & T_{xz}\\T_{yx} & T_{yy} & T_{yz}\\T_{zx} & T_{zy} & T_{zz}\end{pmatrix} $是张量$ \mathbf T $$3 \times 3$个方向上的分量,恰巧用``矩阵''表示,记为$ [\mathbf T] $
\parinterval 以上的内容是明确张量的原始定义,以避免对这个概念的误解。但是,本书仍然遵循深度学习中常用的概念,把张量理解为多维数组。在保证数学表达的简洁性的同时,使程序实现接口更加统一。 \parinterval 以上的内容是帮助大家明确张量的原始定义,以避免对这个概念的误解。但是,本书仍然遵循深度学习中常用的概念,把张量理解为多维数组。在保证数学表达的简洁性的同时,使程序实现接口更加统一。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
...@@ -1025,7 +1025,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -1025,7 +1025,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\label{} \label{}
\end{eqnarray} \end{eqnarray}
\parinterval 将矩阵乘法扩展到高阶张量中:一个张量$ \mathbf x $若要与矩阵$ \mathbf w $做矩阵乘法,则$ \mathbf x $一维度需要与$ \mathbf w $的行数大小相等,即:若张量$ \mathbf x $的形状为$ \cdot \times n $$ \mathbf w $须为$ n\times \cdot $的矩阵。如下是一个例子: \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)
\label{eq:5-25} \label{eq:5-25}
...@@ -1052,7 +1052,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -1052,7 +1052,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\item $ \mathbf s+\mathbf b $中的单元加就是对张量中的每个位置都进行加法。在例中$ \mathbf s $是形状为$ (1:4,1:4,1:2) $的3阶张量,而$ \mathbf b $是含有4个元素的向量,在形状不同的情况下是怎样进行单元加的呢?在这里需要引入{\small\sffamily\bfseries{广播机制}}\index{广播机制}:如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失或长度为1的维度上进行,它是深度学习框架中常用的计算方式。来看一个具体的例子,如图\ref{fig:5-28}所示,$ \mathbf s $是一个$ 2\times 4 $的矩阵而$ \mathbf b $是一个长度为4的向量,这两者进行单元加运算时,广播机制会将$ \mathbf b $沿第一个维度复制后,再与$ \mathbf s $做加法运算。 \item $ \mathbf s+\mathbf b $中的单元加就是对张量中的每个位置都进行加法。在例中$ \mathbf s $是形状为$ (1:4,1:4,1:2) $的3阶张量,而$ \mathbf b $是含有4个元素的向量,在形状不同的情况下是怎样进行单元加的呢?在这里需要引入{\small\sffamily\bfseries{广播机制}}\index{广播机制}:如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失或长度为1的维度上进行,它是深度学习框架中常用的计算方式。来看一个具体的例子,如图\ref{fig:5-28}所示,$ \mathbf s $是一个$ 2\times 4 $的矩阵而$ \mathbf b $是一个长度为4的向量,这两者进行单元加运算时,广播机制会将$ \mathbf b $沿第一个维度复制后,再与$ \mathbf s $做加法运算。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1064,7 +1064,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -1064,7 +1064,7 @@ x_0\cdot w_0+x_1\cdot w_1+x_2\cdot w_2 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
%------------------------------------------- %-------------------------------------------
\vspace{0.5em} \vspace{0.5em}
\item 除了单位加之外,张量之间也可以使用减法操作、乘法操作,也可以对张量作激活操作。这里将其称作为函数的{\small\bfnew{向量化}}\index{向量化}(Vectorization)\index{Vectorization}。例如,对向量(1阶张量)作ReLU激活,其中ReLU激活函数的公式为: \item 除了单位加之外,张量之间也可以使用减法操作、乘法操作。此外也可以对张量作激活操作,这里将其称作为函数的{\small\bfnew{向量化}}\index{向量化}(Vectorization)\index{Vectorization}。例如,对向量(1阶张量)作ReLU激活,ReLU激活函数的公式为:
\begin{eqnarray} \begin{eqnarray}
f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases} f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\label{eq:5-26} \label{eq:5-26}
...@@ -1086,9 +1086,9 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases} ...@@ -1086,9 +1086,9 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\vspace{0.5em} \vspace{0.5em}
\item 张量$ \mathbf T(1:3) $表示一个含有三个元素的向量(1阶张量),其物理存储如图\ref{fig:5-29}(a)所示。 \item 张量$ \mathbf T(1:3) $表示一个含有三个元素的向量(1阶张量),其物理存储如图\ref{fig:5-29}(a)所示。
\vspace{0.5em} \vspace{0.5em}
\item 张量$ \mathbf T(1:2,1:3) $表示一个$ 3\times 2 $的矩阵(2阶张量),其物理存储如图\ref{fig:5-29}(b)所示。 \item 张量$ \mathbf T(1:2,1:3) $表示一个$ 2\times 3 $的矩阵(2阶张量),其物理存储如图\ref{fig:5-29}(b)所示。
\vspace{0.5em} \vspace{0.5em}
\item 张量$ \mathbf T(1:2,1:2,1:3) $表示一个大小$ 3\times 2\times 2 $的3阶张量,其物理存储如图\ref{fig:5-29}(c)所示。 \item 张量$ \mathbf T(1:2,1:2,1:3) $表示一个大小$ 2\times 2\times 3 $的3阶张量,其物理存储如图\ref{fig:5-29}(c)所示。
\vspace{0.5em} \vspace{0.5em}
\end{itemize} \end{itemize}
...@@ -1191,7 +1191,7 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases} ...@@ -1191,7 +1191,7 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 除了上述单元算子外,NiuTensor还支持张量之间的高阶运算,其中最常用的矩阵乘法,图\ref{fig:5-36}是张量之间进行矩阵乘法的程序示例。表\ref{tab:5-2}展示了一些NiuTensor支持的其他函数操作,除此还有很多其他操作无法在此一一列举,有兴趣可以参考网站上的详细说明。 \parinterval 除了上述单元算子外,NiuTensor还支持张量之间的高阶运算,其中最常用的矩阵乘法,图\ref{fig:5-36}是张量之间进行矩阵乘法的程序示例。表\ref{tab:5-2}展示了一些NiuTensor支持的其他函数操作,除此还有很多其他操作无法在此一一列举,有兴趣可以参考网站上的详细说明。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1232,7 +1232,7 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases} ...@@ -1232,7 +1232,7 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\end{table} \end{table}
%-------------------------------------------------------------------- %--------------------------------------------------------------------
\parinterval 随后的内容会使用NiuTensor作为一种张量``语言''来完成神经网络的描述,以便于读者理解一个抽象的神经网络是如何和具体的程序对应起来的。当然,神经网络也可以使用TensorFlow和PyTorch等框架进行定义,方法都是非常相似的。 \parinterval 随后的内容会使用NiuTensor作为一种张量``语言''来完成神经网络的描述,以便于读者理解一个抽象的神经网络是如何和具体的程序对应起来的。当然,神经网络也可以使用TensorFlow和PyTorch等框架进行定义,方法都是非常相似的。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
...@@ -1253,9 +1253,9 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases} ...@@ -1253,9 +1253,9 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 它可以被描述为公式\ref{eq:5-27},其中隐藏层的激活函数是Tanh函数,输出层的激活函数是Sigmoid函数: \parinterval 它可以被描述为公式\ref{eq:5-27},其中隐藏层的激活函数是Tanh函数,输出层的激活函数是Sigmoid函数$\mathbf w^{[1]}$$\mathbf b^{[1]}$分别表示第一层的权重矩阵和偏置,$\mathbf w^{[2]}$$b^{[2]}$分别表示第二层的权重矩阵和偏置且偏置$b^{[2]}$是标量
\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]}+ b^{[2]} )
\label{eq:5-27} \label{eq:5-27}
\end{eqnarray} \end{eqnarray}
...@@ -1268,9 +1268,9 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat ...@@ -1268,9 +1268,9 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 前向计算实现如图\ref{fig:5-38}所示,图中对各张量和其他参数的形状做了详细说明。输入$ \mathbf x=(x_1,x_2,x_3) $是一个$1\times 3$的张量,其三个维度分别对应天空状况、低空气温、水平气压三个方面的数据。输入数据经过隐藏层的线性变换$ \mathbf x\cdot \mathbf w^1+\mathbf b^1 $和Tanh函数的激活,得到新的张量$ \mathbf a=(a_1,a_2) $,其中$a_1$$a_2$分别对应着从输入数据中提取出的温度和风速两方面特征;神经网络在获取到天气情况的特征$ \mathbf a $后,继续对其进行线性变换$ \mathbf a\cdot \mathbf w^2+ b^2 $(其中$b^2$是标量)和Sigmoid函数的激活操作,得到神经网络的最终输出$ y $,即神经网络此时预测的穿衣指数。 \parinterval 前向计算实现如图\ref{fig:5-38}所示,图中对各张量和其他参数的形状做了详细说明。输入$ \mathbf x=(x_1,x_2,x_3) $是一个$1\times 3$的张量,其三个维度分别对应天空状况、低空气温、水平气压三个方面的数据。输入数据经过隐藏层的线性变换$ \mathbf x\cdot \mathbf w^{[1]}+\mathbf b^{[1]}$和Tanh函数的激活,得到新的张量$ \mathbf a=(a_1,a_2) $,其中$a_1$$a_2$分别对应着从输入数据中提取出的温度和风速两方面特征;神经网络在获取到天气情况的特征$ \mathbf a $后,继续对其进行线性变换$ \mathbf a\cdot \mathbf w^{[2]}+ b^{[2]} $和Sigmoid函数的激活操作,得到神经网络的最终输出$ y $,即神经网络此时预测的穿衣指数。
\parinterval\ref{fig:5-38}实际上是神经网络的一种{\small\bfnew{计算图}}\index{计算图}(Computation Graph)\index{Computation Graph}表示。现在很多深度学习框架都是把神经网络转化为计算图,这样可以把复杂的运算分解为简单的运算。通过对计算图中节点的遍历,可以方便地完成神经网络的计算。比如,可以对图中节点进行拓扑排序(由输入到输出),之后依次访问每个节点同时完成相应的计算。这也就实现了一个前向计算的过程。构建计算图的方式有很多,比如,动态图、静态图等。在\ref{sec5:para-training}节会进一步对计算图在模型参数训练中的应用进行介绍。 \parinterval\ref{fig:5-38}实际上是神经网络的一种{\small\bfnew{计算图}}\index{计算图}(Computation Graph)\index{Computation Graph}表示。现在很多深度学习框架都是把神经网络转化为计算图,这样可以把复杂的运算分解为简单的运算。通过对计算图中节点的遍历,可以方便地完成神经网络的计算。比如,可以对图中节点进行拓扑排序(由输入到输出),之后依次访问每个节点,同时完成相应的计算,这也就实现了一个前向计算的过程。构建计算图的方式有很多,比如,动态图、静态图等。在\ref{sec5:para-training}节会进一步对计算图在模型参数训练中的应用进行介绍。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
...@@ -1318,7 +1318,7 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat ...@@ -1318,7 +1318,7 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat
\sectionnewpage \sectionnewpage
\section{神经网络的参数训练} \section{神经网络的参数训练}
\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{模型参数}}\index{模型参数}(Model Parameters)\index{Model Parameters}。确定了函数表达式和模型参数,也就确定了神经网络模型。通常,表达式的形式需要系统开发者设计,而模型参数的数量有时会非常巨大,因此需要自动学习,这个过程也被称为模型学习或{\small\bfnew{训练}}\index{训练}(Training)\index{Training}。为了实现这个目标,通常会准备一定量的带有标准答案的数据,称之为{\small\sffamily\bfseries{有标注数据}}\index{有标注数据}(Annotated Data/Labeled Data)\index{Annotated Data/Labeled Data}。这些数据会用于对模型参数的学习,这也对应了统计模型中的参数估计过程。在机器学习中,一般把这种使用有标注数据进行统计模型参数训练的过程称为{\small\sffamily\bfseries{有指导的训练}}\index{有指导的训练}{\small\sffamily\bfseries{有监督的训练}}\index{有监督的训练}(Supervised Training)\index{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{模型参数}}\index{模型参数}(Model Parameters)\index{Model Parameters}。确定了函数表达式和模型参数,也就确定了神经网络模型。通常,表达式的形式需要系统开发者设计,而模型参数的数量有时会非常巨大,因此需要自动学习,这个过程也被称为模型学习或{\small\bfnew{训练}}\index{训练}(Training)\index{Training}。为了实现这个目标,通常会准备一定量的带有标准答案的数据,称之为{\small\sffamily\bfseries{有标注数据}}\index{有标注数据}(Annotated Data/Labeled Data)\index{Annotated Data/Labeled Data}。这些数据会用于对模型参数的学习,这也对应了统计模型中的参数估计过程。在机器学习中,一般把这种使用有标注数据进行统计模型参数训练的过程称为{\small\sffamily\bfseries{有指导的训练}}\index{有指导的训练}{\small\sffamily\bfseries{有监督的训练}}\index{有监督的训练}(Supervised Training)\index{Supervised Training}。在本章中,如果没有特殊说明,模型训练都是指有监督的训练。那么神经网络内部是怎样利用有标注数据对参数进行训练的呢?
\parinterval 为了回答这个问题,可以把模型参数的学习过程看作是一个优化问题,即找到一组参数,使得模型达到某种最优的状态。这个问题又可以被转化为两个新的问题: \parinterval 为了回答这个问题,可以把模型参数的学习过程看作是一个优化问题,即找到一组参数,使得模型达到某种最优的状态。这个问题又可以被转化为两个新的问题:
...@@ -1381,7 +1381,7 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat ...@@ -1381,7 +1381,7 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat
\subsection{基于梯度的参数优化}\label{sec5:para-training} \subsection{基于梯度的参数优化}\label{sec5:para-training}
\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}
\widehat{\mathbf w}&=&\mathop{\arg\min}_{\mathbf w}\frac{1}{n}\sum_{i=1}^{n}{L(\mathbf x_i,\mathbf {\widetilde y}_i;\mathbf w)} \widehat{\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{eq:5-28} \label{eq:5-28}
...@@ -1397,7 +1397,7 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat ...@@ -1397,7 +1397,7 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat
\subsubsection{梯度下降} \subsubsection{梯度下降}
\parinterval 梯度下降法是一种常用的优化方法,非常适用于目标函数可微分的问题。它基本思想是,给定函数上的第一个点,可以找到使函数值变化最大的方向,然后前进一``步'',这样模型就可以朝着更大(或更小)的函数值以最快的速度移动\footnote{梯度下降的一种实现是{\scriptsize\bfnew{最速下降}}(Steepest Descent)。该方法的每一步移动都选取合适的步长,进而使目标函数能得到最大程度的增长(或下降)。}。具体来说,梯度下降通过迭代更新参数$ \mathbf w $,不断沿着梯度的反方向让参数$ \mathbf w $朝着损失函数更小的方向移动:如果$ J(\mathbf w) $$ \mathbf w $可微分,则$ \frac{\partial J(\mathbf w)}{\partial \mathbf w} $将指向$ J(\mathbf w) $$ \mathbf w $处变化最大的方向,这里将其称之为梯度方向。$ \mathbf w $沿着梯度方向更新,新的$ \mathbf w $可以使函数更接近极值,其过程如图\ref{fig:5-43}所示。 \parinterval 梯度下降法是一种常用的优化方法,非常适用于目标函数可微分的问题。它的基本思想是:给定函数上的第一个点,找到使函数值变化最大的方向,然后前进一``步'',这样模型就可以朝着更大(或更小)的函数值以最快的速度移动\footnote{梯度下降的一种实现是{\scriptsize\bfnew{最速下降}}(Steepest Descent)。该方法的每一步移动都选取合适的步长,进而使目标函数能得到最大程度的增长(或下降)。}。具体来说,梯度下降通过迭代更新参数$ \mathbf w $,不断沿着梯度的反方向让参数$ \mathbf w $朝着损失函数更小的方向移动:如果$ J(\mathbf w) $$ \mathbf w $可微分,则$ \frac{\partial J(\mathbf w)}{\partial \mathbf w} $将指向$ J(\mathbf w) $$ \mathbf w $处变化最大的方向,这里将其称之为梯度方向。$ \mathbf w $沿着梯度方向更新,新的$ \mathbf w $可以使函数更接近极值,其过程如图\ref{fig:5-43}所示。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1414,7 +1414,7 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat ...@@ -1414,7 +1414,7 @@ y&=&{\rm{Sigmoid}}({\rm{Tanh}}(\mathbf x\cdot \mathbf w^1+\mathbf b^1)\cdot \mat
\label{eq:5-29} \label{eq:5-29}
\end{eqnarray} \end{eqnarray}
\noindent 其中$t $表示更新的步数,$ \alpha $是一个参数,被称作{\small\sffamily\bfseries{学习率}}\index{学习率}(Learning Rate)\index{Learning Rate},表示更新步幅的大小。$ \alpha $的设置需要根据任务进行调整。 \noindent 其中$t $表示更新的步数,$ \alpha $是一个参数,被称作{\small\sffamily\bfseries{学习率}}\index{学习率}(Learning Rate)\index{Learning Rate},表示更新步幅的大小。$ \alpha $的设置需要根据任务进行调整。
\parinterval 从优化的角度看,梯度下降是一种典型的 {\small\bfnew{基于梯度的方法}}\index{基于梯度的方法}(Gradient-based Method)\index{Gradient-based Method},属于基于一阶导数的方法。其他类似的方法还有牛顿法、共轭方向法、拟牛顿法等。在具体实现时,公式\ref{eq:5-29}可以有以下不同的形式。 \parinterval 从优化的角度看,梯度下降是一种典型的 {\small\bfnew{基于梯度的方法}}\index{基于梯度的方法}(Gradient-based Method)\index{Gradient-based Method},属于基于一阶导数的方法。其他类似的方法还有牛顿法、共轭方向法、拟牛顿法等。在具体实现时,公式\ref{eq:5-29}可以有以下不同的形式。
...@@ -1450,7 +1450,7 @@ J(\mathbf w)&=&L(\mathbf x_i,\mathbf {\widetilde y}_i;\mathbf w) ...@@ -1450,7 +1450,7 @@ J(\mathbf w)&=&L(\mathbf x_i,\mathbf {\widetilde y}_i;\mathbf w)
\label{eq:5-31} \label{eq:5-31}
\end{eqnarray} \end{eqnarray}
\noindent 由于每次只随机选取一个样本$(\mathbf x_i,\mathbf {\widetilde y}_i)$进行优化,这样更新的计算代价低,参数更新的速度大大加快,而且也适用于利用少量样本进行在线学习的情况\footnote{比如,训练数据不是一次给定的,而是随着模型的使用不断追加的。这时,需要不断地用新的训练样本更新模型,这种模式也被称作{\scriptsize\bfnew{在线学习}}(Online Learning)} \noindent 由于每次只随机选取一个样本$(\mathbf x_i,\mathbf {\widetilde y}_i)$进行优化,这样更新的计算代价低,参数更新的速度大大加快,而且也适用于利用少量样本进行在线学习的情况\footnote{比如,训练数据不是一次给定的,而是随着模型的使用不断追加的。这时,需要不断地用新的训练样本更新模型,这种模式也被称作{\scriptsize\bfnew{在线学习}}(Online Learning)}
\parinterval 因为随机梯度下降算法每次优化的只是某一个样本上的损失,所以它的问题也非常明显:单个样本上的损失无法代表在全部样本上的损失,因此参数更新的效率低,方法收敛速度极慢。即使在目标函数为强凸函数的情况下,SGD仍旧无法做到线性收敛。 \parinterval 因为随机梯度下降算法每次优化的只是某一个样本上的损失,所以它的问题也非常明显:单个样本上的损失无法代表在全部样本上的损失,因此参数更新的效率低,方法收敛速度极慢。即使在目标函数为强凸函数的情况下,SGD仍旧无法做到线性收敛。
...@@ -1561,7 +1561,7 @@ $+2x^2+x+1)$ & \ \ $(x^4+2x^3+2x^2+x+1)$ & $+6x+1$ \\ ...@@ -1561,7 +1561,7 @@ $+2x^2+x+1)$ & \ \ $(x^4+2x^3+2x^2+x+1)$ & $+6x+1$ \\
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 前向计算实际上就是网络构建的过程,所有的计算都会被转化为计算图上的节点,前向计算和反向计算都依赖计算图来完成。通常,构建计算图有以下两种实现方式 \parinterval 前向计算实际上就是网络构建的过程,所有的计算都会被转化为计算图上的节点,前向计算和反向计算都依赖计算图来完成。通常,构建计算图有以下两种实现方式
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
...@@ -1596,7 +1596,7 @@ $+2x^2+x+1)$ & \ \ $(x^4+2x^3+2x^2+x+1)$ & $+6x+1$ \\ ...@@ -1596,7 +1596,7 @@ $+2x^2+x+1)$ & \ \ $(x^4+2x^3+2x^2+x+1)$ & $+6x+1$ \\
\label{} \label{}
\end{eqnarray} \end{eqnarray}
\noindent 其中$ \alpha $是一个参数,表示更新步幅的大小,称作{\small\bfnew{学习率}}\index{学习率}(Learning Rate)\index{Learning Rate}。当然,这是一种最基本的梯度下降方法。如果函数的形状非均向,比如呈延伸状,搜索最优点的路径就会非常低效,因为这时梯度的方向并没有指向最小值的方向,并且随着参数的更新,梯度方向往往呈锯齿状,这将是一条相当低效的路径;此外这种梯度下降算法并不是总能到达最优点,而是在其附近徘徊;还有一个最令人苦恼的问题\ \dash \ 设置学习率,如果学习率设置的比较小,会导致训练收敛速度慢,如果学习率设置的比较大,会导致训练过程中因为优化幅度过大而频频跳过最优点。我们希望网络在优化的时候损失函数有一个很好的收敛速度同时又不至于摆动幅度太大。 \noindent 其中$ \alpha $是一个参数,表示更新步幅的大小,称作{\small\bfnew{学习率}}\index{学习率}(Learning Rate)\index{Learning Rate}。当然,这是一种最基本的梯度下降方法。如果函数的形状非均向,比如呈延伸状,搜索最优点的路径就会非常低效,因为这时梯度的方向并没有指向最小值的方向,并且随着参数的更新,梯度方向往往呈锯齿状,这将是一条相当低效的路径;此外这种梯度下降算法并不是总能到达最优点,而是在其附近徘徊;还有一个最令人苦恼的问题\ \dash \ 设置学习率,如果学习率设置的比较小,会导致训练收敛速度慢,如果学习率设置的比较大,会导致训练过程中因为优化幅度过大而频频跳过最优点。我们希望网络在优化的时候损失函数有一个很好的收敛速度同时又不至于摆动幅度太大。
\parinterval 针对以上问题,很多学者尝试对梯度下降方法做出改进,如Momentum, Adagrad, Adadelta, RMSprop, Adam, AdaMax, Nadam, AMSGrad等等,在这里将介绍Momentum、AdaGrad、RMSprop、Adam这4 种方法。 \parinterval 针对以上问题,很多学者尝试对梯度下降方法做出改进,如Momentum, Adagrad, Adadelta, RMSprop, Adam, AdaMax, Nadam, AMSGrad等等,在这里将介绍Momentum、AdaGrad、RMSprop、Adam这4 种方法。
...@@ -1645,7 +1645,7 @@ w_{t+1}&=&w_t-\eta \frac{1}{\sqrt{z_t}}\cdot \frac{\partial L}{\partial w_t} ...@@ -1645,7 +1645,7 @@ w_{t+1}&=&w_t-\eta \frac{1}{\sqrt{z_t}}\cdot \frac{\partial L}{\partial w_t}
\label{eq:5-37} \label{eq:5-37}
\end{eqnarray} \end{eqnarray}
\parinterval 这里新出现了变量$ z $,它保存了以前的所有梯度值的平方和,在更新参数时,通过乘以$ \frac{1}{\sqrt{z_t}} $ ,就可以调整学习的尺度。这意味着,变动较大(被大幅更新)的参数的学习率将变小。也就是说,可以按参数的元素进行学习率衰减,使变动大的参数的学习率逐渐减小。 \parinterval 这里新出现了变量$ z $,它保存了以前的所有梯度值的平方和,在更新参数时,通过乘以$ \frac{1}{\sqrt{z_t}} $ ,就可以调整学习的尺度。这意味着,变动较大(被大幅更新)的参数的学习率将变小。也就是说,可以按参数的元素进行学习率衰减,使变动大的参数的学习率逐渐减小。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% %
...@@ -1686,7 +1686,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1686,7 +1686,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\noindent 可以看到Adam 算法相当于在RMSProp算法中引入了Momentum算法中的动量项,这样做使得Adam算法兼具了Momentum算法和RMSProp算法的优点:既能使梯度更为``平滑''地更新,同时可以为神经网络中的每个参数设置不同的学习率。 \noindent 可以看到Adam 算法相当于在RMSProp算法中引入了Momentum算法中的动量项,这样做使得Adam算法兼具了Momentum算法和RMSProp算法的优点:既能使梯度更为``平滑''地更新,同时可以为神经网络中的每个参数设置不同的学习率。
\parinterval 需要注意的是包括Adam在内的很多参数更新算法中的学习率都需要人为设置。而且模型学习的效果与学习率的设置关系极大,甚至在研发实际系统时工程师需要进行大量的实验,得到最佳的模型。第六章还会具体介绍在机器翻译中参数更新学习率设置的策略。 \parinterval 需要注意的是包括Adam在内的很多参数更新算法中的学习率都需要人为设置。而且模型学习的效果与学习率的设置关系极大,甚至在研发实际系统时工程师需要进行大量的实验,才能得到最佳的模型。第六章还会具体介绍在机器翻译中参数更新学习率设置的策略。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
...@@ -1713,7 +1713,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1713,7 +1713,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\end {figure} \end {figure}
%------------------------------------------- %-------------------------------------------
\parinterval\ref{fig:5-47}对比了同步更新和异步更新的区别,在这个例子中,使用4台设备对一个两层神经网络中的参数进行更新,其中使用了一个{\small\bfnew{参数服务器}}\index{参数服务器}(Parameter Server\index{Parameter Server},图中的G4)来保存最新的参数,不同设备(Worker,图中的G1、G2、G3)可以通过同步或者异步的方式访问参数服务器。图中的$ \mathbf w_o $$ \mathbf w_h $分别代表输出层和隐藏层的全部参数,操作push(P) 表示设备向参数服务器传送梯度,操作fetch(F)表示参数服务器向设备传送更新后的参数。 \parinterval\ref{fig:5-47}对比了同步更新和异步更新的区别,在这个例子中,使用4台设备对一个两层神经网络中的参数进行更新,其中使用了一个{\small\bfnew{参数服务器}}\index{参数服务器}(Parameter Server\index{Parameter Server})来保存最新的参数,不同设备(Worker,图中的G1、G2、G3)可以通过同步或者异步的方式访问参数服务器。图中的$ \mathbf w_o $$ \mathbf w_h $分别代表输出层和隐藏层的全部参数,操作push(P) 表示设备向参数服务器传送梯度,操作fetch(F)表示参数服务器向设备传送更新后的参数。
\parinterval 此外,在使用多个设备进行并行训练的时候,由于设备间带宽的限制,大量的数据传输会有较高的延时。对于复杂神经网络来说,设备间参数和梯度传递的时间消耗也会成为一个不得不考虑的因素。有时候,设备间数据传输的时间甚至比模型计算的时间都长,大大降低了并行度\cite{xiao2017fast}。对于这种问题,可以考虑对数据进行压缩或者减少传输的次数来缓解问题。 \parinterval 此外,在使用多个设备进行并行训练的时候,由于设备间带宽的限制,大量的数据传输会有较高的延时。对于复杂神经网络来说,设备间参数和梯度传递的时间消耗也会成为一个不得不考虑的因素。有时候,设备间数据传输的时间甚至比模型计算的时间都长,大大降低了并行度\cite{xiao2017fast}。对于这种问题,可以考虑对数据进行压缩或者减少传输的次数来缓解问题。
...@@ -1802,7 +1802,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1802,7 +1802,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval (3){\small\bfnew{残差网络}}\index{残差网络}(Residual Networks)\index{Residual Networks} \parinterval (3){\small\bfnew{残差网络}}\index{残差网络}(Residual Networks)\index{Residual Networks}
\parinterval 最初,残差网络是为了解决神经网络持续加深时的模型退化问题\cite{DBLP:journals/corr/HeZRS15},但是残差结构对解决梯度消失和梯度爆炸问题也有所帮助。有了残差结构,可以很轻松的构建几十甚至上百层的神经网络,而不用担心层数过深造成的梯度消失问题。残差网络的结构如图\ref{fig:5-51}所示: \parinterval 最初,残差网络是为了解决神经网络持续加深时的模型退化问题\cite{DBLP:journals/corr/HeZRS15},但是残差结构对解决梯度消失和梯度爆炸问题也有所帮助。有了残差结构,可以很轻松的构建几十甚至上百层的神经网络,而不用担心层数过深造成的梯度消失问题。残差网络的结构如图\ref{fig:5-51}所示:
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1888,7 +1888,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1888,7 +1888,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
& = & \sum{h_j^{k-1}w_{j,i}^k} & = & \sum{h_j^{k-1}w_{j,i}^k}
\end{eqnarray} \end{eqnarray}
\vspace{0.5em} \vspace{0.5em}
\item $ f^k $:第$ k $层的激活函数,$ \mathbf h_k=f^k(\mathbf s^k)$ \item $ f^k $:第$ k $层的激活函数,$ \mathbf h^k=f^k(\mathbf s^k)$
\vspace{0.5em} \vspace{0.5em}
\end{itemize} \end{itemize}
...@@ -1960,7 +1960,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -1960,7 +1960,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\begin{spacing}{1.6} \begin{spacing}{1.6}
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\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))$
\vspace{0.5em} \vspace{0.5em}
...@@ -2073,7 +2073,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -2073,7 +2073,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\subsubsection{程序实现} \subsubsection{程序实现}
\parinterval 在了解了反向传播的原理之后,实现反向传播就变得非常容易了。实际上,现在主流的深度学习框架都支持自动微分。这里,为了进一步说明反向传播的过程,这里使用NiuTensor工具构建两个简单的实例,并分别尝试手动编写反向传播代码和使用NiuTensor自带的自动微分模块。 \parinterval 在了解了反向传播的原理之后,实现反向传播就变得非常容易了。实际上,现在主流的深度学习框架都支持自动微分。为了进一步说明反向传播的过程,这里使用NiuTensor工具构建两个简单的实例,并分别尝试手动编写反向传播代码和使用NiuTensor自带的自动微分模块。
\parinterval\ref{fig:5-58}展示了一个简单的神经网络的反向传播程序示例。这种反向传播的实现方式正是上一节内容的代码实现:按层实现自动微分并将梯度向前一层传播。 \parinterval\ref{fig:5-58}展示了一个简单的神经网络的反向传播程序示例。这种反向传播的实现方式正是上一节内容的代码实现:按层实现自动微分并将梯度向前一层传播。
...@@ -2114,7 +2114,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -2114,7 +2114,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\subsection{基于神经网络的语言建模} \subsection{基于神经网络的语言建模}
\parinterval 回顾一下第二章的内容,语言建模的问题被定义为:对于一个词序列$ w_1w_2\dots w_m$,如何计算的可能性?词序列出现的概率可以通过链式法则得到: \parinterval 回顾一下第二章的内容,语言建模的问题被定义为:对于一个词序列$ w_1w_2\dots w_m$,如何计算该词序列的可能性?词序列出现的概率可以通过链式法则得到:
\begin{eqnarray} \begin{eqnarray}
{\rm P}(w_1w_2\dots w_m)&=&{\rm P}(w_1){\rm P}(w_2|w_1){\rm P}(w_3|w_1w_2)\dots {\rm P}(w_m|w_1\dots w_{m-1}) {\rm P}(w_1w_2\dots w_m)&=&{\rm P}(w_1){\rm P}(w_2|w_1){\rm P}(w_3|w_1w_2)\dots {\rm P}(w_m|w_1\dots w_{m-1})
\label{eq:5-57} \label{eq:5-57}
...@@ -2176,7 +2176,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -2176,7 +2176,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 在FNNLM中,所有的参数、输入、输出都是连续变量,因此FNNLM也是典型的一个连续空间模型。通过使用交叉熵等损失函数,FNNLM很容易进行优化。比如,可以使梯度下降方法对FNNLM的模型参数进行训练。 \parinterval 在FNNLM中,所有的参数、输入、输出都是连续变量,因此FNNLM也是典型的一个连续空间模型。通过使用交叉熵等损失函数,FNNLM很容易进行优化。比如,可以使梯度下降方法对FNNLM的模型参数进行训练。
\parinterval FNNLM的实现也非常简单,图\ref{fig:5-61}展示了基于NiuTensor的FNNLM的部分代码。需要注意的是,在程序实现时, Tanh函数一般会用HardTanh函数代替。因为 Tanh函数中的指数运算容易导致溢出: \parinterval FNNLM的实现也非常简单,图\ref{fig:5-61}展示了基于NiuTensor的FNNLM的部分代码。需要注意的是,在程序实现时, Tanh函数一般会用HardTanh函数代替。因为 Tanh函数中的指数运算容易导致溢出:
\begin{eqnarray} \begin{eqnarray}
...@@ -2201,7 +2201,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -2201,7 +2201,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval 虽然FNNLM模型形式简单,却为处理自然语言提供了一个全新的视角。首先,该模型重新定义了``词是什么''\ \dash \ 它并非词典的一项,而是可以用一个连续实数向量进行表示的可计算的``量''。此外,由于$n$-gram不再是离散的符号序列,模型不需要记录$n$-gram,所以很好的缓解了上面所提到的数据稀疏问题,模型体积也大大减小。 \parinterval 虽然FNNLM模型形式简单,却为处理自然语言提供了一个全新的视角。首先,该模型重新定义了``词是什么''\ \dash \ 它并非词典的一项,而是可以用一个连续实数向量进行表示的可计算的``量''。此外,由于$n$-gram不再是离散的符号序列,模型不需要记录$n$-gram,所以很好的缓解了上面所提到的数据稀疏问题,模型体积也大大减小。
\parinterval 当然,FNNLM模型也引发后人的许多思考,比如:神经网络每一层都学到了什么?是词法、句法还是一些其他知识?如何理解词的分布式表示?等等。在随后的内容中也会看到,随着近几年深度学习和自然语言处理的发展,部分问题已经得到了很好的解答,但是仍有许多问题需要进一步探索。 \parinterval 当然,FNNLM模型也引发后人的许多思考,比如:神经网络每一层都学到了什么?是词法、句法还是一些其他知识?如何理解词的分布式表示?等等。在随后的内容中也会看到,随着近几年深度学习和自然语言处理的发展,部分问题已经得到了很好的解答,但是仍有许多问题需要进一步探索。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION % NEW SUBSUB-SECTION
...@@ -2248,9 +2248,9 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -2248,9 +2248,9 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\parinterval 通过引入记忆历史的能力,RNNLM缓解了$n$-gram模型中有限上下文的局限性,但依旧存在一些问题。随着序列变长,不同单词之间信息传递路径变长,信息传递的效率变低。对于长序列,很难通过很多次的循环单元操作保留很长的历史信息。过长的序列还容易引起梯度消失和梯度爆炸问题(详见\ref{sec:5.4.4}节),增加模型训练的难度。 \parinterval 通过引入记忆历史的能力,RNNLM缓解了$n$-gram模型中有限上下文的局限性,但依旧存在一些问题。随着序列变长,不同单词之间信息传递路径变长,信息传递的效率变低。对于长序列,很难通过很多次的循环单元操作保留很长的历史信息。过长的序列还容易引起梯度消失和梯度爆炸问题(详见\ref{sec:5.4.4}节),增加模型训练的难度。
\parinterval 对于这个问题,研究者又提出了一种新的结构$\ \dash \ ${\small\bfnew{自注意力机制}}\index{自注意力机制}(Self-Attention Mechanism)\index{Self-Attention Mechanism}。自注意力是一种特殊的神经网络结构,它可以对序列上任意两个词的相互作用直接进行建模,这样也就避免了循环神经网络中随着距离变长信息传递步骤增多的缺陷。在自然语言处理领域,自注意力机制被成功地应用在机器翻译,形成了著名的Transformer模型\cite{NIPS2017_7181}。第六章会系统地介绍自注意力机制和Transformer模型。 \parinterval 对于这个问题,研究者又提出了一种新的结构$\ \dash \ ${\small\bfnew{自注意力机制}}\index{自注意力机制}(Self-Attention Mechanism)\index{Self-Attention Mechanism}。自注意力是一种特殊的神经网络结构,它可以对序列上任意两个词的相互作用直接进行建模,这样也就避免了循环神经网络中随着距离变长信息传递步骤增多的缺陷。在自然语言处理领域,自注意力机制被成功地应用在机器翻译任务上,形成了著名的Transformer模型\cite{NIPS2017_7181}。第六章会系统地介绍自注意力机制和Transformer模型。
\parinterval 这里,先简单了解一下基于Transformer的语言模型结构(图\ref{fig:5-63})。与FNNLM\\和RNNLM一样,Transformer首先对输入单词进行分布式表示,同时加上每个位置的编码构成了整个模型的输入(蓝色方框)。之后,利用自注意力机制对输入的向量进行处理(绿色方框)。自注意力的结果会被送入一个前馈神经网络,之后再送给Softmax输出层(橙色方框)。 \parinterval 这里,先简单了解一下基于Transformer的语言模型结构(图\ref{fig:5-63})。与FNNLM\\和RNNLM一样,Transformer首先对输入单词进行分布式表示,同时加上每个单词的位置编码构成了整个模型的输入(蓝色方框)。之后,利用自注意力机制对输入的向量进行处理(绿色方框)。自注意力的结果会被送入一个前馈神经网络,之后再送给Softmax输出层(橙色方框)。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -2275,7 +2275,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t ...@@ -2275,7 +2275,7 @@ w_{t+1}&=&w_t-\frac{\eta}{\sqrt{z_t+\epsilon}} v_t
\label{eq:5-65} \label{eq:5-65}
\end{eqnarray} \end{eqnarray}
\parinterval 本质上,PPL反映了语言模型对序列可能性预测能力的一种评估。因为$ w_1\dots w_m $\\是真实的自然语言,``完美''的模型会得到$ {\rm P} (w_1\dots w_m)=1 $,它对应了最低的困惑度$ {\rm{PPL}}=1$这说明模型可以完美地对词序列出现的可能性进行预测。当然,真实的语言模型是无法达到$ {\rm{PPL}}=1$的,比如,在著名的Penn Treebank(PTB)数据上最好的语言模型的PPL值也只能到达35左右。可见自然语言处理任务的困难程度。 \parinterval 本质上,PPL反映了语言模型对序列可能性预测能力的一种评估。如果$ w_1\dots w_m $\\是真实的自然语言,``完美''的模型会得到$ {\rm P} (w_1\dots w_m)=1 $,它对应了最低的困惑度$ {\rm{PPL}}=1$这说明模型可以完美地对词序列出现的可能性进行预测。当然,真实的语言模型是无法达到$ {\rm{PPL}}=1$的,比如,在著名的Penn Treebank(PTB)数据上最好的语言模型的PPL值也只能到达35左右。可见自然语言处理任务的困难程度。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
...@@ -2372,7 +2372,7 @@ Jobs was the CEO of {\red{\underline{apple}}}. ...@@ -2372,7 +2372,7 @@ Jobs was the CEO of {\red{\underline{apple}}}.
\qquad \qquad \; He finally ate the {\red{\underline{apple}}}. \qquad \qquad \; He finally ate the {\red{\underline{apple}}}.
\end{example} \end{example}
\parinterval 这两句中``apple''的语义显然是不同的,第一句中的上下文``Jobs''和``CEO''可以帮助我们判断``apple''是一个公司名字,而不是水果。但是词嵌入只有一个结果,因此无法区分这两种情况。这个例子给我们一个启发:在一个句子中,不能孤立的看待单词,应同时考虑其上下文的信息。也就是需要一个能包含句子中上下文信息的表示模型。 \parinterval 这两句中``apple''的语义显然是不同的,第一句中的上下文``Jobs''和``CEO''可以帮助我们判断``apple''是一个公司名字,而不是水果。但是词嵌入只有一个结果,因此无法区分这两种情况。这个例子给我们一个启发:在一个句子中,不能孤立的看待单词,应同时考虑其上下文的信息。也就是需要一个能包含句子中上下文信息的表示模型。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION % NEW SUBSUB-SECTION
...@@ -2456,7 +2456,7 @@ Jobs was the CEO of {\red{\underline{apple}}}. ...@@ -2456,7 +2456,7 @@ Jobs was the CEO of {\red{\underline{apple}}}.
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\item 第一个任务被称为Masked LM。在输入的词序列中随机挡住一定量的的词(比如15\%的单词被挡住),然后让模型去预测挡住的这些词。这个过程有些类似于英语考试中的完形填空。这么做的好处是,模型能够从多个方向去预测这些被遮罩住的词(图\ref{fig:5-72}),而不是像传统语言模型一样从单个方向预测(自左向右或者自右向左)。Masked LM的思想也影响了很多预训练模型的设计。 \item 第一个任务被称为Masked LM。在输入的词序列中随机挡住一定量的的词(比如15\%的单词被挡住),然后让模型去预测挡住的这些词。这个过程有些类似于英语考试中的完形填空。这么做的好处是,模型能够从多个方向去预测这些被遮罩住的词(图\ref{fig:5-72}),而不是像传统语言模型一样从单个方向预测(自左向右或者自右向左)。Masked LM的思想也影响了很多预训练模型的设计。
\vspace{0.5em} \vspace{0.5em}
\item 第二个任务是预测下一个句子。当选择句子a与b作为预训练样本时,b有一半几率可能是a的下一句,也有一半几率来自语料库的随机句子,从而可以更好地学习句子之间的相关性。 \item 第二个任务是预测下一个句子。当选择句子a与b作为预训练样本时,b有一半几率可能是a的下一句,也有一半几率来自语料库的随机句子,从而可以更好地学习句子之间的相关性。
\vspace{0.5em} \vspace{0.5em}
...@@ -2515,6 +2515,6 @@ Jobs was the CEO of {\red{\underline{apple}}}. ...@@ -2515,6 +2515,6 @@ Jobs was the CEO of {\red{\underline{apple}}}.
\vspace{0.5em} \vspace{0.5em}
\item 词嵌入是自然语言处理近些年的重要进展。所谓“嵌入”是一类方法,理论上,把一个事物进行分布式表示的过程都可以被看作是广义上的“嵌入”。基于这种思想的表示学习也成为了自然语言处理中的前沿方法。比如,如何对树结构,甚至图结构进行分布式表示\cite{plank2013embedding}\cite{perozzi2014deepwalk}成为了分析自然语言的重要方法。此外,除了语言建模,还有很多方式可以进行词嵌入的学习,比如,SENNA\cite{collobert2011natural}、word2vec\cite{mikolov2013efficient}\cite{mikolov2013distributed}、Glove\cite{pennington2014glove}、CoVe\cite{mccann2017learned}等。 \item 词嵌入是自然语言处理近些年的重要进展。所谓“嵌入”是一类方法,理论上,把一个事物进行分布式表示的过程都可以被看作是广义上的“嵌入”。基于这种思想的表示学习也成为了自然语言处理中的前沿方法。比如,如何对树结构,甚至图结构进行分布式表示\cite{plank2013embedding}\cite{perozzi2014deepwalk}成为了分析自然语言的重要方法。此外,除了语言建模,还有很多方式可以进行词嵌入的学习,比如,SENNA\cite{collobert2011natural}、word2vec\cite{mikolov2013efficient}\cite{mikolov2013distributed}、Glove\cite{pennington2014glove}、CoVe\cite{mccann2017learned}等。
\vspace{0.5em} \vspace{0.5em}
\item 预训练是表示学习的重要产物。预训练已经在图像处理等领域得到应用。在自然语言处理中,以BERT为代表的预训练模型席卷了很多自然语言处理任务,在阅读理解等比赛(如Stanford Question Answering)中已经成为了所有参赛系统的标配。除了ELMO、GPT、BERT,还有很多优秀的预训练模型,包括GPT-2\cite{radford2019language}、XLM\cite{lample2019cross}、MASS\cite{song2019mass}、XLNet\cite{yang2019xlnet},等等。但是,预训练往往依赖大规模的数据和并行运算设备,这使得很多普通研究者对训练这样的模型望而却步。不过,也有一些研究关注轻量的预训练方法,也受到了很多关注,例如ALBERT\cite{lan2019albert} \item 预训练是表示学习的重要产物。预训练已经在图像处理等领域得到应用。在自然语言处理中,以BERT为代表的预训练模型席卷了很多自然语言处理任务,在阅读理解等比赛(如Stanford Question Answering)中已经成为了所有参赛系统的标配。除了ELMO、GPT、BERT,还有很多优秀的预训练模型,包括GPT-2\cite{radford2019language}、XLM\cite{lample2019cross}、MASS\cite{song2019mass}、XLNet\cite{yang2019xlnet},等等。但是,预训练往往依赖大规模的数据和并行运算设备,这使得很多普通研究者对训练这样的模型望而却步。不过,也有一些研究轻量的预训练方法,也受到了很多关注,例如ALBERT\cite{lan2019albert}
\vspace{0.5em} \vspace{0.5em}
\end{itemize} \end{itemize}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论