Commit d6accf60 by 曹润柘

合并分支 'caorunzhe' 到 'master'

Caorunzhe

查看合并请求 !1059
parents 1578d0e9 0714800c
......@@ -170,11 +170,11 @@
\begin{scope}
{
% forget gate formula
\node[formulanode,anchor=south east,text width=10em] () at ([shift={(4\base,1.5\base)}]aux51) {遗忘门\\$\mathbi{f}_t=\sigma(\mathbi{W}_f[\mathbi{h}_{t-1},\mathbi{x}_t]+\mathbi{b}_f)$};
\node[formulanode,anchor=south east,text width=10em] () at ([shift={(4\base,1.5\base)}]aux51) {遗忘门\\$\mathbi{f}_t=\sigma([\mathbi{h}_{t-1},\mathbi{x}_t] \mathbi{W}_f +\mathbi{b}_f)$};
}
{
% input gate formula
\node[formulanode,anchor=north east,text width=10em] () at ([shift={(4\base,-1.5\base)}]aux21) {输入门\\$\mathbi{i}_t=\sigma(\mathbi{W}_i[\mathbi{h}_{t-1},\mathbi{x}_t]+\mathbi{b}_i)$\\$\hat{\mathbi{c}}_t=\mathrm{Tanh}(\mathbi{W}_c[\mathbi{h}_{t-1},\mathbi{x}_t]+\mathbi{b}_c)$};
\node[formulanode,anchor=north east,text width=10em] () at ([shift={(4\base,-1.5\base)}]aux21) {输入门\\$\mathbi{i}_t=\sigma([\mathbi{h}_{t-1},\mathbi{x}_t] \mathbi{W}_i +\mathbi{b}_i)$\\$\hat{\mathbi{c}}_t=\mathrm{Tanh}([\mathbi{h}_{t-1},\mathbi{x}_t] \mathbi{W}_c +\mathbi{b}_c)$};
}
{
% cell update formula
......@@ -182,7 +182,7 @@
}
{
% output gate formula
\node[formulanode,anchor=north west,text width=10em] () at ([shift={(-4\base,-1.5\base)}]aux29) {输出门\\$\mathbi{o}_t=\sigma(\mathbi{W}_o[\mathbi{h}_{t-1},\mathbi{x}_t]+\mathbi{b}_o)$\\$\mathbi{h}_{t}=\mathbi{o}_t\cdot \mathrm{Tanh}(\mathbi{c}_{t})$};
\node[formulanode,anchor=north west,text width=10em] () at ([shift={(-4\base,-1.5\base)}]aux29) {输出门\\$\mathbi{o}_t=\sigma([\mathbi{h}_{t-1},\mathbi{x}_t] \mathbi{W}_o +\mathbi{b}_o)$\\$\mathbi{h}_{t}=\mathbi{o}_t\cdot \mathrm{Tanh}(\mathbi{c}_{t})$};
}
\end{scope}
\end{tikzpicture}
......
......@@ -530,7 +530,7 @@ $\funp{P}({y_j | \mathbi{s}_{j-1} ,y_{j-1},\mathbi{C}})$由Softmax实现,Softm
\vspace{0.5em}
\item {\small\bfnew{遗忘}}\index{遗忘}。顾名思义,遗忘的目的是忘记一些历史,在LSTM中通过遗忘门实现,其结构如图\ref{fig:10-11}(a)所示。$\mathbi{x}_{t}$表示时刻$t$的输入向量,$\mathbi{h}_{t-1}$是时刻$t-1$的循环单元的输出,$\mathbi{x}_{t}$$\mathbi{h}_{t-1}$都作为$t$时刻循环单元的输入。$\sigma$将对$\mathbi{x}_{t}$$\mathbi{h}_{t-1}$进行筛选,以决定遗忘的信息,其计算如下:
\begin{eqnarray}
\mathbi{f}_t &=& \sigma(\mathbi{W}_f [\mathbi{h}_{t-1},\mathbi{x}_{t}] + \mathbi{b}_f )
\mathbi{f}_t &=& \sigma([\mathbi{h}_{t-1},\mathbi{x}_{t}] \mathbi{W}_f + \mathbi{b}_f )
\label{eq:10-6}
\end{eqnarray}
......@@ -538,8 +538,8 @@ $\funp{P}({y_j | \mathbi{s}_{j-1} ,y_{j-1},\mathbi{C}})$由Softmax实现,Softm
\vspace{0.5em}
\item {\small\bfnew{记忆更新}}\index{记忆更新}。首先,要生成当前时刻需要新增加的信息,该部分由输入门完成,其结构如图\ref{fig:10-11}(b)红色线部分,图中“$\bigotimes$”表示进行点乘操作。输入门的计算分为两部分,首先利用$\sigma$决定门控参数$\mathbi{i}_t$,如公式\eqref{eq:10-7},然后通过Tanh函数得到新的信息$\hat{\mathbi{c}}_t$,如公式\eqref{eq:10-8}
\begin{eqnarray}
\mathbi{i}_t & = & \sigma (\mathbi{W}_i [\mathbi{h}_{t-1},\mathbi{x}_{t}] + \mathbi{b}_i ) \label{eq:10-7} \\
\hat{\mathbi{c}}_t & = & \textrm{Tanh} (\mathbi{W}_c [\mathbi{h}_{t-1},\mathbi{x}_{t}] + \mathbi{b}_c ) \label{eq:10-8}
\mathbi{i}_t & = & \sigma ([\mathbi{h}_{t-1},\mathbi{x}_{t}] \mathbi{W}_i + \mathbi{b}_i ) \label{eq:10-7} \\
\hat{\mathbi{c}}_t & = & \textrm{Tanh} ([\mathbi{h}_{t-1},\mathbi{x}_{t}] \mathbi{W}_c + \mathbi{b}_c ) \label{eq:10-8}
\end{eqnarray}
之后,用$\mathbi{i}_t$点乘$\hat{\mathbi{c}}_t$,得到当前需要记忆的信息,记为$\mathbi{i}_t \cdot \hat{\mathbi{c}}_t$。接下来需要更新旧的信息$\mathbi{c}_{t-1}$,得到新的记忆信息$\mathbi{c}_t$,更新的操作如图\ref{fig:10-11}(c)红色线部分所示,“$\bigoplus$”表示相加。具体规则是通过遗忘门选择忘记一部分上文信息$\mathbi{f}_t$,通过输入门计算新增的信息$\mathbi{i}_t \cdot \hat{\mathbi{c}}_t$,然后根据“$\bigotimes$”门与“$\bigoplus$”门进行相应的乘法和加法计算,如公式\eqref{eq:10-9}
......@@ -550,7 +550,7 @@ $\funp{P}({y_j | \mathbi{s}_{j-1} ,y_{j-1},\mathbi{C}})$由Softmax实现,Softm
\vspace{-1.0em}
\item {\small\bfnew{输出}}\index{输出}。该部分使用输出门计算最终的输出信息$\mathbi{h}_t$,其结构如图\ref{fig:10-11}(d)红色线部分所示。在输出门中,首先将$\mathbi{x}_t$$\mathbi{h}_{t-1}$通过$\sigma$函数变换得到$\mathbi{o}_t$,如公式\eqref{eq:10-10}。其次,将上一步得到的新记忆信息$\mathbi{c}_t$通过Tanh函数进行变换,得到值在[-1,1]范围的向量。最后将这两部分进行点乘,具体如公式\eqref{eq:10-11}
\begin{eqnarray}
\mathbi{o}_t & = & \sigma (\mathbi{W}_o [\mathbi{h}_{t-1},\mathbi{x}_{t}] + \mathbi{b}_o ) \label{eq:10-10} \\
\mathbi{o}_t & = & \sigma ([\mathbi{h}_{t-1},\mathbi{x}_{t}] \mathbi{W}_o + \mathbi{b}_o ) \label{eq:10-10} \\
\mathbi{h}_t & = & \mathbi{o}_t \cdot \textrm{Tanh} (\mathbi{c}_t) \label{eq:10-11}
\end{eqnarray}
\vspace{0.5em}
......@@ -589,19 +589,19 @@ $\funp{P}({y_j | \mathbi{s}_{j-1} ,y_{j-1},\mathbi{C}})$由Softmax实现,Softm
\parinterval GRU的输入和RNN是一样的,由输入$\mathbi{x}_t$$t-1$时刻的状态$\mathbi{h}_{t-1}$组成。GRU只有两个门信号,分别是重置门和更新门。重置门$\mathbi{r}_t$用来控制前一时刻隐藏状态的记忆程度,其结构如图\ref{fig:10-13}(a),其计算如公式\eqref{eq:10-12}。更新门用来更新记忆,使用一个门同时完成遗忘和记忆两种操作,其结构如图\ref{fig:10-13}(b),其计算如公式\eqref{eq:10-13}
\begin{eqnarray}
\mathbi{r}_t & = &\sigma (\mathbi{W}_r [\mathbi{h}_{t-1},\mathbi{x}_{t}] ) \label{eq:10-12} \\
\mathbi{u}_t & = & \sigma (\mathbi{W}_u [\mathbi{h}_{t-1},\mathbi{x}_{t}]) \label{eq:10-13}
\mathbi{r}_t & = &\sigma ([\mathbi{h}_{t-1},\mathbi{x}_{t}] \mathbi{W}_r ) \label{eq:10-12} \\
\mathbi{u}_t & = & \sigma ([\mathbi{h}_{t-1},\mathbi{x}_{t}] \mathbi{W}_u ) \label{eq:10-13}
\end{eqnarray}
\parinterval 当完成了重置门和更新门计算后,就需要更新当前隐藏状态,如图\ref{fig:10-13}(c)所示。在计算得到了重置门的权重$\mathbi{r}_t$后,使用其对前一时刻的状态$\mathbi{h}_{t-1}$进行重置($\mathbi{r}_t \cdot \mathbi{h}_{t-1}$),将重置后的结果与$\mathbi{x}_t$拼接,通过Tanh激活函数将数据变换到[-1,1]范围内,具体计算为:
\begin{eqnarray}
\hat{\mathbi{h}}_t &=& \textrm{Tanh} (\mathbi{W}_h [\mathbi{r}_t \cdot \mathbi{h}_{t-1},\mathbi{x}_{t}])
\hat{\mathbi{h}}_t &=& \textrm{Tanh} ([\mathbi{r}_t \cdot \mathbi{h}_{t-1},\mathbi{x}_{t}] \mathbi{W}_h )
\label{eq:10-14}
\end{eqnarray}
\parinterval $\hat{\mathbi{h}}_t$在包含了输入信息$\mathbi{x}_t$的同时,引入了$\mathbi{h}_{t-1}$的信息,可以理解为,记忆了当前时刻的状态。下一步是计算更新后的隐藏状态也就是更新记忆,如下:
\begin{eqnarray}
\mathbi{h}_t &=& (1-\mathbi{u}_t) \cdot \mathbi{h}_{t-1} +\mathbi{u}_t \cdot \hat{\mathbi{h}}_t
\mathbi{h}_t &=& \mathbi{h}_{t-1} \cdot (1-\mathbi{u}_t) + \hat{\mathbi{h}}_t \cdot \mathbi{u}_t
\label{eq:10-15}
\end{eqnarray}
......@@ -753,7 +753,7 @@ a (\mathbi{s},\mathbi{h}) &=& \left\{ \begin{array}{ll}
\mathbi{s} \mathbi{h}^{\textrm{T}} & \textrm{向量乘} \\
\textrm{cos}(\mathbi{s}, \mathbi{h}) & \textrm{向量夹角} \\
\mathbi{s} \mathbi{W} \mathbi{h}^{\textrm{T}} & \textrm{线性模型} \\
\textrm{Tanh}(\mathbi{W}[\mathbi{s},\mathbi{h}])\mathbi{v}^{\textrm{T}} & \textrm{拼接}[\mathbi{s},\mathbi{h}]+\textrm{单层网络}
\textrm{Tanh}([\mathbi{s},\mathbi{h}] \mathbi{W})\mathbi{v}^{\textrm{T}} & \textrm{拼接}[\mathbi{s},\mathbi{h}]+\textrm{单层网络}
\end{array}
\right.
\label{eq:10-18}
......
......@@ -382,13 +382,13 @@
\parinterval 在ConvS2S模型中,解码器同样采用堆叠的多层门控卷积网络来对目标语言进行序列建模。区别于编码器,解码器在每一层卷积网络之后引入了注意力机制,用来参考源语言信息。ConvS2S选用了点乘注意力,并且通过类似残差连接的方式将注意力操作的输入与输出同时作用于下一层计算,称为多步注意力。其具体计算方式如下:
\begin{eqnarray}
\alpha_{ij}^l &=& \frac{ \textrm{exp} (\mathbi{d}_{j}^l\mathbi{h}_i) }{\sum_{i^{'}=1}^m \textrm{exp} (\mathbi{d}_{j}^l\mathbi{h}_{i^{'}})}
\alpha_{ij}^l &=& \frac{ \textrm{exp} (\mathbi{h}_i \mathbi{d}_{j}^l) }{\sum_{i^{'}=1}^m \textrm{exp} (\mathbi{h}_{i^{'}} \mathbi{d}_{j}^l )}
\label{eq:11-10}
\end{eqnarray}
\noindent 不同于公式\eqref{eq:11-9}中使用的目标语言端隐藏层表示$\mathbi{s}_{j-1}$,公式\eqref{eq:11-10}中的$\mathbi{d}_{j}^l$同时结合了$\mathbi{s}_{j}$的卷积计算结果和目标语言端的词嵌入$\mathbi{g}_j$,其具体计算如公式\eqref{eq:11-11}\eqref{eq:11-12}所示:
\begin{eqnarray}
\mathbi{d}_{j}^l &=& \mathbi{W}_{d}^{l} \mathbi{z}_{j}^{l} + \mathbi{b}_{d}^{l} + \mathbi{g}_j \label{eq:11-11} \\
\mathbi{d}_{j}^l &=& \mathbi{z}_{j}^{l} \mathbi{W}_{d}^{l} + \mathbi{b}_{d}^{l} + \mathbi{g}_j \label{eq:11-11} \\
\mathbi{z}_j^l &=& \textrm{Conv}(\mathbi{s}_j^l) \label{eq:11-12}
\end{eqnarray}
......@@ -477,7 +477,7 @@
\parinterval 给定输入序列表示$\seq{x} = \{ \mathbi{x}_1,...,\mathbi{x}_m \}$,其中$m$为序列长度,$\mathbi{x}_i \in \mathbb{R}^{O} $$O$ 即输入序列的通道数。为了获得与输入序列长度相同的卷积输出结果,首先需要进行填充。为了方便描述,这里在输入序列尾部填充 $K-1$ 个元素($K$为卷积核窗口的长度),其对应的卷积结果为$\seq{z} = \{ \mathbi{z}_1,...,\mathbi{z}_m \}$
在标准卷积中,若使用N表示卷积核的个数,也就是标准卷积输出序列的通道数,那么对于第$i$个位置的第$n$个通道$ \mathbi{z}_{i,n}^\textrm{\,std}$,其标准卷积具体计算如下:
\begin{eqnarray}
\mathbi{z}_{i,n}^\textrm{\,std} &=& \sum_{o=1}^{O} \sum_{k=0}^{K-1} \mathbi{W}_{k,o,n}^\textrm{\,std} \mathbi{x}_{i+k,o}
\mathbi{z}_{i,n}^\textrm{\,std} &=& \sum_{o=1}^{O} \sum_{k=0}^{K-1} \mathbi{x}_{i+k,o} \mathbi{W}_{k,o,n}^\textrm{\,std}
\label{eq:11-18}
\end{eqnarray}
......@@ -487,7 +487,7 @@
\parinterval 相应的,深度卷积只考虑不同词之间的依赖性,而不考虑不同通道之间的关系,相当于使用$O$个卷积核逐个通道对不同的词进行卷积操作。因此深度卷积不改变输出的表示维度,输出序列表示的通道数与输入序列一致,其计算如下:
\begin{eqnarray}
\mathbi{z}_{i,o}^\textrm{\,dw} &=& \sum_{k=0}^{K-1} \mathbi{W}_{k,o}^\textrm{\,dw} \mathbi{x}_{i+k,o}
\mathbi{z}_{i,o}^\textrm{\,dw} &=& \sum_{k=0}^{K-1} \mathbi{x}_{i+k,o} \mathbi{W}_{k,o}^\textrm{\,dw}
\label{eq:11-19}
\end{eqnarray}
......@@ -548,7 +548,7 @@
\parinterval 此外,和标准卷积不同的是,轻量卷积之前需要先对卷积参数进行归一化,具体计算过程为:
\begin{eqnarray}
\mathbi{z}_{i,o}^\textrm{\,lw} &=& \sum_{k=0}^{K-1} \textrm{Softmax}(\mathbi{W}^\textrm{\,lw})_{k,[\frac{oa}{d}]} \mathbi{x}_{i+k,o}
\mathbi{z}_{i,o}^\textrm{\,lw} &=& \sum_{k=0}^{K-1} \mathbi{x}_{i+k,o} \textrm{Softmax}(\mathbi{W}^\textrm{\,lw})_{k,[\frac{oa}{d}]}
\label{eq:11-21}
\end{eqnarray}
......@@ -563,7 +563,7 @@
\parinterval 在轻量卷积中,模型使用的卷积参数是静态的,与序列位置无关, 维度大小为$K\times a$;而在动态卷积中,为了增强模型的表示能力,卷积参数来自于当前位置输入的变换,具体计算为:
\begin{eqnarray}
\funp{f} (\mathbi{x}_{i}) &=& \sum_{c=1}^d \mathbi{W}_{:,:,c} \odot \mathbi{x}_{i,c}
\funp{f} (\mathbi{x}_{i}) &=& \sum_{c=1}^d \mathbi{x}_{i,c} \odot \mathbi{W}_{:,:,c}
\label{eq:11-22}
\end{eqnarray}
......
......@@ -15,7 +15,7 @@
\node [neuronnode] (neuron_y') at (2.4 * \nodespace,-1.5 * \neuronsep) {\scriptsize{$x_{i}^{l+1}$}};
\node [anchor=north,align=left,font=\scriptsize] (standard) at ([xshift=2em,yshift=-3em]neuron_z.south) {使用Dropout前的\\一层神经网络};
\node [] (standard) at ([xshift=-1em]neuron_z.west) {\scriptsize{$\mathbi{w}_{i}^{l}$}};
\node [] (standard) at ([xshift=-1em]neuron_z.west) {\scriptsize{$w_{i}^{l}$}};
\node [] (standard) at ([xshift=0.6em,yshift=0.3em]neuron_z.east) {\scriptsize{$f$}};
\draw [->,line width=0.3mm] (neuron_b.east) -- (neuron_z.130);
......@@ -41,7 +41,7 @@
\node [neuronnode] (drop_neuron_r1) at (4.4*\nodespace,-2.5*\neuronsep) {\scriptsize{$r_{1}^{l}$}};
\node [anchor=north,align=left,font=\scriptsize] (standard) at ([xshift=2em,yshift=-3em]drop_neuron_z.south) {使用Dropout后的\\一层神经网络};
\node [] (standard) at ([xshift=-1em]drop_neuron_z.west) {\scriptsize{$\mathbi{w}_{i}^{l}$}};
\node [] (standard) at ([xshift=-1em]drop_neuron_z.west) {\scriptsize{$w_{i}^{l}$}};
\node [] (standard) at ([xshift=0.6em,yshift=0.3em]drop_neuron_z.east) {\scriptsize{$f$}};
%structure
\draw [->,line width=0.3mm] (drop_neuron_b.east) -- (drop_neuron_z.130);
......@@ -64,7 +64,7 @@
\node [anchor=north west,inner sep = 2pt] (line3) at (line2.south west) {$x_{i}^{l+1}=f\left(z_{i}^{l+1}\right)$};
\node [anchor=north west,inner sep = 2pt] (line4) at (line3.south west) {应用Dropout:};
\node [anchor=north west,inner sep = 2pt] (line5) at (line4.south west) {$r_{i}^{l} \sim$ Bernoulli $(1-p)$};
\node [anchor=north west,inner sep = 2pt] (line6) at (line5.south west) {$\tilde{\mathbi{x}}=\mathbi{r} * \mathbi{x}$};
\node [anchor=north west,inner sep = 2pt] (line6) at (line5.south west) {$\tilde{\mathbi{x}}=\mathbi{r} \mathbi{x}$};
\node [anchor=north west,inner sep = 2pt] (line7) at (line6.south west) {$z_{i}^{l+1}=\mathbi{w}^{l} \widetilde{\mathbi{x}}^{l} + b^{l}$};
\node [anchor=north west,inner sep = 2pt] (line8) at (line7.south west) {$x_{i}^{l+1}=f\left(z_{i}^{l+1}\right)$};
......
......@@ -23,11 +23,11 @@
\node[attnnode,anchor=south] (attn11) at ([yshift=0.1\hnode]layer11.south) {};
\node[anchor=north west,inner sep=4pt,font=\small] () at (attn11.north west) {注意力};
\node[anchor=south,inner sep=0pt] (out11) at ([yshift=0.3\hseg]attn11.north) {$\cdots$};
\node[thinnode,anchor=south west,thick,draw=dblue,text=black] (q11) at ([xshift=0.1\wseg,yshift=0.2\hseg]attn11.south west) {$Q^n$};
\node[thinnode,anchor=south,thick,draw=orange,text=black] (k11) at ([yshift=0.2\hseg]attn11.south) {$K^n$};
\node[thinnode,anchor=south east,thick,draw=purple,text=black] (v11) at ([xshift=-0.1\wseg,yshift=0.2\hseg]attn11.south east) {$V^n$};
\node[fatnode,anchor=south,thick,draw] (s11) at ([xshift=0.5\wseg,yshift=0.8\hseg]q11.north east) {$S^n\!=\!S(Q^n\!\cdot\!K^n)$};
\node[fatnode,anchor=south,thick,draw] (a11) at ([xshift=0.45\wseg,yshift=1.3\hseg+0.6\hnode]k11.north east) {$A^n\!=\!S^n\!\cdot\!V$};
\node[thinnode,anchor=south west,thick,draw=dblue,text=black] (q11) at ([xshift=0.1\wseg,yshift=0.2\hseg]attn11.south west) {${\mathbi Q}^n$};
\node[thinnode,anchor=south,thick,draw=orange,text=black] (k11) at ([yshift=0.2\hseg]attn11.south) {${\mathbi K}^n$};
\node[thinnode,anchor=south east,thick,draw=purple,text=black] (v11) at ([xshift=-0.1\wseg,yshift=0.2\hseg]attn11.south east) {${\mathbi V}^n$};
\node[fatnode,anchor=south,thick,draw] (s11) at ([xshift=0.5\wseg,yshift=0.8\hseg]q11.north east) {${\mathbi S}^n\!=\!{\mathbi S}({\mathbi Q}^n\!\cdot\!{\mathbi K}^n)$};
\node[fatnode,anchor=south,thick,draw] (a11) at ([xshift=0.45\wseg,yshift=1.3\hseg+0.6\hnode]k11.north east) {${\mathbi A}^n\!=\!{\mathbi S}^n\!\cdot\!{\mathbi V}$};
\begin{scope}[fill=black!100]
\draw[-latex',thick,draw=black!100] (q11.north) .. controls +(north:0.5\hseg) and +(south:0.8\hseg) .. (s11.south);
\draw[-latex',thick,draw=black!100] (k11.north) .. controls +(north:0.5\hseg) and +(south:0.8\hseg) .. (s11.south);
......@@ -43,11 +43,11 @@
\node[attnnode,anchor=south] (attn12) at ([yshift=0.1\hnode]layer12.south) {};
\node[anchor=north west,inner sep=4pt,font=\small] () at (attn12.north west) {注意力};
\node[anchor=south,inner sep=0pt] (out12) at ([yshift=0.3\hseg]attn12.north) {$\cdots$};
\node[thinnode,anchor=south west,thick,draw=dblue!40,text=black!40] (q12) at ([xshift=0.1\wseg,yshift=0.2\hseg]attn12.south west) {$Q^n$};
\node[thinnode,anchor=south,thick,draw=orange!40,text=black!40] (k12) at ([yshift=0.2\hseg]attn12.south) {$K^n$};
\node[thinnode,anchor=south east,thick,draw=purple,text=black] (v12) at ([xshift=-0.1\wseg,yshift=0.2\hseg]attn12.south east) {$V^n$};
\node[fatnode,anchor=south,thick,densely dashed,draw] (s12) at ([xshift=0.5\wseg,yshift=0.8\hseg]q12.north east) {$S^n\!=\!S^m$};
\node[fatnode,anchor=south,thick,draw] (a12) at ([xshift=0.45\wseg,yshift=1.3\hseg+0.6\hnode]k12.north east) {$A^n\!=\!S^n\!\cdot\!V$};
\node[thinnode,anchor=south west,thick,draw=dblue!40,text=black!40] (q12) at ([xshift=0.1\wseg,yshift=0.2\hseg]attn12.south west) {${\mathbi Q}^n$};
\node[thinnode,anchor=south,thick,draw=orange!40,text=black!40] (k12) at ([yshift=0.2\hseg]attn12.south) {${\mathbi K}^n$};
\node[thinnode,anchor=south east,thick,draw=purple,text=black] (v12) at ([xshift=-0.1\wseg,yshift=0.2\hseg]attn12.south east) {${\mathbi V}^n$};
\node[fatnode,anchor=south,thick,densely dashed,draw] (s12) at ([xshift=0.5\wseg,yshift=0.8\hseg]q12.north east) {${\mathbi S}^n\!=\!{\mathbi S}^m$};
\node[fatnode,anchor=south,thick,draw] (a12) at ([xshift=0.45\wseg,yshift=1.3\hseg+0.6\hnode]k12.north east) {${\mathbi A}^n\!=\!{\mathbi S}^n\!\cdot\!{\mathbi V}$};
\begin{scope}[fill=black!40]
\draw[-latex',thick,draw=black!40] (q12.north) .. controls +(north:0.5\hseg) and +(south:0.8\hseg) .. (s12.south);
\draw[-latex',thick,draw=black!40] (k12.north) .. controls +(north:0.5\hseg) and +(south:0.8\hseg) .. (s12.south);
......@@ -63,11 +63,11 @@
\node[attnnode,anchor=south] (attn13) at ([yshift=0.1\hnode]layer13.south) {};
\node[anchor=north west,inner sep=4pt,font=\small] () at (attn13.north west) {注意力};
\node[anchor=south,inner sep=0pt] (out13) at ([yshift=0.3\hseg]attn13.north) {$\cdots$};
\node[thinnode,anchor=south west,thick,draw=dblue!40,text=black!40] (q13) at ([xshift=0.1\wseg,yshift=0.2\hseg]attn13.south west) {$Q^n$};
\node[thinnode,anchor=south,thick,draw=orange!40,text=black!40] (k13) at ([yshift=0.2\hseg]attn13.south) {$K^n$};
\node[thinnode,anchor=south east,thick,draw=purple!40,text=black!40] (v13) at ([xshift=-0.1\wseg,yshift=0.2\hseg]attn13.south east) {$V^n$};
\node[fatnode,anchor=south,thick,draw=black!40,text=black!40] (s13) at ([xshift=0.5\wseg,yshift=0.8\hseg]q13.north east) {$S^n$};
\node[fatnode,anchor=south,thick,densely dashed,draw] (a13) at ([xshift=0.45\wseg,yshift=1.3\hseg+0.6\hnode]k13.north east) {$A^n\!=\!A^m$};
\node[thinnode,anchor=south west,thick,draw=dblue!40,text=black!40] (q13) at ([xshift=0.1\wseg,yshift=0.2\hseg]attn13.south west) {${\mathbi Q}^n$};
\node[thinnode,anchor=south,thick,draw=orange!40,text=black!40] (k13) at ([yshift=0.2\hseg]attn13.south) {${\mathbi K}^n$};
\node[thinnode,anchor=south east,thick,draw=purple!40,text=black!40] (v13) at ([xshift=-0.1\wseg,yshift=0.2\hseg]attn13.south east) {${\mathbi V}^n$};
\node[fatnode,anchor=south,thick,draw=black!40,text=black!40] (s13) at ([xshift=0.5\wseg,yshift=0.8\hseg]q13.north east) {${\mathbi S}^n$};
\node[fatnode,anchor=south,thick,densely dashed,draw] (a13) at ([xshift=0.45\wseg,yshift=1.3\hseg+0.6\hnode]k13.north east) {${\mathbi A}^n\!=\!{\mathbi A}^m$};
\begin{scope}[fill=black!40]
\draw[-latex',thick,draw=black!40] (q13.north) .. controls +(north:0.5\hseg) and +(south:0.8\hseg) .. (s13.south);
\draw[-latex',thick,draw=black!40] (k13.north) .. controls +(north:0.5\hseg) and +(south:0.8\hseg) .. (s13.south);
......@@ -87,11 +87,11 @@
\node[anchor=north west,inner sep=4pt,font=\small] () at (attn\i\j.north west) {注意力};
\node[anchor=south,inner sep=0pt] (out\i\j) at ([yshift=0.3\hseg]attn\i\j.north) {$\cdots$};
\node[thinnode,anchor=south west,thick,draw=dblue!\q,text=black] (q\i\j) at ([xshift=0.1\wseg,yshift=0.2\hseg]attn\i\j.south west) {$Q^m$};
\node[thinnode,anchor=south,thick,draw=orange!\q,text=black] (k\i\j) at ([yshift=0.2\hseg]attn\i\j.south) {$K^m$};
\node[thinnode,anchor=south east,thick,draw=purple!\s,text=black] (v\i\j) at ([xshift=-0.1\wseg,yshift=0.2\hseg]attn\i\j.south east) {$V^m$};
\node[fatnode,anchor=south,thick,draw=black!\s] (s\i\j) at ([xshift=0.45\wseg,yshift=0.8\hseg]q\i\j.north east) {$S^m\!=\!S(Q^m\!\cdot\!K^m)$};
\node[fatnode,anchor=south,thick,draw=black!80] (a\i\j) at ([xshift=0.45\wseg,yshift=1.3\hseg+0.6\hnode]k\i\j.north east) {$A^m\!=\!S^m\!\cdot\!V$};
\node[thinnode,anchor=south west,thick,draw=dblue!\q,text=black] (q\i\j) at ([xshift=0.1\wseg,yshift=0.2\hseg]attn\i\j.south west) {${\mathbi Q}^m$};
\node[thinnode,anchor=south,thick,draw=orange!\q,text=black] (k\i\j) at ([yshift=0.2\hseg]attn\i\j.south) {${\mathbi K}^m$};
\node[thinnode,anchor=south east,thick,draw=purple!\s,text=black] (v\i\j) at ([xshift=-0.1\wseg,yshift=0.2\hseg]attn\i\j.south east) {${\mathbi V}^m$};
\node[fatnode,anchor=south,thick,draw=black!\s] (s\i\j) at ([xshift=0.45\wseg,yshift=0.8\hseg]q\i\j.north east) {${\mathbi S}^m\!=\!{\mathbi S}({\mathbi Q}^m\!\cdot\!{\mathbi K}^m)$};
\node[fatnode,anchor=south,thick,draw=black!80] (a\i\j) at ([xshift=0.45\wseg,yshift=1.3\hseg+0.6\hnode]k\i\j.north east) {${\mathbi A}^m\!=\!{\mathbi S}^m\!\cdot\!{\mathbi V}$};
\begin{scope}[fill=black!\q]
\draw[-latex',thick,draw=black!\t] (q\i\j.north) .. controls +(north:0.5\hseg) and +(south:0.8\hseg) .. (s\i\j.south);
\draw[-latex',thick,draw=black!\t] (k\i\j.north) .. controls +(north:0.5\hseg) and +(south:0.8\hseg) .. (s\i\j.south);
......
......@@ -31,7 +31,7 @@
\vspace{0.5em}
\item 神经机器翻译的基本问题,如推断方向、译文长度控制等。
\vspace{0.5em}
\item 神经机器翻译的推断加速方法,如轻量模型、非自回归模型等。
\item 神经机器翻译的推断加速方法,如轻量模型、非自回归翻译模型等。
\vspace{0.5em}
\item 多模型集成推断。
\vspace{0.5em}
......@@ -61,25 +61,25 @@
\begin{itemize}
\vspace{0.5em}
\item {\small\sffamily\bfseries{预测模块}},它根据已经生成的部分译文和源语言信息,预测下一个要生成的译文单词的概率分布\footnote{在统计机器翻译中,翻译的每一步也可以同时预测若干个连续的单词,即短语。在神经机器翻译中也有类似于生成短语的方
\item {\small\sffamily\bfseries{预测模块}},它根据已经生成的部分译文和源语言信息,预测下一个要生成的译文单词的概率分布\footnote{在统计机器翻译中,也可以同时预测若干个连续的单词,即短语。在神经机器翻译中也有类似于生成短语的方
法,但是主流的方法还是按单词为单位进行生成。}。因此预测模块实际上就是一个模型打分装置;
\vspace{0.5em}
\item {\small\sffamily\bfseries{搜索模块}},它会利用预测结果,对当前的翻译假设进行打分,并根据模型得分对翻译假设进行排序和剪枝。
\vspace{0.5em}
\end{itemize}
\parinterval 预测模块是由模型决定的,而搜索模块可以与模型无关。也就是说,不同的模型可以共享同一个搜索模块完成推断。比如,对于基于循环神经网络的模型,预测模块需要读入前一个状态的信息和前一个位置的译文单词,然后预测当前位置单词的概率分布;对于Transformer,预测模块需要对前面的所有位置做注意力运算,之后预测当前位置单词的概率分布。不过,这两个模型都可以使用同一个搜索模块。图\ref{fig:14-1}给出了这种架构的示意图。
\parinterval 预测模块是由模型决定的,而搜索模块可以与模型无关。也就是说,不同的模型可以共享同一个搜索模块完成推断。比如,对于基于循环神经网络的模型,预测模块需要读入前一个状态的信息和前一个位置的译文单词,然后预测当前位置单词的概率分布;对于Transformer,预测模块需要对前面的所有位置做注意力运算,之后预测当前位置单词的概率分布。不过,这两个模型都可以使用同一个搜索模块。图\ref{fig:14-1}给出了神经机器翻译推断系统的结构示意图。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter14/Figures/figure-main-module}
\caption{神经机器翻译推断系统结构}
\caption{神经机器翻译推断系统结构}
\label{fig:14-1}
\end{figure}
%----------------------------------------------
\parinterval 这是一个非常通用的框架,同样适用于统计机器翻译模型。因此,神经机器翻译推断中的很多问题与统计机器翻译是一致的,比如:束搜索的宽度、解码终止条件等等。
\parinterval 这是一个非常通用的结构框架,同样适用于统计机器翻译模型。因此,神经机器翻译推断中的很多问题与统计机器翻译是一致的,比如:束搜索的宽度、解码终止条件等等。
\parinterval 一般来说,设计机器翻译推断系统需要考虑三个因素:搜索的准确性、搜索的时延、搜索所需要的存储。通常,准确性是研究人员最关心的问题,比如可以通过增大搜索空间来找到模型得分更高的结果。而搜索的时延和存储消耗是实践中必须要考虑的问题,比如可以设计更小的模型和更高效的推断方法来提高系统的可用性。
......@@ -89,7 +89,7 @@
\vspace{0.5em}
\item 搜索的基本问题在神经机器翻译中有着特殊的现象。比如,在统计机器翻译中,减少搜索错误是提升翻译品质的一种手段。但是神经机器翻译中,简单的减少搜索错误可能无法带来性能的提升,甚至会造成翻译品质的下降\upcite{li-etal-2018-simple,Stahlberg2019OnNS}
\vspace{0.5em}
\item 搜索的时延很高,系统实际部署的成本很高。与统计机器翻译系统不同的是,神经机器翻译依赖大量的浮点运算。这导致神经机器翻译系统的推断会比统计机器翻译系统慢很多。虽然可以使用GPU来提高神经机器翻译的推断速度,但是也大大增加了成本;
\item 搜索的时延很高,系统实际部署的成本很高。与统计机器翻译系统不同的是,神经机器翻译系统依赖大量的浮点运算。这导致神经机器翻译系统的推断会比统计机器翻译系统慢很多。虽然可以使用GPU来提高神经机器翻译的推断速度,但是也大大增加了成本;
\vspace{0.5em}
\item 神经机器翻译在优化过程中容易陷入局部最优,单模型的表现并不稳定。由于神经机器翻译优化的目标函数非常不光滑,每次训练得到的模型往往只是一个局部最优解。在新数据上使用这个局部最优模型进行推断时,模型的表现可能不稳定。
\vspace{0.5em}
......@@ -146,11 +146,11 @@
\subsection{译文长度控制}
\parinterval 机器翻译推断的一个特点是译文长度需要额外的机制进行控制\upcite{Kikuchi2016ControllingOL,Takase2019PositionalET,Murray2018CorrectingLB,Sountsov2016LengthBI}。这是因为机器翻译在建模时仅考虑了将训练样本(即标准答案)上的损失最小化,但是推断的时候会看到从未见过的样本,而且这些未见样本占据了样本空间的绝大多数。该问题会导致的一个现象是:直接使用训练好的模型会翻译出长度短得离谱的译文。神经机器翻译模型使用单词概率的乘积表示整个句子的翻译概率,它天然就倾向生成短译文,因为概率为大于0小于1的常数,短译文会使用更少的概率因式相乘,倾向于得到更高的句子得分,而模型只关心每个目标语言位置是否被正确预测,对于译文长度没有考虑。统计机器翻译模型中也存在译文长度不合理的问题,解决该问题的常见策略是在推断过程中引入译文长度控制机制\upcite{Koehn2007Moses}。神经机器翻译也借用了类似的思想来控制译文长度,有以下几种方法:
\parinterval 机器翻译推断的一个特点是译文长度需要额外的机制进行控制\upcite{Kikuchi2016ControllingOL,Takase2019PositionalET,Murray2018CorrectingLB,Sountsov2016LengthBI}。这是因为机器翻译在建模时仅考虑了将训练样本(即标准答案)上的损失最小化,但是推断的时候会看到从未见过的样本,甚至样本空间中的绝大多数都是未见样本。该问题会导致的一个现象是:直接使用训练好的模型会翻译出长度短得离谱的译文。神经机器翻译模型使用单词概率的乘积表示整个句子的翻译概率,它天然就倾向生成短译文,因为概率为大于0小于1的常数,短译文会使用更少的概率因式相乘,倾向于得到更高的句子得分,而模型只关心每个目标语言位置是否被正确预测,对于译文长度没有考虑。统计机器翻译模型中也存在译文长度不合理的问题,解决该问题的常见策略是在推断过程中引入译文长度控制机制\upcite{Koehn2007Moses}。神经机器翻译也借用了类似的思想来控制译文长度,有以下几种方法:
\begin{itemize}
\vspace{0.5em}
\item {\small\sffamily\bfseries{长度惩罚因子}}。用译文长度来归一化翻译概率是最常用的方法:对于源语言句子$\seq{x}$和译文句子$\seq{y}$,模型得分$\textrm{score}(\seq{x},\seq{y})$的值会随着译文$\seq{y}$ 的长度增大而减小。为了避免此现象,可以引入一个长度惩罚函数$\textrm{lp}(\seq{y})$,并定义模型得分如公式\eqref{eq:14-12}所示:
\item {\small\sffamily\bfseries{长度惩罚因子}}。用译文长度来归一化翻译概率是最常用的方法:对于源语言句子$\seq{x}$和译文句子$\seq{y}$,模型得分$\textrm{score}(\seq{x},\seq{y})$的值会随着译文$\seq{y}$ 的长度增大而减小。为了避免此现象,可以引入一个长度惩罚因子$\textrm{lp}(\seq{y})$,并定义模型得分如公式\eqref{eq:14-12}所示:
\begin{eqnarray}
\textrm{score}(\seq{x},\seq{y}) &=& \frac{\log \funp{P}(\seq{y}\vert\seq{x})}{\textrm{lp}(\seq{y})}
\label{eq:14-12}
......@@ -189,7 +189,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\label{eq:14-6}
\end{eqnarray}
\noindent 其中,$\textrm{cp}(\seq{x},\seq{y}) $表示覆盖度模型,它度量了译文对源语言每个单词的覆盖程度。$\textrm{cp}(\seq{x},\seq{y}) $的定义中,$\beta$是一需要自行设置的超参数,$a_{ij}$表示源语言第$i$个位置与译文 第$j$个位置的注意力权重,这样$\sum \limits_{j}^{|\seq{y}|} a_{ij}$就可以用来衡量源语言第$i$个单词中的信息被翻译的程度,如果它大于1,表明翻译多了;如果小于1,表明翻译少了。公式\eqref{eq:14-6}会惩罚那些欠翻译的翻译假设。对覆盖度模型的一种改进形式是\upcite{li-etal-2018-simple}
\noindent 其中,$\textrm{cp}(\seq{x},\seq{y}) $表示覆盖度模型,它度量了译文对源语言每个单词的覆盖程度。$\textrm{cp}(\seq{x},\seq{y}) $的定义中,$\beta$是一需要自行设置的超参数,$a_{ij}$表示源语言第$i$个位置与译文 第$j$个位置的注意力权重,这样$\sum \limits_{j}^{|\seq{y}|} a_{ij}$就可以用来衡量源语言第$i$个单词中的信息被翻译的程度,如果它大于1,则表明出现了过翻译问题;如果小于1,则表明出现了欠翻译问题。公式\eqref{eq:14-6}会惩罚那些欠翻译的翻译假设。对覆盖度模型的一种改进形式是\upcite{li-etal-2018-simple}
\begin{eqnarray}
\textrm{cp}(\seq{x},\seq{y}) &=& \sum_{i=1}^{|\seq{x}|} \log( \textrm{max} ( \sum_{j}^{|\seq{y}|} a_{ij},\beta))
\label{eq:14-7}
......@@ -219,7 +219,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{译文多样性}
\parinterval 机器翻译系统的输出并不仅限于单个译文。很多情况下,需要多个译文。比如,译文重排序中通常就需要系统的$n$-best输出,在交互式机器翻译中也往往需要提供多个译文供用户选择\upcite{Peris2017InteractiveNM,Peris2018ActiveLF}。但是,无论是统计机器翻译还是神经机器翻译,都面临一个同样的问题:$n$-best输出中的译文十分相似。实例\ref{eg:14-1}就展示了一个神经机器翻译输出的多个翻译结果,可以看到这些译文的区别很小。这个问题也被看做是机器翻译缺乏译文多样性的问题\upcite{Gimpel2013ASE,Li2016MutualIA,DBLP:conf/emnlp/DuanLXZ09,DBLP:conf/acl/XiaoZZW10,xiao2013bagging}
\parinterval 机器翻译系统的输出并不仅限于单个译文。很多情况下,需要多个译文。比如,译文重排序中通常就需要系统的$n$-best输出,在交互式机器翻译中也往往需要提供多个译文供用户选择\upcite{Peris2017InteractiveNM,Peris2018ActiveLF}。但是,无论是统计机器翻译还是神经机器翻译,都面临一个同样的问题:$n$-best输出中的译文十分相似。实例\ref{eg:14-1}就展示了一个神经机器翻译系统输出的多个翻译结果,可以看到这些译文的区别很小。这个问题也被看做是机器翻译缺乏译文多样性的问题\upcite{Gimpel2013ASE,Li2016MutualIA,DBLP:conf/emnlp/DuanLXZ09,DBLP:conf/acl/XiaoZZW10,xiao2013bagging}
\begin{example}
源语言句子:我们/期待/安理会/尽早/就此/作出/决定/ 。
......@@ -251,7 +251,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\parinterval 机器翻译的错误分为两类:搜索错误和模型错误。搜索错误是指由于搜索算法的限制,即使潜在的搜索空间中有更好的解,模型也无法找到。比较典型的例子是,在对搜索结果进行剪枝的时候,如果剪枝过多,找到的结果很有可能不是最优的,这时就出现了搜索错误。而模型错误则是指由于模型学习能力的限制,即使搜索空间中存在最优解,模型也无法将该解排序在前面。
\parinterval 在统计机器翻译中,搜索错误可以通过减少剪枝进行缓解。比较简单的方式是增加搜索束宽度,这往往会带来一定的性能提升\upcite{Xiao2016ALA}。也可以对搜索问题进行单独建模,以保证学习到的模型出现更少的搜索错误\upcite{Liu2014SearchAwareTF,Yu2013MaxViolationPA}。但是,在神经机器翻译中,这个问题却表现出不同的现象:在很多神经机器翻译系统中,随着搜索束的增大,系统的BLEU不升反降。图\ref{fig:14-3}展示了神经机器翻译系统中BLEU随搜索束大小的变化曲线,这里为了使该图更加规整直观,横坐标处将束大小进行了取对数操作。这个现象与传统的常识是相违背的,因此也有一些研究尝试解释这个现象\upcite{Stahlberg2019OnNS,Niehues2017AnalyzingNM}
\parinterval 在统计机器翻译中,搜索错误可以通过减少剪枝进行缓解。比较简单的方式是增加搜索束宽度,这往往会带来一定的性能提升\upcite{Xiao2016ALA}。也可以对搜索问题进行单独建模,以保证学习到的模型出现更少的搜索错误\upcite{Liu2014SearchAwareTF,Yu2013MaxViolationPA}。但是,在神经机器翻译中,这个问题却表现出不同的现象:在很多神经机器翻译系统中,随着搜索束的增大,系统的BLEU值不升反降。图\ref{fig:14-3}展示了神经机器翻译系统中BLEU值随搜索束大小的变化曲线,这里为了使该图更加规整直观,横坐标处对束大小取对数。这个现象与传统的常识是相违背的,因此也有一些研究尝试解释这个现象\upcite{Stahlberg2019OnNS,Niehues2017AnalyzingNM}
%----------------------------------------------------------------------
\begin{figure}[htp]
......@@ -281,7 +281,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\parinterval 神经机器翻译需要对输入和输出的单词进行分布式表示。但是,由于真实的词表通常很大,因此计算并保存这些单词的向量表示会消耗较多的计算和存储资源。特别是对于基于Softmax 的输出层,大词表的计算十分耗时。虽然可以通过BPE 和限制词汇表规模的方法降低输出层计算的负担\upcite{DBLP:conf/acl/SennrichHB16a},但是为了获得可接受的翻译品质,词汇表也不能过小,因此输出层的计算代价仍然很高。
\parinterval 通过改变输出层的结构,可以一定程度上缓解这个问题\upcite{DBLP:conf/acl/JeanCMB15}。一种比较简单的方法是对可能输出的单词进行筛选,即词汇选择。这里,可以利用类似于统计机器翻译的翻译表,获得每个源语言单词最可能的译文。在翻译过程中,利用注意力机制找到每个目标语言位置对应的源语言位置,之后获得这些源语言单词最可能的翻译候选。之后,Softmax 只需要在这个有限的翻译候选单词集合上进行计算,大大降低了输出层的计算量。尤其对于CPU 上的系统,这个方法往往会带来明显的速度提升。图\ref{fig:14-4}对比了标准Softmax与词汇选择方法中的Softmax。
\parinterval 通过改变输出层的结构,可以一定程度上缓解这个问题\upcite{DBLP:conf/acl/JeanCMB15}。一种比较简单的方法是对可能输出的单词进行筛选,即词汇选择。这里,可以利用类似于统计机器翻译的翻译表,获得每个源语言单词最可能的译文。在翻译过程中,利用注意力机制找到每个目标语言位置对应的源语言位置,之后获得这些源语言单词最可能的翻译候选。之后,只需要在这个有限的翻译候选单词集合上进行Softmax计算,此方法大大降低了输出层的计算量。尤其对于CPU 上的系统,这个方法往往会带来明显的速度提升。图\ref{fig:14-4}对比了标准Softmax与词汇选择方法中的Softmax。
%----------------------------------------------
\begin{figure}[htp]
......@@ -302,7 +302,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\parinterval 消除不必要的计算是加速机器翻译系统的另一种方法。比如,在统计机器翻译时代,假设重组就是一种典型的避免冗余计算的手段(见{\chapterseven})。在神经机器翻译中,消除冗余计算的一种简单有效的方法是对解码器的注意力结果进行缓存。以Transformer为例,在生成每个译文时,Transformer 模型会对当前位置之前的所有位置进行自注意力操作,但是这些计算里只有和当前位置相关的计算是“新” 的,前面位置之间的注意力结果已经在之前的解码步骤里计算过,因此可以对其进行缓存。
\parinterval 此外,由于Transformer 模型较为复杂,还存在很多冗余。比如,Transformer 的每一层会包含自注意力机制、层正则化、残差连接、前馈神经网络等多种不同的结构。同时,不同结构之间还会包含一些线性变换。多层Transformer模型会更加复杂。但是,这些层可能在做相似的事情,甚至有些计算根本就是重复的。图\ref{fig:14-5}中展示了解码器自注意力和编码-解码注意力中不同层的注意力权重的相似性,这里的相似性利用Jensen-Shannon散度进行度量\upcite{61115}。可以看到,自注意力中,2-6层之间的注意力权重的分布非常相似。编码-解码注意力也有类似的现象,临近的层之间有非常相似的注意力权重。这个现象说明:在多层神经网络中有些计算是冗余的,因此很自然的想法是消除这些冗余使得机器翻译变得更“轻”。
\parinterval 此外,由于Transformer 模型较为复杂,还存在很多冗余。比如,Transformer 的每一层会包含自注意力机制、层正则化、残差连接、前馈神经网络等多种不同的结构,不同结构之间还会包含一些线性变换。多层Transformer模型会更加复杂。但是,这些层可能在做相似的事情,甚至有些计算根本就是重复的。图\ref{fig:14-5}中展示了解码器自注意力和编码-解码注意力中不同层的注意力权重的相似性,这里的相似性利用Jensen-Shannon散度进行度量\upcite{61115}。可以看到,自注意力中,2-6层之间的注意力权重的分布非常相似。编码-解码注意力也有类似的现象,临近的层之间有非常相似的注意力权重。这个现象说明:在多层神经网络中有些计算是冗余的,因此很自然的想法是消除这些冗余使得机器翻译变得更“轻”。
%----------------------------------------------
\begin{figure}[htp]
......@@ -337,7 +337,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\parinterval 比较简单的做法是把解码器的网络变得更“浅”、更“窄”。所谓浅网络是指使用更少的层构建神经网络,比如,使用3 层,甚至1 层网络的Transformer 解码器。所谓窄网络是指将网络中某些层中神经元的数量减少。不过,直接训练这样的小模型会造成翻译品质下降。这时会考虑使用知识蒸馏等技术来提升小模型的品质(见{\chapterthirteen})。
\parinterval 化简Transformer 解码器的神经网络也可以提高推断速度。比如,可以使用平均注意力机制代替原始Transformer 中的自注意力机制\upcite{DBLP:journals/corr/abs-1805-00631},也可以使用运算更轻的卷积操作代替注意力模块\upcite{Wu2019PayLA}。前面提到的基于共享注意力机制的模型也是一种典型的轻量模型\upcite{Xiao2019SharingAW}。这些方法本质上也是对注意力模型结构的优化,这类思想在近几年也受到了很多关注 \upcite{Kitaev2020ReformerTE,Katharopoulos2020TransformersAR,DBLP:journals/corr/abs-2006-04768},在{\chapterfifteen}也会有进一步讨论。
\parinterval 化简Transformer 解码器的神经网络也可以提高推断速度。比如,可以使用平均注意力机制代替原始Transformer 模型中的自注意力机制\upcite{DBLP:journals/corr/abs-1805-00631},也可以使用运算更轻的卷积操作代替注意力模块\upcite{Wu2019PayLA}。前面提到的基于共享注意力机制的模型也是一种典型的轻量模型\upcite{Xiao2019SharingAW}。这些方法本质上也是对注意力模型结构的优化,这类思想在近几年也受到了很多关注 \upcite{Kitaev2020ReformerTE,Katharopoulos2020TransformersAR,DBLP:journals/corr/abs-2006-04768},在{\chapterfifteen}也会有进一步讨论。
\parinterval 此外,使用异构神经网络也是一种平衡精度和速度的有效方法。在很多研究中发现,基于Transformer 的编码器对翻译品质的影响更大,而解码器的作用会小一些。因此,一种想法是使用速度更快的解码器结构,比如,用基于循环神经网络的解码器代替Transformer模型中基于注意力机制的解码器\upcite{Chen2018TheBO}。这样,既能发挥Transformer 在编码上的优势,同时也能利用循环神经网络在解码器速度上的优势。使用类似的思想,也可以用卷积神经网络等结构进行解码器的设计。
......@@ -376,7 +376,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{低精度运算}
\parinterval 降低运算强度也是计算密集型任务的加速手段之一。标准的神经机器翻译系统大多基于单精度浮点运算。从计算机的硬件发展看,单精度浮点运算还是很“重” 的。当计算能容忍一些精度损失的时候,可以考虑降低运算精度来达到加速的目的。比如:
\parinterval 降低运算强度也是计算密集型任务的加速手段之一。标准的神经机器翻译系统大多基于单精度浮点运算。从计算机的硬件发展看,单精度浮点运算还是很“重” 的。当计算能容忍一些精度损失的时候,可以考虑使用以下方法降低运算精度来达到加速的目的。
\begin{itemize}
\vspace{0.5em}
......@@ -398,7 +398,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\end{tabular}
\label{tab:14-3}
\end{table}
\footnotetext{表中比较了几种通用数据类型的乘法运算速度,不同硬件和架构上不同类型的数据的计算速度略有不同。总体来看整型数据类型和浮点型数据相比具有显著的计算速度优势,INT4相比于FP32数据类型的计算最高能达到8倍的速度提升。}
\footnotetext{表中比较了几种通用数据类型的乘法运算速度,不同硬件和架构上不同类型的数据的计算速度略有不同。总体来看整型数据和浮点型数据相比具有显著的计算速度优势,INT4相比于FP32数据类型的计算最高能达到8倍的速度提升。}
%--------------------------------------
\parinterval 实际上,低精度运算的另一个好处是可以减少模型存储的体积。比如,如果要把机器翻译模型作为软件的一部分打包存储,这时可以考虑用低精度的方式保存模型参数,使用时再恢复成原始精度的参数。值得注意的是,参数的离散化表示(比如整型表示)的一个极端例子是{\small\sffamily\bfseries{二值神经网络}}\index{二值神经网络}(Binarized Neural Networks)\index{Binarized Neural Networks}\upcite{DBLP:conf/nips/HubaraCSEB16},即只用−1和+1 表示神经网络的每个参数\footnote{也存在使用0或1表示神经网络参数的二值神经网络。}。二值化可以被看作是一种极端的量化手段。不过,这类方法还没有在机器翻译中得到大规模验证。
......@@ -409,7 +409,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\sectionnewpage
\section{非自回归翻译}
\parinterval 目前大多数神经机器翻译模型都使用自左向右逐词生成译文的策略,即第$j$个目标语言单词的生成依赖于先前生成的$j-1$ 个词。这种翻译方式也被称作{\small\sffamily\bfseries{自回归解码}}\index{自回归解码}(Autoregressive Decoding)\index{Autoregressive Decoding}。虽然以Transformer为代表的模型使得训练过程高度并行化,加快了训练速度。但由于推断过程自回归的特性,模型无法同时生成译文中的所有单词,导致模型的推断过程非常缓慢,这对于神经机器翻译的实际应用是个很大的挑战。因此,如何设计一个在训练和推断阶段都能够并行化的模型是目前研究的热点之一。
\parinterval 目前大多数神经机器翻译模型都使用自左向右逐词生成译文的策略,即第$j$个目标语言单词的生成依赖于先前生成的$j-1$ 个词。这种翻译方式也被称作{\small\sffamily\bfseries{自回归解码}}\index{自回归解码}(Autoregressive Decoding)\index{Autoregressive Decoding}。虽然以Transformer为代表的模型使得训练过程高度并行化,加快了训练速度。但由于推断过程自回归的特性,模型无法同时生成译文中的所有单词,导致模型的推断过程非常缓慢,这对于神经机器翻译的实际应用是个很大的挑战。因此,如何设计一个在训练和推断阶段都能够并行化进行的模型是目前研究的热点之一。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
......@@ -417,7 +417,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{自回归 vs 非自回归}
\parinterval 目前主流的神经机器翻译的推断是一种{\small\sffamily\bfseries{自回归翻译}}\index{自回归翻译}(Autoregressive Translation)\index{Autoregressive Translation}过程。所谓自回归是一种描述时间序列生成的方式:对于目标序列$\seq{y}=\{y_1,\dots,y_n\}$,如果$j$时刻状态$y_j$的生成依赖于之前的状态$\{y_1,\dots,y_{j-1}\}$,而且$y_j$$\{y_1,\dots,y_{j-1}\}$构成线性关系,那么称目标序列$\seq{y}$的生成过程是自回归的。神经机器翻译借用了这个概念,但是并不要求$y_j$$\{y_1,\dots,y_{j-1}\}$构成线性关系,\ref{sec:14-2-1}节提到的自左向右翻译模型和自右向左翻译模型都属于自回归翻译模型。自回归模型在机器翻译任务上也有很好的表现,特别是配合束搜索往往能够有效地寻找近似最优译文。但是,由于解码器的每个步骤必须顺序地而不是并行地运行,自回归翻译模型会阻碍不同译文单词生成的并行化。特别是在GPU 上,翻译的自回归性会大大降低计算的并行度和设备利用率。
\parinterval 目前主流的神经机器翻译的推断是一种{\small\sffamily\bfseries{自回归翻译}}\index{自回归翻译}(Autoregressive Translation)\index{Autoregressive Translation}过程。所谓自回归是一种描述时间序列生成的方式:对于目标序列$\seq{y}=\{y_1,\dots,y_n\}$,如果$j$时刻状态$y_j$的生成依赖于之前的状态$\{y_1,\dots,y_{j-1}\}$,而且$y_j$$\{y_1,\dots,y_{j-1}\}$构成线性关系,那么称目标序列$\seq{y}$的生成过程是自回归的。神经机器翻译借用了这个概念,但是并不要求$y_j$$\{y_1,\dots,y_{j-1}\}$构成线性关系,\ref{sec:14-2-1}节提到的自左向右翻译模型和自右向左翻译模型都属于自回归翻译模型。自回归翻译模型在机器翻译任务上也有很好的表现,特别是配合束搜索往往能够有效地寻找近似最优译文。但是,由于解码器的每个步骤必须顺序地而不是并行地运行,自回归翻译模型会阻碍不同译文单词生成的并行化。特别是在GPU 上,翻译的自回归性会大大降低计算的并行度和设备利用率。
\parinterval 对于这个问题,研究人员也考虑移除翻译的自回归性,进行{\small\sffamily\bfseries{非自回归翻译}}\index{非自回归翻译}(Non-Autoregressive Translation,NAT)\index{Non-Autoregressive Translation}\upcite{Gu2017NonAutoregressiveNM}。一个简单的非自回归翻译模型将问题建模为公式\eqref{eq:14-9}
\begin{eqnarray}
......@@ -433,7 +433,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{非自回归翻译模型的结构}
\parinterval 在介绍非自回归模型的具体结构之前,先来看看如何实现一个简单的非自回归翻译模型。这里用标准的Transformer来举例。首先为了一次性生成所有的词,需要丢弃解码器对未来信息屏蔽的矩阵,从而去掉模型的自回归性。此外,还要考虑生成译文的长度。在自回归模型中,每步的输入是上一步解码出的结果,当预测到终止符<eos>时,序列的生成就自动停止了,然而非自回归模型却没有这样的特性,因此还需要一个长度预测器来预测出其长度,之后再用这个长度得到每个位置的表示,将其作为解码器的输入,进而完成整个序列的生成。
\parinterval 在介绍非自回归翻译模型的具体结构之前,先来看看如何实现一个简单的非自回归翻译模型。这里用标准的Transformer来举例。首先为了一次性生成所有的词,需要丢弃解码器对未来信息屏蔽的矩阵,从而去掉模型的自回归性。此外,还要考虑生成译文的长度。在自回归翻译模型中,每步的输入是上一步解码出的结果,当预测到终止符<eos>时,序列的生成就自动停止了,然而非自回归翻译模型却没有这样的特性,因此还需要一个长度预测器来预测出其长度,之后再用这个长度得到每个位置的表示,将其作为解码器的输入,进而完成整个序列的生成。
%----------------------------------------------------------------------
\begin{figure}[htp]
......@@ -444,30 +444,29 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\end{figure}
%----------------------------------------------------------------------
\parinterval\ref{fig:14-12}对比了自回归翻译模型和简单的非自回归翻译模型。可以看到这种自回归翻译模型可以一次性生成完整的译文。不过,高并行性也带来了翻译品质的下降。比如,在IWSLT 英德等数据上的BLEU[\%] 值只有个位数,而现在最好的自回归模型已经能够达到30左右的BLEU得分。这是因为每个位置词的预测只依赖于源语言句子$\seq{x}$,使得预测不准确。需要注意的是,图\ref{fig:14-12}(b)中将位置编码作为非自回归模型解码器的输入只是一个最简单的例子,在真实的系统中,非自回归解码器的输入一般是拷贝的源语言句子词嵌入与位置编码的融合。
\parinterval\ref{fig:14-12}对比了自回归翻译模型和简单的非自回归翻译模型。可以看到这种自回归翻译模型可以一次性生成完整的译文。不过,高并行性也带来了翻译品质的下降。例如,对于IWSLT英德等数据,非自回归翻译模型的BLEU值只有个位数,而现在最好的自回归模型的BLEU值已经能够达到30左右。这是因为每个位置词的预测只依赖于源语言句子$\seq{x}$,使得预测不准确。需要注意的是,图\ref{fig:14-12}(b)中将位置编码作为非自回归翻译模型解码器的输入只是一个最简单的例子,在真实的系统中,非自回归解码器的输入一般是复制编码器端的输入,即源语言句子词嵌入与位置编码的融合。
\parinterval 完全独立地对每个词建模,会出现什么问题呢?来看一个例子,将汉语句子“干/得/好/!”翻译成英文,可以翻译成“Good job !”或者“Well done !”。假设生成这两种翻译的概率是相等的,即一半的概率是“Good job !”,另一半的概率是“Well done !”。由于非自回归模型的条件独立性假设,推断时第一个词“Good”和“Well”的概率是差不多大的,如果第二个词“job”和“done”的概率也差不多大,会使得模型生成出“Good done !”或者“Well job !”这样错误的翻译,如图\ref{fig:14-13}所示。这便是影响句子质量的关键问题,称之为{\small\sffamily\bfseries{多峰问题}}\index{多峰问题}(Multimodality Problem)\index{Multimodality Problem}\upcite{Gu2017NonAutoregressiveNM}。如何有效处理非自回归模型中的多峰问题 是提升非自回归模型质量的关键。
\parinterval 完全独立地对每个词建模,会出现什么问题呢?来看一个例子,将汉语句子“干/得/好/!”翻译成英文,可以翻译成“Good job !”或者“Well done !”。假设生成这两种翻译的概率是相等的,即一半的概率是“Good job !”,另一半的概率是“Well done !”。由于非自回归翻译模型的条件独立性假设,推断时第一个词“Good”和“Well”的概率是差不多大的,如果第二个词“job”和“done”的概率也差不多大,会使得模型生成出“Good done !”或者“Well job !”这样错误的翻译,如图\ref{fig:14-13}所示。这便是影响句子质量的关键问题,称之为{\small\sffamily\bfseries{多峰问题}}\index{多峰问题}(Multimodality Problem)\index{Multimodality Problem}\upcite{Gu2017NonAutoregressiveNM}。如何有效处理非自回归翻译模型中的多峰问题 是提升非自回归翻译模型质量的关键。
%----------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter14/Figures/figure-multi-modality}
\caption{非自回归模型中的多峰问题}
\caption{非自回归翻译模型中的多峰问题}
\label{fig:14-13}
\end{figure}
%----------------------------------------------------------------------
\parinterval 因此,非自回归翻译的研究大多集中在针对以上问题的求解。有三个角度:使用繁衍率预测译文长度、使用句子级知识蒸馏来降低学习难度、使用自回归模型进行翻译候选打分。下面将依次对这些方法进行介绍。
\parinterval 因此,非自回归翻译的研究大多集中在针对以上问题的求解。有三个角度:使用繁衍率预测译文长度、使用句子级知识蒸馏来降低学习难度、使用自回归翻译模型进行翻译候选打分。下面将依次对这些方法进行介绍。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{1. 基于繁衍率的非自回归模型}
\subsubsection{1. 基于繁衍率的非自回归翻译模型}
\parinterval\ref{fig:14-14}给出了基于繁衍率的Transformer非自回归模型的结构\upcite{Gu2017NonAutoregressiveNM},由三个模块组成:编码器,解码器,繁衍率预测器。类似于标准的Transformer模型,这里编码器和解码器都完全由前馈神经网络和多头注意力模块组成。唯一的不同是解码器中新增了位置注意力模块(图\ref{fig:14-14}中被红色虚线框住的模块),用于更好的捕捉目标语言端的位置信息。
\parinterval\ref{fig:14-14}给出了基于繁衍率的Transformer非自回归翻译模型的结构\upcite{Gu2017NonAutoregressiveNM},由三个模块组成:编码器,解码器,繁衍率预测器。类似于标准的Transformer模型,这里编码器和解码器都完全由前馈神经网络和多头注意力模块组成。唯一的不同是解码器中新增了位置注意力模块(图\ref{fig:14-14}中被红色虚线框住的模块),用于更好的捕捉目标语言端的位置信息。
\parinterval 繁衍率预测器的一个作用是预测整个译文句子的长度,以便并行地生成所有译文单词。可以通过对每个源语言单词计算繁衍率来估计最终译文的长度。具体来说,繁衍率指的是:根据每个源语言单词预测出其对应的目标语言单词的个数(见\chaptersix),如图\ref{fig:14-14}所示,翻译过程中英语单词“We”对应一个汉语单词“我们”,其繁衍率为1。于是,可以得到源语言句子对应的繁衍率序列(图\ref{fig:14-14}中的数字1\ 1\ 2\ 0\ 1),最终译文长度则由源语言单词的繁衍率之和决定。之后将源语言单词按该繁衍率序列进行拷贝,在图中的例子中,将“We”、“totally”、“.”拷贝一次,将"accept"、“it”分别拷贝两次和零次,就得到了最终解码器的输入“We totally accept accept .”。在模型训练阶段,繁衍率序列可以通过外部词对齐工具得到, 用于之后训练繁衍率预测器。但由于外部词对齐系统会出现错误,因此在模型收敛之后,可以对繁衍率预测器进行额外的微调。
......@@ -475,7 +474,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\begin{figure}[htp]
\centering
\input{./Chapter14/Figures/figure-reproduction-rate}
\caption{基于繁衍率的非自回归模型}
\caption{基于繁衍率的非自回归翻译模型}
\label{fig:14-14}
\end{figure}
%----------------------------------------------------------------------
......@@ -490,15 +489,15 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsubsection{2. 句子级知识蒸馏}
\parinterval 知识蒸馏的基本思路是把教师模型的知识传递给学生模型,让学生模型可以更好地学习(见\chapterthirteen)。通过这种方法,可以降低非自回归模型的学习难度。具体来说,可以让自回归模型作为“教师”,非自回归模型作为“学生”。把自回归神经机器翻译模型生成的句子作为新的训练样本,送给非自回归机器翻译模型进行学习\upcite{Lee2018DeterministicNN,Zhou2020UnderstandingKD,Guo2020FineTuningBC}。有研究发现自回归模型生成的结果的“确定性”更高,也就是不同句子中相同源语言片段翻译的多样性相对低一些\upcite{Gu2017NonAutoregressiveNM}。虽然从人工翻译的角度看,这可能并不是理想的译文,但是使用这样的译文可以在一定程度上缓解多峰问题。因为,经过训练的自回归模型会始终将相同的源语言句子翻译成相同的译文。这样得到的数据集噪声更少,能够降低非自回归模型学习的难度。此外,相比人工标注的译文,自回归模型输出的译文更容易让模型进行学习,这也是句子级知识蒸馏有效的原因之一。
\parinterval 知识蒸馏的基本思路是把教师模型的知识传递给学生模型,让学生模型可以更好地学习(见\chapterthirteen)。通过这种方法,可以降低非自回归翻译模型的学习难度。具体来说,可以让自回归翻译模型作为“教师”,非自回归翻译模型作为“学生”。把自回归翻译模型生成的句子作为新的训练样本,送给非自回归翻译模型进行学习\upcite{Lee2018DeterministicNN,Zhou2020UnderstandingKD,Guo2020FineTuningBC}。有研究发现自回归翻译模型生成的结果的“确定性”更高,也就是不同句子中相同源语言片段翻译的多样性相对低一些\upcite{Gu2017NonAutoregressiveNM}。虽然从人工翻译的角度看,这可能并不是理想的译文,但是使用这样的译文可以在一定程度上缓解多峰问题。因为,经过训练的自回归翻译模型会始终将相同的源语言句子翻译成相同的译文。这样得到的数据集噪声更少,能够降低非自回归翻译模型学习的难度。此外,相比人工标注的译文,自回归翻译模型输出的译文更容易让模型进行学习,这也是句子级知识蒸馏有效的原因之一。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{3.自回归模型打分}
\subsubsection{3.自回归翻译模型打分}
\parinterval 通过采样不同的繁衍率序列,可以得到多个不同的翻译候选。之后,把这些不同的译文再交给自回归模型来评分,选择一个最好的结果作为最终的翻译结果。通常,这种方法能够很有效地提升非自回归翻译模型的译文质量,并且保证较高的推断速度\upcite{Gu2017NonAutoregressiveNM,Wei2019ImitationLF,Guo2019NonAutoregressiveNM,Wang2019NonAutoregressiveMT,Ma2019FlowSeqNC}。但是,缺点是需要同时部署自回归和非自回归两套系统。
\parinterval 通过采样不同的繁衍率序列,可以得到多个不同的翻译候选。之后,把这些不同的译文再交给自回归翻译模型来评分,选择一个最好的结果作为最终的翻译结果。通常,这种方法能够很有效地提升非自回归翻译模型的译文质量,并且保证较高的推断速度\upcite{Gu2017NonAutoregressiveNM,Wei2019ImitationLF,Guo2019NonAutoregressiveNM,Wang2019NonAutoregressiveMT,Ma2019FlowSeqNC}。但是,缺点是需要同时部署自回归翻译和非自回归翻译两套系统。
%----------------------------------------------------------------------------------------
% NEW SUBSECTION
......@@ -506,11 +505,11 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{更好的训练目标}
\parinterval 虽然非自回归翻译可以显著提升翻译速度,但是很多情况下其翻译质量还是低于传统的自回归翻译\upcite{Gu2017NonAutoregressiveNM,Kaiser2018FastDI,Guo2020FineTuningBC}。因此,很多工作致力于缩小自回归模型和非自回归模型的性能差距\upcite{Ran2020LearningTR,Tu2020ENGINEEI,Shu2020LatentVariableNN}
\parinterval 虽然非自回归翻译可以显著提升翻译速度,但是很多情况下其翻译质量还是低于传统的自回归翻译\upcite{Gu2017NonAutoregressiveNM,Kaiser2018FastDI,Guo2020FineTuningBC}。因此,很多工作致力于缩小自回归翻译模型和非自回归翻译模型的性能差距\upcite{Ran2020LearningTR,Tu2020ENGINEEI,Shu2020LatentVariableNN}
\parinterval 一种直接的方法是层级知识蒸馏\upcite{Li2019HintBasedTF}。由于自回归模型和非自回归模型的结构相差不大,因此可以将翻译质量更高的自回归模型作为“教师”,通过给非自回归模型提供监督信号,使其逐块地学习前者的分布。研究人员发现了两点非常有意思的现象:1)非自回归模型容易出现“重复翻译”的现象,这些相邻的重复单词所对应的位置的隐藏状态非常相似。2)非自回归模型的注意力分布比自回归模型的分布更加尖锐。这两点发现启发了研究人员使用自回归模型中的隐层状态和注意力矩阵等中间表示来指导非自回归模型的学习过程。可以计算两个模型隐层状态的距离以及注意力矩阵的KL散度\footnote{KL散度即相对熵。},将它们作为额外的损失指导非自回归模型的训练。类似的做法也出现在基于模仿学习的方法中\upcite{Wei2019ImitationLF},它也可以被看作是对自回归模型不同层行为的模拟。不过,基于模仿学习的方法会使用更复杂的模块来完成自回归模型对非自回归模型的指导,比如,在自回归模型和非自回归模型中都使用一个额外的神经网络,用于传递自回归模型提供给非自回归模型的层级监督信号。
\parinterval 一种直接的方法是层级知识蒸馏\upcite{Li2019HintBasedTF}。由于自回归翻译模型和非自回归翻译模型的结构相差不大,因此可以将翻译质量更高的自回归翻译模型作为“教师”,通过给非自回归翻译模型提供监督信号,使其逐块地学习前者的分布。研究人员发现了两点非常有意思的现象:1)非自回归翻译模型容易出现“重复翻译”的现象,这些相邻的重复单词所对应的位置的隐藏状态非常相似。2)非自回归翻译模型的注意力分布比自回归翻译模型的分布更加尖锐。这两点发现启发了研究人员使用自回归翻译模型中的隐层状态和注意力矩阵等中间表示来指导非自回归翻译模型的学习过程。可以计算两个模型隐层状态的距离以及注意力矩阵的KL散度\footnote{KL散度即相对熵。},将它们作为额外的损失指导非自回归翻译模型的训练。类似的做法也出现在基于模仿学习的方法中\upcite{Wei2019ImitationLF},它也可以被看作是对自回归翻译模型不同层行为的模拟。不过,基于模仿学习的方法会使用更复杂的模块来完成自回归翻译模型对非自回归翻译模型的指导,比如,在自回归翻译模型和非自回归翻译模型中都使用一个额外的神经网络,用于传递自回归翻译模型提供给非自回归翻译模型的层级监督信号。
\parinterval 此外,也可以使用基于正则化因子的方法\upcite{Wang2019NonAutoregressiveMT}。非自回归模型的翻译结果中存在着两种非常严重的错误:重复翻译和不完整的翻译。重复翻译问题是因为解码器隐层状态中相邻的两个位置过于相似,因此翻译出来的单词也一样。对于不完整翻译,即欠翻译问题,通常是由于非自回归模型在翻译的过程中丢失了一些源语言句子的信息。针对这两个问题,可以通过在相邻隐层状态间添加相似度约束来计算一个重构损失。具体实践时,对于翻译$\seq{x}\to\seq{y}$,通过一个反向的自回归模型再将$\seq{y}$翻译成$\seq{x'}$,最后计算$\seq{x}$$\seq{x'}$的差异性作为损失。
\parinterval 此外,也可以使用基于正则化因子的方法\upcite{Wang2019NonAutoregressiveMT}。非自回归翻译模型的翻译结果中存在着两种非常严重的错误:重复翻译和不完整的翻译。重复翻译问题是因为解码器隐层状态中相邻的两个位置过于相似,因此翻译出来的单词也一样。对于不完整翻译,即欠翻译问题,通常是由于非自回归翻译模型在翻译的过程中丢失了一些源语言句子的信息。针对这两个问题,可以通过在相邻隐层状态间添加相似度约束来计算一个重构损失。具体实践时,对于翻译$\seq{x}\to\seq{y}$,通过一个反向的自回归翻译模型再将$\seq{y}$翻译成$\seq{x'}$,最后计算$\seq{x}$$\seq{x'}$的差异性作为损失。
%----------------------------------------------------------------------------------------
......@@ -519,7 +518,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{引入自回归模块}
\parinterval 非自回归翻译消除了序列生成过程中不同位置预测结果间的依赖,在每个位置都进行独立的预测,但这反而会导致翻译质量显著下降,因为缺乏不同单词间依赖关系的建模。因此,也有研究聚焦于在非自回归模型中添加一些自回归组件。
\parinterval 非自回归翻译消除了序列生成过程中不同位置预测结果间的依赖,在每个位置都进行独立的预测,但这反而会导致翻译质量显著下降,因为缺乏不同单词间依赖关系的建模。因此,也有研究聚焦于在非自回归翻译模型中添加一些自回归组件。
\parinterval 一种做法是将句法信息作为目标语言句子的框架\upcite{Akoury2019SyntacticallyST}。具体来说,先自回归地预测出一个目标语言的句法块序列,将句法块作为序列信息的抽象,然后根据句法块序列非自回归地生成所有目标语言单词。如图\ref{fig:14-21}所示,该模型由一个编码器和两个解码器组成。其中编码器和第一个解码器与标准的Transformer模型相同,用来自回归地预测句法树信息;第二个解码器将第一个解码器的句法信息作为输入,之后再非自回归地生成整个译文。在训练过程中,通过使用外部句法分析器获得对句法预测任务的监督信号。虽然可以简单地让模型预测整个句法树,但是这种方法会显著增加自回归步骤的数量,从而增大时间开销。因此,为了维持句法信息与解码时间的平衡,这里预测一些由句法标记和子树大小组成的块标识符(如VP3)而不是整个句法树。关于基于句法的神经机器翻译模型在{\chapterfifteen}还会有进一步讨论。
......@@ -527,12 +526,12 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\begin{figure}[htp]
\centering
\input{./Chapter14/Figures/figure-syntax}
\caption{基于句法结构的非自回归模型}
\caption{基于句法结构的非自回归翻译模型}
\label{fig:14-21}
\end{figure}
%----------------------------------------------
\parinterval 另一种做法是半自回归地生成译文\upcite{Wang2018SemiAutoregressiveNM}。如图\ref{fig:14-20}所示,自回归模型从左到右依次生成译文,具有“最强”的自回归性;而非自回归模型完全独立的生成每个译文单词,具有“最弱”的自回归性;半自回归模型则是将整个译文分成$k$个块,在块内执行非自回归解码,在块间则执行自回归的解码,能够在每个时间步并行产生多个连续的单词。通过调整块的大小,半自回归模型可以灵活的调整为自回归翻译(当$k$等于1)和非自回归翻译(当$k$大于等于最大的译文长度)。
\parinterval 另一种做法是半自回归地生成译文\upcite{Wang2018SemiAutoregressiveNM}。如图\ref{fig:14-20}所示,自回归翻译模型从左到右依次生成译文,具有“最强”的自回归性;而非自回归翻译模型完全独立的生成每个译文单词,具有“最弱”的自回归性;半自回归翻译模型则是将整个译文分成$k$个块,在块内执行非自回归解码,在块间则执行自回归的解码,能够在每个时间步并行产生多个连续的单词。通过调整块的大小,半自回归翻译模型可以灵活的调整为自回归翻译(当$k$等于1)和非自回归翻译(当$k$大于等于最大的译文长度)。
%----------------------------------------------
\begin{figure}[htp]
......@@ -543,13 +542,13 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\end{figure}
%----------------------------------------------
\parinterval 还有一种做法引入了轻量级的自回归调序模块\upcite{Ran2019GuidingNN}。为了解决非自回归模型解码搜索空间过大的问题,可以使用调序技术在相对较少的翻译候选上进行自回归模型的计算。如图\ref{fig:14-22}所示,该方法对源语言句子进行重新排列转换成由源语言单词组成但位于目标语言结构中的伪译文,然后将伪译文进一步转换成目标语言以获得最终的翻译。其中,这个调序模块可以是一个轻量自回归模型,例如,一层的循环神经网络。
\parinterval 还有一种做法引入了轻量级的自回归调序模块\upcite{Ran2019GuidingNN}。为了解决非自回归翻译模型解码搜索空间过大的问题,可以使用调序技术在相对较少的翻译候选上进行自回归翻译模型的计算。如图\ref{fig:14-22}所示,该方法对源语言句子进行重新排列转换成由源语言单词组成但位于目标语言结构中的伪译文,然后将伪译文进一步转换成目标语言以获得最终的翻译。其中,这个调序模块可以是一个轻量自回归翻译模型,例如,一层的循环神经网络。
%----------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter14/Figures/figure-reranking}
\caption{引入调序模块的非自回归模型}
\caption{引入调序模块的非自回归翻译模型}
\label{fig:14-22}
\end{figure}
%----------------------------------------------------------------------
......@@ -560,7 +559,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{基于迭代精化的非自回归翻译模型}
\parinterval 如果一次并行生成整个序列,往往很难捕捉单词之间的关系,而且即便生成了错误的译文单词,这类方法也无法修改。针对这些问题,也可以使用迭代式的生成方式\upcite{Lee2018DeterministicNN,Ghazvininejad2019MaskPredictPD,Kasai2020NonAutoregressiveMT}。这种方法放弃了一次生成最终的译文句子,而是将解码出的译文再重新送给解码器,在每次迭代中来改进之前生成的译文单词,可以理解为句子级的自回归模型。这样做的好处在于,每次迭代的过程中可以利用已经生成的部分翻译结果,来指导其它部分的生成。
\parinterval 如果一次性并行地生成整个译文序列,往往很难捕捉单词之间的关系,而且即便生成了错误的译文单词,这类方法也无法修改。针对这些问题,也可以使用迭代式的生成方式\upcite{Lee2018DeterministicNN,Ghazvininejad2019MaskPredictPD,Kasai2020NonAutoregressiveMT}。这种方法放弃了一次生成最终的译文句子,而是将解码出的译文再重新送给解码器,在每次迭代中来改进之前生成的译文单词,可以理解为句子级的自回归翻译模型。这样做的好处在于,每次迭代的过程中可以利用已经生成的部分翻译结果,来指导其它部分的生成。
\parinterval\ref{fig:14-18}展示了这种方法的简单示例。它拥有一个编码器和$N$个解码器。编码器首先预测出译文的长度,然后将输入$\seq{x}$按照长度复制出$\seq{x'}$作为第一个解码器的输入,之后生成$\seq{y}^{[1]}$作为第一轮迭代的输出。接下来再把$\seq{y}^{[1]}$输入给第二个解码器,然后输出$\seq{y}^{[2]}$,以此类推。那么迭代到什么时候结束呢?一种简单的做法是提前制定好迭代次数,这种方法能够自主地对生成句子的质量和效率进行平衡。另一种称之为“自适应”的方法,具体是通过计算当前生成的句子与上一次生成句子之间的变化量来判断是否停止,例如,使用杰卡德相似系数作为变化量函数\footnote{杰卡德相似系数是衡量有限样本集之间的相似性与差异性的一种指标,杰卡德相似系数值越大,样本相似度越高。}。另外,需要说明的是,图\ref{fig:14-18}中是使用多个解码器的一种逻辑示意。真实的系统仅需要一个解码器,并运行多次,就达到了迭代精化的目的。
......@@ -573,7 +572,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\end{figure}
%----------------------------------------------
\parinterval 除了使用上一个步骤的输出,当前解码器的输入还可以使用了添加噪声的正确目标语言句子\upcite{Lee2018DeterministicNN}。另外,对于译文长度的预测,也可以使用编码器的输出单独训练一个独立的长度预测模块,这种方法也推广到了目前大多数非自回归模型上。
\parinterval 除了使用上一个步骤的输出,当前解码器的输入还可以使用了添加噪声的正确目标语言句子\upcite{Lee2018DeterministicNN}。另外,对于译文长度的预测,也可以使用编码器的输出单独训练一个独立的长度预测模块,这种方法也推广到了目前大多数非自回归翻译模型上。
\parinterval 另一种方法借鉴了BERT的思想\upcite{devlin2019bert},称为Mask-Predict\upcite{Ghazvininejad2019MaskPredictPD}。类似于BERT中的<CLS>标记,该方法在源语言句子的最前面加上了一个特殊符号<LEN>作为输入,用来预测目标句的长度$n$。之后,将特殊符<Mask>(与BERT中的<Mask>有相似的含义)复制$n$次作为解码器的输入,然后用非自回归的方式生成所有的译文单词。这样生成的翻译可能是比较差的,因此可以将第一次生成的这些词中不确定(即生成概率比较低)的一些词“擦”掉,依据剩余的译文单词以及源语言句子重新进行预测,不断迭代,直到满足停止条件为止。图\ref{fig:14-19}给出了一个示例。
......@@ -650,15 +649,15 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\vspace{0.5em}
\item 改变模型宽度和深度,即用不同层数或者不同隐藏层大小得到多个模型;
\vspace{0.5em}
\item 使用不同的参数进行初始化,即用不同的随机种子初始化参数训练多个模型;
\item 使用不同的参数进行初始化,即使用不同的随机种子初始化参数,训练多个模型;
\vspace{0.5em}
\item 不同模型(局部)架构的调整,比如,使用不同的位置编码模型\upcite{Shaw2018SelfAttentionWR}、多层融合模型\upcite{WangLearning}等;
\vspace{0.5em}
\item 利用不同数量以及不同数据增强方式产生的伪数据训练模型\upcite{zhang-EtAl:2020:WMT}
\vspace{0.5em}
\item 利用多分支多通道的模型,不同分支可能有不同结构,使得模型能有更好的表示能力\upcite{zhang-EtAl:2020:WMT}
\item 利用多分支多通道的模型,使得模型能有更好的表示能力\upcite{zhang-EtAl:2020:WMT}
\vspace{0.5em}
\item 利用预训练进行参数共享之后微调的模型
\item 利用预训练方法进行参数共享,然后对模型进行微调
\vspace{0.5em}
\end{itemize}
......@@ -697,7 +696,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\sectionnewpage
\section{小结与拓展阅读}
\parinterval 推断系统(或解码系统)是神经机器翻译的重要组成部分。在神经机器翻译研究中,单独针对推断问题开展的讨论并不多见。更多的工作是将其与实践结合,常见于开源系统、评测比赛中。但是,从应用的角度看,研发高效的推断系统是机器翻译能够被大规模使用的前提。本章也从神经机器翻译推断的基本问题出发,重点探讨了推断系统的效率、非自回归翻译、多模型集成等问题。但是,由于推断问题涉及的问题十分广泛,因此本章也无法对其进行全面覆盖。关于神经机器翻译模型推断还有以下若干研究方向值得关注:
\parinterval 推断系统(或解码系统)是神经机器翻译的重要组成部分。在神经机器翻译研究中,单独针对推断问题开展的讨论并不多见。更多的工作是将其与实践结合,常见于开源系统、评测比赛中。但是,从应用的角度看,研发高效的推断系统是机器翻译能够被大规模使用的前提。本章也从神经机器翻译推断的基本问题出发,重点探讨了推断系统的效率、非自回归翻译、多模型集成等问题。但是,由于推断阶段涉及的问题十分广泛,因此本章也无法对其进行全面覆盖。关于神经机器翻译模型推断还有以下若干研究方向值得关注:
\begin{itemize}
\vspace{0.5em}
......@@ -705,11 +704,11 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\vspace{0.5em}
\item 推断系统也可以受益于更加高效的神经网络结构。这方面工作集中在结构化剪枝、减少模型的冗余计算、低秩分解等方向。结构化剪枝中的代表性工作是LayerDrop\upcite{DBLP:conf/iclr/FanGJ20,DBLP:conf/emnlp/WangXZ20,DBLP:journals/corr/abs-2002-02925},这类方法在训练时随机选择部分子结构,在推断时根据输入来选择模型中的部分层进行计算,而跳过其余层,达到加速的目的。有关减少冗余计算的研究主要集中在改进注意力机制上,本章已经有所介绍。低秩分解则针对词向量或者注意力的映射矩阵进行改进,例如词频自适应表示\upcite{DBLP:conf/iclr/BaevskiA19},词频越高则对应的向量维度越大,反之则越小,或者层数越高注意力映射矩阵维度越小\upcite{DBLP:journals/corr/abs-2006-04768,DBLP:journals/corr/abs-1911-12385,DBLP:journals/corr/abs-1906-09777,DBLP:conf/nips/YangLSL19}。在实践中比较有效的是较深的编码器与较浅的解码器结合的方式,极端情况下解码器仅使用1层神经网络即可取得与多层神经网络相媲美的翻译品质,从而极大地提升翻译效率\upcite{DBLP:journals/corr/abs-2006-10369,DBLP:conf/aclnmt/HuLLLLWXZ20,DBLP:journals/corr/abs-2010-02416}。在{\chapterfifteen}还会进一步对高效神经机器翻译的模型结构进行讨论。
\vspace{0.5em}
\item 在对机器翻译推断系统进行实际部署时,对存储的消耗也是需要考虑的因素。因此如何让模型变得更小也是研发人员所关注的方向。当前的模型压缩方法主要可以分为几类:剪枝、量化、知识蒸馏和轻量方法,其中轻量方法主要是基于更轻量模型结构的设计,这类方法已经在本章进行了介绍。剪枝主要包括权重大小剪枝\upcite{Han2015LearningBW,Lee2019SNIPSN,Frankle2019TheLT,Brix2020SuccessfullyAT}、 面向多头注意力的剪枝\upcite{Michel2019AreSH,DBLP:journals/corr/abs-1905-09418}、网络层以及其他结构剪枝等\upcite{Liu2017LearningEC,Liu2019RethinkingTV},还有一些方法也通过在训练期间采用正则化的方式来提升剪枝能力\upcite{DBLP:conf/iclr/FanGJ20}。量化方法主要通过截断浮点数来减少模型的存储大小,使其仅使用几个比特位的数字表示方法便能存储整个模型,虽然会导致舍入误差,但压缩效果显著\upcite{DBLP:journals/corr/abs-1906-00532,Cheong2019transformersZ,Banner2018ScalableMF,Hubara2017QuantizedNN}。一些方法利用知识蒸馏手段还将Transformer模型蒸馏成如LSTMs 等其他各种推断速度更快的结构\upcite{Hinton2015Distilling,Munim2019SequencelevelKD,Tang2019DistillingTK}
\item 在对机器翻译推断系统进行实际部署时,对存储的消耗也是需要考虑的因素。因此如何让模型变得更小也是研发人员所关注的方向。当前的模型压缩方法主要可以分为几类:剪枝、量化、知识蒸馏和轻量方法,其中轻量方法的研究重点集中于更轻量模型结构的设计,这类方法已经在本章进行了介绍。剪枝主要包括权重大小剪枝\upcite{Han2015LearningBW,Lee2019SNIPSN,Frankle2019TheLT,Brix2020SuccessfullyAT}、 面向多头注意力的剪枝\upcite{Michel2019AreSH,DBLP:journals/corr/abs-1905-09418}、网络层以及其他结构剪枝等\upcite{Liu2017LearningEC,Liu2019RethinkingTV},还有一些方法也通过在训练期间采用正则化的方式来提升剪枝能力\upcite{DBLP:conf/iclr/FanGJ20}。量化方法主要通过截断浮点数来减少模型的存储大小,使其仅使用几个比特位的数字表示方法便能存储整个模型,虽然会导致舍入误差,但压缩效果显著\upcite{DBLP:journals/corr/abs-1906-00532,Cheong2019transformersZ,Banner2018ScalableMF,Hubara2017QuantizedNN}。一些方法利用知识蒸馏手段还将Transformer模型蒸馏成如LSTMs 等其他各种推断速度更快的结构\upcite{Hinton2015Distilling,Munim2019SequencelevelKD,Tang2019DistillingTK}
\vspace{0.5em}
\item 目前的翻译模型使用交叉熵损失作为优化函数,这在自回归模型上取得了非常优秀的性能。交叉熵是一个严格的损失函数,每个预测错误的单词所对应的位置都会受到惩罚,即使是编辑距离很小的输出序列\upcite{Ghazvininejad2020AlignedCE}。自回归模型会很大程度上避免这种惩罚,因为当前位置的单词是根据先前生成的词得到的,然而非自回归模型无法获得这种信息。如果在预测时漏掉一个单词,就可能会将正确的单词放在错误的位置上。为此,一些研究工作通过改进损失函数来提高非自回归模型的性能。一种做法使用一种新的交叉熵函数\upcite{Ghazvininejad2020AlignedCE},它通过忽略绝对位置、关注相对顺序和词汇匹配来为非自回归模型提供更精确的训练信号。另外,也可以使用基于$n$-gram的训练目标\upcite{Shao2020MinimizingTB}来最小化模型与参考译文之间的$n$-gram差异。该训练目标在$n$-gram 的层面上评估预测结果,因此能够建模目标序列单词之间的依赖关系。
\item 目前的翻译模型使用交叉熵损失作为优化函数,这在自回归翻译模型上取得了非常优秀的性能。交叉熵是一个严格的损失函数,每个预测错误的单词所对应的位置都会受到惩罚,即使是编辑距离很小的输出序列\upcite{Ghazvininejad2020AlignedCE}。自回归翻译模型会很大程度上避免这种惩罚,因为当前位置的单词是根据先前生成的词得到的,然而非自回归翻译模型无法获得这种信息。如果在预测时漏掉一个单词,就可能会将正确的单词放在错误的位置上。为此,一些研究工作通过改进损失函数来提高非自回归翻译模型的性能。一种做法使用一种新的交叉熵函数\upcite{Ghazvininejad2020AlignedCE},它通过忽略绝对位置、关注相对顺序和词汇匹配来为非自回归翻译模型提供更精确的训练信号。另外,也可以使用基于$n$-gram的训练目标\upcite{Shao2020MinimizingTB}来最小化模型与参考译文之间的$n$-gram差异。该训练目标在$n$-gram 的层面上评估预测结果,因此能够建模目标序列单词之间的依赖关系。
\vspace{0.5em}
\item 自回归模型解码时,当前位置单词的生成依赖于先前生成的单词,已生成的单词提供了较强的目标端上下文信息。与自回归模型相比,非自回归模型的解码器需要在信息更少的情况下执行翻译任务。一些研究工作通过将条件随机场引入非自回归模型中来对序列依赖进行建模\upcite{Ma2019FlowSeqNC}。也有工作引入了词嵌入转换矩阵来将源语言端的词嵌入转换为目标语言端的词嵌入来为解码器提供更好的输入\upcite{Guo2019NonAutoregressiveNM}。此外,研究人员也提出了轻量级的调序模块来显式地建模调序信息,以指导非自回归模型的推断\upcite{Ran2019GuidingNN}
\item 自回归翻译模型解码时,当前位置单词的生成依赖于先前生成的单词,已生成的单词提供了较强的目标端上下文信息。与自回归翻译模型相比,非自回归翻译模型的解码器需要在信息更少的情况下执行翻译任务。一些研究工作通过将条件随机场引入非自回归翻译模型中来对序列依赖进行建模\upcite{Ma2019FlowSeqNC}。也有工作引入了词嵌入转换矩阵来将源语言端的词嵌入转换为目标语言端的词嵌入来为解码器提供更好的输入\upcite{Guo2019NonAutoregressiveNM}。此外,研究人员也提出了轻量级的调序模块来显式地建模调序信息,以指导非自回归翻译模型的推断\upcite{Ran2019GuidingNN}
\vspace{0.5em}
\end{itemize}
......
......@@ -79,17 +79,17 @@
\noindent 这里,$\mathbi{z}_{i}$可以被看做是输入序列的线性加权表示结果。权重$\alpha_{ij}$通过Softmax函数得到:
\begin{eqnarray}
\alpha_{ij} &=& \frac{\exp (\mathbi{e}_{ij})}{\sum_{k=1}^{m}\exp (\mathbi{e}_{ik})}
\alpha_{ij} &=& \frac{\exp ({e}_{ij})}{\sum_{k=1}^{m}\exp ({e}_{ik})}
\label{eq:15-5}
\end{eqnarray}
\noindent 进一步,$\mathbi{e}_{ij}$被定义为:
\noindent 进一步,${e}_{ij}$被定义为:
\begin{eqnarray}
\mathbi{e}_{ij} &=& \frac{(\mathbi{x}_i \mathbi{W}_Q){(\mathbi{x}_j \mathbi{W}_K)}^{\textrm{T}}}{\sqrt{d_k}}
{e}_{ij} &=& \frac{(\mathbi{x}_i \mathbi{W}_Q){(\mathbi{x}_j \mathbi{W}_K)}^{\textrm{T}}}{\sqrt{d_k}}
\label{eq:15-6}
\end{eqnarray}
\noindent 其中,$d_k$为模型中隐藏层的维度\footnote[3]{在多头注意力中,$d_k$为经过多头分割后每个头的维度。}$\mathbi{e}_{ij}$实际上就是$\mathbi{Q}$$\mathbi{K}$的向量积缩放后的一个结果。
\noindent 其中,$d_k$为模型中隐藏层的维度\footnote[3]{在多头注意力中,$d_k$为经过多头分割后每个头的维度。}${e}_{ij}$实际上就是$\mathbi{Q}$$\mathbi{K}$的向量积缩放后的一个结果。
\parinterval 基于上述描述,相对位置模型可以按如下方式实现:
......@@ -616,20 +616,20 @@ v_i &=& \mathbi{I}_d^{\textrm{T}}\textrm{Tanh}(\mathbi{W}_d\mathbi{Q}_i)
\noindent 其中,$u(-\gamma,\gamma)$表示$-\gamma$$\gamma$间的均匀分布,$n_i$$n_o$分别为线性变换$\mathbi{W}$中输入和输出的维度,也就是上一层神经元的数量和下一层神经元的数量。通过使用这种初始化方式,即可维持神经网络在前向与反向计算过程中,每一层的输入与输出方差的一致性\upcite{DBLP:conf/iccv/HeZRS15}
\parinterval 令模型中某层神经元的输出表示为$\mathbi{Z}=\sum_{j=1}^{n_i}{w_j x_j}$。可以看出,$\mathbi{Z}$的核心是计算两个变量$w_j$$x_j$乘积。两个变量乘积的方差的展开式为:
\parinterval 令模型中某层神经元的输出表示为$Z=\sum_{j=1}^{n_i}{w_j x_j}$。可以看出,$Z$的核心是计算两个变量$w_j$$x_j$乘积。两个变量乘积的方差的展开式为:
\begin{eqnarray}
\textrm{Var}(w_j x_j) &=& E[w_j]^2 \textrm{Var}(x_j) + E[x_j]^2 \textrm{Var}(w_j) + \textrm{Var}(w_j)\textrm{Var}(x_j)
\label{eq:15-41}
\end{eqnarray}
\parinterval 其中$\textrm{Var}(\cdot)$表示求方差操作,由于在大多数情况下,现有模型中的各种标准化方法可以维持$E[w_j]^2$$E[x_j]^2$等于或者近似为0。因此,模型中一层神经元输出的方差可以表示为:
\parinterval 其中$\textrm{Var}(\cdot)$表示求方差操作,由于在大多数情况下,现有模型中的各种标准化方法可以维持$E[w_j]^2$$E[x_j]^2$等于或者近似为0。由于输入$x_j(1<j<n_i)$独立同分布,此处可以使用$x$表示输入服从的分布,对于参数$w_j$也可以有同样的表示$w$因此,模型中一层神经元输出的方差可以表示为:
\begin{eqnarray}
\textrm{Var}(\mathbi{Z}) &=& \sum_{j=1}^{n_i}{\textrm{Var}(x_j) \textrm{Var}(w_j)} \nonumber \\
&=& {n_i}\textrm{Var}(\mathbi{W})\textrm{Var}(\mathbi{X})
\textrm{Var}(Z) &=& \sum_{j=1}^{n_i}{\textrm{Var}(x_j) \textrm{Var}(w_j)} \nonumber \\
&=& {n_i}\textrm{Var}({w})\textrm{Var}({x})
\label{eq:15-42}
\end{eqnarray}
\parinterval 通过观察公式\eqref{eq:15-42}可以发现,在前向传播的过程中,当$\textrm{Var}(\mathbi{W})=\frac{1}{n_i}$时,可以保证每层的输入和输出的方差一致。类似的,通过相关计算可以得知,为了保证模型中每一层的输入和输出的方差一致,反向传播时应有$\textrm{Var}(\mathbi{W})=\frac{1}{n_o}$,通过对两种情况取平均值,控制参数$\mathbi{W}$的方差为$\frac{2}{n_i+n_o}$,则可以维持神经网络在前向与反向计算过程中,每一层的输入与输出方差的一致性。若将参数初始化为一个服从边界为$[-a,b]$的均匀分布,那么其方差为$\frac{{(b+a)}^2}{12}$,为了达到$\mathbi{W}$的取值要求,初始化时应有$a=b=\sqrt{\frac{6}{n_i+n_o}}$
\parinterval 通过观察公式\eqref{eq:15-42}可以发现,在前向传播的过程中,当$\textrm{Var}(w)=\frac{1}{n_i}$时,可以保证每层的输入和输出的方差一致。类似的,通过相关计算可以得知,为了保证模型中每一层的输入和输出的方差一致,反向传播时应有$\textrm{Var}(w)=\frac{1}{n_o}$,通过对两种情况取平均值,控制参数$w$的方差为$\frac{2}{n_i+n_o}$,则可以维持神经网络在前向与反向计算过程中,每一层的输入与输出方差的一致性。若将参数初始化为一个服从边界为$[-a,b]$的均匀分布,那么其方差为$\frac{{(b+a)}^2}{12}$,为了达到$w$的取值要求,初始化时应有$a=b=\sqrt{\frac{6}{n_i+n_o}}$
\parinterval 但是随着神经网络层数的增加,上述初始化方法已经不能很好地约束基于Post-Norm的Transformer模型的输出方差。当神经网络堆叠很多层时,模型顶层输出的方差较大,同时反向传播时顶层的梯度范数也要大于底层。因此,一个自然的想法是根据网络的深度对不同层的参数矩阵采取不同的初始化方式,进而强化对各层输出方差的约束,可以描述为:
\begin{eqnarray}
......
......@@ -129,7 +129,7 @@
}
\node [anchor=south west] (label24) at (-0.8,0.9) {\footnotesize{\ding{175}}};
{
\node [anchor=north] (xlabel) at (0,-1.2) {${\mathbi{x}} \cdot {\mathbi{W}}$};
\node [anchor=north] (xlabel) at (0,-1.2) {${\mathbi{x}} {\mathbi{W}}$};
\node [anchor=center] (elabel) at (-0.9in,0) {\Huge{$\textbf{=}$}};
}
\end{scope}
......
......@@ -46,7 +46,7 @@
\subsection{发展简史}
\parinterval 神经网络最早出现在控制论中,随后更多地在连接主义中被提及。神经网络被提出的初衷并不是做一个简单的计算模型,而是希望将神经网络应用到一些自动控制相关的场景中。然而随着神经网络技术的持续发展,神经网络方法已经被广泛应用到各行各业的研究和实践工作中。
\parinterval 神经网络最早出现在控制论中,随后更多地在联结主义中被提及。神经网络被提出的初衷并不是做一个简单的计算模型,而是希望将神经网络应用到一些自动控制相关的场景中。然而随着神经网络技术的持续发展,神经网络方法已经被广泛应用到各行各业的研究和实践工作中。
\parinterval 人工神经网络诞生至今,经历了多次高潮和低谷,这是任何一种技术都无法绕开的命运。然而,好的技术和方法终究不会被埋没,直到今天,神经网络和深度学习迎来了最好的时代。
......@@ -66,13 +66,13 @@
\subsubsection{2. 神经网络的第二次高潮和第二次寒冬}
\parinterval 虽然第一代神经网络受到了打击,但是在20世纪80年代,第二代人工神经网络开始萌发新的生机。在这个发展阶段,生物属性已经不再是神经网络的唯一灵感来源,在{\small\bfnew{连接主义}}\index{连接主义}(Connectionism)\index{Connectionism}和分布式表示两种思潮的影响下,神经网络方法再次走入了人们的视线。
\parinterval 虽然第一代神经网络受到了打击,但是在20世纪80年代,第二代人工神经网络开始萌发新的生机。在这个发展阶段,生物属性已经不再是神经网络的唯一灵感来源,在{\small\bfnew{联结主义}}\index{联结主义}(Connectionism)\index{Connectionism}和分布式表示两种思潮的影响下,神经网络方法再次走入了人们的视线。
\vspace{0.3em}
\parinterval 1)符号主义与连接主义
\parinterval 1)符号主义与联结主义
\vspace{0.3em}
\parinterval 人工智能领域始终存在着符号主义和连接主义之争。早期的人工智能研究在认知学中被称为{\small\bfnew{符号主义}}\index{符号主义}(Symbolicism)\index{Symbolicism},符号主义认为人工智能源于数理逻辑,希望将世界万物的所有运转方式归纳成像文法一样符合逻辑规律的推导过程。符号主义的支持者们坚信基于物理符号系统(即符号操作系统)假设和有限合理性原理,就能通过逻辑推理来模拟智能。但被他们忽略的一点是,模拟智能的推理过程需要大量的先验知识支持,哪怕是在现代,生物学界也很难准确解释大脑中神经元的工作原理,因此也很难用符号系统刻画人脑逻辑。此外,连接主义则侧重于利用人工神经网络中神经元的连接去探索并模拟输入与输出之间存在的某种关系,这个过程不需要任何先验知识,其核心思想是“大量简单的计算单元连接到一起可以实现智能行为”,这种思想也推动了反向传播等多种神经网络方法的应用,并发展了包括长短时记忆模型在内的经典建模方法。2019年3月27日,ACM 正式宣布将图灵奖授予 Yoshua Bengio, Geoffrey Hinton 和 Yann LeCun,以表彰他们提出的概念和工作使得深度学习神经网络有了重大突破,这三位获奖人均是人工智能连接主义学派的主要代表,从这件事中也可以看出连接主义对当代人工智能和深度学习的巨大影响。
\parinterval 人工智能领域始终存在着符号主义和联结主义之争。早期的人工智能研究在认知学中被称为{\small\bfnew{符号主义}}\index{符号主义}(Symbolicism)\index{Symbolicism},符号主义认为人工智能源于数理逻辑,希望将世界万物的所有运转方式归纳成像文法一样符合逻辑规律的推导过程。符号主义的支持者们坚信基于物理符号系统(即符号操作系统)假设和有限合理性原理,就能通过逻辑推理来模拟智能。但被他们忽略的一点是,模拟智能的推理过程需要大量的先验知识支持,哪怕是在现代,生物学界也很难准确解释大脑中神经元的工作原理,因此也很难用符号系统刻画人脑逻辑。此外,联结主义则侧重于利用人工神经网络中神经元的连接去探索并模拟输入与输出之间存在的某种关系,这个过程不需要任何先验知识,其核心思想是“大量简单的计算单元连接到一起可以实现智能行为”,这种思想也推动了反向传播等多种神经网络方法的应用,并发展了包括长短时记忆模型在内的经典建模方法。2019年3月27日,ACM 正式宣布将图灵奖授予 Yoshua Bengio, Geoffrey Hinton 和 Yann LeCun,以表彰他们提出的概念和工作使得深度学习神经网络有了重大突破,这三位获奖人均是人工智能联结主义学派的主要代表,从这件事中也可以看出联结主义对当代人工智能和深度学习的巨大影响。
\vspace{0.3em}
\parinterval 2)分布式表示
......@@ -127,7 +127,7 @@
\subsubsection{1. 端到端学习和表示学习}
\parinterval 端到端学习使机器学习不再依赖传统的特征工程方法,因此也不需要繁琐的数据预处理、特征选择、降维等过程,而是直接利用人工神经网络自动从输入数据中提取、组合更复杂的特征,大大提升了模型能力和工程效率。以图\ref{fig:9-2}中的图像分类为例,在传统方法中,图像分类需要很多阶段的处理。首先,需要提取一些手工设计的图像特征,在将其降维之后,需要利用SVM等分类算法对其进行分类。与这种多阶段的流水线似的处理流程相比,端到端深度学习只训练一个神经网络,输入就是图片的像素表示,输出直接是分类类别。
\parinterval 端到端学习使机器学习不再依赖传统的特征工程方法,因此也不需要繁琐的数据预处理、特征选择、降维等过程,而是直接利用人工神经网络自动从输入数据中提取、组合更复杂的特征,大大提升了模型能力和工程效率。以图\ref{fig:9-2}中的图像分类为例,在传统方法中,图像分类需要很多阶段的处理。首先,需要提取一些手工设计的图像特征,在将其降维之后,需要利用SVM等分类算法对其进行分类。与这种多阶段的流水线似的处理流程相比,端到端深度学习只训练一个神经网络,输入图片的像素表示,输出是图片的类别。
%----------------------------------------------
\begin{figure}[htp]
......@@ -457,11 +457,11 @@ l_p({\mathbi{x}}) & = & {\Vert{\mathbi{x}}\Vert}_p \nonumber \\
\parinterval $ l_2 $范数为向量的各个元素平方和的二分之一次方:
\begin{eqnarray}
{\Vert{\mathbi{x}}\Vert}_2&=&\sqrt{\sum_{i=1}^{n}{{x_{i}}^2}} \nonumber \\
&=&\sqrt{{{\mathbi{x}}\cdot\mathbi{x}}^{\textrm T}}
&=&\sqrt{{{\mathbi{x}}\mathbi{x}}^{\textrm T}}
\label{eq:9-16}
\end{eqnarray}
\parinterval $ l_2 $范数被称为{\small\bfnew{欧几里得范数}}\index{欧几里得范数}(Euclidean Norm)\index{Euclidean Norm}。从几何角度,向量也可以表示为从原点出发的一个带箭头的有向线段,其$ l_2 $范数为线段的长度,也常被称为向量的模。$ l_2 $ 范数在机器学习中非常常用。向量$ {\mathbi{x}} $$ l_2 $范数经常简化表示为$ \Vert{\mathbi{x}}\Vert $,可以通过点积$ {{\mathbi{x}}\cdot \mathbi{x}}^{\textrm T} $进行计算。
\parinterval $ l_2 $范数被称为{\small\bfnew{欧几里得范数}}\index{欧几里得范数}(Euclidean Norm)\index{Euclidean Norm}。从几何角度,向量也可以表示为从原点出发的一个带箭头的有向线段,其$ l_2 $范数为线段的长度,也常被称为向量的模。$ l_2 $ 范数在机器学习中非常常用。向量$ {\mathbi{x}} $$ l_2 $范数经常简化表示为$ \Vert{\mathbi{x}}\Vert $,可以通过点积$ {{\mathbi{x}} \mathbi{x}}^{\textrm T} $进行计算。
\parinterval $ l_{\infty} $范数为向量的各个元素的最大绝对值:
\begin{eqnarray}
......@@ -492,7 +492,7 @@ l_p({\mathbi{x}}) & = & {\Vert{\mathbi{x}}\Vert}_p \nonumber \\
%----------------------------------------------------------------------------------------
\subsection{人工神经元和感知机}
\parinterval 生物学中,神经元是神经系统的基本组成单元。同样,人工神经元是人工神经网络的基本单元。在人们的想象中,人工神经元应该与生物神经元类似。但事实上,二者在形态上是有明显差别的。如图\ref{fig:9-4} 是一个典型的人工神经元,其本质是一个形似$ y=f({\mathbi{x}}\cdot {\mathbi{w}}+b) $的函数。显而易见,一个神经元主要由$ {\mathbi{x}} $$ {\mathbi{w}} $$ b $$ f $四个部分构成。其中$ {\mathbi{x}} $是一个形如$ (x_1,x_2,\dots,x_n) $ 的实数向量,在一个神经元中担任“输入”的角色。$ {\mathbi{w}} $通常被理解为神经元连接的{\small\sffamily\bfseries{权重}}\index{权重}(Weight)\index{Weight}(对于一个人工神经元,权重是一个向量,表示为$ {\mathbi{w}} $;对于由多个神经元组成的神经网络,权重是一个矩阵,表示为$ {\mathbi{W}} $),其中的每一个元素都对应着一个输入和一个输出,代表着“某输入对某输出的贡献程度”。$ b $被称作偏置(对于一个人工神经元,偏置是一个实数,表示为$b$;对于神经网络中的某一层,偏置是一个向量,表示为${\mathbi{b}}$)。$ f $被称作激活函数,用于对输入向量各项加权和后进行某种变换。可见,一个人工神经元的功能是将输入向量与权重矩阵右乘(做内积)后,加上偏置量,经过一个激活函数得到一个标量结果。
\parinterval 生物学中,神经元是神经系统的基本组成单元。同样,人工神经元是人工神经网络的基本单元。在人们的想象中,人工神经元应该与生物神经元类似。但事实上,二者在形态上是有明显差别的。如图\ref{fig:9-4} 是一个典型的人工神经元,其本质是一个形似$ y=f({\mathbi{x}}{\mathbi{w}}+b) $的函数。显而易见,一个神经元主要由$ {\mathbi{x}} $$ {\mathbi{w}} $$ b $$ f $四个部分构成。其中$ {\mathbi{x}} $是一个形如$ (x_1,x_2,\dots,x_n) $ 的实数向量,在一个神经元中担任“输入”的角色。$ {\mathbi{w}} $通常被理解为神经元连接的{\small\sffamily\bfseries{权重}}\index{权重}(Weight)\index{Weight}(对于一个人工神经元,权重是一个向量,表示为$ {\mathbi{w}} $;对于由多个神经元组成的神经网络,权重是一个矩阵,表示为$ {\mathbi{W}} $),其中的每一个元素都对应着一个输入和一个输出,代表着“某输入对某输出的贡献程度”。$ b $被称作偏置(对于一个人工神经元,偏置是一个实数,表示为$b$;对于神经网络中的某一层,偏置是一个向量,表示为${\mathbi{b}}$)。$ f $被称作激活函数,用于对输入向量各项加权和后进行某种变换。可见,一个人工神经元的功能是将输入向量与权重矩阵右乘(做内积)后,加上偏置量,经过一个激活函数得到一个标量结果。
%----------------------------------------------
\begin{figure}[htp]
......@@ -704,13 +704,13 @@ x_1\cdot w_1+x_2\cdot w_2+x_3\cdot w_3 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\vspace{0.5em}
\item 从代数角度看,对于线性空间$ \textrm V $,任意$ {\mathbi{a}}$${\mathbi{a}}\in {\textrm V} $和数域中的任意$ \alpha $,线性变换$ T(\cdot) $需满足:$ T({\mathbi{a}}+{\mathbi{b}})=T({\mathbi{a}})+T({\mathbi{b}}) $,且$ T(\alpha {\mathbi{a}})=\alpha T({\mathbi{a}}) $
\vspace{0.5em}
\item 从几何角度看,公式中的${\mathbi{x}}\cdot {\mathbi{W}}+{\mathbi{b}}$${\mathbi{x}}$右乘${\mathbi{W}}$相当于对$ {\mathbi{x}} $进行旋转变换。例如,对三个点$ (0,0) $$ (0,1) $$ (1,0) $及其围成的矩形区域右乘如下矩阵:
\item 从几何角度看,公式中的${\mathbi{x}}{\mathbi{W}}+{\mathbi{b}}$${\mathbi{x}}$右乘${\mathbi{W}}$相当于对$ {\mathbi{x}} $进行旋转变换。例如,对三个点$ (0,0) $$ (0,1) $$ (1,0) $及其围成的矩形区域右乘如下矩阵:
\begin{eqnarray}
{\mathbi{W}}&=&\begin{pmatrix} 1 & 0 & 0\\ 0 & -1 & 0\\ 0 & 0 & 1\end{pmatrix}
\label{eq:9-106}
\end{eqnarray}
这样,矩形区域由第一象限旋转90度到了第四象限,如图\ref{fig:9-13}第一步所示。公式$ {\mathbi{x}}\cdot {\mathbi{W}}+{\mathbi{b}}$中的公式中的${\mathbi{b}}$相当于对其进行平移变换。其过程如图\ref{fig:9-13} 第二步所示,偏置矩阵$ {\mathbi{b}}=\begin{pmatrix} 0.5 & 0 & 0\\ 0 & 0 & 0\\ 0 & 0 & 0\end{pmatrix} $将矩形区域沿$x$轴向右平移了一段距离。
这样,矩形区域由第一象限旋转90度到了第四象限,如图\ref{fig:9-13}第一步所示。公式$ {\mathbi{x}} {\mathbi{W}}+{\mathbi{b}}$中的公式中的${\mathbi{b}}$相当于对其进行平移变换。其过程如图\ref{fig:9-13} 第二步所示,偏置矩阵$ {\mathbi{b}}=\begin{pmatrix} 0.5 & 0 & 0\\ 0 & 0 & 0\\ 0 & 0 & 0\end{pmatrix} $将矩形区域沿$x$轴向右平移了一段距离。
%----------------------------------------------
\begin{figure}[htp]
......@@ -902,7 +902,7 @@ x_1\cdot w_1+x_2\cdot w_2+x_3\cdot w_3 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\subsubsection{1. 张量}
\parinterval 对于神经网络中的某层神经元${\mathbi{y}}=f({\mathbi{x}}\cdot {\mathbi{W}}+{\mathbi{b}}) $,其中$ {\mathbi{W}} $是权重矩阵,例如$ \begin{pmatrix} 1 & 2\\ 3 & 4\end{pmatrix} $${\mathbi{b}} $ 是偏置向量,例如$ (1,3) $。在这里,输入$ {\mathbi{x}} $和输出$ {\mathbi{y}} $,可以不是简单的向量或是矩阵形式,而是深度学习中更加通用的数学量\ \dash \ {\small\bfnew{张量}}\index{张量}(Tensor)\index{Tensor},比如公式\eqref{eq:9-107}中的几种情况都可以看作是深度学习中定义数据的张量:
\parinterval 对于神经网络中的某层神经元${\mathbi{y}}=f({\mathbi{x}}{\mathbi{W}}+{\mathbi{b}}) $,其中$ {\mathbi{W}} $是权重矩阵,例如$ \begin{pmatrix} 1 & 2\\ 3 & 4\end{pmatrix} $${\mathbi{b}} $ 是偏置向量,例如$ (1,3) $。在这里,输入$ {\mathbi{x}} $和输出$ {\mathbi{y}} $,可以不是简单的向量或是矩阵形式,而是深度学习中更加通用的数学量\ \dash \ {\small\bfnew{张量}}\index{张量}(Tensor)\index{Tensor},比如公式\eqref{eq:9-107}中的几种情况都可以看作是深度学习中定义数据的张量:
\begin{eqnarray}
{\mathbi{x}}&=&\begin{pmatrix} -1 & 3\end{pmatrix}\qquad
{\mathbi{x}}\;\;=\;\;\begin{pmatrix} -1 & 3\\ 0.2 & 2\end{pmatrix}\qquad
......@@ -931,7 +931,7 @@ x_1\cdot w_1+x_2\cdot w_2+x_3\cdot w_3 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\subsubsection{2. 张量的矩阵乘法}
\parinterval 对于一个单层神经网络,$ {\mathbi{y}}=f({\mathbi{x}}\cdot{\mathbi{W}}+{\mathbi{b}}) $中的${\mathbi{x}}\cdot {\mathbi{W}} $表示对输入${\mathbi{x}} $进行线性变换,其中${\mathbi{x}}$是输入张量,$ {\mathbi{W}}$是权重矩阵。$ {\mathbi{x}}\cdot {\mathbi{W}} $表示的是矩阵乘法,需要注意的是这里是矩阵乘法而不是张量乘法。
\parinterval 对于一个单层神经网络,$ {\mathbi{y}}=f({\mathbi{x}}{\mathbi{W}}+{\mathbi{b}}) $中的${\mathbi{x}}{\mathbi{W}} $表示对输入${\mathbi{x}} $进行线性变换,其中${\mathbi{x}}$是输入张量,$ {\mathbi{W}}$是权重矩阵。$ {\mathbi{x}} {\mathbi{W}} $表示的是矩阵乘法,需要注意的是这里是矩阵乘法而不是张量乘法。
\parinterval 张量乘以矩阵是怎样计算呢?可以先回忆一下\ref{sec:9.2.1}节的线性代数的知识。假设$ {\mathbi{A}} $$ m\times p $的矩阵,$ {\mathbi{B}} $$ p\times n $的矩阵,对${\mathbi{A}} $${\mathbi{B}}$ 作矩阵乘积的结果是一个$ m\times n $的矩阵${\mathbi{C}}$,其中矩阵${\mathbi{C}}$中第$ i $行、第$ j $列的元素可以表示为:
\begin{eqnarray}
......@@ -969,7 +969,7 @@ x_1\cdot w_1+x_2\cdot w_2+x_3\cdot w_3 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\subsubsection{3. 张量的单元操作}
\vspace{0.5em}
\parinterval 对于神经网络中的某层神经元$ {\mathbi{y}}=f({\mathbi{x}}\cdot {\mathbi{W}}+{\mathbi{b}}) $,也包含有其他张量单元操作:1)加法:$ {\mathbi{s}}+{\mathbi{b}}$,其中张量$ {\mathbi{s}}={\mathbi{x}}\cdot {\mathbi{W}} $;2)激活函数:$ f(\cdot) $。具体来说:
\parinterval 对于神经网络中的某层神经元$ {\mathbi{y}}=f({\mathbi{x}} {\mathbi{W}}+{\mathbi{b}}) $,也包含有其他张量单元操作:1)加法:$ {\mathbi{s}}+{\mathbi{b}}$,其中张量$ {\mathbi{s}}={\mathbi{x}}{\mathbi{W}} $;2)激活函数:$ f(\cdot) $。具体来说:
\begin{itemize}
\vspace{0.5em}
......@@ -1084,11 +1084,11 @@ f(x)&=&\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\parinterval 它可以被描述为公式\eqref{eq:9-27},其中隐藏层的激活函数是Tanh函数,输出层的激活函数是Sigmoid函数,${\mathbi{W}}^{[1]}$${\mathbi{b}}^{[1]}$分别表示第一层的权重矩阵和偏置,${\mathbi{W}}^{[2]}$$b^{[2]}$分别表示第二层的权重矩阵和偏置\footnote{注意这里${\mathbi{b}}^{[1]}$是向量而$b^{[2]}$是标量,因而前者加粗后者未加粗}
\begin{eqnarray}
y&=&{\textrm{Sigmoid}}({\textrm{Tanh}}({\mathbi{x}}\cdot {\mathbi{W}}^{[1]}+{\mathbi{b}}^{[1]})\cdot {\mathbi{W}}^{[2]}+ b^{[2]} )
y&=&{\textrm{Sigmoid}}({\textrm{Tanh}}({\mathbi{x}}{\mathbi{W}}^{[1]}+{\mathbi{b}}^{[1]}){\mathbi{W}}^{[2]}+ b^{[2]} )
\label{eq:9-27}
\end{eqnarray}
\parinterval 前向计算实现如图\ref{fig:9-38}所示,图中对各张量和其他参数的形状做了详细说明。输入$ {\mathbi{x}}=(x_1,x_2,x_3) $是一个$1\times 3$的张量,其三个维度分别对应天空状况、低空气温、水平气压三个方面的数据。输入数据经过隐藏层的线性变换$ {\mathbi{x}}\cdot {\mathbi{W}}^{[1]}+{\mathbi{b}}^{[1]}$和Tanh函数的激活,得到新的张量$ {\mathbi{a}}=(a_1,a_2) $,其中$a_1$$a_2$分别对应着从输入数据中提取出的温度和风速两方面特征;神经网络在获取到天气情况的特征$ {\mathbi{a}}$后,继续对其进行线性变换${\mathbi{a}}\cdot {\mathbi{W}}^{[2]}+ b^{[2]} $和Sigmoid函数的激活操作,得到神经网络的最终输出$ y $,即神经网络此时预测的穿衣指数。
\parinterval 前向计算实现如图\ref{fig:9-38}所示,图中对各张量和其他参数的形状做了详细说明。输入$ {\mathbi{x}}=(x_1,x_2,x_3) $是一个$1\times 3$的张量,其三个维度分别对应天空状况、低空气温、水平气压三个方面的数据。输入数据经过隐藏层的线性变换$ {\mathbi{x}} {\mathbi{W}}^{[1]}+{\mathbi{b}}^{[1]}$和Tanh函数的激活,得到新的张量$ {\mathbi{a}}=(a_1,a_2) $,其中$a_1$$a_2$分别对应着从输入数据中提取出的温度和风速两方面特征;神经网络在获取到天气情况的特征$ {\mathbi{a}}$后,继续对其进行线性变换${\mathbi{a}} {\mathbi{W}}^{[2]}+ b^{[2]} $和Sigmoid函数的激活操作,得到神经网络的最终输出$ y $,即神经网络此时预测的穿衣指数。
%----------------------------------------------
\begin{figure}[htp]
\centering
......@@ -1109,7 +1109,7 @@ y&=&{\textrm{Sigmoid}}({\textrm{Tanh}}({\mathbi{x}}\cdot {\mathbi{W}}^{[1]}+{\ma
\sectionnewpage
\section{神经网络的参数训练}
\parinterval 简单来说,神经网络可以被看作是由变量和函数组成的表达式,例如:$ {\mathbi{y}}={\mathbi{x}}+{\mathbi{b}} $$ {\mathbi{y}}={\textrm{ReLU}}({\mathbi{x}}\cdot {\mathbi{W}}+{\mathbi{b}}) $$ {\mathbi{y}}={\textrm{Sigmoid}}({\textrm{ReLU}}({\mathbi{x}}\cdot {\mathbi{W}}^{[1]}+{\mathbi{b}}^{[1]})\cdot {\mathbi{W}}^{[2]}+{\mathbi{b}}^{[2]}) $等等,其中的$ {\mathbi{x}} $$ {\mathbi{y}} $作为输入和输出向量, ${\mathbi{W}}$${\mathbi{b}}$等其他变量作为{\small\sffamily\bfseries{模型参数}}\index{模型参数}(Model Parameters)\index{Model Parameters}。确定了函数表达式和模型参数,也就确定了神经网络模型。通常,表达式的形式需要系统开发者设计,而模型参数的数量有时会非常巨大,因此需要自动学习,这个过程也被称为模型学习或训练。为了实现这个目标,通常会准备一定量的带有标准答案的数据,称之为有标注数据。这些数据会用于对模型参数的学习,这也对应了统计模型中的参数估计过程。在机器学习中,一般把这种使用有标注数据进行统计模型参数训练的过程称为{\small\sffamily\bfseries{有指导的训练}}\index{有指导的训练}{\small\sffamily\bfseries{有监督的训练}}\index{有监督的训练}(Supervised Training)\index{Supervised Training}。在本章中,如果没有特殊说明,模型训练都是指有监督的训练。那么神经网络内部是怎样利用有标注数据对参数进行训练的呢?
\parinterval 简单来说,神经网络可以被看作是由变量和函数组成的表达式,例如:$ {\mathbi{y}}={\mathbi{x}}+{\mathbi{b}} $$ {\mathbi{y}}={\textrm{ReLU}}({\mathbi{x}} {\mathbi{W}}+{\mathbi{b}}) $$ {\mathbi{y}}={\textrm{Sigmoid}}({\textrm{ReLU}}({\mathbi{x}}{\mathbi{W}}^{[1]}+{\mathbi{b}}^{[1]}){\mathbi{W}}^{[2]}+{\mathbi{b}}^{[2]}) $等等,其中的$ {\mathbi{x}} $$ {\mathbi{y}} $作为输入和输出向量, ${\mathbi{W}}$${\mathbi{b}}$等其他变量作为{\small\sffamily\bfseries{模型参数}}\index{模型参数}(Model Parameters)\index{Model Parameters}。确定了函数表达式和模型参数,也就确定了神经网络模型。通常,表达式的形式需要系统开发者设计,而模型参数的数量有时会非常巨大,因此需要自动学习,这个过程也被称为模型学习或训练。为了实现这个目标,通常会准备一定量的带有标准答案的数据,称之为有标注数据。这些数据会用于对模型参数的学习,这也对应了统计模型中的参数估计过程。在机器学习中,一般把这种使用有标注数据进行统计模型参数训练的过程称为{\small\sffamily\bfseries{有指导的训练}}\index{有指导的训练}{\small\sffamily\bfseries{有监督的训练}}\index{有监督的训练}(Supervised Training)\index{Supervised Training}。在本章中,如果没有特殊说明,模型训练都是指有监督的训练。那么神经网络内部是怎样利用有标注数据对参数进行训练的呢?
\parinterval 为了回答这个问题,可以把模型参数的学习过程看作是一个优化问题,即找到一组参数,使得模型达到某种最优的状态。这个问题又可以被转化为两个新的问题:
......@@ -1301,7 +1301,7 @@ J({\bm \theta})&=&\frac{1}{m}\sum_{i=j}^{j+m-1}{L({\mathbi{x}}^{[i]},{\mathbi{y}
\noindent {\small\sffamily\bfseries{2)符号微分\index{符号微分}(Symbolic Differentiation)\index{Symbolic Differentiation}}}
\vspace{0.5em}
\parinterval 顾名思义,符号微分就是通过建立符号表达式求解微分的方法:借助符号表达式和求导公式,推导出目标函数关于自变量的微分表达式,最后再带入具体数值得到微分结果。例如,对于表达式$ L({\bm \theta})={\mathbi{x}}\cdot {\bm \theta}+2{\bm \theta}^2 $,可以手动推导出微分表达式$ \frac{\partial L({\bm \theta})}{\partial {\bm \theta}}=\mathbi{x}+4{\bm \theta} $,最后将具体数值$ \mathbi{x} = {(\begin{array}{cc} 2 & -3\end{array})} $$ {\bm \theta} = {(\begin{array}{cc} -1 & 1\end{array})} $带入后,得到微分结果$\frac{\partial L({\bm \theta})}{\partial {\bm \theta}}= {(\begin{array}{cc} 2 & -3\end{array})}+4{(\begin{array}{cc} -1 & 1\end{array})}= {(\begin{array}{cc} -2 & 1\end{array})}$
\parinterval 顾名思义,符号微分就是通过建立符号表达式求解微分的方法:借助符号表达式和求导公式,推导出目标函数关于自变量的微分表达式,最后再带入具体数值得到微分结果。例如,对于表达式$ L({\bm \theta})={\mathbi{x}}{\bm \theta}+2{\bm \theta}^2 $,可以手动推导出微分表达式$ \frac{\partial L({\bm \theta})}{\partial {\bm \theta}}=\mathbi{x}+4{\bm \theta} $,最后将具体数值$ \mathbi{x} = {(\begin{array}{cc} 2 & -3\end{array})} $$ {\bm \theta} = {(\begin{array}{cc} -1 & 1\end{array})} $带入后,得到微分结果$\frac{\partial L({\bm \theta})}{\partial {\bm \theta}}= {(\begin{array}{cc} 2 & -3\end{array})}+4{(\begin{array}{cc} -1 & 1\end{array})}= {(\begin{array}{cc} -2 & 1\end{array})}$
\parinterval 使用这种求梯度的方法,要求必须将目标函数转化成一种完整的数学表达式,这个过程中存在{\small\bfnew{表达式膨胀}}\index{表达式膨胀}(Expression Swell)\index{Expression Swell}的问题,很容易导致符号微分求解的表达式急速“膨胀”,大大增加系统存储和处理表达式的负担。关于这个问题的一个实例请看表\ref{tab:9-4}。在深层的神经网络中,神经元数量和参数量极大,损失函数的表达式会非常冗长,不易存储和管理,而且,仅仅写出损失函数的微分表达式就是一个很庞大的工作量。从另一方面来说,这里真正需要的是微分的结果值,而不是微分表达式,推导微分表达式仅仅是求解过程中的中间产物。
......@@ -1912,7 +1912,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f
\parinterval $ {\mathbi{o}}_{i-3} $$ {\mathbi{o}}_{i-2} $$ {\mathbi{o}}_{i-1} $为该语言模型的输入(绿色方框),输入为每个词(如上文的$ w_{i-1}$$ w_{i-2}$等)的One-hot向量表示(维度大小与词表大小一致),每个One-hot向量仅一维为1,其余为0,比如:$ (0,0,1,\dots,0) $ 表示词表中第三个单词。之后把One-hot向量乘以一个矩阵$ \mathbi{C} $得到单词的分布式表示(紫色方框)。令$ {\mathbi{o}}_i $为第$ i $个词的One-hot表示,$ {\mathbi{e}}_i $为第$ i $个词的分布式表示,则分布式表示$ {\mathbi{e}}_i $的计算方式如下:
\begin{eqnarray}
{\mathbi{e}}_i&=&{\mathbi{o}}_i\cdot{\mathbi{C}}
{\mathbi{e}}_i&=&{\mathbi{o}}_i{\mathbi{C}}
\label{eq:9-60}
\end{eqnarray}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论