Commit af4b1dd3 by zengxin

合并分支 'caorunzhe' 到 'zengxin'

Caorunzhe

查看合并请求 !704
parents fe3b090d d7f57e4f
\begin{tikzpicture}
\tikzstyle{node} = [minimum height=1.0*1.2em,draw,fill=green!20]
\tikzstyle{legend} = [minimum height=1.0*1.2em,minimum width=1.0*1.2em,draw]
\tikzstyle{node2} = [minimum width=1.0*1.2em,minimum height=4.1*1.2em,draw,fill=blue!20]
\node[node,minimum width=2.8*1.2em] (node1) at (0,0) {};
\node[node,minimum width=4.0*1.2em,anchor=north west] (node2) at (node1.south west) {};
\node[node,minimum width=3.2*1.2em,anchor=north west] (node3) at (node2.south west) {};
\node[node,minimum width=3.0*1.2em,anchor=north west] (node4) at (node3.south west) {};
\node[node2,anchor = north west] (grad1) at ([xshift=1.2em]node1.north east) {};
\node[node,minimum width=3.7*1.2em,anchor=north west] (node5) at (grad1.north east) {};
\node[node,minimum width=2.8*1.2em,anchor=north west] (node6) at (node5.south west) {};
\node[node,minimum width=3.2*1.2em,anchor=north west] (node7) at (node6.south west) {};
\node[node,minimum width=4.0*1.2em,anchor=north west] (node8) at (node7.south west) {};
\node[font=\footnotesize,anchor=east] (line1) at (node1.west) {GPU1};
\node[font=\footnotesize,anchor=east] (line2) at (node2.west) {GPU2};
\node[font=\footnotesize,anchor=east] (line3) at (node3.west) {GPU3};
\node[font=\footnotesize,anchor=east] (line4) at (node4.west) {GPU4};
\node[node2,anchor = north west] (grad2) at ([xshift=0.3em]node5.north east) {};
\draw[->,thick] (-1.4em*1.2,-3.62*1.2em) -- (9em*1.2,-3.62*1.2em);
\node[node,minimum width=2.8*1.2em] (node9) at (16em,0) {};
\node[node,minimum width=4.0*1.2em,anchor=north west] (node10) at (node9.south west) {};
\node[node,minimum width=3.2*1.2em,anchor=north west] (node11) at (node10.south west) {};
\node[node,minimum width=3.0*1.2em,anchor=north west] (node12) at (node11.south west) {};
\node[node,minimum width=3.7*1.2em,anchor=north west] (node13) at (node9.north east) {};
\node[node,minimum width=2.8*1.2em,anchor=north west] (node14) at (node10.north east) {};
\node[node,minimum width=3.2*1.2em,anchor=north west] (node15) at (node11.north east) {};
\node[node,minimum width=4.0*1.2em,anchor=north west] (node16) at (node12.north east) {};
\node[node2,anchor = north west] (grad3) at ([xshift=0.5em]node13.north east) {};
\node[font=\footnotesize,anchor=east] (line1) at (node9.west) {GPU1};
\node[font=\footnotesize,anchor=east] (line2) at (node10.west) {GPU2};
\node[font=\footnotesize,anchor=east] (line3) at (node11.west) {GPU3};
\node[font=\footnotesize,anchor=east] (line4) at (node12.west) {GPU4};
\draw[->,thick] (node12.south west) -- ([xshift=3em]node16.south east);
\begin{pgfonlayer}{background}
\node [rectangle,inner sep=-0.0em,draw] [fit = (node1) (node2) (node3) (node4)] (box1) {};
\node [rectangle,inner sep=-0.0em,draw] [fit = (node5) (node6) (node7) (node8)] (box2) {};
\node [rectangle,inner sep=-0.0em,draw] [fit = (node9) (node13) (node12) (node16)] (box2) {};
\end{pgfonlayer}
\node[font=\footnotesize,anchor=north] (legend1) at ([xshift=3em]node4.south) {一步一更新};
\node[font=\footnotesize,anchor=north] (legend2) at ([xshift=2.5em]node12.south) {累积两步更新};
\node[font=\footnotesize,anchor=north] (time1) at (grad2.south) {time};
\node[font=\footnotesize,anchor=north] (time1) at (grad3.south) {time};
\node[legend] (legend3) at (2em,2em) {};
\node[font=\footnotesize,anchor=west] (idle) at (legend3.east) {:空闲};
\node[legend,anchor=west,draw,fill=green!30] (legend4) at ([xshift = 2em]idle.east) {};
\node[font=\footnotesize,anchor=west] (FB) at (legend4.east) {:前向/反向};
\node[legend,anchor=west,draw,fill=blue!30] (legend5) at ([xshift = 2em]FB.east) {};
\node[font=\footnotesize,anchor=west] (grad_sync) at (legend5.east) {:梯度更新};
\end{tikzpicture}
\ No newline at end of file
......@@ -19,10 +19,10 @@
\node[node,anchor = west] (node8) at ([xshift = 2em,yshift = 2em]node7.east) {对于词表外的词lowest};
\node[node,anchor = north west] (node9) at ([yshift = 0.3em]node8.south west) {可以被分割为low est};
\node[node,font=\scriptsize,anchor = north,fill=ugreen!5,drop shadow] (dict) at ([xshift = 8em,yshift = -5em]node6.south){\begin{tabular}{llllll}
\multirow{3}{*}{子词词表:} & `es' & `est' & `est$<$e$>$' & `lo' & `low' \\
& `ne' & `new'&`newest$<$e$>$' & `low$<$e$>$'& `wi'\\
& `wid' & `widest$<$e$>$' & `lowe' & `lower'& `lower$<$e$>$'
\node[node,font=\scriptsize,anchor = north,fill=ugreen!5,drop shadow] (dict) at ([xshift = 5em,yshift = -5em]node6.south){\begin{tabular}{llllll}
\multirow{3}{*}{符号合并表:} & ('e','s') & ('es','t') & ('est','$<$e$>$') & ('l','o') & ('lo','w') \\
& ('n','e') & ('ne','w') & ('new','est$<$e$>$') & ('low','$<$e$>$') & 'w','i') \\
& ('wi','d') & ('wid','est$<$e$>$') & ('low','e') & ('lowe','r') & ('lower','$<$e$>$')
\end{tabular}};
\node[node,anchor=west] (line1) at ([xshift = 8em]node1.south east) {按字符拆分,并添加};
......
\begin{tikzpicture}
\setlength{\base}{1.2em}
\tikzstyle{node} = [rounded corners=1pt,minimum width=1.2em,minimum height=1.2em,draw,fill=green!30!white]
\tikzstyle{node2} = [rounded corners=1pt,minimum width=1.2em,minimum height=1.2em,draw,fill=blue!30!white]
\node[node] (enc1) at (0,0) {};
\node[node] (enc2) at ([xshift = \base]enc1.east) {};
\node[node] (enc3) at ([xshift = \base]enc2.east) {};
\node[node] (enc4) at ([xshift = \base]enc3.east) {};
\node[node] (enc5) at ([xshift = \base]enc4.east) {};
\node[node] (enc6) at ([xshift = \base]enc5.east) {};
\node[] (enc7) at ([xshift = \base]enc6.east) {...};
\node[node] (enc8) at ([xshift = \base]enc7.east) {};
\node[node] (enc9) at ([xshift = \base]enc8.east) {};
\node[node] (enc10) at ([xshift = \base]enc9.east) {};
\node[font=\scriptsize,rotate=270] (src) at ([xshift = -\base]enc1.west) {src};
\draw [->] ([xshift=-0.75em]enc1.west) -- (enc1.west);
\draw [decorate,decoration={brace}] ([yshift=0.3em]enc1.north west) to node [auto,anchor=south,font=\scriptsize] {$N$x} ([yshift=0.3em]enc10.north east);
\draw [->] (enc1.east) -- (enc2.west);
\draw [->] (enc2.east) -- (enc3.west);
\draw [->] (enc3.east) -- (enc4.west);
\draw [->] (enc4.east) -- (enc5.west);
\draw [->] (enc5.east) -- (enc6.west);
\draw [->] (enc8.east) -- (enc9.west);
\draw [->] (enc9.east) -- (enc10.west);
\node[node2,anchor=north] (dec1) at ([yshift=-2em]enc1.south) {};
\node[node2,anchor=north] (dec2) at ([yshift=-2em]enc2.south) {};
\node[node2,anchor=north] (dec3) at ([yshift=-2em]enc3.south) {};
\node[node2,anchor=north] (dec4) at ([yshift=-2em]enc4.south) {};
\node[node2,anchor=north] (dec5) at ([yshift=-2em]enc5.south) {};
\node[node2,anchor=north] (dec6) at ([yshift=-2em]enc6.south) {};
\node[font=\scriptsize,rotate=270] (tgt) at ([xshift = -\base]dec1.west) {tgt};
\node[font=\scriptsize,rotate=270] (tgt) at ([xshift = \base]dec6.east) {out};
\draw [->] ([xshift=-0.75em]dec1.west) -- (dec1.west);
\draw [->] (dec6.east) -- ([xshift=0.75em]dec6.east);
\draw [decorate,decoration={brace,mirror}] ([yshift=-0.3em]dec1.south west) to node [auto,anchor=north,font=\scriptsize] {6x} ([yshift=-0.3em]dec6.south east);
\draw [->] (dec1.east) -- (dec2.west);
\draw [->] (dec2.east) -- (dec3.west);
\draw [->] (dec3.east) -- (dec4.west);
\draw [->] (dec4.east) -- (dec5.west);
\draw [->] (dec5.east) -- (dec6.west);
\node[node] (enc_legend) at ([xshift = 2\base]enc10.east) {};
\node[node2,anchor=north] (dec_legend) at ([yshift = -\base]enc_legend.south) {};
\node[font=\scriptsize,anchor=west] (line1) at (enc_legend.east) {:编码层};
\node[font=\scriptsize,anchor=west] (line1) at (dec_legend.east) {:解码层};
%\node[node] (dec1) at ([xshift=4em]enc1.east) {Decoder};
%\node[node2] (enc2) at ([xshift=4em]dec1.east) {Encoder};
%\node[node] (dec2) at ([xshift=4em]enc2.east) {Decoder};
\coordinate (c1) at ([xshift=1em]enc10.east);
\coordinate (c2) at ([yshift=-1.6em]c1.south);
\draw [->,rounded corners] (enc10.east) -- (c1) -- (c2)--([yshift=1em]dec1.north) -- (dec1.north);
\draw [->,rounded corners] (enc10.east) -- (c1) -- (c2)--([yshift=1em]dec2.north) -- (dec2.north);
\draw [->,rounded corners] (enc10.east) -- (c1) -- (c2)--([yshift=1em]dec3.north) -- (dec3.north);
\draw [->,rounded corners] (enc10.east) -- (c1) -- (c2)--([yshift=1em]dec4.north) -- (dec4.north);
\draw [->,rounded corners] (enc10.east) -- (c1) -- (c2)--([yshift=1em]dec5.north) -- (dec5.north);
\draw [->,rounded corners] (enc10.east) -- (c1) -- (c2)--([yshift=1em]dec6.north) -- (dec6.north);
\end{tikzpicture}
\ No newline at end of file
\begin{tikzpicture}
\tikzstyle{node} = [minimum height=1.0*1.2em,draw,fill=green!20]
\node[node,minimum width=2.0*1.2em] (sent1) at (0,0) {};
\node[node,minimum width=5.0*1.2em,anchor=north west] (sent2) at (sent1.south west) {};
\node[node,minimum width=1.0*1.2em,anchor=north west] (sent3) at (sent2.south west) {};
\node[node,minimum width=3.0*1.2em,anchor=north west] (sent4) at (sent3.south west) {};
\node[node,minimum width=4.0*1.2em] (sent5) at (14em,0) {};
\node[node,minimum width=4.5*1.2em,anchor=north west] (sent6) at (sent5.south west) {};
\node[node,minimum width=4.5*1.2em,anchor=north west] (sent7) at (sent6.south west) {};
\node[node,minimum width=5*1.2em,anchor=north west] (sent8) at (sent7.south west) {};
\node[font=\footnotesize,anchor=east] (line1) at (sent1.west) {句子1};
\node[font=\footnotesize,anchor=east] (line2) at (sent2.west) {句子2};
\node[font=\footnotesize,anchor=east] (line3) at (sent3.west) {句子3};
\node[font=\footnotesize,anchor=east] (line4) at (sent4.west) {句子4};
\node[font=\footnotesize,anchor=east] (line5) at (sent5.west) {句子1};
\node[font=\footnotesize,anchor=east] (line6) at (sent6.west) {句子2};
\node[font=\footnotesize,anchor=east] (line7) at (sent7.west) {句子3};
\node[font=\footnotesize,anchor=east] (line8) at (sent8.west) {句子4};
\begin{pgfonlayer}{background}
\node [rectangle,inner sep=-0.0em,draw] [fit = (sent1) (sent2) (sent3) (sent4)] (box1) {};
\node [rectangle,inner sep=-0.0em,draw] [fit = (sent5) (sent6) (sent7) (sent8)] (box2) {};
\end{pgfonlayer}
\node[font=\footnotesize] (node1) at ([yshift=-3.4em]sent2.south) {随机生成};
\node[font=\footnotesize] (node2) at ([yshift=-1em]sent8.south) {排序生成};
\end{tikzpicture}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3,6 +3,7 @@
\tikzstyle{snode} = [draw,inner sep=1pt,minimum width=3em,minimum height=0.5em,rounded corners=1pt,fill=green!20!white]
\tikzstyle{pnode} = [draw,inner sep=1pt,minimum width=1em,minimum height=0.5em,rounded corners=1pt]
\node [anchor=west] (des) at (1.5,3) {\normalsize\bfnew{$\bm{m}$:显存\quad$\bm{t}$:时间\quad$\bm{m_1>m_2}$\quad$\bm{t_1>t_2}$}};
\node [anchor=west,snode] (s1) at (0,0) {\tiny{}};
\node [anchor=north west,snode,minimum width=6.3em] (s2) at ([yshift=-0.3em]s1.south west) {\tiny{}};
\node [anchor=north west,snode,minimum width=2em] (s3) at ([yshift=-0.3em]s2.south west) {\tiny{}};
......@@ -76,13 +77,5 @@
\draw [very thick,decorate,decoration={brace}] ([xshift=3pt]box1.north east) to node [midway,name=final] {} ([xshift=3pt]box1.south east);
\draw [very thick,decorate,decoration={brace}] ([xshift=3pt]box3.north east) to node [midway,name=final] {} ([xshift=3pt]box3.south east);
\node [rectangle,inner sep=0.5em,rounded corners=2pt,draw,fill=red!5,font=\scriptsize] at ([yshift=-2em,xshift=9em]sbi1.east) {
\begin{tabular}{l}
$m$: 显存 \\
$t$: 时间 \\
$m_1>m_2$ \\
$t_1>t_2$
\end{tabular}
};
\end{tikzpicture}
\ No newline at end of file
%%%------------------------------------------------------------------------------------------------------------
\begin{tikzpicture}
\scriptsize{
\begin{tikzpicture}
\scriptsize{
\begin{axis}[
width=8cm,
height=5cm,
yticklabel style={/pgf/number format/.cd,fixed,precision=2},
xticklabel style={color=white},
xlabel={\footnotesize{Beam Size}},ylabel={\footnotesize{BLEU}},
ymin=28.8,ymax=30.4,
xmin=0,xmax=10,
xtick={0,4,6,7,8,9,10},
ytick={28.8,29.0,29.2,29.4,29.6,29.8,30.0,30.2,30.4},
legend style={yshift=-5em,xshift=0em,legend cell align=left,legend plot pos=right}
width=8cm,
height=5cm,
yticklabel style={/pgf/number format/.cd,fixed,precision=2},
xticklabel style={/pgf/number format/.cd,fixed,precision=2},
xlabel={\footnotesize{$\log$\;(束大小)}},ylabel={\footnotesize{BLEU\ (\%)}},
ymin=28.8,ymax=30.4,
xmin=0,xmax=7,
xtick={0,1,2,3,4,5,6,7},
ytick={28.8,29.0,29.2,29.4,29.6,29.8,30.0,30.2,30.4},
xticklabels={0,1,2,3,4,5,6,7},
yticklabels={28.8,29.0,29.2,29.4,29.6,29.8,30.0,30.2,30.4},
legend style={yshift=-5em,xshift=0em,legend cell align=left,legend plot pos=right}
]
\addplot[purple,mark=square,mark=star,very thick] coordinates {(0,29.3) (4,29.7) (6,30.05) (7,30.1) (7.6,30.2) (8,30.3) (8.3,30.2) (8.7,30.08) (9,29.98) (9.6,29.6)(10,28.8) };
\addplot[purple,mark=square,mark=star,very thick] coordinates {(0,29.3) (1,29.7) (1.58,30.05) (2.32,30.1) (2.73,30.2) (3.32,30.3) (3.84,30.2) (4.23,30.08) (4.91,29.98) (5.81,29.6)(6.64,28.8) };
\end{axis}
}
\node[inner sep=0pt] at (0,-1em) {1};
\node[inner sep=0pt] at (9.15em,-1em) {2};
\node[inner sep=0pt] at (13.75em,-1em) {3};
\node[inner sep=0pt] at (16.05em,-1em) {5};
\node[inner sep=0pt] at (18.35em,-1em) {10};
\node[inner sep=0pt] at (20.65em,-1em) {30};
\node[inner sep=0pt] at (22.9em,-1em) {100};
\end{tikzpicture}
\end{tikzpicture}
......
......@@ -119,9 +119,9 @@
\draw[->,thick] ([yshift=-0.15em]dot3\i.north) -- ([yshift=-0.3em]attn2\i.south);
}
\node[anchor=north,align=left,inner sep=1pt,font=\footnotesize] () at (dot31.south) {(a) 标准的多层自注意力};
\node[anchor=north,align=left,inner sep=1pt,font=\footnotesize] () at (dot32.south) {(b) 共享自注意力};
\node[anchor=north,align=left,inner sep=1pt,font=\footnotesize] () at (dot33.south) {(c) 共享编码-解码注意力};
\node[anchor=north,align=left,inner sep=1pt,font=\footnotesize] () at (dot31.south) {\small{(a) 标准的多层自注意力}};
\node[anchor=north,align=left,inner sep=1pt,font=\footnotesize] () at (dot32.south) {\small{(b) 共享自注意力}};
\node[anchor=north,align=left,inner sep=1pt,font=\footnotesize] () at (dot33.south) {\small{(c) 共享编码-解码注意力}};
\end{scope}
\end{tikzpicture}
\ No newline at end of file
......@@ -3,7 +3,7 @@
\centering
\hspace*{\fill}
\subfigure[假设选择]
\subfigure[\small{假设选择}]
{
\begin{tikzpicture}[scale=0.5]
\tikzstyle{system} = [rectangle,very thick,minimum width=1cm,font=\tiny];
......@@ -33,7 +33,7 @@
\end{tikzpicture}
}
\hfill
\subfigure[预测融合]
\subfigure[\small{预测融合}]
{
\begin{tikzpicture}[scale=0.5]
\tikzstyle{system} = [rectangle,very thick,minimum width=1cm,font=\tiny];
......@@ -60,7 +60,7 @@
}
\hspace*{\fill}
\\
\subfigure[译文重组]
\subfigure[\small{译文重组}]
{
\begin{tikzpicture}[scale=0.5]
\tikzstyle{system} = [rectangle,very thick,minimum width=1cm,font=\tiny];
......
......@@ -65,7 +65,7 @@
\draw [->,line width=1pt] (out3) |- (plabel9.east);
\end{scope}
\node [anchor=north,font=\scriptsize] () at ([yshift=-0.2em]STANDARD.south) {(a) 标准方法};
\node [anchor=north,font=\scriptsize] () at ([xshift=1.2em]SELECTION.south) {(b) 词汇选择};
\node [anchor=north,font=\scriptsize] () at ([yshift=-0.2em]STANDARD.south) {\small(a) 标准方法};
\node [anchor=north,font=\scriptsize] () at ([xshift=1.2em]SELECTION.south) {\small(b) 词汇选择};
\end{tikzpicture}
\ No newline at end of file
......@@ -42,7 +42,7 @@
\node [] () at ([yshift=0.4cm]output3.north) {$\vdots$};
\end{scope}
\node [align=center,anchor=north,font=\small] () at ([yshift=-0.3cm]MULTIPLE.south) {\footnotesize{(a) 多系统输出结果融合}};
\node [align=center,anchor=north,font=\small] () at ([yshift=-0.3cm]SINGLE.south) {\footnotesize{(b) 单系统多输出结果融合}};
\node [align=center,anchor=north,font=\small] () at ([yshift=-0.3cm]MULTIPLE.south) {\small{(a) 多系统输出结果融合}};
\node [align=center,anchor=north,font=\small] () at ([yshift=-0.3cm]SINGLE.south) {\small{(b) 单系统多输出结果融合}};
\end{tikzpicture}
\ No newline at end of file
......@@ -6,10 +6,10 @@
\begin{tikzpicture}[node distance = 0,scale = 0.75]
\tikzstyle{every node}=[scale=0.75]
\node (encoder)[er,very thick,draw=taupegray,fill=ugreen!20]{\Large{编码器}};
\node (decoder_1)[er,very thick,draw=taupegray,right of=encoder,xshift=4cm,fill=red!20]{\Large{解码器1}};
\node (decoder_2)[er,very thick,draw=taupegray,right of=decoder_1,xshift=4cm,fill=red!20]{\Large{解码器2}};
\node (decoder_1)[er,very thick,draw=taupegray,right of=encoder,xshift=4cm,fill=red!20]{\Large{解码器}};
\node (decoder_2)[er,very thick,draw=taupegray,right of=decoder_1,xshift=4cm,fill=red!20]{\Large{解码器}};
\node (point)[right of=decoder_2,xshift=2.5cm,]{\LARGE{...}};
\node (decoder_3)[er,very thick,draw=taupegray,right of=point,xshift=2.5cm,fill=red!20]{\Large{解码器3}};
\node (decoder_3)[er,very thick,draw=taupegray,right of=point,xshift=2.5cm,fill=red!20]{\Large{解码器}};
\draw [->,very thick,draw=black!70]([xshift=0.2cm]encoder.east) -- ([xshift=-0.2cm]decoder_1.west);
\draw [->,very thick,draw=black!70]([xshift=0.2cm]decoder_1.east) -- ([xshift=-0.2cm]decoder_2.west);
\draw [->,very thick,draw=black!70]([xshift=0.2cm]decoder_2.east) -- ([xshift=-0.1cm]point.west);
......
......@@ -5,7 +5,7 @@
\node [anchor=south] (text) at ([xshift=0.5em,yshift=-3.5em]part1.south) {\scriptsize{源语言句子(编码器输出)}};
\node [anchor=east,draw=black!70,rounded corners,drop shadow,very thick,minimum width=6em,minimum height=3.5em,fill=blue!15,align=center,text=black] (part2) at ([xshift=10em]part1.east) {\scriptsize{搜索模块}};
\node [anchor=south] (text1) at ([xshift=0.5em,yshift=2.2em]part1.north) {\scriptsize{已经生成的目标语单词}};
\node [anchor=south] (text1) at ([xshift=0.5em,yshift=2.2em]part1.north) {\scriptsize{译文中已经生成的单词}};
\node [anchor=south] (text2) at ([xshift=0.5em,yshift=2.2em]part2.north) {\scriptsize{预测当前位置的单词分布}};
\draw [->,draw=black, thick] ([yshift=2em]part1.north) -- ([yshift=0.1em]part1.north);
......
......@@ -4,15 +4,16 @@
%%% outline
%-------------------------------------------------------------------------
\begin{tikzpicture}
\tikzstyle{word} = [draw=ugreen!20,minimum size=1.8em, fill=ugreen!40, font=\scriptsize, rounded corners=1pt]
\tikzstyle{word} = [font=\scriptsize]
\tikzstyle{tgt} = [minimum height=1.6em,minimum width=5.2em,fill=black!10!yellow!30,font=\footnotesize,drop shadow={shadow xshift=0.15em,shadow yshift=-0.15em,}]
\tikzstyle{p} = [fill=blue!15,minimum width=0.4em,inner sep=0pt]
\node[ rounded corners=3pt, fill=red!20, drop shadow, minimum width=10em,minimum height=4em] (encoder) at (0,0) {Transformer 编码器 };
\node[anchor=west, rounded corners=3pt, fill=red!20, drop shadow, minimum width=14em,minimum height=4em] (decoder) at ([xshift=0.8cm]encoder.east) {Transformer 解码器};
\tikzstyle{p} = [fill=ugreen!15,minimum width=0.4em,inner sep=0pt]
\node[ rounded corners=3pt, fill=red!20, drop shadow, minimum width=10em,minimum height=4em,draw] (encoder) at (0,0) {Transformer 编码器 };
\node[anchor=west, rounded corners=3pt, fill=blue!20, drop shadow, minimum width=14em,minimum height=4em,draw] (decoder) at ([xshift=0.8cm]encoder.east) {Transformer 解码器};
\node[anchor=north,word] (en1) at ([yshift=-1.3em,xshift=-3em]encoder.south) {};
\node[anchor=north,word] (en2) at ([yshift=-1.3em]encoder.south) {};
\node[anchor=north,word] (en3) at ([yshift=-1.3em,xshift=3em]encoder.south) {};
\node[anchor=north,word] (en1) at ([yshift=-1.3em,xshift=-3em]encoder.south) {};
\node[anchor=north,word] (en2) at ([yshift=-1.3em,xshift=-1em]encoder.south) {};
\node[anchor=north,word] (en3) at ([yshift=-1.3em,xshift=1em]encoder.south) {};
\node[anchor=north,word] (en4) at ([yshift=-1.3em,xshift=3em]encoder.south) {};
\node[anchor=north,word] (de1) at ([yshift=-1.3em,xshift=-4em]decoder.south) {1};
......@@ -24,7 +25,7 @@
\node[p,anchor=south,minimum height=0.7em] (w1_3) at ([xshift=0.3em]w1_2.south east){};
\node[p,anchor=south,minimum height=0.6em] (w1_4) at ([xshift=0.3em]w1_3.south east){};
\node[p,anchor=south,minimum height=0.2em] (w1_5) at ([xshift=0.3em]w1_4.south east){};
\node[p,anchor=south,minimum height=0.3em] (w1_6) at ([xshift=0.3em]w1_5.south east){};
\node[p,anchor=south,minimum height=1.9em] (w1_6) at ([xshift=0.3em]w1_5.south east){};
\node[p,anchor=south,minimum height=0.6em] (w1_7) at ([xshift=0.3em]w1_6.south east){};
\node[p,anchor=south,minimum height=0.8em] (w1_8) at ([xshift=0.3em]w1_7.south east){};
......@@ -37,30 +38,32 @@
\node[p,anchor=south,minimum height=0.6em] (w2_7) at ([xshift=0.3em]w2_6.south east){};
\node[p,anchor=south,minimum height=0.8em] (w2_8) at ([xshift=0.3em]w2_7.south east){};
\node[p,anchor=south, minimum height=0.5em] (w3_1) at ([xshift=3.2em,yshift=1.5em]decoder.north){};
\node[p,anchor=south,minimum height=2em] (w3_2) at ([xshift=0.3em]w3_1.south east){};
\node[p,anchor=south, minimum height=0.4em] (w3_1) at ([xshift=3.2em,yshift=1.5em]decoder.north){};
\node[p,anchor=south,minimum height=0.5em] (w3_2) at ([xshift=0.3em]w3_1.south east){};
\node[p,anchor=south,minimum height=0.7em] (w3_3) at ([xshift=0.3em]w3_2.south east){};
\node[p,anchor=south,minimum height=0.6em] (w3_4) at ([xshift=0.3em]w3_3.south east){};
\node[p,anchor=south,minimum height=1.9em] (w3_5) at ([xshift=0.3em]w3_4.south east){};
\node[p,anchor=south,minimum height=2em] (w3_4) at ([xshift=0.3em]w3_3.south east){};
\node[p,anchor=south,minimum height=0.8em] (w3_5) at ([xshift=0.3em]w3_4.south east){};
\node[p,anchor=south,minimum height=0.3em] (w3_6) at ([xshift=0.3em]w3_5.south east){};
\node[p,anchor=south,minimum height=0.6em] (w3_7) at ([xshift=0.3em]w3_6.south east){};
\node[p,anchor=south,minimum height=0.8em] (w3_8) at ([xshift=0.3em]w3_7.south east){};
\node[p,anchor=south,minimum height=0.4em] (w3_7) at ([xshift=0.3em]w3_6.south east){};
\node[p,anchor=south,minimum height=0.6em] (w3_8) at ([xshift=0.3em]w3_7.south east){};
\node[inner sep=0pt,font=\scriptsize] at ([yshift=0.3em]w1_2.north){Thanks};
\node[inner sep=0pt,font=\scriptsize] at ([yshift=0.3em]w2_2.north){a};
\node[inner sep=0pt,font=\scriptsize] at ([yshift=0.3em]w2_5.north){to};
\node[inner sep=0pt,font=\scriptsize] at ([yshift=0.3em]w3_2.north){lot};
\node[inner sep=0pt,font=\scriptsize] at ([yshift=0.3em]w3_5.north){you};
\node[inner sep=0pt,font=\scriptsize] at ([yshift=0.3em]w1_2.north){Good};
\node[inner sep=0pt,font=\scriptsize] at ([yshift=0.3em]w1_6.north){Well};
\node[inner sep=0pt,font=\scriptsize] at ([yshift=0.3em]w2_2.north){job};
\node[inner sep=0pt,font=\scriptsize] at ([yshift=0.3em]w2_5.north){done};
\node[inner sep=0pt,font=\scriptsize] at ([yshift=0.3em]w3_4.north){!};
\draw[-latex, very thick, ublue] ([yshift=0.1em]en1.north) -- ([xshift=-3em,yshift=-0.1em]encoder.south);
\draw[-latex, very thick, ublue] ([yshift=0.1em]en2.north) -- ([xshift=0em,yshift=-0.1em]encoder.south);
\draw[-latex, very thick, ublue] ([yshift=0.1em]en3.north) -- ([xshift=3em,yshift=-0.1em]encoder.south);
\draw[-latex, very thick, ublue] ([yshift=0.1em]de1.north) -- ([xshift=-4em,yshift=-0.1em]decoder.south);
\draw[-latex, very thick, ublue] ([yshift=0.1em]de2.north) -- ([xshift=0em,yshift=-0.1em]decoder.south);
\draw[-latex, very thick, ublue] ([yshift=0.1em]de3.north) -- ([xshift=4em,yshift=-0.1em]decoder.south);
\draw[->, thick] ([yshift=0.1em]en1.north) -- ([xshift=-3em,yshift=-0.1em]encoder.south);
\draw[->, thick] ([yshift=0.1em]en2.north) -- ([xshift=-1em,yshift=-0.1em]encoder.south);
\draw[->, thick] ([yshift=0.1em]en3.north) -- ([xshift=1em,yshift=-0.1em]encoder.south);
\draw[->, thick] ([yshift=0.1em]en4.north) -- ([xshift=3em,yshift=-0.1em]encoder.south);
\draw[-latex, very thick, ublue] (encoder.east) -- (decoder.west);
\draw[->, thick] ([yshift=0.1em]de1.north) -- ([xshift=-4em,yshift=-0.1em]decoder.south);
\draw[->, thick] ([yshift=0.1em]de2.north) -- ([xshift=0em,yshift=-0.1em]decoder.south);
\draw[->, thick] ([yshift=0.1em]de3.north) -- ([xshift=4em,yshift=-0.1em]decoder.south);
\draw[->, line width=1.5pt] (encoder.east) -- (decoder.west);
\begin{pgfonlayer}{background}
{
......@@ -70,14 +73,14 @@
}
\end{pgfonlayer}
\draw[-latex, very thick, ublue] ([yshift=-1.2em]box1.south) -- (box1.south);
\draw[-latex, very thick, ublue] ([yshift=-1.2em]box2.south) -- (box2.south);
\draw[-latex, very thick, ublue] ([yshift=-1.2em]box3.south) -- (box3.south);
\draw[->,thick] ([yshift=-1.2em]box1.south) -- (box1.south);
\draw[->, thick] ([yshift=-1.2em]box2.south) -- (box2.south);
\draw[->, thick] ([yshift=-1.2em]box3.south) -- (box3.south);
\node[tgt,anchor=west,align=left] (tgt1) at ([xshift=2em]box3.east) {Thanks a lot};
\node[tgt,,anchor=north,align=left](tgt2) at ([yshift=-1em]tgt1.south) {Thanks to you};
\node[tgt,,anchor=north,align=left] (tgt3) at ([yshift=-1em]tgt2.south) {Thanks a you};
\node[tgt,,anchor=north,align=left] (tgt4) at ([yshift=-1em]tgt3.south) {Thanks to lot};
\node[tgt,anchor=west,align=left] (tgt1) at ([xshift=2em]box3.east) {Good job!};
\node[tgt,,anchor=north,align=left](tgt2) at ([yshift=-1em]tgt1.south) {Well done!};
\node[tgt,,anchor=north,align=left] (tgt3) at ([yshift=-1em]tgt2.south) {Good done!};
\node[tgt,,anchor=north,align=left] (tgt4) at ([yshift=-1em]tgt3.south) {Well job!};
\node[text=ugreen] at ([xshift=1em]tgt1.east){\ding{51}};
\node[text=ugreen] at ([xshift=1em]tgt2.east){\ding{51}};
\node[text=red] at ([xshift=1em]tgt3.east){\ding{55}};
......
......@@ -4,53 +4,48 @@
%%% outline
%-------------------------------------------------------------------------
\begin{tikzpicture}
\tikzstyle{word} = [draw=ugreen!20,minimum size=1.5em, fill=ugreen!40, font=\scriptsize, rounded corners=1pt]
\node[rounded corners=3pt, fill=red!20, drop shadow, minimum width=11em,minimum height=4em] (encoder) at (0,0) {Transformer 编码器 };
\node[draw=blue!10,anchor=west, rounded corners=2pt, fill=blue!20,minimum width=2.5cm,minimum height=2em] (attention) at ([xshift=0.8cm]encoder.east) {注意力模块};
\node[anchor=west, rounded corners=3pt, fill=red!20, drop shadow, minimum width=12em,minimum height=4em] (decoder) at ([xshift=0.8cm]attention.east) {Transformer 解码器};
\node[anchor=north,word] (en1) at ([yshift=-1.4em,xshift=-3.6em]encoder.south) {hello};
\node[anchor=north,word] (en2) at ([yshift=-1.4em,xshift=-1.2em]encoder.south) {,};
\node[anchor=north,word] (en3) at ([yshift=-1.4em,xshift=1.2em]encoder.south) {world};
\node[anchor=north,word] (en4) at ([yshift=-1.4em,xshift=3.6em]encoder.south) {!};
\node[anchor=north,word] (de1) at ([yshift=-1.4em,xshift=-5em]decoder.south) {1};
\node[anchor=north,word] (de2) at ([yshift=-1.4em,xshift=-3em]decoder.south) {2};
\node[anchor=north,word] (de3) at ([yshift=-1.4em,xshift=-1 em]decoder.south) {3};
\node[anchor=north,word] (de4) at ([yshift=-1.4em,xshift=1em]decoder.south) {4};
\node[anchor=north,word] (de5) at ([yshift=-1.4em,xshift=3em]decoder.south) {5};
\node[anchor=north,word] (de6) at ([yshift=-1.4em,xshift=5em]decoder.south) {6};
\node[anchor=south,word] (out1) at ([yshift=1.4em,xshift=-5em]decoder.north) {};
\node[anchor=south,word] (out2) at ([yshift=1.4em,xshift=-3em]decoder.north) {};
\node[anchor=south,word] (out3) at ([yshift=1.4em,xshift=-1em]decoder.north) {};
\node[anchor=south,word] (out4) at ([yshift=1.4em,xshift=1em]decoder.north) {};
\node[anchor=south,word] (out5) at ([yshift=1.4em,xshift=3em]decoder.north) {};
\node[anchor=south,word] (out6) at ([yshift=1.4em,xshift=5em]decoder.north) {};
\draw[-latex, very thick,ublue] ([yshift=0.1em]en1.north) -- ([xshift=-3.6em,yshift=-0.1em]encoder.south);
\draw[-latex, very thick,ublue] ([yshift=0.1em]en2.north) -- ([xshift=-1.2em,yshift=-0.1em]encoder.south);
\draw[-latex, very thick,ublue] ([yshift=0.1em]en3.north) -- ([xshift=1.2em,yshift=-0.1em]encoder.south);
\draw[-latex, very thick,ublue] ([yshift=0.1em]en4.north) -- ([xshift=3.6em,yshift=-0.1em]encoder.south);
\draw[-latex, very thick,ublue] ([yshift=0.1em]de1.north) -- ([xshift=-5em]decoder.south);
\draw[-latex, very thick,ublue] ([yshift=0.1em]de2.north) -- ([xshift=-3em]decoder.south);
\draw[-latex, very thick,ublue] ([yshift=0.1em]de3.north) -- ([xshift=-1em]decoder.south);
\draw[-latex, very thick,ublue] ([yshift=0.1em]de4.north) -- ([xshift=1em]decoder.south);
\draw[-latex, very thick,ublue] ([yshift=0.1em]de5.north) -- ([xshift=3em]decoder.south);
\draw[-latex, very thick,ublue] ([yshift=0.1em]de6.north) -- ([xshift=5em]decoder.south);
\draw[-latex, very thick,ublue] ([xshift=-5em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out1.south);
\draw[-latex, very thick,ublue] ([xshift=-3em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out2.south);
\draw[-latex, very thick,ublue] ([xshift=-1em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out3.south);
\draw[-latex, very thick,ublue] ([xshift=1em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out4.south);
\draw[-latex, very thick,ublue] ([xshift=3em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out5.south);
\draw[-latex, very thick,ublue] ([xshift=5em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out6.south);
\draw[-latex, very thick, ublue] (encoder.east) -- (attention.west);
\draw[-latex, very thick, ublue] (attention.east) -- (decoder.west);
\draw[decorate,decoration={brace, mirror},ublue, very thick] ([yshift=-0.4em]de1.-135) -- node[font=\scriptsize,text=black,yshift=-1em]{预测译文长度 \& 计算位置编码}([yshift=-0.4em]de6.-45);
\tikzstyle{word} = [font=\scriptsize]
\node[rounded corners=3pt, fill=red!20, drop shadow, minimum width=10em,minimum height=4em,draw] (encoder) at (0,0) {Transformer 编码器 };
\node[draw,anchor=west, rounded corners=2pt, fill=orange!20,minimum width=2.5cm,minimum height=2em] (attention) at ([xshift=0.8cm]encoder.east) {注意力模块};
\node[anchor=west, rounded corners=3pt, fill=blue!20, drop shadow, minimum width=10em,minimum height=4em,draw] (decoder) at ([xshift=0.8cm]attention.east) {Transformer 解码器};
\node[anchor=north,word] (en1) at ([yshift=-1.3em,xshift=-3em]encoder.south) {hello};
\node[anchor=north,word] (en2) at ([yshift=-1.6em,xshift=-1em]encoder.south) {,};
\node[anchor=north,word] (en3) at ([yshift=-1.3em,xshift=1em]encoder.south) {world};
\node[anchor=north,word] (en4) at ([yshift=-1.3em,xshift=3em]encoder.south) {!};
\node[anchor=north,word] (de1) at ([yshift=-1.3em,xshift=-3em]decoder.south) {1};
\node[anchor=north,word] (de2) at ([yshift=-1.3em,xshift=-1em]decoder.south) {2};
\node[anchor=north,word] (de3) at ([yshift=-1.3em,xshift=1 em]decoder.south) {3};
\node[anchor=north,word] (de4) at ([yshift=-1.3em,xshift=3em]decoder.south) {4};
\node[anchor=south,word] (out1) at ([yshift=1.3em,xshift=-3em]decoder.north) {你好};
\node[anchor=south,word] (out2) at ([yshift=1.3em,xshift=-1em]decoder.north) {};
\node[anchor=south,word] (out3) at ([yshift=1.3em,xshift=1em]decoder.north) {世界};
\node[anchor=south,word] (out4) at ([yshift=1.3em,xshift=3em]decoder.north) {};
\draw[->, thick] ([yshift=0.1em]en1.north) -- ([xshift=-3em,yshift=-0.1em]encoder.south);
\draw[->, thick] ([yshift=0.3em]en2.north) -- ([xshift=-1em,yshift=-0.1em]encoder.south);
\draw[->, thick] ([yshift=0.1em]en3.north) -- ([xshift=1em,yshift=-0.1em]encoder.south);
\draw[->, thick] ([yshift=0.1em]en4.north) -- ([xshift=3em,yshift=-0.1em]encoder.south);
\draw[->,thick] ([yshift=0.1em]de1.north) -- ([xshift=-3em]decoder.south);
\draw[->, thick] ([yshift=0.1em]de2.north) -- ([xshift=-1em]decoder.south);
\draw[->, thick] ([yshift=0.1em]de3.north) -- ([xshift=1em]decoder.south);
\draw[->, thick] ([yshift=0.1em]de4.north) -- ([xshift=3em]decoder.south);
\draw[->, thick] ([xshift=-3em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out1.south);
\draw[->, thick] ([xshift=-1em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out2.south);
\draw[->, thick] ([xshift=1em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out3.south);
\draw[->, thick] ([xshift=3em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out4.south);
\draw[->,line width=1.5pt] (encoder.east) -- (attention.west);
\draw[->,line width=1.5pt] (attention.east) -- (decoder.west);
\draw[decorate,decoration={brace, mirror},ublue, very thick] ([xshift=0.5em,yshift=-0.4em]de1.-135) -- node[font=\scriptsize,text=black,yshift=-1em]{预测译文长度 \& 计算位置编码}([xshift=-0.5em,yshift=-0.4em]de4.-45);
%\begin{pgfonlayer}{background}
%{
......
......@@ -73,8 +73,13 @@
\node[draw=taupegray,thick,fill=blue!7,inner sep=0pt,minimum height=13.3em,minimum width=9.5em,rounded corners=4pt,drop shadow] (box3) at (12em,10.1em){};
}
\end{pgfonlayer}
\node[] at ([xshift=-2em]box1.west){{$M \times$}};
\node[] at ([xshift=2em]box3.east){{$\times N$}};
\node[] at ([yshift=1.8em]box2.north){\normalsize{译文长度:5}};
\node[] at ([xshift=-2em,yshift=0.5em]box2.west){\normalsize{繁衍率}};
\node[] at ([xshift=-2em,yshift=-0.5em]box2.west){\normalsize{预测器}};
\node[] at ([xshift=-2em]box1.west){\normalsize{编码器}};
\node[] at ([xshift=-1em,yshift=-2.5em]box1.west){{$M \times$}};
\node[] at ([xshift=2em]box3.east){\normalsize{解码器}};
\node[] at ([xshift=1em,yshift=-6em]box3.east){{$\times N$}};
\draw[line,dotted,rounded corners=4pt,violet] (box2.north) -- ([yshift=1em]box2.north) -- ([yshift=1em,xshift=6.2em]box2.north) -- ([xshift=-2.2em]tgt_emb.west) -- (tgt_emb.west);
\draw[line,-,dotted,rounded corners=4pt,violet,] (src_emb.east) -- ([xshift=-2em]tgt_emb.west);
......
......@@ -29,7 +29,7 @@
\end{pgfonlayer}
\node[anchor=north,font=\scriptsize,align=center] (w1) at ([yshift=-2em]encoder.south){\scriptsize\bfnew{There exist different} \\ \scriptsize\bfnew{opinions on this question}};
\node[anchor=north,font=\scriptsize,align=center] (w2) at ([yshift=-2em]decoder.south){\scriptsize\bfnew{There exist different} \\ \scriptsize\bfnew{opinions on this question}};
\node[anchor=north,font=\scriptsize,text=gray] (w3) at ([yshift=0.6em]w2.south){\scriptsize\bfnew{(copy source sentence)}};
\node[anchor=north,font=\scriptsize,text=gray] (w3) at ([yshift=0.6em]w2.south){\scriptsize\bfnew{(复制源语言句子)}};
\node[anchor=south,font=\scriptsize,align=center] (w4) at ([yshift=1.6em]box2.north){\scriptsize\bfnew{on this question} \\ \scriptsize\bfnew{There exist different opinions}};
\node[anchor=south,font=\scriptsize,align=center] (w5) at ([yshift=1.6em]box3.north){\tiny\bfnew{\ 这个 \ 问题 \ 存在 \ 不同的 \ 看法}};
\node[font=\tiny] at ([xshift=-0.8em,yshift=-0.6em]encoder.east) {$N\times$};
......
......@@ -16,7 +16,7 @@
\setlength{\fboxsep}{2.2mm} % box size
\begin{tabular}{C{.20\textwidth}C{.20\textwidth}C{.20\textwidth}C{.20\textwidth}}
\setlength{\tabcolsep}{0pt}
\subfigure [\footnotesize{自注意力}] {
\subfigure [\small{自注意力}] {
\begin{tabular}{ccC{1em}}
\setlength{\tabcolsep}{0pt}
~
......@@ -62,7 +62,7 @@
}
&
\subfigure [\footnotesize{编码-解码注意力}] {
\subfigure [\small{编码-解码注意力}] {
\setlength{\tabcolsep}{0pt}
\begin{tabular}{ccC{1em}}
\setlength{\tabcolsep}{0pt}
......
......@@ -79,15 +79,15 @@
\begin{itemize}
\vspace{0.5em}
\item 搜索的基本问题在神经机器翻译中有着特殊的现象。比如,在统计机器翻译中,降低搜索错误是提升翻译效果的一种手段。但是神经机器翻译中,简单的降低搜索错误可能无法带来性能的提升,甚至造成翻译品质的下降\upcite{li-etal-2018-simple,Stahlberg2019OnNS}
\item 搜索的基本问题在神经机器翻译中有着特殊的现象。比如,在统计机器翻译中,降低搜索错误是提升翻译效果的一种手段。但是神经机器翻译中,简单的降低搜索错误可能无法带来性能的提升,甚至造成翻译品质的下降\upcite{li-etal-2018-simple,Stahlberg2019OnNS}
\vspace{0.5em}
\item 搜索的时延很高,系统实际部署的成本很高。与统计机器翻译系统不同的是,神经机器翻译依赖大量的浮点预算。这也造成神经机器翻译系统的推断会比统计机器翻译系统慢很多。虽然可以使用GPU来加速神经机器翻译的推断速度,但是也大大增加了成本;
\item 搜索的时延很高,系统实际部署的成本很高。与统计机器翻译系统不同的是,神经机器翻译依赖大量的浮点运算。这也导致神经机器翻译系统的推断会比统计机器翻译系统慢很多。虽然可以使用GPU来加速神经机器翻译的推断速度,但是也大大增加了成本;
\vspace{0.5em}
\item 神经机器翻译在优化过程中容易陷入局部最优,单模型的表现并不稳定。由于神经机器翻译优化的目标函数非常不光滑,每次训练得到的模型往往只是一个局部最优解。在新数据上使用这个局部最优模型进行推断时,模型的表现可能不稳定。
\vspace{0.5em}
\end{itemize}
\parinterval 研究者们也针对以上问题开展了大量的研究工作。在\ref{sec:14-2}节中,我们会对神经机器翻译推断中所涉及的一些基本问题进行讨论。虽然这些问题在统计机器翻译中均有涉及,但是在神经机器翻译中却有着不同的现象和解决思路。在\ref{sec:14-3}-\ref{sec:14-5}节中,我们会针对如何改进神经机器翻译推断效率和怎样进行多模型融合这两个问题展开讨论。
\parinterval 研究人员也针对以上问题开展了大量的研究工作。在\ref{sec:14-2}节中,本章会对神经机器翻译推断中所涉及的一些基本问题进行讨论。虽然这些问题在统计机器翻译中均有涉及,但是在神经机器翻译中却有着不同的现象和解决思路。在\ref{sec:14-3}-\ref{sec:14-5}节中,会针对如何改进神经机器翻译推断效率和怎样进行多模型融合这两个问题展开讨论。
%----------------------------------------------------------------------------------------
% NEW SECTION
......@@ -105,32 +105,32 @@
\parinterval 机器翻译有两种常用的推断方式\ \dash \ 自左向右推断和自右向左推断。自左向右推断符合现实世界中人类的语言使用规律,因为人在翻译一个句子时,总是习惯从句子开始的部分往后生成\footnote{有些语言中,文字是自右向左书写,这时自右向左推断更符合人类使用这种语言的习惯。}。不过,有时候人也会使用当前单词后面的译文信息。也就是说,翻译也需要“未来” 的文字信息。于是很容易想到使用自右向左的方法对译文进行生成。
\parinterval 以上两种推断方式在神经机器翻译中都有应用,对于源语言句子$\seq{x}=\{x_1,x_2,\dots,x_m\}$和目标语句子$\seq{y}=\{y_1,y_2,\dots,y_n\}$,自左向右的翻译可以被描述为
\parinterval 以上两种推断方式在神经机器翻译中都有应用,对于源语言句子$\seq{x}=\{x_1,x_2,\dots,x_m\}$和目标语言句子$\seq{y}=\{y_1,y_2,\dots,y_n\}$,自左向右的翻译可以被描述为公式\eqref{eq:14-1}
\begin{eqnarray}
\funp{P}(\seq{y}\vert\seq{x}) &=& \prod_{j=1}^n \funp{P}(y_j\vert\seq{y}_{<j},\seq{x})
\label{eq:14-1}
\end{eqnarray}
\parinterval 自右向左的翻译可以被描述为:
\parinterval 自右向左的翻译可以被描述为公式\eqref{eq:14-2}
\begin{eqnarray}
\funp{P}(\seq{y}\vert\seq{x}) &=&\prod_{j=1}^n \funp{P}(y_{n+1-j}\vert\seq{y}_{>j},\seq{x})
\label{eq:14-2}
\end{eqnarray}
\noindent 其中,$\seq{y}_{<j}=\{y_1,y_2,\dots,y_{j-1}\}$$\seq{y}_{>j}=\{y_{j+1},y_{j+2},\dots,y_n\}$。可以看到,自左向右推断和自右向左推断本质上是一样的。{\chapterten} $\sim$ {\chaptertwelve} 均使用了自左向右的推断方法。自右向左推断比较简单的实现方式是:在训练过程中直接将双语数据中的目标语句子进行反向,之后仍然使用原始的模型进行训练即可。在推断的时候,生成的目标语词串也需要进行反向得到最终的译文。有时候,使用自右向左的推断方式会取得更好的效果\upcite{DBLP:conf/wmt/SennrichHB16}。不过更多情况下需要同时使用词串左端(历史)和右端(未来)的信息。有多种思路可以融合左右两端信息:
\noindent 其中,$\seq{y}_{<j}=\{y_1,y_2,\dots,y_{j-1}\}$$\seq{y}_{>j}=\{y_{j+1},y_{j+2},\dots,y_n\}$。可以看到,自左向右推断和自右向左推断本质上是一样的。{\chapterten}{\chaptertwelve}均使用了自左向右的推断方法。自右向左推断比较简单的实现方式是:在训练过程中直接将双语数据中的目标语言句子进行反向,之后仍然使用原始的模型进行训练即可。在推断的时候,生成的目标语言词串也需要进行反向得到最终的译文。有时候,使用自右向左的推断方式会取得更好的效果\upcite{DBLP:conf/wmt/SennrichHB16}。不过更多情况下需要同时使用词串左端(历史)和右端(未来)的信息。有多种思路可以融合左右两端信息:
\begin{itemize}
\vspace{0.5em}
\item {\small\sffamily\bfseries{重排序}}\index{重排序}(Reranking)\index{Reranking}。可以用一个基础模型(比如自左向右的模型)得到每个源语言句子的$n$-best翻译结果,之后同时用基础模型的得分和自右向左模型对$n$-best翻译结果进行重排序\upcite{Liu2016AgreementOT,DBLP:conf/wmt/SennrichHB16,DBLP:conf/wmt/LiLXLLLWZXWFCLL19}。也有研究利用最小贝叶斯风险的方法进行重排序\upcite{Stahlberg2018TheUO}。由于这类方法不会改变基础模型的翻译过程,因此相对“安全”,不会对系统性能造成副作用。
\item {\small\sffamily\bfseries{重排序}}\index{重排序}(Reranking)\index{Reranking}。可以用一个基础模型(比如自左向右的模型)得到每个源语言句子的$n$-best翻译结果,之后同时用基础模型的得分和自右向左模型对$n$-best翻译结果进行重排序\upcite{Liu2016AgreementOT,DBLP:conf/wmt/SennrichHB16,DBLP:conf/wmt/LiLXLLLWZXWFCLL19}。也有研究人员利用最小贝叶斯风险的方法进行重排序\upcite{Stahlberg2018TheUO}。由于这类方法不会改变基础模型的翻译过程,因此相对“安全”,不会对系统性能造成副作用。
\vspace{0.5em}
\item {\small\sffamily\bfseries{双向推断}}\index{双向推断}(Bidirectional Inference)\index{Bidirectional Inference}另一种方法是,让自左向右和自右向左模型同步进行,也就是同时考虑译文左侧和右侧的文字信息\upcite{DBLP:conf/aaai/ZhangSQLJW18,Zhou2019SynchronousBN,DBLP:conf/aaai/ZhangSQLJW18}。例如,可以同时对左边和右边生成的译文进行注意力计算,得到当前位置的单词预测结果。这种方法能够更加充分的融合双向翻译的优势。
\item {\small\sffamily\bfseries{双向推断}}\index{双向推断}(Bidirectional Inference)\index{Bidirectional Inference}除了自左向右推断和自右向左推断,另一种方法让自左向右和自右向左模型同步进行,也就是同时考虑译文左侧和右侧的文字信息\upcite{DBLP:conf/aaai/ZhangSQLJW18,Zhou2019SynchronousBN,DBLP:conf/aaai/ZhangSQLJW18}。例如,可以同时对左边和右边生成的译文进行注意力计算,得到当前位置的单词预测结果。这种方法能够更加充分地融合双向翻译的优势。
\vspace{0.5em}
\item {\small\sffamily\bfseries{多阶段推断}}\index{多阶段推断}(Multi-stage Inference)\index{Multi-stage Inference}。在第一阶段,通过一个基础模型生成一个初步的翻译结果。在第二阶段,同时使用第一阶段生成的翻译结果和源语言句子,进一步生成更好的译文\upcite{Li2017EnhancedNM,ElMaghraby2018EnhancingTF,Geng2018AdaptiveMD}。由于第一阶段的结果已经包含了完整的译文信息,因此在第二阶段中,系统实际上已经同时使用了整个译文串的两端信息。上述过程可以扩展为迭代式的译文生成方法,配合掩码等技术,可以在生成每个译文单词时,同时考虑左右两端的上下文信息\upcite{Lee2018DeterministicNN,Gu2019LevenshteinT,Guo2020JointlyMS}
\vspace{0.5em}
\end{itemize}
\parinterval 不论是自左向右还是自右向左推断,本质上都是在对上下文信息进行建模。除了自左向右和自右向左的推断策略,研究者们也提出了许多新的译文生成策略,比如,从中部向外生成、按源语言顺序生成\upcite{Stahlberg2018AnOS}、基于插入的方式生成\upcite{Stern2019InsertionTF,stling2017NeuralMT}等。或者将翻译问题松弛化为一个连续空间模型的优化问题,进而在推断的过程中同时使用译文串左右两端的信息\upcite{Geng2018AdaptiveMD}
\parinterval 不论是自左向右还是自右向左推断,本质上都是在对上下文信息进行建模。除了自左向右和自右向左的推断策略,研究人员也提出了许多新的译文生成策略,比如,从中部向外生成\upcite{DBLP:conf/nips/MehriS18}、按源语言顺序生成\upcite{Stahlberg2018AnOS}、基于插入的方式生成\upcite{Stern2019InsertionTF,stling2017NeuralMT}等。或者将翻译问题松弛化为一个连续空间模型的优化问题,进而在推断的过程中同时使用译文串左右两端的信息\upcite{Geng2018AdaptiveMD}
\parinterval 最近,以BERT 为代表的预训练语言模型已经证明,一个单词的“历史” 和“未来” 信息对于生成当前单词都是有帮助的\upcite{devlin2019bert}。类似的观点也在神经机器翻译编码器设计中得到验证。比如,在基于循环神经网络的模型中,经常同时使用自左向右和自右向左的方式对源语言句子进行编码。还有,Transformer 编码器会使用整个句子的信息对每一个源语言位置进行表示。因此,在神经机器翻译的解码端采用类似的策略是有其合理性的。
......@@ -176,15 +176,15 @@ a &=& \omega_{\textrm{low}}\cdot |\seq{x}| \label{eq:14-3}\\
b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\end{eqnarray}
\vspace{0.5em}
\noindent 其中,$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$分别表示译文长度的下限和上限,比如,很多系统中设置为$\omega_{\textrm{low}}=1/2$$\omega_{\textrm{high}}=2$,表示译文至少有源语言句子一半长,最多有源语言句子两倍长。$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$的设置对推断效率影响很大,$\omega_{\textrm{high}}$可以被看作是一个推断的终止条件,最理想的情况是$\omega_{\textrm{high}} \cdot |\seq{x}|$恰巧就等于最佳译文的长度,这时没有任何计算的浪费。反过来的一种情况,$\omega_{\textrm{high}} \cdot |\seq{x}|$远大于最佳译文的长度,这时很多计算都是无用的。为了找到长度预测的准确率和召回率之间的平衡,一般需要大量的实验最终确定$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$。当然,利用统计模型预测$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$也是非常值得探索的方向,比如基于繁衍率的模型\upcite{Gu2017NonAutoregressiveNM,Feng2016ImprovingAM}
\noindent 其中,$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$分别表示译文长度的下限和上限,比如,很多系统中设置为$\omega_{\textrm{low}}=1/2$$\omega_{\textrm{high}}=2$,表示译文至少有源语言句子一半长,最多有源语言句子两倍长。$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$的设置对推断效率影响很大,$\omega_{\textrm{high}}$可以被看作是一个推断的终止条件,最理想的情况是$\omega_{\textrm{high}} \cdot |\seq{x}|$恰巧就等于最佳译文的长度,这时没有浪费任何计算资源。反过来的一种情况,$\omega_{\textrm{high}} \cdot |\seq{x}|$远大于最佳译文的长度,这时很多计算都是无用的。为了找到长度预测的准确率和召回率之间的平衡,一般需要大量的实验最终确定$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$。当然,利用统计模型预测$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$也是非常值得探索的方向,比如基于繁衍率的模型\upcite{Gu2017NonAutoregressiveNM,Feng2016ImprovingAM}
\vspace{0.5em}
\item 覆盖度模型。译文长度过长或过短的问题,本质上对应着 {\small\sffamily\bfseries{过翻译}}\index{过翻译}(Over Translation)\index{Over Translation}{\small\sffamily\bfseries{欠翻译}}\index{欠翻译}(Under Translation)\index{Under Translation}的问题\upcite{Yang2018OtemUtemOA}。这两种问题出现的原因主要在于:神经机器翻译没有对过翻译和欠翻译建模,即机器翻译覆盖度问题\upcite{TuModeling}。针对此问题,最常用的方法是在推断的过程中引入一个度量覆盖度的模型。比如,使用GNMT 覆盖度模型定义模型得分\upcite{Wu2016GooglesNM}
\item 覆盖度模型。译文长度过长或过短的问题,本质上对应着 {\small\sffamily\bfseries{过翻译}}\index{过翻译}(Over Translation)\index{Over Translation}{\small\sffamily\bfseries{欠翻译}}\index{欠翻译}(Under Translation)\index{Under Translation}的问题\upcite{Yang2018OtemUtemOA}。这两种问题出现的原因主要在于:神经机器翻译没有对过翻译和欠翻译建模,即机器翻译覆盖度问题\upcite{TuModeling}。针对此问题,最常用的方法是在推断的过程中引入一个度量覆盖度的模型。比如,使用GNMT 覆盖度模型定义模型得分\upcite{Wu2016GooglesNM},如\eqref{eq:14-5}\eqref{eq:14-6}所示
\begin{eqnarray}
\textrm{score}(\seq{x},\seq{y}) &=& \frac{\log \funp{P}(\seq{y} | \seq{x})}{\textrm{lp}(\seq{y})} + \textrm{cp}(\seq{x},\seq{y}) \label {eq:14-5}\\
\textrm{cp}(\seq{x},\seq{y}) &=& \beta \cdot \sum_{i=1}^{|\seq{x}|} \log(\textrm{min} (\sum_{j}^{|\seq{y}|} a_{ij} , 1))
\label{eq:14-6}
\end{eqnarray}
\noindent 其中,$\textrm{cp}(\seq{x},\seq{y}) $表示覆盖度模型,它度量了译文对源语言每个单词的覆盖程度。$\textrm{cp}(\seq{x},\seq{y}) $的定义中,$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))
......@@ -200,11 +200,11 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{搜索终止条件}
\parinterval 在机器翻译推断中,何时终止搜索是一个非常基础的问题。如\chaptertwo 所述,系统研发者一方面希望尽可能遍历更大的搜索空间,找到更好的结果,另一方面也希望在尽可能短的时间内得到结果。这时搜索的终止条件就是一个非常关键的指标。在束搜索中有很多终止条件可以使用,比如,在生成一定数量的译文之后就终止搜索,或者当最佳译文与排名第二的译文之间的分数差距超过一个阈值时就终止搜索等。
\parinterval 在机器翻译推断中,何时终止搜索是一个非常基础的问题。如{\chaptertwo}所述,系统研发者一方面希望尽可能遍历更大的搜索空间,找到更好的结果,另一方面也希望在尽可能短的时间内得到结果。这时搜索的终止条件就是一个非常关键的指标。在束搜索中有很多终止条件可以使用,比如,在生成一定数量的译文之后就终止搜索,或者当最佳译文与排名第二的译文之间的分数差距超过一个阈值时就终止搜索等。
\parinterval 在统计机器翻译中,搜索的终止条件相对容易设计。因为所有的翻译结果都可以用相同步骤的搜索过程生成,比如,在CYK解码中搜索的步骤仅与构建的分析表大小有关。在神经机器翻译中,这个问题要更加复杂。当系统找到一个完整的译文之后,可能还有很多译文没有被生成完,这时就面临着一个问题\ \dash \ 如何决定是否继续搜索。
\parinterval 针对这些问题,研究人员设计了很多新的方法。比如,可以在束搜索中使用启发性信息让搜索尽可能早停止,同时保证搜索结果是“最优的”\upcite{DBLP:conf/emnlp/HuangZM17}。也可以将束搜索建模为优化问题\upcite{Wiseman2016SequencetoSequenceLA,DBLP:conf/emnlp/Yang0M18},进而设计出新的终止条件\upcite{Ma2019LearningTS}。很多开源机器翻译系统也都使用了简单有效的终止条件,比如,在OpenNMT 系统中当搜索束中当前最好的假设生成了完整的译文搜索就会停止\upcite{KleinOpenNMT},在RNNSearch系统中当找到预设数量的译文时搜索就会停止,同时在这个过程中会不断减小搜索束的大小\upcite{bahdanau2014neural}
\parinterval 针对这些问题,研究人员设计了很多新的方法。比如,可以在束搜索中使用启发性信息让搜索尽可能早停止,同时保证搜索结果是“最优的”\upcite{DBLP:conf/emnlp/HuangZM17}。也可以将束搜索建模为优化问题\upcite{Wiseman2016SequencetoSequenceLA,DBLP:conf/emnlp/Yang0M18},进而设计出新的终止条件\upcite{Ma2019LearningTS}。很多开源机器翻译系统也都使用了简单有效的终止条件,比如,在OpenNMT 系统中当搜索束中当前最好的假设生成了完整的译文搜索就会停止\upcite{KleinOpenNMT},在RNNSearch系统中当找到预设数量的译文时搜索就会停止,同时在这个过程中会不断减小搜索束的大小\upcite{bahdanau2014neural}
\parinterval 实际上,设计搜索终止条件反映了搜索时延和搜索精度之间的一种折中\upcite{Eisner2011LearningST,Jiang2012LearnedPF}。在很多应用中,这个问题会非常关键。比如,在同声传译中,对于输入的长文本,何时开始翻译、何时结束翻译都是十分重要的\upcite{Zheng2020OpportunisticDW,Ma2019STACLST}。在很多线上翻译应用中,翻译结果的响应不能超过一定的时间,这时就需要一种{\small\sffamily\bfseries{时间受限的搜索}}\index{时间受限的搜索}(Time-constrained Search)\index{Time-constrained Search}策略\upcite{DBLP:conf/emnlp/StahlbergHSB17}
......@@ -214,28 +214,29 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{译文多样性}
\parinterval 机器翻译系统的输出并不仅限于单个译文。很多情况下,需要多个译文。比如,译文重排序中通常就需要系统的$n$-best输出,而在交互式机器翻译中也往往需要提供多个译文供用户选择\upcite{Peris2017InteractiveNM,Peris2018ActiveLF}。但是,无论是统计机器翻译还是神经机器翻译,都面临一个同样的问题:$n$-best输出中的译文十分相似。\ref{tab:14-2}就展示了一个神经机器翻译输出的多个翻译结果,可以看到这些译文的区别很小。这个问题也被看做是机器翻译缺乏{\small\sffamily\bfseries{译文多样性}}\index{译文多样性}(Translation Diversity)\index{Translation Diversity}的问题\upcite{Gimpel2013ASE,Li2016MutualIA,DBLP:conf/emnlp/DuanLXZ09,DBLP:conf/acl/XiaoZZW10,xiao2013bagging}
\parinterval 机器翻译系统的输出并不仅限于单个译文。很多情况下,需要多个译文。比如,译文重排序中通常就需要系统的$n$-best输出,而在交互式机器翻译中也往往需要提供多个译文供用户选择\upcite{Peris2017InteractiveNM,Peris2018ActiveLF}。但是,无论是统计机器翻译还是神经机器翻译,都面临一个同样的问题:$n$-best输出中的译文十分相似。实例\ref{eg:14-1}就展示了一个神经机器翻译输出的多个翻译结果,可以看到这些译文的区别很小。这个问题也被看做是机器翻译缺乏{\small\sffamily\bfseries{译文多样性}}\index{译文多样性}(Translation Diversity)\index{Translation Diversity}的问题\upcite{Gimpel2013ASE,Li2016MutualIA,DBLP:conf/emnlp/DuanLXZ09,DBLP:conf/acl/XiaoZZW10,xiao2013bagging}
%----------------------------------------------------------------------
\begin{table}[htp]{
\begin{center}
\caption{汉英神经机器翻译系统的3-best结果实例}
{
\begin{tabular}{c|l}
源文 & 那只敏捷的棕色狐狸跳过了那只懒惰的狗。 \\
\hline
\rule{0pt}{10pt} {\small{NO.1}} & The agile brown fox jumped over the lazy dog. \\
\rule{0pt}{10pt} {\small{NO.2}} &The quick brown fox jumped over the lazy dog. \\
\rule{0pt}{10pt} {\small{NO.3}} & The quick brown fox jumps over the lazy dog. \\
\end{tabular}
\label{tab:14-2}
}
\end{center}
}\end{table}
%----------------------------------------------------------------------
\parinterval 机器翻译输出缺乏多样性会带来很多问题。一个直接的问题是在重排序时很难选择到更好的译文,因为所有候选都没有太大的差别。另一方面,当需要利用$n$-best输出来表示翻译假设空间时,缺乏多样性的译文也会使得翻译后验概率的估计不够准确,造成建模的偏差。在一些模型训练方法中,这种后验概率估计的偏差也会造成较大的影响\upcite{DBLP:conf/acl/ShenCHHWSL16}。从人工翻译的角度,同一个源语言句子的译文应该是多样的,因此过于相似的译文也无法反映足够多的翻译现象。
\begin{example}
源语言句子:我们期待安理会尽早就此作出决定。
\qquad\ 机器译文\ \,1\ :We look forward to the Security Council making a decision on this
\hspace{8.3em}as soon as possible.
\qquad\ 机器译文\ \,2\ :We look forward to the Security Council making a decision on this
\parinterval 因此增加译文多样性成为了机器翻译中一个有价值的研究方向。在统计机器翻译中就有很多尝试\upcite{DBLP:conf/emnlp/DuanLXZ09,DBLP:conf/acl/XiaoZZW10,xiao2013bagging}。主要思路是通过加入一些“扰动”让翻译模型的行为发生变化,进而得到区别更大的译文。类似的方法也同样适用于神经机器翻译。例如,可以在推断过程中加入额外的模型,用于惩罚出现相似译文的情况\upcite{Li2016ADO,Li2016MutualIA}。也可以在翻译模型中引入新的隐含变量或者加入新的干扰,进而控制多样性译文的输出\upcite{He2018SequenceTS,Shen2019MixtureMF,Wu2020GeneratingDT}。类似的,也可以利用模型中局部结构的多样性来生成多样的译文\upcite{Sun2020GeneratingDT}。除了考虑每个译文之间的多样性,也可以对译文进行分组,之后增加不同组之间的多样性\upcite{Vijayakumar2016DiverseBS}
\hspace{8.3em}issue as soon as possible.
\qquad\ 机器译文\ \,3\ :We hope that the Security Council will make a decision on this
\hspace{8.4em}issue as soon as possible.
\label{eg:14-1}
\end{example}
\parinterval 机器翻译输出缺乏多样性会带来很多问题。一个直接的问题是在重排序时很难选择到更好的译文,因为所有候选都没有太大的差别。此外,当需要利用$n$-best输出来表示翻译假设空间时,缺乏多样性的译文也会使得翻译后验概率的估计不够准确,造成建模的偏差。在一些模型训练方法中,这种后验概率估计的偏差也会造成较大的影响\upcite{DBLP:conf/acl/ShenCHHWSL16}。从人工翻译的角度,同一个源语言句子的译文应该是多样的,因此过于相似的译文也无法反映足够多的翻译现象。
\parinterval 因此增加译文多样性成为了机器翻译中一个有价值的研究方向。在统计机器翻译中就有很多尝试\upcite{DBLP:conf/emnlp/DuanLXZ09,DBLP:conf/acl/XiaoZZW10,xiao2013bagging}。主要思路是通过加入一些“扰动”让翻译模型的行为发生变化,进而得到区别更大的译文。类似的方法也同样适用于神经机器翻译。例如,可以在推断过程中加入额外的模型,用于惩罚出现相似译文的情况\upcite{Li2016ADO,Li2016MutualIA}。也可以在翻译模型中引入新的隐含变量或者加入新的干扰,进而控制多样性译文的输出\upcite{He2018SequenceTS,Shen2019MixtureMF,Wu2020GeneratingDT}。类似地,也可以利用模型中局部结构的多样性来生成多样的译文\upcite{Sun2020GeneratingDT}。除了考虑每个译文之间的多样性,也可以对译文进行分组,之后增加不同组之间的多样性\upcite{Vijayakumar2016DiverseBS}
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
......@@ -245,7 +246,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}。在实验中,研究人员也发现增加搜索束的大小会导致翻译生成的结果变得更短。他们将这个现象归因于:增加搜索束的大小,会导致更多的模型错误,因为神经机器翻译的建模是基于局部归一的最大似然估计\upcite{Sountsov2016LengthBI,Murray2018CorrectingLB,StahlbergNeural}。另一方面,也有研究人员把这种翻译过短的现象归因于搜索错误\upcite{Stahlberg2019OnNS}。由于搜索时所面临的搜索空间是十分巨大的,因此搜索时可能无法找到模型定义的“最好”的译文。在某种意义上,这也体现了一种训练和推断不一致的问题。
\parinterval 在统计机器翻译中,搜索错误可以通过减少剪枝进行缓解。比较简单的方式是增加搜索束宽度,这往往会带来一定的性能提升\upcite{Xiao2016ALA}。也可以对搜索问题进行单独建模,以保证学习到的模型出现更少的搜索错误\upcite{Liu2014SearchAwareTF,Yu2013MaxViolationPA}。但是,在神经机器翻译中,这个问题却表现出不同的现象:在很多神经机器翻译系统中,随着搜索束的增大,系统的BLEU不升反降。图\ref{fig:14-3}展示了BLEU随束大小的变化曲线\footnote{为了使该图更加规整直观,横坐标处将束大小进行了取对数操作。}。这个现象与传统的常识是相违背的,因此也有一些研究尝试解释这个现象\upcite{Stahlberg2019OnNS,Niehues2017AnalyzingNM}。在实验中,研究人员也发现增加搜索束的大小会导致翻译生成的结果变得更短。他们将这个现象归因于:增加搜索束的大小,会导致更多的模型错误,因为神经机器翻译的建模是基于局部归一的最大似然估计\upcite{Sountsov2016LengthBI,Murray2018CorrectingLB,StahlbergNeural}。此外,也有研究人员把这种翻译过短的现象归因于搜索错误\upcite{Stahlberg2019OnNS}。由于搜索时所面临的搜索空间是十分巨大的,因此搜索时可能无法找到模型定义的“最好”的译文。在某种意义上,这也体现了一种训练和推断不一致的问题。
%----------------------------------------------------------------------
\begin{figure}[htp]
......@@ -256,7 +257,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\end{figure}
%----------------------------------------------------------------------
\parinterval 一种解决问题的思路是从训练和推断的行为和目标不一致的角度切入。比如,为了解决{\small\sffamily\bfseries{曝光偏置}}\index{曝光偏置}(Exposure Bias)\index{Exposure Bias}问题\upcite{Ranzato2016SequenceLT},可以让系统使用前面步骤的预测结果作为预测下一个词所需要的历史信息,而不是依赖于标准答案\upcite{Bengio2015ScheduledSF,Zhang2019BridgingTG}另一方面,为了解决训练和推断目标不一致的问题,可以在训练的时候模拟推断的行为,同时让模型训练的目标与评价系统的标准尽可能一致\upcite{DBLP:conf/acl/ShenCHHWSL16}
\parinterval 一种解决问题的思路是从训练和推断的行为和目标不一致的角度切入。比如,为了解决{\small\sffamily\bfseries{曝光偏置}}\index{曝光偏置}(Exposure Bias)\index{Exposure Bias}问题\upcite{Ranzato2016SequenceLT},可以让系统使用前面步骤的预测结果作为预测下一个词所需要的历史信息,而不是依赖于标准答案\upcite{Bengio2015ScheduledSF,Zhang2019BridgingTG}此外,为了解决训练和推断目标不一致的问题,可以在训练的时候模拟推断的行为,同时让模型训练的目标与评价系统的标准尽可能一致\upcite{DBLP:conf/acl/ShenCHHWSL16}
\parinterval 需要注意的是,前面提到的搜索束变大造成的翻译品质下降的问题还有其它解决方法。比如,可以通过对结果重排序来缓解这个问题\upcite{DBLP:conf/emnlp/Yang0M18},也可以通过设计更好的覆盖度模型来生成长度更加合理的译文\upcite{li-etal-2018-simple}。从这个角度说,上述问题的成因也较为复杂,因此需要同时考虑模型错误和搜索错误。
......@@ -276,7 +277,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\parinterval 神经机器翻译需要对输入和输出的单词进行分布式表示,比如,每一个单词都用一个512 维向量进行表示。但是,由于真实的词表通常很大,因此计算并保存这些单词的向量表示会消耗较多的计算和存储资源。特别是对于基于Softmax 的输出层,使用大词表往往会占用较多的系统运算时间。虽然可以通过BPE 和限制词汇表规模的方法降低输出层计算的负担\upcite{DBLP:conf/acl/SennrichHB16a},但是为了获得可接受的翻译品质,词汇表也不能过小,因此输出层的计算仍然十分耗时。
\parinterval 对于这个问题,可以通过改变输出层的网络结构进行缓解\upcite{DBLP:conf/acl/JeanCMB15}。一种比较简单的方法是对可能输出的单词进行筛选,简称词汇选择。这里,可以利用类似于统计机器翻译的翻译表,获得每个源语言单词最可能的译文。在翻译过程中,利用注意力机制找到每个目标语位置对应的源语言位置,之后获得这些源语言单词最可能的翻译候选。之后,Softmax 只需要在这个有限的翻译候选单词集合上进行计算,大大降低了输出层的计算量。尤其对于CPU 上的系统,这个方法往往会带来明显的速度提升,同时保证翻译品质。图\ref{fig:14-4}给出了词汇选择方法的示意图。
\parinterval 通过改变输出层的网络结构,可以一定程度上缓解这个问题\upcite{DBLP:conf/acl/JeanCMB15}。一种比较简单的方法是对可能输出的单词进行筛选,简称词汇选择。这里,可以利用类似于统计机器翻译的翻译表,获得每个源语言单词最可能的译文。在翻译过程中,利用注意力机制找到每个目标语言位置对应的源语言位置,之后获得这些源语言单词最可能的翻译候选。之后,Softmax 只需要在这个有限的翻译候选单词集合上进行计算,大大降低了输出层的计算量。尤其对于CPU 上的系统,这个方法往往会带来明显的速度提升,同时保证翻译品质。图\ref{fig:14-4}给出了词汇选择方法的示意图。
%----------------------------------------------
\begin{figure}[htp]
......@@ -295,7 +296,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{消除冗余计算}
\parinterval 消除不必要的计算是加速机器翻译系统的另一种方法。比如,在统计机器翻译时代,假设重组就是一种典型的避免冗余计算的手段(见\chapterseven)。对于神经机器翻译中的Transformer 模型,消除冗余计算的一种简单有效的方法是对解码端的注意力结果进行缓存。在生成每个目标语译文时,Transformer 模型会对当前位置之前的所有位置进行自注意力操作,但是这些计算里只有和当前位置相关的计算是“新” 的,前面位置之间的注意力结果已经在之前的解码步骤里计算过,因此可以对其进行缓存。
\parinterval 消除不必要的计算是加速机器翻译系统的另一种方法。比如,在统计机器翻译时代,假设重组就是一种典型的避免冗余计算的手段(见\chapterseven)。对于神经机器翻译中的Transformer 模型,消除冗余计算的一种简单有效的方法是对解码端的注意力结果进行缓存。在生成每个目标语译文时,Transformer 模型会对当前位置之前的所有位置进行自注意力操作,但是这些计算里只有和当前位置相关的计算是“新” 的,前面位置之间的注意力结果已经在之前的解码步骤里计算过,因此可以对其进行缓存。
\parinterval 此外,由于Transformer 模型较为复杂,还存在很多冗余。比如,Transformer 的每一层会包含自注意力机制、层正则化、残差连接、前馈神经网络等多种不同的结构。同时,不同结构之间还会包含一些线性变换。多层Transformer(通常为6 层)模型会更加复杂。但是,这些层可能在做相似的事情,甚至有些计算根本就是重复的。图\ref{fig:14-5}中展示了解码端自注意力和编码-解码注意力中不同层的注意力权重的相似性,这里的相似性利用Jensen-Shannon散度进行度量\upcite{61115}。可以看到,自注意力中,2-5层之间的注意力权重的分布非常相似。编码-解码注意力也有类似的现象,临近的层之间有非常相似的注意力权重。这个现象说明:在多层神经网络中有些计算是冗余的,因此很自然的想法是消除这些冗余使得机器翻译变得更“轻”。
......@@ -307,7 +308,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\label{fig:14-5}
\end{figure}
%----------------------------------------------
\parinterval 一种方法是将不同层的注意力权重进行共享,这样上层的注意力权重可以复用下层的注意力权重\upcite{Xiao2019SharingAW}。在编码-解码注意力中,由于注意力机制中输入的Value 都是一样的\footnote{在Transformer 解码端,编码解码注意力输入的Value 是编码端的输出,因此是相同的(见\chaptertwelve},我们甚至可以直接复用前一层注意力计算的结果。图\ref{fig:14-6}给出了不同方法的对比,其中$S$表示注意力权重,$A$表示注意模型的输出。可以看到,使用共享的思想,可以大大减少冗余的计算。
\parinterval 一种方法是将不同层的注意力权重进行共享,这样上层的注意力权重可以复用下层的注意力权重\upcite{Xiao2019SharingAW}。在编码-解码注意力中,由于注意力机制中输入的Value 都是一样的\footnote{在Transformer解码端,编码解码注意力输入的Value是编码端的输出,因此是相同的(见\chaptertwelve}甚至可以直接复用前一层注意力计算的结果。图\ref{fig:14-6}给出了不同方法的对比,其中$S$表示注意力权重,$A$表示注意模型的输出。可以看到,使用共享的思想,可以大大减少冗余的计算。
%----------------------------------------------
\begin{figure}[htp]
......@@ -328,15 +329,15 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{轻量解码端及小模型}
\parinterval 在推断时,神经机器翻译的解码端是最耗时的,因为每个目标语位置需要单独输出单词的分布,同时在搜索过程中每一个翻译假设都要被扩展成多个翻译假设,进一步增加了计算量。因此,另一种加速系统的思路是使用更加轻量的解码器\upcite{DBLP:journals/corr/HintonVD15,Munim2019SequencelevelKD}
\parinterval 在推断时,神经机器翻译的解码端是最耗时的,因为每个目标语位置需要单独输出单词的分布,同时在搜索过程中每一个翻译假设都要被扩展成多个翻译假设,进一步增加了计算量。因此,另一种加速系统的思路是使用更加轻量的解码器\upcite{DBLP:journals/corr/HintonVD15,Munim2019SequencelevelKD}
\parinterval 比较简单的做法是把解码端的网络变得更“浅”、更“窄”。所谓浅网络是指使用更少的层构建神经网络,比如,使用3 层,甚至1 层网络的Transformer 解码器。所谓窄网络是指将网络中某些层中神经元的数量减少。不过,直接训练这样的小模型会带来翻译品质的下降。这时会考虑使用知识蒸馏(也称作知识精炼)等技术来提升小模型的品质。
\parinterval 另一种思路是化简Transformer 解码端的神经网络。比如,可以使用平均注意力机制代替原始Transformer 中的自注意力机制\upcite{DBLP:journals/corr/abs-1805-00631},也可以使用运算更轻的卷积操作代替注意力模块\upcite{Wu2019PayLA}。前面提到的基于共享注意力机制的模型也是一种典型的轻量模型\upcite{Xiao2019SharingAW}。这些方法本质上也是对注意力模型的结构的优化,这类思想在近几年也受到了很多关注 \upcite{Kitaev2020ReformerTE,Katharopoulos2020TransformersAR,DBLP:journals/corr/abs-2006-04768}
\parinterval 另一种思路是化简Transformer 解码端的神经网络。比如,可以使用平均注意力机制代替原始Transformer 中的自注意力机制\upcite{DBLP:journals/corr/abs-1805-00631},也可以使用运算更轻的卷积操作代替注意力模块\upcite{Wu2019PayLA}。前面提到的基于共享注意力机制的模型也是一种典型的轻量模型\upcite{Xiao2019SharingAW}。这些方法本质上也是对注意力模型的结构的优化,这类思想在近几年也受到了很多关注 \upcite{Kitaev2020ReformerTE,Katharopoulos2020TransformersAR,DBLP:journals/corr/abs-2006-04768}
\parinterval 此外,使用异构神经网络也是一种平衡精度和速度的有效方法。在很多研究中发现,基于Transformer 的编码器对翻译品质的影响更大,而解码端的作用会小一些。因此,一种想法是使用更快速的解码端结构,比如,用基于循环神经网络的解码端代替基于Transformer 的解码端\upcite{Chen2018TheBO}。这样,既能发挥Transformer 在编码上的优势,同时也能利用循环神经网络在解码端速度上的优势。使用类似的思想,也可以用卷积神经网络等结构进行解码端的设计。
\parinterval 针对轻量级Transformer模型的设计也包括层级的结构剪枝,这类方法试图通过跳过某些操作或者某些层来降低计算量。典型的相关工作是样本自适应网络结构,如 FastBERT\upcite{Liu2020FastBERTAS}、Depth Adaptive Transformer\upcite{Elbayad2020DepthAdaptiveT} 和LayerDrop\upcite{DBLP:conf/iclr/FanGJ20}等,与传统的Transformer的解码过程不同,这类网络结构在推断时不需要计算全部的解码层,而是根据输入自动选择模型的部分层进行计算,达到加速和减少参数量的目的。此外,矩阵分解也是一种轻量级模型解决方案,这类方法通过矩阵分解的方法提升计算效率,通过简化复杂的矩阵计算来达到加速模型训练和推断的目的。例如, 有研究人员提出词频自适应表示方法,词频越高则对应的词向量维度越大,反之越小,该方法可以显著减少词向量参数矩阵大小\upcite{DBLP:conf/iclr/BaevskiA19}
\parinterval 针对轻量级Transformer模型的设计也包括层级的结构剪枝,这类方法试图通过跳过某些操作或者某些层来降低计算量。典型的相关工作是样本自适应网络结构,如 FastBERT\upcite{Liu2020FastBERTAS}、Depth Adaptive Transformer\upcite{Elbayad2020DepthAdaptiveT} 和LayerDrop\upcite{DBLP:conf/iclr/FanGJ20}等,与传统的Transformer的解码过程不同,这类网络结构在推断时不需要计算全部的解码层,而是根据输入自动选择模型的部分层进行计算,达到加速和减少参数量的目的。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
......@@ -377,9 +378,9 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\vspace{0.5em}
\item 半精度浮点运算。半精度浮点运算是随着近几年GPU 技术发展而逐渐流行的一种运算方式。简单来说,半精度的表示要比单精度需要更少的存储单元,所表示的浮点数范围也相应的变小。不过,实践中已经证明神经机器翻译中的许多运算用半精度计算就可以满足对精度的要求。因此,直接使用半精度运算可以大大加速系统的训练和推断进程,同时对翻译品质的影响很小。不过,需要注意的是,在分布式训练的时候,由于参数服务器需要对多个计算节点上的梯度进行累加,因此保存参数的部分仍然会使用单精度浮点以保证多次累加之后不会造成精度过大的损失。
\vspace{0.5em}
\item 整型运算。整数运算是一种比浮点运算“轻” 很多的运算。无论是芯片占用面积、能耗还是处理单次运算的时钟周期数,整数运算相比浮点运算都有着明显的优势。因此,使用整数运算也是很有潜力的加速手段。不过,整数的表示和浮点数有着很大的不同。一个基本的问题是,整数是不连续的,因此无法准确的刻画浮点数中很小的小数。对于这个问题,一种解决方法是利用“量化+ 反量化+ 缩放” 的策略让整数运算近似浮点运算的效果\upcite{DBLP:journals/corr/abs-1906-00532,DBLP:conf/cvpr/JacobKCZTHAK18,DBLP:journals/corr/abs-1910-10485}。所谓“量化” 就是把一个浮点数离散化为一个整数,“反量化” 是这个过程的逆过程。由于浮点数可能超出整数的范围,因此会引入一个缩放因子。在量化前将浮点数缩放到整数可以表示的范围,反量化前再缩放回原始浮点数的表示范围。这种方法在理论上可以带来很好的加速效果。不过由于量化和反量化的操作本身也有时间消耗,而且在不同处理器上的表现差异较大。因此不同的实现方式带来的加速效果并不相同,需要通过实验测算。
\item 整型运算。整型运算是一种比浮点运算“轻” 很多的运算。无论是芯片占用面积、能耗还是处理单次运算的时钟周期数,整型运算相比浮点运算都有着明显的优势。因此,使用整型运算也是很有潜力的加速手段。不过,整数的表示和浮点数有着很大的不同。一个基本的问题是,整数是不连续的,因此无法准确的刻画浮点数中很小的小数。对于这个问题,一种解决方法是利用“量化+ 反量化+ 缩放” 的策略让整型运算达到近似浮点运算的效果\upcite{DBLP:journals/corr/abs-1906-00532,DBLP:conf/cvpr/JacobKCZTHAK18,DBLP:journals/corr/abs-1910-10485}。所谓“量化” 就是把一个浮点数离散化为一个整数,“反量化” 是这个过程的逆过程。由于浮点数可能超出整数的范围,因此会引入一个缩放因子。在量化前将浮点数缩放到整数可以表示的范围,反量化前再缩放回原始浮点数的表示范围。这种方法在理论上可以带来很好的加速效果。不过由于量化和反量化的操作本身也有时间消耗,而且在不同处理器上的表现差异较大。因此不同的实现方式带来的加速效果并不相同,需要通过实验测算。
\vspace{0.5em}
\item 低精度整型运算。使用更低精度的整型运算是进一步加速的手段之一。比如使用16 位整数、8 位整数,甚至4 位整数在理论上都会带来速度的提升,如表\ref{tab:14-3}所示。不过,并不是所有处理器都支持低精度整数的运算。开发这样的系统,一般需要硬件和特殊低精度整数计算库的支持。而且相关计算大多是在CPU 上实现,应用会受到一定的限制。
\item 低精度整型运算。使用更低精度的整型运算是进一步加速的手段之一。比如使用16 位整数、8 位整数,甚至4 位整数在理论上都会带来速度的提升,如表\ref{tab:14-3}所示。不过,并不是所有处理器都支持低精度整型的运算。开发这样的系统,一般需要硬件和特殊低精度整型计算库的支持。而且相关计算大多是在CPU 上实现,应用会受到一定的限制。
\vspace{0.5em}
\end{itemize}
......@@ -404,7 +405,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\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
......@@ -412,16 +413,16 @@ 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}\}$构成线性关系,那么生成$y_j$就是自回归的序列生成过程。神经机器翻译借用了这个概念,但是并不要求使用线性模型。对于输入的源语言序列$\seq{x}=\{x_1,\dots,x_m\}$,用自回归翻译模型生成译文序列$\seq{y}=\{y_1,\dots,y_n\}$的概率可以被定义为:
\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}\}$构成线性关系,那么生成$y_j$就是自回归的序列生成过程。神经机器翻译借用了这个概念,但是并不要求使用线性模型。对于输入的源语言序列$\seq{x}=\{x_1,\dots,x_m\}$,用自回归翻译模型生成译文序列$\seq{y}=\{y_1,\dots,y_n\}$的概率可以被定义为公式\eqref{eq:14-8}
\begin{eqnarray}
\funp{P}(\seq{y}|\seq{x}) &=& \prod_{j=1}^n {\funp{P}(y_j|y_{<j},\seq{x})}
\label{eq:14-8}
\end{eqnarray}
\noindent 即译文单词$y_{j}$的生成依赖前面已经生成的单词序列$y_{<j}=\{y_1,\dots,y_{j-1}\}$和源语言序列$\{x_1,\dots,x_m\}$。这种自回归的翻译方式符合人们阅读和生成句子时的习惯。它在机器翻译等任务上也取得了较好的性能,特别是配合束搜索也能够有效寻找近似最优译文。但是,由于解码器的每个步骤必须顺序地而不是并行地运行,自回归翻译模型会阻碍不同译文单词生成的并行化。特别是在GPU 上,翻译的自回归性会大大降低计算的并行度,导致推断过程的效率比较低下,设备利用率低。
\noindent 即译文单词$y_{j}$的生成依赖前面已经生成的单词序列$y_{<j}=\{y_1,\dots,y_{j-1}\}$和源语言序列$\{x_1,\dots,x_m\}$。这种自回归的翻译方式符合人们阅读和生成句子时的习惯。它在机器翻译等任务上也取得了较好的性能,特别是配合束搜索也能够有效寻找近似最优译文。但是,由于解码器的每个步骤必须顺序地而不是并行地运行,自回归翻译模型会阻碍不同译文单词生成的并行化。特别是在GPU 上,翻译的自回归性会大大降低计算的并行度,导致推断过程的效率比较低下,设备利用率低。
\parinterval 对于这个问题,研究者也考虑移除翻译的自归回性,进行{\small\sffamily\bfseries{非自回归翻译}}\index{非自回归翻译}(Non-Autoregressive Translation,NAT)\index{Non-Autoregressive Translation}\upcite{Gu2017NonAutoregressiveNM}。一个简单的非自回归翻译模型将问题建模为
\parinterval 对于这个问题,研究人员也考虑移除翻译的自回归性,进行{\small\sffamily\bfseries{非自回归翻译}}\index{非自回归翻译}(Non-Autoregressive Translation,NAT)\index{Non-Autoregressive Translation}\upcite{Gu2017NonAutoregressiveNM}。一个简单的非自回归翻译模型将问题建模为公式\eqref{eq:14-9}
\begin{eqnarray}
\funp{P}(\seq{y}|\seq{x}) &=& \prod_{j=1}^n {\funp{P}(y_j|\seq{x})}
......@@ -436,9 +437,9 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{非自回归翻译模型的结构}
\parinterval 在介绍非自回归模型的具体结构之前,先来看看如何实现一个简单的非自回归翻译模型。这里用标准的Transformer来举例。首先为了一次性能够生成所有的词,需要丢弃解码端对未来信息屏蔽的矩阵,从而去掉模型的自回归性。此外,还要考虑生成一问的长度。自回归模型每步的输入是上一步解码出的结果,当预测到终止符<eos>时序列的生成就自动停止了,然而非自回归模型却没有这样的特性,因此还需要一个长度预测器来预测出其长度,之后再用这个长度得到每个位置的表示,进而完成整个序列的生成。
\parinterval 在介绍非自回归模型的具体结构之前,先来看看如何实现一个简单的非自回归翻译模型。这里用标准的Transformer来举例。首先为了一次性能够生成所有的词,需要丢弃解码端对未来信息屏蔽的矩阵,从而去掉模型的自回归性。此外,还要考虑生成译文的长度。自回归模型每步的输入是上一步解码出的结果,当预测到终止符<eos>时序列的生成就自动停止了,然而非自回归模型却没有这样的特性,因此还需要一个长度预测器来预测出其长度,之后再用这个长度得到每个位置的表示,进而完成整个序列的生成。
\parinterval\ref{fig:14-12}就是一个最简单的非自回归翻译模型,它的推断过程可以一次性解码出整个目标序列。但是这样得到的模型所翻译出的句子质量很低。比如,在IWSLT英德等数据上的BLEU值只有个位数,而现在最好的自回归模型已经能够达到30左右的BLEU值。这是因为每个位置词的分布$\funp{P}(y_j)$只依赖于源语言句子$\seq{x}$,使得$\funp{P}(y_j)$的预测不准确。
\parinterval\ref{fig:14-12}就是一个最简单的非自回归翻译模型,它的推断过程可以一次性解码出整个目标语言序列。但是这样得到的模型所翻译出的句子质量很低。比如,在IWSLT英德等数据上的BLEU值只有个位数,而现在最好的自回归模型已经能够达到30左右的BLEU值。这是因为每个位置词的分布$\funp{P}(y_j)$只依赖于源语言句子$\seq{x}$,使得$\funp{P}(y_j)$的预测不准确。
%----------------------------------------------------------------------
\begin{figure}[htp]
......@@ -449,7 +450,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\end{figure}
%----------------------------------------------------------------------
\parinterval 完全独立地对每个词建模,会出现什么问题呢?来看一个例子,将中文“谢谢你”翻译成英文,可以翻译成“Thanks to you”或者“Thanks a lot”。假设生成这两种翻译的概率是相等的,即一半的概率是“Thanks to you”,另一半的概率是“Thanks a lot”。由于非自回归模型的条件独立性假设,解码时第二个词“to”和“a”的概率是差不多大的,第三个词“you”和“lot”的概率差不多大的,会使得模型生成出“Thanks to lot”或者“Thanks a you”这样错误的翻译,如图\ref{fig:14-13}所示。这便是影响句子质量的关键问题,称之为{\small\sffamily\bfseries{多峰问题}}\index{多峰问题}(Multi-modality Problem)\index{Multi-modality 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{多峰问题}(Multi-modality Problem)\index{Multi-modality Problem}\upcite{Gu2017NonAutoregressiveNM}。针对非自回归模型难以处理多峰问题进行改进是提升非自回归模型质量的关键。
%----------------------------------------------------------------------
\begin{figure}[htp]
......@@ -479,9 +480,9 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\end{figure}
%----------------------------------------------------------------------
\parinterval 与自回归翻译模型类似,Transformer模型的编码器和解码器都完全由前馈神经网络和多头注意力模块组成。在非自回归模型在解码开始之前,非自回归模型需要知道目标句子的长度,以便并行生成所有单词。更重要的是,非自回归模型需要一次性生成出所有的目标词,因此不能像自回归模型那样用已生成的词作为第一个解码器层的输入。那么非自回归模型解码器的输入是什么呢?如果完全省略第一个解码器层的输入,或者仅使用位置嵌入,将会导致非常差的性能。这里使用繁衍率来解决这个问题,繁衍率指的是对于每个源语言单词预测所对应的目标语单词的个数(见\chapterthree)。翻译过程取决于繁衍率序列(图\ref{fig:14-14}中的数字1\ 1\ 2\ 0\ 1),最终目标句子长度则由所有源语言单词对应的繁衍率之和决定。这个繁衍率序列可以通过外部词对齐工具来得到,从而来训练这个繁衍率预测器。但由于外部词对齐系统的会出现错误,因此在模型收敛之后,需要在繁衍率预测器上加一个强化学习的损失来进行微调。
\parinterval 与自回归翻译模型类似,Transformer模型的编码器和解码器都完全由前馈神经网络和多头注意力模块组成。在解码开始之前,非自回归模型需要知道译文的长度,以便并行生成所有单词。更重要的是,非自回归模型需要一次性生成出所有的译文单词,因此不能像自回归模型那样用已生成的词作为第一个解码器层的输入。那么非自回归模型解码器的输入是什么呢?如果完全省略第一个解码器层的输入,或者仅使用位置嵌入,将会导致性能非常差。这里使用繁衍率来解决这个问题,繁衍率指的是对于每个源语言单词预测所对应的目标语言单词的个数(见\chaptersix)。翻译过程取决于繁衍率序列(图\ref{fig:14-14}中的数字1\ 1\ 2\ 0\ 1),最终译文长度则由所有源语言单词对应的繁衍率之和决定。这个繁衍率序列可以通过外部词对齐工具得到,从而来训练这个繁衍率预测器。但由于外部词对齐系统会出现错误,因此在模型收敛之后,需要在繁衍率预测器上加一个强化学习的损失来进行微调。
\parinterval 另外,在每个解码器层中还包括额外的位置注意力模块,该模块与Transformer模型的其它部分中使用的多头注意力机制相同,如
\parinterval 另外,在每个解码器层中还包括额外的位置注意力模块,该模块与Transformer模型的其它部分中使用的多头注意力机制相同,如公式\eqref{eq:14-10}
\begin{eqnarray}
\textrm{Attention}(\mathbi{Q},\mathbi{K},\mathbi{V}) &=& \textrm{Softmax}(\frac{\mathbi{Q}{\mathbi{K}}^{T}}{\sqrt{d_k}})\cdot \mathbi{V}
......@@ -506,7 +507,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsubsection{3.自回归模型打分}
\parinterval 通过采样不同的繁衍率序列,可以得到多个不同的翻译候选。之后,把这些不同的译文再交给自回归模型来评分,选择一个最好的结果作为最终的翻译。在这里,可以使用强制解码同时对多个译文进行打分,因此这个过程可以充分并行。通常,这种方法能够很有效提升非自回归翻译模型的译文质量,并且保持较高的推断速度\upcite{Gu2017NonAutoregressiveNM,Wei2019ImitationLF,Guo2019NonAutoregressiveNM,Wang2019NonAutoregressiveMT,Ma2019FlowSeqNC}。但是,缺点是需要同时部署自回归和非自回归两套系统。
\parinterval 通过采样不同的繁衍率序列,可以得到多个不同的翻译候选。之后,把这些不同的译文再交给自回归模型来评分,选择一个最好的结果作为最终的翻译。在这里,可以使用强制解码同时对多个译文进行打分,因此这个过程可以充分并行。通常,这种方法能够很有效提升非自回归翻译模型的译文质量,并且保持较高的推断速度\upcite{Gu2017NonAutoregressiveNM,Wei2019ImitationLF,Guo2019NonAutoregressiveNM,Wang2019NonAutoregressiveMT,Ma2019FlowSeqNC}。但是,缺点是需要同时部署自回归和非自回归两套系统。
%----------------------------------------------------------------------------------------
% NEW SUBSECTION
......@@ -518,11 +519,11 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\begin{itemize}
\vspace{0.5em}
\item 基于层级知识蒸馏的方法\upcite{Li2019HintBasedTF}。由于自回归模型和非自回归模型的结构相差不大,因此可以将翻译质量更高的自回归模型作为“教师”,通过给非自回归模型提供监督信号,使其逐块学习前者的分布。研究人员发现了两点非常有意思的现象:1)非自回归模型输出的重复单词的位置的隐藏状态非常相似。2)非自回归模型的注意力分布比自回归模型的分布更加分散。这两点发现启发了研究人员使用自回归模型中的隐层状态来指导非自回归模型学习。通过计算两个模型隐层状态的距离以及注意力矩阵的KL散度\footnote{KL散度即相对熵}作为额外的损失来帮助非自回归模型的训练过程。
\item 基于层级知识蒸馏的方法\upcite{Li2019HintBasedTF}。由于自回归模型和非自回归模型的结构相差不大,因此可以将翻译质量更高的自回归模型作为“教师”,通过给非自回归模型提供监督信号,使其逐块学习前者的分布。研究人员发现了两点非常有意思的现象:1)非自回归模型输出的重复单词的位置的隐藏状态非常相似。2)非自回归模型的注意力分布比自回归模型的分布更加分散。这两点发现启发了研究人员使用自回归模型中的隐层状态来指导非自回归模型学习。通过计算两个模型隐层状态的距离以及注意力矩阵的KL散度\footnote{KL散度即相对熵}作为额外的损失来帮助非自回归模型的训练过程。
\vspace{0.5em}
\item 基于模仿学习的方法\upcite{Wei2019ImitationLF}。这种观点认为非自回归模型可以从性能优越的自回归模型中学得知识。{\small\bfnew{模仿学习}}\index{模仿学习}(Imitation Learning\index{Imitation Learning})是强化学习中的一个概念,即从专家那里学习正确的行为,与监督学习很相似\upcite{Ho2016ModelFreeIL,Ho2016GenerativeAI,Duan2017OneShotIL}。与其不同的是,模仿学习不是照搬专家的行为,而是学习专家为什么要那样做。换句话说,学习的不是专家的镜像,而是一个专家的行为分布。这里,可以将自回归模型作为专家,非自回归模型学习不同时间步和不同层的解码状态,最后将模仿学习的损失与交叉熵损失加权求和后作为最终的优化目标。
\vspace{0.5em}
\item 基于正则化因子的方法\upcite{Wang2019NonAutoregressiveMT}。非自回归模型的翻译结果中存在着两种非常严重的错误:重复翻译和不完整的翻译。第一种问题是因为解码器隐层状态中相邻的两个位置过于相似,因此翻译出来的单词也一样。对于第二个问题,通常将其归咎于非自回归模型在翻译的过程中丢失了一些源语信息,从而造成了翻译效果的下降。针对这两个问题,可以通过在相邻隐层状态间添加相似度约束来计算一个重构损失。具体来说,对于目前正在进行的翻译$\seq{x}\to\seq{y}$,通过利用一个反向的自回归模型再将$\seq{y}$翻译成$\seq{x'}$,最后计算$\seq{x}$$\seq{x'}$的差异性作为损失。
\item 基于正则化因子的方法\upcite{Wang2019NonAutoregressiveMT}。非自回归模型的翻译结果中存在着两种非常严重的错误:重复翻译和不完整的翻译。第一种问题是因为解码器隐层状态中相邻的两个位置过于相似,因此翻译出来的单词也一样。对于第二个问题,通常将其归咎于非自回归模型在翻译的过程中丢失了一些源语言句子的信息,从而造成了翻译效果的下降。针对这两个问题,可以通过在相邻隐层状态间添加相似度约束来计算一个重构损失。具体来说,对于目前正在进行的翻译$\seq{x}\to\seq{y}$,通过利用一个反向的自回归模型再将$\seq{y}$翻译成$\seq{x'}$,最后计算$\seq{x}$$\seq{x'}$的差异性作为损失。
\vspace{0.5em}
\end{itemize}
......@@ -534,7 +535,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\parinterval 非自回归翻译消除了序列生成中不同位置间的依赖,在每个位置都进行独立的预测,但这反过来会导致翻译质量显着下降,因为缺乏不同单词间依赖关系的建模。因此,也有研究聚焦于在非自回归模型中添加一些自回归组件来提升网络结构的表达能力。
\parinterval 一种做法是将语法作为目标语言句子的框架\upcite{Akoury2019SyntacticallyST}。具体来说,先自回归地预测出一个目标语言的句法块序列,将句法树作为序列信息的抽象,然后根据句法块序列非自回归地生成所有目标语言单词。如图\ref{fig:14-21}所示,该模型由一个编码器和两个解码器组成。其中编码器和第一个解码器与标准的Transformer模型相同,用来自回归地预测句法树信息;第二个解码器将第一个解码器的句法信息作为输入,之后再非自回归地生成整个目标句子。在训练过程中,通过使用外部句法分析器获得对句法预测任务的监督信号。虽然可以简单地让模型预测整个句法树,但是这种方法会显著增加自回归步骤的数量,从而增大时间开销。因此,为了维持句法信息与解码时间的平衡,这里预测一些由句法类型和子树大小组成的块标识符(如VP3)而不是整个句法树。
\parinterval 一种做法是将语法作为目标语言句子的框架\upcite{Akoury2019SyntacticallyST}。具体来说,先自回归地预测出一个目标语言的句法块序列,将句法树作为序列信息的抽象,然后根据句法块序列非自回归地生成所有目标语言单词。如图\ref{fig:14-21}所示,该模型由一个编码器和两个解码器组成。其中编码器和第一个解码器与标准的Transformer模型相同,用来自回归地预测句法树信息;第二个解码器将第一个解码器的句法信息作为输入,之后再非自回归地生成整个译文。在训练过程中,通过使用外部句法分析器获得对句法预测任务的监督信号。虽然可以简单地让模型预测整个句法树,但是这种方法会显著增加自回归步骤的数量,从而增大时间开销。因此,为了维持句法信息与解码时间的平衡,这里预测一些由句法类型和子树大小组成的块标识符(如VP3)而不是整个句法树。
%----------------------------------------------
\begin{figure}[htp]
......@@ -545,7 +546,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\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]
......@@ -575,7 +576,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\parinterval 如果一次并行生成整个序列,往往会导致单词之间的关系很难捕捉,因此也限制了这类方法的能力。即使生成了错误的译文单词,这类方法也无法修改。针对这些问题,也可以使用迭代式的生成方式\upcite{Lee2018DeterministicNN,Ghazvininejad2019MaskPredictPD,Kasai2020NonAutoregressiveMT}。这种方法放弃了一次生成最终的译文句子,而是将解码出的文本再重新送给解码器,在每次迭代中来改进之前生成的译文单词,可以理解为句子级的自回归模型。这样做的好处在于,每次迭代的过程中可以利用已经生成的部分翻译结果,来指导其它部分的生成。
\parinterval\ref{fig:14-18}展示了这种方法的简单示例。它拥有一个解码器和$N$个编码器。解码器首先预测出目标句子的长度,然后将输入$\seq{x}$按照长度复制出$\seq{x'}$作为第一个解码器的输入,之后生成$\seq{y'}$出作为第一轮迭代的输出。接下来再把$\seq{y'}$输入给解码器2输出$\seq{y''}$,以此类推。那么迭代到什么时候结束呢?一种简单的做法是提前制定好迭代次数,这种方法能够自主地对生成句子的质量和效率进行平衡。另一种称之为“自适应”的方法,具体是通过计算当前生成的句子上一次生成的变化量来自动停止,例如,使用杰卡德相似系数作为变化量函数\footnote{杰卡德相似系数是衡量有限样本集之间的相似性与差异性的一种指标,杰卡德相似系数值越大,样本相似度越高。}。另外,需要说明的是,图\ref{fig:14-18}中使用多个解码器一种逻辑示意。真实的系统仅需要一个解码器,并运行多次,就达到了迭代精化的目的。
\parinterval\ref{fig:14-18}展示了这种方法的简单示例。它拥有一个编码器和$N$个解码器。编码器首先预测出译文的长度,然后将输入$\seq{x}$按照长度复制出$\seq{x'}$作为第一个解码器的输入,之后生成$\seq{y'}$作为第一轮迭代的输出。接下来再把$\seq{y'}$输入给第二个解码器输出$\seq{y''}$,以此类推。那么迭代到什么时候结束呢?一种简单的做法是提前制定好迭代次数,这种方法能够自主地对生成句子的质量和效率进行平衡。另一种称之为“自适应”的方法,具体是通过计算当前生成的句子上一次生成的变化量来自动停止,例如,使用杰卡德相似系数作为变化量函数\footnote{杰卡德相似系数是衡量有限样本集之间的相似性与差异性的一种指标,杰卡德相似系数值越大,样本相似度越高。}。另外,需要说明的是,图\ref{fig:14-18}中是使用多个解码器的一种逻辑示意。真实的系统仅需要一个解码器,并运行多次,就达到了迭代精化的目的。
%----------------------------------------------
\begin{figure}[htp]
......@@ -586,7 +587,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}给出了一个示例。
......@@ -619,7 +620,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\begin{itemize}
\vspace{0.5em}
\item 假设生成。构建翻译假设集合是假设选择的第一步,也是最重要的一步。理想的情况下,我们希望这个集合尽可能包含更多高质量的翻译假设,这样后面有更大的几率选出更好的结果。不过,由于单个模型的性能是有上限的,因此无法期望这些翻译假设的品质超越单个模型的上限。研究人员更加关心的是翻译假设的多样性,因为已经证明多样的翻译假设非常有助于提升系统融合的性能\upcite{DBLP:journals/corr/LiMJ16,xiao2013bagging}。为了生成多样的翻译假设,通常有两种思路:1)使用不同的模型生成翻译假设;2)使用同一个模型的不同参数和设置生成翻译假设。图\ref{fig:14-8}展示了二者的区别。比如,可以使用基于RNN 的模型和Transformer 模型生成不同的翻译假设,之后都放入集合中;也可以只用Transformer 模型,但是用不同的模型参数构建多个系统,之后分别生成翻译假设。在神经机器翻译中,经常采用的是第二种方式,因为系统开发的成本更低。比如,很多研究工作都是基于一个基础模型,用不同的初始参数、不同层数、不同解码方式生成多个模型进行翻译假设生成。
\item 假设生成。构建翻译假设集合是假设选择的第一步,也是最重要的一步。理想的情况下,这个集合应该尽可能包含更多高质量的翻译假设,这样后面有更大的几率选出更好的结果。不过,由于单个模型的性能是有上限的,因此无法期望这些翻译假设的品质超越单个模型的上限。研究人员更加关心的是翻译假设的多样性,因为已经证明多样的翻译假设非常有助于提升系统融合的性能\upcite{DBLP:journals/corr/LiMJ16,xiao2013bagging}。为了生成多样的翻译假设,通常有两种思路:1)使用不同的模型生成翻译假设;2)使用同一个模型的不同参数和设置生成翻译假设。图\ref{fig:14-8}展示了二者的区别。比如,可以使用基于RNN 的模型和Transformer 模型生成不同的翻译假设,之后都放入集合中;也可以只用Transformer 模型,但是用不同的模型参数构建多个系统,之后分别生成翻译假设。在神经机器翻译中,经常采用的是第二种方式,因为系统开发的成本更低。比如,很多研究工作都是基于一个基础模型,用不同的初始参数、不同层数、不同解码方式生成多个模型进行翻译假设生成。
%----------------------------------------------
\begin{figure}[htp]
......@@ -631,7 +632,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
%----------------------------------------------
\vspace{0.5em}
\item 选择模型。所谓假设选择实际上就是要用一个更强的模型在候选中进行选择。这个“强” 模型一般是由更多、更复杂的子模型组合而成。常用的方法是直接使用翻译假设生成时的模型构建“强” 模型。比如,使用两个模型生成了翻译假设集合,之后对所有翻译假设都分别用这两个模型进行打分。最后,综合两个模型的打分(如线性插值)得到翻译假设的最终得分,并进行选择。当然,也可以使用更强大的统计模型对多个子模型进行组合(如使用多层神经网络)。
\item 选择模型。所谓假设选择实际上就是要用一个更强的模型在候选中进行选择。这个“强” 模型一般是由更多、更复杂的子模型组合而成。常用的方法是直接使用翻译假设生成时的模型构建“强” 模型。比如,使用两个模型生成了翻译假设集合,之后对所有翻译假设都分别用这两个模型进行打分。最后,综合两个模型的打分(如线性插值)得到翻译假设的最终得分,并进行选择。当然,也可以使用更强大的统计模型对多个子模型进行组合(如使用多层神经网络)。
\vspace{0.5em}
\end{itemize}
......@@ -661,7 +662,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\end{figure}
%----------------------------------------------
\parinterval 公式\eqref{eq:14-11}是一种典型的线性插值模型,这类模型在语言建模等任务中已经得到成功应用。从统计学习的角度,多个模型的插值可以有效的降低经验错误率。不过,多模型集成依赖一个假设:这些模型之间需要有一定的互补性。这种互补性有时也体现在多个模型预测的上限上,称为Oracle。比如,可以把这$K$个模型输出中BLEU最高的结果作为Oracle,也可以选择每个预测结果中使BLEU 达到最高的译文单词,这样构成的句子作为Oracle。当然,并不是说Oracle 提高,模型集成的结果一定会变好。因为Oracle 是最理想情况下的结果,而实际预测的结果与Oracle 往往有很大差异。如何使用Oracle 进行模型优化也是很多研究者在探索的问题。
\parinterval 公式\eqref{eq:14-11}是一种典型的线性插值模型,这类模型在语言建模等任务中已经得到成功应用。从统计学习的角度,多个模型的插值可以有效地降低经验错误率。不过,多模型集成依赖一个假设:这些模型之间需要有一定的互补性。这种互补性有时也体现在多个模型预测的上限上,称为Oracle。比如,可以把这$K$个模型输出中BLEU最高的结果作为Oracle,也可以选择每个预测结果中使BLEU 达到最高的译文单词,这样构成的句子作为Oracle。当然,并不是说Oracle 提高,模型集成的结果一定会变好。因为Oracle 是最理想情况下的结果,而实际预测的结果与Oracle 往往有很大差异。如何使用Oracle 进行模型优化也是很多研究人员在探索的问题。
\parinterval 此外,如何构建集成用的模型也是非常重要的,甚至说这部分工作会成为模型集成方法中最困难的部分\upcite{DBLP:conf/wmt/LiLXLLLWZXWFCLL19,Wang2018TencentNM,DBLP:conf/wmt/SennrichHB16}。为了增加模型的多样性,常用的方法有:
......@@ -673,9 +674,9 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\vspace{0.5em}
\item 不同模型(局部)架构的调整,比如,使用不同的位置编码模型\upcite{Shaw2018SelfAttentionWR}、多层融合模型\upcite{WangLearning}等;
\vspace{0.5em}
\item 利用不同数量以及不同数据增强方式产生的伪数据训练模型{\color{red} 参考文献:今年的报告}
\item 利用不同数量以及不同数据增强方式产生的伪数据训练模型\upcite{zhang-EtAl:2020:WMT}
\vspace{0.5em}
\item 利用多分支多通道的模型,不同分支可能有不同结构,使得模型能有更好的表示能力{\color{red} 参考文献:今年的报告}
\item 利用多分支多通道的模型,不同分支可能有不同结构,使得模型能有更好的表示能力\upcite{zhang-EtAl:2020:WMT}
\vspace{0.5em}
\item 利用预训练进行参数共享之后微调的模型;
\vspace{0.5em}
......@@ -687,7 +688,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\subsection{译文重组}
\parinterval 假设直接从已经生成的译文中进行选择,因此无法产生“新” 的译文,也就是它的输出只能是某个单模型的输出。另一方面,预测融合需要同时使用多个模型进行推断,对计算和内存消耗较大。而且这两种方法有一个共性问题:搜索都是基于一个个字符串,相比指数级的译文空间,所看到的结果还是非常小的一部分。对于这个问题,一种方法是利用更加紧凑的数据结构对指数级的译文串进行表示。比如,可以使用格(Lattice)对多个译文串进行表示\upcite{DBLP:conf/emnlp/TrombleKOM08}。图\ref{fig:14-10}展示了基于$n$-best词串和基于Lattice 的表示方法的区别。可以看到,Lattice 中从起始状态到结束状态的每一条路径都表示一个译文,不同译文的不同部分可以通过Lattice 中的节点得到共享\footnote{本例中的Lattice 也是一个混淆网络(Confusion Network)。}。理论上,Lattice 可以把指数级数量的词串用线性复杂度的结构表示出来。
\parinterval 假设直接从已经生成的译文中进行选择,因此无法产生“新” 的译文,也就是它的输出只能是某个单模型的输出。此外,预测融合需要同时使用多个模型进行推断,对计算和内存消耗较大。而且这两种方法有一个共性问题:搜索都是基于一个个字符串,相比指数级的译文空间,所看到的结果还是非常小的一部分。对于这个问题,一种方法是利用更加紧凑的数据结构对指数级的译文串进行表示。比如,可以使用{\small\sffamily\bfseries{}}\index{}(Lattice\index{Lattice})对多个译文串进行表示\upcite{DBLP:conf/emnlp/TrombleKOM08}。图\ref{fig:14-10}展示了基于$n$-best词串和基于Lattice 的表示方法的区别。可以看到,Lattice 中从起始状态到结束状态的每一条路径都表示一个译文,不同译文的不同部分可以通过Lattice 中的节点得到共享\footnote{本例中的Lattice 也是一个{\small\sffamily\bfseries{混淆网络}}\index{混淆网络}(Confusion Network\index{Confusion Network})。}。理论上,Lattice 可以把指数级数量的词串用线性复杂度的结构表示出来。
%----------------------------------------------------------------------
\begin{figure}[htp]
......@@ -726,9 +727,11 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\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{DBLP:journals/corr/HintonVD15,Munim2019SequencelevelKD,Tang2019DistillingTK}。另外还有一些其他方法不仅在输出上,还在权重矩阵和隐藏的激活层上对“教师模型”知识进行更深入的挖掘\upcite{Jiao2020TinyBERTDB}
\vspace{0.5em}
\item 目前的翻译模型使用交叉熵损失作为优化函数,这在自回归模型上取得了非常优秀的性能。交叉熵是一个严格的损失函数,预测时位置错误的单词都会受到惩罚,即使是编辑距离很小的输出序列。回归模型会避免这种惩罚,因为单词是根据句子前一个词来生成的,而非自回归模型无法获知这个信息。为此,一些研究工作通过改进损失函数来提高非自回归模型的性能。一种做法使用对齐交叉熵函数\upcite{Ghazvininejad2020AlignedCE},其基于标签序列和目标词分布预测序列之间的对齐来计算交叉熵损失,采用动态规划的方法寻找单调对齐使交叉熵损失最小化。也可以使用基于$n$-gram的训练目标\upcite{Shao2020MinimizingTB},希望能最小化模型与参考译文间$n$-gram的差异。该训练目标在$n$-gram的层面上评估预测结果,因此能够建模序列依赖关系。
\item 目前的翻译模型使用交叉熵损失作为优化函数,这在自回归模型上取得了非常优秀的性能。交叉熵是一个严格的损失函数,预测时位置错误的单词都会受到惩罚,即使是编辑距离很小的输出序列。回归模型会避免这种惩罚,因为单词是根据句子前一个词来生成的,而非自回归模型无法获知这个信息。为此,一些研究工作通过改进损失函数来提高非自回归模型的性能。一种做法使用对齐交叉熵函数\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}
......
......@@ -962,7 +962,7 @@ lr &=& d_{model}^{-0.5}\cdot step\_num^{-0.5}
\noindent 其中,$\mathbi{W}$是转换矩阵,$\mathbi{U}$是权重矩阵,$F$代表了特征的数量({\color{red} 特征的数量为啥还要加绝对值});而$\mathbi{E}$是一个特征矩阵,它包含了不同种类特征的数量,$x_{ik}$ 代表了第$i$ 个词在第$k$ 种特征中所表达的值,$\|$操作为拼接操作。公式\eqref{eq:15-52}将从共$F$个特征向量连接成固定大小的向量,作为编码端的输入。这种方法可以很容易地融合如词根、子词、形态、词性以及依存标签等特征。
\parinterval 此外是否有更有效的方法,将句法信息融入到编码器呢?如图\ref{fig:15-22}(a)所示,对于英语句子“I love dogs”,可以得到如图\ref{fig:15-22}(a)所示的句法树。这里,使用$w_i$表示第$i$个单词,如图\ref{fig:15-22}(b)所示。使用$l_j$表示句法解析树中第$j$个语法标签({\color{red}$l$是不是在前面也用到过?而且怎么定义$j$?怎么遍历的树?}),如图\ref{fig:15-22}(c)所示。通过观察句法树的结构可以看出,对一个单词来说,句法树中该单词的父节点({\color{red} 祖先节点及路径?})代表了描述该单词最准确的句法信息。因此可以单词祖先节点及路径信息与原始的词信息构造出新的融合表示${\mathbi{h}'}_i$,并使用这种新的表示计算上下文向量$\mathbi{C}$,即:
\parinterval 另一种方式是将句法信息的表示转化为基于序列的编码,之后与原始的词串融合。这样做的好处在于,并不需要使用基于树结构的编码器,句法信息仍然可以使用基于序列的编码器。而句法信息可以在对句法树的序列化表示中学习得到。如图\ref{fig:15-22}(a) 所示,对于英语句子“I love dogs”,可以得到如图\ref{fig:15-22}(a) 所示的句法树。这里,使用$w_i$ 表示第$i$ 个单词,如图\ref{fig:15-22}(b) 所示。通过对句法树进行遍历,可以得到句法树节点的序列$\{l_1,l_2,...,l_T\}$,其中$T$表示句法树中节点的个数,$l_j$ 表示第$j$ 个节点({\color{red}$l$ 是不是在前面也用到过?而且怎么定义$j$?怎么遍历的树?}),如图\ref{fig:15-22}(c) 所示。通过观察句法树的结构可以看出({\color{red} 怎么看出来的?},对一个单词来说,句法树中该单词的父节点({\color{red} 祖先节点及路径?})代表了描述该单词最准确的句法信息。因此可以单词祖先节点及路径信息与原始的词信息构造出新的融合表示${\mathbi{h}'}_i$,并使用这种新的表示计算上下文向量$\mathbi{C}$,即:
\begin{eqnarray}
\mathbi{C}_j &=& \sum_{i=1}^m \alpha_{i,j} {\mathbi{h}'}_i
......@@ -984,7 +984,7 @@ lr &=& d_{model}^{-0.5}\cdot step\_num^{-0.5}
\vspace{0.5em}
\item 平行结构。利用两个编码端构成平行结构,分别对源语言单词和线性化的句法树进行建模,之后在句法树节点序列中寻找每个单词的父节点(或者祖先),将这个单词和它的父节点的状态相融合,得到新的表示。如图\ref{fig:15-23}(a)所示,图中$\mathbi{h}_{w_i}$为词$w_i$在单词序列中的状态,$\mathbi{h}_{l_j}$为树节点$l_j$在句法表示(序列)中的隐藏状态。如果单词$w_i$是节点$l_j$ 在句法树中的子节点,则将$\mathbi{h}_{w_i}$$\mathbi{h}_{l_j}$向量拼接到一起作为这个词的新表示${\mathbi{h}'}_i$
\vspace{0.5em}
\item 分层结构。将句法表示结果与源语言单词的词嵌入向量进行融合,如图\ref{fig:15-23}(b)所示,其中$\mathbi{e}_{w_i}$为第$i$个词的词嵌入。类似地,如果$w_i$词语是节点$l_j$在句法树中的子节点,则将$\mathbi{e}_{w_i}$$\mathbi{h}_{l_j}$向量拼接到一起作为原始模型的输入,这样${\mathbi{h}'}_i$直接参与注意力计算({\color{red} 这段话看不懂,不是和“平行结构”一样了吗?})。注意,分层结构和平行结构的区别在于,分层结构实际上最终还是使用一个编码器,句法信息只是与词嵌入进行融合,因此最终的结构和原始的模型是一致的;平行结构相当于使用了两个编码器,因此单词和句法信息的融合是在两个编码的输出上进行的;
\item 分层结构。将句法表示结果与源语言单词的词嵌入向量进行融合,如图\ref{fig:15-23}(b)所示,其中$\mathbi{e}_{w_i}$为第$i$个词的词嵌入。类似地,如果$w_i$词语是节点$l_j$在句法树中的子节点,则将$\mathbi{e}_{w_i}$$\mathbi{h}_{l_j}$向量拼接到一起作为原始模型的输入,这样${\mathbi{h}'}_i$直接参与注意力计算({\color{red} 这段话看不懂,不是和“平行结构”一样了吗?})。注意,分层结构和平行结构的区别在于,分层结构最终还是使用了一个编码器,句法信息只是与词嵌入进行融合,因此最终的结构和原始的模型是一致的;平行结构相当于使用了两个编码器,因此单词和句法信息的融合是在两个编码的输出上进行的;
\vspace{0.5em}
\item 混合结构。首先对图\ref{fig:15-22}(a)中句法树进行先序遍历,将句法标记和源语言单词融合到同一个序列中,得到如图\ref{fig:15-23}(c)所示序列。之后使用传统的序列编码器对这个序列进行编码,然后使用序列中源语言单词所对应的状态参与注意力模型的计算。有趣的是,相比于前两种方法,这种方法参数量少而且也十分有效\upcite{DBLP:conf/acl/LiXTZZZ17}
\vspace{0.5em}
......@@ -1001,7 +1001,7 @@ lr &=& d_{model}^{-0.5}\cdot step\_num^{-0.5}
\end{figure}
%-------------------------------------------
\parinterval 总的来说,由于句法信息的生成依赖于句法分析装置,因此句法分析的错误会在很大程度上影响源语言句子的表示结果。如果获得的句法信息不够精确,可能会对翻译系统带来负面的作用。此外,也有研究发现基于词串的神经机器翻译模型本身就能学习到源语言的句法信息\upcite{DBLP:conf/emnlp/ShiPK16},这表明了神经机器翻译模型也有一定的归纳句法的能力。除了循环神经网络结构,也有学者探索如何在Transformer中引入树结构信息。比如,可以在计算编码端自注意力分布的时候,将词与词之间的依存变换成距离表示作为额外的语法信息融入到注意力计算\upcite{DBLP:conf/acl/BugliarelloO20}
\parinterval 需要注意的是,句法分析的错误会在很大程度上影响源语言句子的表示结果。如果获得的句法信息不够准确,可能会对翻译系统带来负面的作用。此外,也有研究发现基于词串的神经机器翻译模型本身就能学习到一些源语言的句法信息\upcite{DBLP:conf/emnlp/ShiPK16},这表明了神经机器翻译模型也有一定的归纳句子结构的能力。除了循环神经网络结构,也有研究人员也探索了如何在Transformer中引入树结构信息。比如,可以在计算自注意力分布的时候,将词与词之间的依存变换成距离表示作为额外的语法信息融入到注意力模型\upcite{DBLP:conf/acl/BugliarelloO20}
%----------------------------------------------------------------------------------------
% NEW SUB-SECTION
......@@ -1009,7 +1009,7 @@ lr &=& d_{model}^{-0.5}\cdot step\_num^{-0.5}
\subsection{解码端使用句法信息}\label{subsec-15.3.2}
\parinterval 也有大量的工作探索如何将句法树加入到解码端中。一种最直接的方式是将目标语言句法树结构进行线性化,这样目标语言句子就变成了一个含有句法信息的序列,神经机器翻译系统不需要进行修改即可完成训练\upcite{Aharoni2017TowardsSN}
\parinterval 不同于在编码器中使用树结构,解码器直接生成树结构是较为复杂的工作。因此,想要在解码器中使用句法信息,一种最直接的方式是将目标语言句法树结构进行线性化,这样目标语言句子就变成了一个含有句法标记和单词的混合序列(见{\chaptereight})。这样,神经机器翻译系统不需要进行修改,直接使用句法树序列化的结果进行训练和推断\upcite{Aharoni2017TowardsSN}。图\ref{fig:15-24}展示了一个目标语言句法树经过线性化后的结果
%----------------------------------------------
\begin{figure}[htp]
......@@ -1020,13 +1020,11 @@ lr &=& d_{model}^{-0.5}\cdot step\_num^{-0.5}
\end{figure}
%-------------------------------------------
\parinterval \ref{fig:15-24}展示了一个目标语言句法树经过线性化后的结果。这种方法的最大优点是简单、易于实现,而且同时适用于在源语言和目标语言引入句法树的情况。不过,这种方法的问题是,推断时预测的目标语言串可能并不对应合理的句法树结构,此时需要额外的模块对结果进行修正或者调整,以得到合理的译文。
\parinterval 不过,直接使用序列化的句法树也会带来新的问题。比如,在推断时,生成的译文序列可能根本不对应合法的句法树。此时,需要额外的模块对结果进行修正或者调整,以得到合理的译文。
\parinterval 另一种方式是直接使用目标语言句法树完成翻译建模。与源语言句法树的建模不同,目标语言句法树的生成伴随着译文的生成,因此无法像源语言端一样将整个句法树一次输入。这样译文生成问题本质上就变成了目标语言树结构的生成,从这个角度说,这个过程与统计机器翻译中串到树的模型是类似的(见{\chaptereight})。树结构的生成有很多种策略,基本的思想均是根据已经生成的局部结构预测新的局部结构,并将这些局部结构拼装成更大的结构,直到得到完整的句法树结构\upcite{DBLP:conf/iclr/Alvarez-MelisJ17}
\parinterval 另一种方法是直接在目标语言端使用句法树进行建模。与源语言句法树的建模不同,目标语言句法树的生成伴随着译文的生成,因此无法像源语言端一样将整个句法树一次输入。这样译文生成问题本质上就变成了目标语言树结构的生成,从这个角度说,这个过程与统计机器翻译中串到树的模型是类似的(见{\chaptereight})。树结构的生成有很多种策略,基本的思想均是根据已经生成的局部结构预测新的局部结构,并将这些局部结构拼装成更大的结构,直到得到完整的句法树结构\upcite{DBLP:conf/iclr/Alvarez-MelisJ17}
\parinterval 实现目标语言句法树生成的一种手段是将形式文法扩展到神经网络模型。这样,我们可以使用形式文法描述句法树的生成过程(见{\chapterthree}),同时利用分布式表示来进行建模和学习。比如,可以使用基于循环神经网络的文法描述方法,把句法分析过程看作是一个循环神经网络的执行过程\upcite{DBLP:conf/naacl/DyerKBS16}。这个过程对应一个移进-规约分析过程\upcite{aho1972theory},因此句法分析实质上就是一个移进-规约动作序列。这样(目标语言)句法树就可以通过基于循环神经网络的移进-规约过程实现。
\parinterval 另一种方式从多任务角度出发,用多个解码端共同完成目标语言句子的生成\upcite{DBLP:journals/corr/LuongLSVK15}。图\ref{fig:15-25}展示了由一个编码器(汉语)和多个解码器组成的序列生成模型。其中不同解码器分别负责不同的任务:第一个用于预测翻译结果,即翻译任务;第二个用于预测句法结构;第三个用于重新生成源语言序列,进行自编码。其设计思想是各个任务之间能够相互辅助,使得编码器的表示能包含更多的信息,进而让多个任务都获得性能提升。这种方法也可以使用多个编码器,其思想是类似的。{\red{图中改成编码器}}
\parinterval 实现目标语言句法树生成的一种手段是将形式文法扩展到神经网络模型。这样,可以使用形式文法描述句法树的生成过程(见{\chapterthree}),同时利用分布式表示来进行建模和学习。比如,可以使用基于循环神经网络的文法描述方法,把句法分析过程看作是一个循环神经网络的执行过程\upcite{DBLP:conf/naacl/DyerKBS16}。此外,也可以从多任务学习出发,用多个解码端共同完成目标语言句子的生成\upcite{DBLP:journals/corr/LuongLSVK15}。图\ref{fig:15-25}展示了由一个编码器(汉语)和多个解码器组成的序列生成模型。其中不同解码器分别负责不同的任务:第一个用于预测翻译结果,即翻译任务;第二个用于预测句法结构;第三个用于重新生成源语言序列,进行自编码。其设计思想是各个任务之间能够相互辅助,使得编码器的表示能包含更多的信息,进而让多个任务都获得性能提升。这种方法也可以使用在多个编码器上,其思想是类似的。{\red{图中改成编码器}}
%----------------------------------------------
\begin{figure}[htp]
......@@ -1037,20 +1035,20 @@ lr &=& d_{model}^{-0.5}\cdot step\_num^{-0.5}
\end{figure}
%-------------------------------------------
\parinterval 针对上述两种在解码端融入句法信息的方法,也有研究者提出过以下问题:紧密的融合词串和句法结构的学习是否优于多任务学习?以及目标语言句法信息的引入是否真的帮助到了机器翻译?\upcite{DBLP:conf/wmt/NadejdeRSDJKB17}。为了回答这个问题,研究者尝试利用{\small\bfnew{CCG}}\index{CCG}(Combinatory Categorial Grammar)\index{Combinatory Categorial Grammar}中的supertags作为句法信息,并比较了直接将CCG标签与句子进行融合(如图\ref{fig:15-24})和将句子与标签分开作为多任务(如图\ref{fig:15-25})两种融合方式进行训练,最后发现第一种方式是更加有效的
\parinterval 针对上述方法,也有以下问题:紧密的融合词串和句法结构的方法是否优于多任务学习的方法?以及,目标语言句法信息的引入是否真的帮助到了机器翻译?\upcite{DBLP:conf/wmt/NadejdeRSDJKB17}。 为了回答这些问题,研究人员尝试利用{\small\bfnew{CCG}}\index{CCG}(Combinatory Categorial Grammar)\index{Combinatory Categorial Grammar}中的supertags 作为句法信息,并发现CCG标签与句子进行融合更加有效
\parinterval 虽然融合树结构和目标语言词串的方法优于基于多任务的方法,但是前者会导致解码端的序列过长,因此会面临难以训练的问题。为了缓解这种现象可以在这两种方法之间设计两个循环神经网络结构,一个生成句子,另一个生成树结构\upcite{DBLP:conf/acl/WuZYLZ17,DBLP:journals/corr/abs-1808-09374}。以生成目标语言依存树为例,生成依存树的循环神经网络仍然是一个移进-规约序列的生成模型。另一个循环神经网络负责预测目标语言词序列,它只有在第一个循环神经网络移进操作的时候才会预测一下词,同时会将当前词状态作为信息送入到第一个循环神经网络中。整个过程如图\ref{fig:15-26}所示,其中$\mathbi{h}_i^\textrm{action}$表示动作RNN的隐藏层状态,$\mathbi{h}_i^\textrm{word}$表示词语RNN的隐藏层状态。动作RNN会结合词语RNN的状态预测出“移位”,“左规约”,“右规约”三种动作,只有当动作RNN预测出“移位”操作时,词语RNN才会预测下一时刻的词语。最后词语RNN预测出结束符号<eos>时,整个过程结束。需要注意的是,这种方法并不依赖循环神经网络结构,也可以将其替换为Transformer等结构来完成序列的生成
\parinterval 虽然,融合树结构和目标语言词串的方法有其优越性,但是这种方法会导致目标语言端的序列过长,导致模型难以训练。为了缓解这个问题,可以使用两个模型(如循环神经网络),一个生成句子,另一个生成树结构\upcite{DBLP:conf/acl/WuZYLZ17,DBLP:journals/corr/abs-1808-09374}。以生成目标语言依存树为例,生成依存树的模型仍然是一个移进-规约序列的生成模型,称为动作模型。另一个模型负责预测目标语言词序列,成为词预测模型。它只有在第一个模型进行进操作的时候才会预测一下词,同时会将当前词的状态作为信息送入到第一个模型中。整个过程如图\ref{fig:15-26}所示,这里使用循环神经网络构建了动作模型和词预测模型。$\mathbi{h}_i^\textrm{action}$ 表示动作模型的隐藏层状态,$\mathbi{h}_i^\textrm{word}$表示词预测模型的隐藏层状态。动作模型会结合词预测模型的状态预测出“移位”,“左规约”,“右规约”三种动作,只有当动作模型预测出“移位”操作时,词预测模型才会预测下一时刻的词语;而动作模型预测“左规约”和“右规约相当于完成了依存关系的预测(依存树见图\ref{fig:15-26}右侧)。最后词预测模型预测出结束符号<eos> 时,整个过程结束
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.5]{./Chapter15/Figures/figure-parallel-RNN-structure.png}
\caption{平行RNN结构}
\caption{平行RNN结构{\color{red} 看前面的文字:一个叫动作模型,一个叫词预测模型。还有右侧图的依存的箭头方向一定再确定一下!}}
\label{fig:15-26}
\end{figure}
%-------------------------------------------
\parinterval 相较于在编码端融入句法信息,在解码端融入句法信息更为困难。由于解码过程存在着前向依赖,因此树结构信息与词语的生成反而是一个相互影响的过程,如果严格按照给定的树结构翻译,即先生成结构再根据结构生成标签,那么一旦结构有误解码结果就会受到影响,而如果用一种不太严格的方式,即将树结构和目标语言一起预测,树结构对译文的预测作用又会减弱。在统计机器翻译中,句法信息究竟应该使用到什么程度已经有一些讨论\upcite{Tong2016Syntactic},而在神经机器翻译中,如何更有效地引入树结构信息以及如何平衡树结构信息与词串的作用还有待进一步确认
\parinterval 相较于在编码端融入句法信息,在解码端融入句法信息更为困难。由于树结构与单词的生成是一个相互影响的过程,如果先生成树结构,再根据树得到译文单词串,那么一旦树结构有误,翻译结果就会有问题。在统计机器翻译中,句法信息究竟应该使用到什么程度已经有一些讨论\upcite{Tong2016Syntactic}。而在神经机器翻译中,如何更有效地引入树结构信息以及如何平衡树结构信息与词串的作用还有待确认。如前文所述,基于词串的神经机器翻译模型已经能够捕捉到一些句法结构信息,虽然有些信息是不容易通过人的先验知识进行解释的。这时,使用人工总结的句法结构来约束或者强化翻译模型,是否可以补充模型无法学到的信息,还是需要进一步研究
%----------------------------------------------------------------------------------------
% NEW SECTION
......@@ -1059,39 +1057,39 @@ lr &=& d_{model}^{-0.5}\cdot step\_num^{-0.5}
\sectionnewpage
\section{基于结构搜索的翻译模型优化}
\parinterval 目前为止,对模型的很多改良都来自于研究人员自身的经验及灵感。从某种意义上说,很多时候,模型结构的优化依赖于研究人员的经验,包括其对任务的理解以及自身的想象力。此外所设计出的模型结构还需要在对应任务上进行实验,优秀的模型往往需要很长时间的探索与验证。因此,人们希望在无需外部干预的情况下,让计算机自动地找到最适用于当前任务的神经网络模型结构,这种方法被称作{\small\bfnew{神经架构搜索}}\index{神经架构搜索}(Neural Architecture Search)\index{Neural Architecture Search},在神经网络模型中有时也被称作{\small\bfnew{神经网络结构搜索}}\index{神经网络结构搜索}{\small\bfnew{网络结构搜索}}\index{网络结构搜索}\upcite{DBLP:conf/iclr/ZophL17,DBLP:conf/cvpr/ZophVSL18,Real2019AgingEF}
%----------------------------------------------------------------------------------------
% NEW SUB-SECTION
%----------------------------------------------------------------------------------------
\subsection{神经网络结构搜索}
\parinterval 目前为止,对模型的很多改良都来自于研究人员自身的经验及灵感。从某种意义上说,很多时候,模型结构的优化依赖于研究人员的经验,包括其对任务的理解以及自身的想象力。此外所设计出的模型结构还需要在对应任务上进行实验,优秀的模型往往需要很长时间的探索与验证。因此,人们希望在无需外部干预的情况下,让计算机自动地找到最适用于当前任务的神经网络模型结构,这种方法被称作{\small\bfnew{神经架构搜索}}\index{神经架构搜索}(Neural Architecture Search)\index{Neural Architecture Search},在神经网络模型中有时也被称作{\small\bfnew{神经网络结构搜索}}\index{神经网络结构搜索}{\small\bfnew{网络结构搜索}}\index{网络结构搜索}\upcite{DBLP:conf/iclr/ZophL17,DBLP:conf/cvpr/ZophVSL18,Real2019AgingEF}
\parinterval 网络结构搜索属于{\small\bfnew{自动机器学习}}\index{自动机器学习}(Automated Machine Learning)\index{Automated Machine Learning}的范畴,其目的是根据对应任务上的数据找到最合适的模型结构。在这个过程中,模型结构就像神经网络中的参数一样被自动地学习出来。以机器翻译任务为例,通过网络结构搜索方法能够以Transformer模型为基础,对神经网络结构进行自动优化,找到更适用于机器翻译任务的模型结构。图\ref{fig:15-27}(a) 展示了人工设计的Transformer编码器的局部结构,图\ref{fig:15-27}(b) 给出对该结构使用进化算法优化后得到的结构图\upcite{DBLP:conf/icml/SoLL19}。可以看到,使用网络结构搜索方法得到的模型中,出现了与人工设计的结构不同的跨层连接,同时还搜索到了全新的多分支网络结构。这种结构也是人工不易设计出来的。
\parinterval 网络结构搜索属于{\small\bfnew{自动机器学习}}\index{自动机器学习}(Automated Machine Learning)\index{Automated Machine Learning}的范畴,其目的是根据对应任务上的数据找到最合适的模型结构。在这个过程中,模型结构就像神经网络中的参数一样被自动地学习出来。以机器翻译任务为例,通过网络结构搜索方法能够以Transformer模型为基础,对神经网络结构进行自动优化,找到更适用于机器翻译任务的模型结构。图\ref{fig:15-27}(a) 展示了人工设计的Transformer编码器的局部结构,图\ref{fig:15-27}(b) 给出对该结构使用进化算法优化后得到的结构\upcite{DBLP:conf/icml/SoLL19}。可以看到,使用网络结构搜索方法得到的模型中,出现了与人工设计的结构不同的跨层连接,同时还搜索到了全新的多分支结构。这种结构也是人工不易设计出来的。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter15/Figures/figure-encoder-structure-of-transformer-model-optimized-by-nas}
\caption{传统Transformer以及通过网络结构搜索方法优化后的Transformer模型编码器结构}
\caption{传统Transformer以及通过网络结构搜索方法优化后的Transformer模型编码器结构{\color{red} 如果图是别的论文的,需要引用!层正则化写全!正则化=层正则化?}}
\label{fig:15-27}
\end{figure}
%-------------------------------------------
\parinterval 那么网络结构搜索究竟是一种什么样的技术呢?实际上,人类一直希望能够自动化、快速地解决自己所遇到的问题。机器学习也是为了达到这个目的所产生的技术。如图\ref{fig:15-28}所示,机器学习方法可以看做是一个黑盒模型,这个模型能够根据人类所提供的输入自动给出所期望的输出,这里的输入和输出既可以是图像信息,也可以是自然语言领域中的文字。在传统机器学习方法中,研究者需要设计大量的特征来描述待解决的问题,即“特征工程”。在深度学习时代,神经网络模型可以完成特征的抽取和学习,但是却需要人工设计神经网络结构,这项工作仍然十分繁重。因此一些科研人员开始思考,能否将设计模型结构的工作也交由机器自动完成?深度学习方法中模型参数能够通过梯度下降等方式进行自动优化,那么模型结构是否可以也看做是一种特殊的参数,使用搜索算法自动找到最适用于当前任务的模型结构?
\parinterval 那么网络结构搜索究竟是一种什么样的技术呢?实际上,人类一直希望能够自动化、快速地解决自己所遇到的问题。机器学习也是为了达到这个目的所产生的技术。如图\ref{fig:15-28}所示,在传统机器学习方法中,研究者需要设计大量的特征来描述待解决的问题,即“特征工程”。在深度学习时代,神经网络模型可以完成特征的抽取和学习,但是却需要人工设计神经网络结构,这项工作仍然十分繁重。因此一些科研人员开始思考,能否将设计模型结构的工作也交由机器自动完成?深度学习方法中模型参数能够通过梯度下降等方式进行自动优化,那么模型结构是否可以也看做是一种特殊的参数,使用搜索算法自动找到最适用于当前任务的模型结构?
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter15/Figures/figure-evolution-and-change-of-ml-methods}
\caption{机器学习方法的演化与变迁}
\caption{机器学习范式对比}
\label{fig:15-28}
\end{figure}
%-------------------------------------------
\parinterval 于是,就诞生了网络结构搜索这个研究方向。早在上世纪八十年代,研究人员就开始使用进化算法对神经网络结构进行设计\upcite{DBLP:conf/icga/MillerTH89},之后也有很多研究人员对基于进化算法的结构搜索进行了探索\upcite{mandischer1993representation,koza1991genetic,DBLP:conf/ijcnn/Dodd90,DBLP:conf/nips/HarpSG89,DBLP:journals/compsys/Kitano90,DBLP:conf/icec/SantosD94}。近些年,随着深度学习技术的发展,神经网络结构搜索这个方向也重新走进更多人的视线中,受到了来自计算机视觉、自然语言处理多个领域的关注与应用。
\parinterval 于是,就诞生了网络结构搜索这个研究方向。早在上世纪八十年代,研究人员就开始使用进化算法对神经网络结构进行设计\upcite{DBLP:conf/icga/MillerTH89},之后也有很多研究人员对基于进化算法的结构搜索进行了探索\upcite{mandischer1993representation,koza1991genetic,DBLP:conf/ijcnn/Dodd90,DBLP:conf/nips/HarpSG89,DBLP:journals/compsys/Kitano90,DBLP:conf/icec/SantosD94}{\color{red} 这个地方可以少放几个参考文献}。近些年,随着深度学习技术的发展,神经网络结构搜索这个方向也重新走进更多人的视线中,受到了来自计算机视觉、自然语言处理多个领域的关注与应用。
\parinterval 目前网络结构搜索技术尚且处于相对初级的阶段,不过在近些年该方向已经在很多任务中受到关注。例如,在WMT19国际机器翻译比赛中,有参赛单位使用了基于梯度的结构搜索方法改进翻译模型\upcite{DBLP:conf/nips/LuoTQCL18}。此外,在语言建模等任务中也大量应用了结构搜索技术,并取得了很好的结果\upcite{DBLP:conf/icml/PhamGZLD18,DBLP:conf/iclr/LiuSY19,DBLP:conf/acl/LiHZXJXZLL20,DBLP:conf/emnlp/JiangHXZZ19}。下面将对结构搜索的基本方法和其在机器翻译中的应用进行介绍。
\parinterval 目前网络结构搜索技术在很多任务中受到关注。例如,在WMT19国际机器翻译比赛中,有参赛单位使用了基于梯度的结构搜索方法改进翻译模型\upcite{DBLP:conf/nips/LuoTQCL18}。此外,在语言建模等任务中也大量应用了结构搜索技术,并取得了很好的结果\upcite{DBLP:conf/icml/PhamGZLD18,DBLP:conf/iclr/LiuSY19,DBLP:conf/acl/LiHZXJXZLL20,DBLP:conf/emnlp/JiangHXZZ19}。下面将对结构搜索的基本方法和其在机器翻译中的应用进行介绍。
%----------------------------------------------------------------------------------------
% NEW SUB-SECTION
......@@ -1099,13 +1097,15 @@ lr &=& d_{model}^{-0.5}\cdot step\_num^{-0.5}
\subsection{结构搜索的基本方法}
\parinterval 对于网络结构搜索而言,其目标在于通过数据驱动的方式自动地找到最合适的模型结构。以机器翻译这类有监督任务为例,对于给定的具有$K$个训练样本的训练集合$\{(\mathbi{x}_{1},\mathbi{y}_{1}),\ldots,(\mathbi{x}_{n},\mathbi{y}_{n})\}$(其中$\mathbi{x}_{i}$表示的是第$i$个样本的输入数据,$\mathbi{y}_{i}$表示该样本的目标标签值),网络结构搜索过程可以被建模为,根据数据找到最佳模型结构$\hat{a}$的过程,如下所示:
\parinterval 对于网络结构搜索而言,其目标在于通过数据驱动的方式自动地找到最合适的模型结构。以有监督学习为例,给定训练集合$\{(\mathbi{x}_{1},\mathbi{y}_{1}),\ldots,(\mathbi{x}_{n},\mathbi{y}_{n})\}$(其中$\mathbi{x}_{i}$表示的是第$i$个样本的输入,$\mathbi{y}_{i}$表示该样本的答案,并假设$\mathbi{x}_{i}$$\mathbi{y}_{i}$均为向量表示),网络结构搜索过程可以被建模为,根据数据找到最佳模型结构$\hat{a}$的过程,如下所示:
\begin{eqnarray}
\hat{a} &=& \arg\max_{a}\sum_{i=1}^{n}{\funp{P}(\mathbi{y}_{i}|\mathbi{x}_{i};a)}
\label{eq:15-54}
\end{eqnarray}
\noindent 公式中$\funp{P}(\mathbi{y}_{i}|\mathbi{x}_{i};a)$为模型$a$观察到数据$\mathbi{x}_{i}$后预测为标签$\mathbi{y}_{i}$的概率,而模型结构$a$本身可以看作是输入$\mathbi{x}$到输出$\mathbi{y}$的映射函数。因此可以简单的把模型$a$看作根据$\mathbi{x}$预测$\mathbi{y}$的一个函数,记为:
\noindent 其中,$\funp{P}(\mathbi{y}_{i}|\mathbi{x}_{i};a)$为模型$a$观察到数据$\mathbi{x}_{i}$后预测$\mathbi{y}_{i}$的概率,而模型结构$a$本身可以看作是输入$\mathbi{x}$到输出$\mathbi{y}$ 的映射函数。因此可以简单第把模型$a$看作根据$\mathbi{x}$预测$\mathbi{y}$的一个函数,记为:
\begin{eqnarray}
a(\mathbi{x}) &=& \funp{P}(\cdot|\mathbi{x})
\label{eq:15-55}
......@@ -1117,7 +1117,7 @@ a(\mathbi{x}) &=& \funp{P}(\cdot|\mathbi{x})
\vspace{0.5em}
\item 设计搜索空间:理论上,网络结构搜索的搜索空间应由所有的潜在模型结构构成(图\ref{fig:15-29})。在这种情况下,如果不对候选模型结构进行限制的话,搜索空间会十分庞大。因此,在实际的结构搜索过程中,往往会针对特定任务设计一个搜索空间,这个搜索空间是全体结构空间的一个子集,之后的搜索过程将在这个子空间中进行。如图\ref{fig:15-29}中的搜索空间所示,该空间由循环神经网络构成,其中候选的模型包括人工设计的LSTM、GRU等模型结构,也包括其他潜在的循环神经网络结构。
\vspace{0.5em}
\item 选择搜索策略:在设计好搜索空间之后,结构搜索的过程将选择一种合适的策略,对搜索空间进行探索。不同于模型参数的学习,模型结构本身不存在直接可计算的关联,所以很难通过传统的最优化算法对其进行学习。因此,搜索策略往往选择采用遗传算法或强化学习等方法,这些方法间接地对模型结构进行设计或优化\upcite{DBLP:conf/icml/SoLL19,DBLP:conf/aaai/RealAHL19,DBLP:conf/icml/RealMSSSTLK17,DBLP:conf/iclr/ElskenMH19,DBLP:conf/iclr/ZophL17,DBLP:conf/cvpr/ZophVSL18,DBLP:conf/icml/PhamGZLD18,DBLP:conf/iclr/BakerGNR17,DBLP:conf/cvpr/TanCPVSHL19,DBLP:conf/iclr/LiuSVFK18}。 不过近些年来也有研究人员开始尝试将模型结构建模为超网络中的参数,这样即可使用基于梯度的方式直接对最优结构进行搜索\upcite{DBLP:conf/nips/LuoTQCL18,DBLP:conf/iclr/LiuSY19,DBLP:conf/iclr/CaiZH19,DBLP:conf/cvpr/LiuCSAHY019,DBLP:conf/cvpr/WuDZWSWTVJK19,DBLP:conf/iclr/XieZLL19,DBLP:conf/uai/LiT19,DBLP:conf/cvpr/DongY19,DBLP:conf/iclr/XuX0CQ0X20,DBLP:conf/iclr/ZelaESMBH20,DBLP:conf/iclr/MeiLLJYYY20}
\item 选择搜索策略:在设计好搜索空间之后,结构搜索的过程将选择一种合适的策略,对搜索空间进行探索。不同于模型参数的学习,模型结构本身不存在直接可计算的关联,所以很难通过传统的最优化算法对其进行学习。因此,搜索策略往往选择采用遗传算法或强化学习等方法,这些方法间接地对模型结构进行设计或优化\upcite{DBLP:conf/icml/SoLL19,DBLP:conf/aaai/RealAHL19,DBLP:conf/icml/RealMSSSTLK17,DBLP:conf/iclr/ElskenMH19,DBLP:conf/iclr/ZophL17,DBLP:conf/cvpr/ZophVSL18,DBLP:conf/icml/PhamGZLD18,DBLP:conf/iclr/BakerGNR17,DBLP:conf/cvpr/TanCPVSHL19,DBLP:conf/iclr/LiuSVFK18}{\color{red} 参考文献太多了!})。 不过近些年来也有研究人员开始尝试将模型结构建模为超网络中的参数,这样即可使用基于梯度的方式直接对最优结构进行搜索\upcite{DBLP:conf/nips/LuoTQCL18,DBLP:conf/iclr/LiuSY19,DBLP:conf/iclr/CaiZH19,DBLP:conf/cvpr/LiuCSAHY019,DBLP:conf/cvpr/WuDZWSWTVJK19,DBLP:conf/iclr/XieZLL19,DBLP:conf/uai/LiT19,DBLP:conf/cvpr/DongY19,DBLP:conf/iclr/XuX0CQ0X20,DBLP:conf/iclr/ZelaESMBH20,DBLP:conf/iclr/MeiLLJYYY20}{\color{red} 参考文献太多了!}
\vspace{0.5em}
\item 进行性能评估:在搜索到模型结构之后需要对其性能进行验证,确定当前时刻模型结构的性能优劣。但是对于结构搜索任务来说,由于搜索过程中会产生大量的中间模型结构,如果直接对所有可能的结构进行评价,其时间代价是难以接受的。因此在结构搜索任务中也有很多研究人员尝试如何快速获取模型性能(绝对性能或相对性能)\upcite{DBLP:conf/nips/LuoTQCL18,DBLP:journals/jmlr/LiJDRT17,DBLP:conf/eccv/LiuZNSHLFYHM18}
\vspace{0.5em}
......@@ -1170,7 +1170,7 @@ a(\mathbi{x}) &=& \funp{P}(\cdot|\mathbi{x})
\label{eq:15-56}
\end{eqnarray}
\parinterval 其中函数$\pi(\cdot)$即为结构表示中的内部结构,而循环单元之间的组织方式(即整体框架)则决定了循环单元的输入信息,也就是上式中的循环单元表示$\hat{\mathbi{h}}_{t-1}$和输入表示$\hat{\mathbi{x}}_{t}$。理论上二者均能获得对应时刻之前所有的表示信息,因此可表示为:
\noindent 其中,函数$\pi(\cdot)$表达的是结构表示中的内部结构。而循环单元之间的组织方式(即整体框架)决定了循环单元的输入信息,也就是上式中的循环单元表示$\hat{\mathbi{h}}_{t-1}$和输入表示$\hat{\mathbi{x}}_{t}$。理论上二者均能获得对应时刻之前所有的表示信息,因此可表示为:
\begin{eqnarray}
\hat{\mathbi{h}}_{t-1} &=& f(\mathbi{h}_{[0,t-1]};\mathbi{x}_{[1,t-1]}) \\
\hat{\mathbi{x}_t} &=& g(\mathbi{x}_{[1,t]};\mathbi{h}_{[0,t-1]})
......@@ -1183,9 +1183,9 @@ a(\mathbi{x}) &=& \funp{P}(\cdot|\mathbi{x})
\begin{itemize}
\vspace{0.5em}
\item 整体框架:如图\ref{fig:15-30}所示,在不同任务下,不同结构往往会有不同的建模能力,类似的结构在结构空间中相对集中。因此在搜索空间的设计中,根据不同的任务特点,整体框架会选择在该任务上已经得到验证的经验性结构,这能够更快速地定位到更有潜力的搜索空间。比如,对于图像任务来说,一般会将卷积神经网络设计为候选搜索空间\upcite{DBLP:conf/iclr/ElskenMH19,DBLP:conf/icml/PhamGZLD18,DBLP:conf/iclr/LiuSY19,DBLP:conf/eccv/LiuZNSHLFYHM18,DBLP:conf/icml/CaiYZHY18},而对于包括机器翻译在内的自然语言处理任务而言,则会更倾向于使用循环神经网络或基于自注意力机制的Transformer模型附近的结构空间作为搜索空间\upcite{DBLP:conf/icml/SoLL19,DBLP:conf/iclr/ZophL17,DBLP:conf/icml/PhamGZLD18,DBLP:conf/iclr/LiuSY19,DBLP:journals/taslp/FanTXQLL20,DBLP:conf/ijcai/ChenLQWLDDHLZ20,DBLP:conf/acl/WangWLCZGH20}。 此外,也可以拓展搜索空间以覆盖更多网络结构\upcite{DBLP:conf/acl/LiHZXJXZLL20}
\item 整体框架:如图\ref{fig:15-30}所示,在不同任务下,不同结构往往会有不同的建模能力,类似的结构在结构空间中相对集中。因此在搜索空间的设计中,根据不同的任务特点,整体框架会选择在该任务上已经得到验证的经验性结构,这能够更快速地定位到更有潜力的搜索空间。比如,对于图像任务来说,一般会将卷积神经网络设计为候选搜索空间\upcite{DBLP:conf/iclr/ElskenMH19,DBLP:conf/icml/PhamGZLD18,DBLP:conf/iclr/LiuSY19,DBLP:conf/eccv/LiuZNSHLFYHM18,DBLP:conf/icml/CaiYZHY18},而对于包括机器翻译在内的自然语言处理任务而言,则会更倾向于使用循环神经网络或基于自注意力机制的Transformer模型附近的结构空间作为搜索空间\upcite{DBLP:conf/icml/SoLL19,DBLP:conf/iclr/ZophL17,DBLP:conf/icml/PhamGZLD18,DBLP:conf/iclr/LiuSY19,DBLP:journals/taslp/FanTXQLL20,DBLP:conf/ijcai/ChenLQWLDDHLZ20,DBLP:conf/acl/WangWLCZGH20}。 此外,也可以拓展搜索空间以覆盖更多结构\upcite{DBLP:conf/acl/LiHZXJXZLL20}
\vspace{0.5em}
\item 内部结构:由于算力限制,网络结构搜索任务通常使用经验性的架构作为模型的整体框架,之后对内部结构堆叠进而得到完整的模型结构。对于内部结构的设计需要考虑到搜索过程中的最小搜索单元,以及搜索单元之间的连接方式。最小搜索单元指的是在结构搜索过程中可被选择的最小独立计算单元(或被称为搜索算子、操作),在不同搜索空间的设计中,最小搜索单元的颗粒度各有不同,较小的搜索粒度主要包括如矩阵乘法、张量缩放等基本数学运算\upcite{DBLP:journals/corr/abs-2003-03384},中等粒度的搜索单元包括常见的激活函数,如ReLU、Tanh等\upcite{DBLP:conf/iclr/LiuSY19,DBLP:conf/acl/LiHZXJXZLL20,Chollet2017XceptionDL},较大颗粒度的搜索单元为局部结构,如注意力机制、层标准化等人工设计的经验性结构\upcite{DBLP:conf/icml/SoLL19,DBLP:conf/nips/LuoTQCL18,DBLP:journals/taslp/FanTXQLL20}。不过,对于搜索颗粒度的问题,目前还缺乏有效的方法针对不同任务进行自动优化。
\item 内部结构:由于算力限制,网络结构搜索任务通常使用经验性的架构作为模型的整体框架,之后对内部结构堆叠进而得到完整的模型结构。对于内部结构的设计需要考虑到搜索过程中的最小搜索单元,以及搜索单元之间的连接方式。最小搜索单元指的是在结构搜索过程中可被选择的最小独立计算单元(或被称为搜索算子),在不同搜索空间的设计中,最小搜索单元的颗粒度各有不同,较小的搜索粒度主要包括如矩阵乘法、张量缩放等基本数学运算\upcite{DBLP:journals/corr/abs-2003-03384},更大粒度的搜索单元包括常见的激活函数,如ReLU、Tanh等\upcite{DBLP:conf/iclr/LiuSY19,DBLP:conf/acl/LiHZXJXZLL20,Chollet2017XceptionDL},甚至搜索单元可以是一些模型的局部结构,如注意力模型、层标准化模型等\upcite{DBLP:conf/icml/SoLL19,DBLP:conf/nips/LuoTQCL18,DBLP:journals/taslp/FanTXQLL20}。不过,对于搜索颗粒度的问题,目前还缺乏有效的方法针对不同任务进行自动优化。
\vspace{0.5em}
\end{itemize}
......@@ -1201,19 +1201,10 @@ a(\mathbi{x}) &=& \funp{P}(\cdot|\mathbi{x})
\begin{itemize}
\vspace{0.5em}
\item 进化算法:进化算法最初被用来对神经网络模型结构以及权重参数进行优化\upcite{DBLP:conf/icga/MillerTH89,DBLP:journals/tnn/AngelineSP94,stanley2002evolving,DBLP:journals/alife/StanleyDG09}。虽然随着最优化算法的发展,近年来,对于网络参数的学习更多地采用梯度下降法的方式,但是进化算法仍被用于对模型结构进行优化\upcite{DBLP:conf/aaai/RealAHL19,DBLP:conf/icml/RealMSSSTLK17,DBLP:conf/iclr/ElskenMH19,DBLP:conf/ijcai/SuganumaSN18,Real2019AgingEF,DBLP:conf/iclr/LiuSVFK18,DBLP:conf/iccv/XieY17}。 从结构优化的角度来说,一般是将模型结构看做遗传算法中种群的个体,使用轮盘赌或锦标赛等抽取方式,对种群中的结构进行取样作为亲本,之后通过亲本模型的突变产生新的模型结构,最终对这些新的模型结构进行适应度评估\ref{subsubsec-15.4.2.3}。根据模型结构在校验集上的性能确定是否将其加入种群,整个过程如图\ref{fig:15-32}所示。进化算法中结构的突变主要指的是对模型中局部结构的改变,如增加跨层连接、替换局部操作等。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter15/Figures/figure-structure-search-based-on-evolutionary-algorithm}
\caption{基于进化算法的结构搜索}
\label{fig:15-32}
\end{figure}
%-------------------------------------------
\item 进化算法:进化算法最初被用来对神经网络模型结构以及权重参数进行优化\upcite{DBLP:conf/icga/MillerTH89,DBLP:journals/tnn/AngelineSP94,stanley2002evolving,DBLP:journals/alife/StanleyDG09}。虽然随着最优化算法的发展,近年来,对于网络参数的学习更多地采用梯度下降法的方式,但是进化算法仍被用于对模型结构进行优化\upcite{DBLP:conf/aaai/RealAHL19,DBLP:conf/icml/RealMSSSTLK17,DBLP:conf/iclr/ElskenMH19,DBLP:conf/ijcai/SuganumaSN18,Real2019AgingEF,DBLP:conf/iclr/LiuSVFK18,DBLP:conf/iccv/XieY17}。 从结构优化的角度来说,一般是将模型结构看做遗传算法中种群的个体,使用轮盘赌或锦标赛等抽取方式,对种群中的结构进行取样作为亲本,之后通过亲本模型的突变产生新的模型结构,最终对这些新的模型结构进行适应度评估。根据模型结构在校验集上的性能确定是否将其加入种群。
\vspace{0.5em}
\item 强化学习:近些年随着强化学习在各领域中的广泛应用,研究人员逐渐将该方法引入到神经网络的结构学习中。例如,将网络结构的设计看做是一种序列生成任务,使用字符序列对网络结构进行表述,通过使用强化学习训练的循环神经网络对该序列(目标任务网络结构)进行预测,从而为目标任务生成高效的网络结构\upcite{DBLP:conf/iclr/ZophL17}。基于强化学习的结构搜索方法过程如图\ref{fig:15-33}所示,其中智能体可以看做是一个用于生成模型结构的生成模型,该模型将产生智能体认为的最适用于当前任务的模型结构,强化学习中的动作在这里指的是由智能体产生一个模型结构,而环境对应着当前任务。当环境获得模型结构后,环境将输出当前任务下该模型的输出以及对输出结果的评价,二者分别对应强化学习中的状态和奖励,接下来这两个信息将反馈给智能体,让结构生成器更好地了解该状态下生成的模型结果,进而对结构生成的模式进行调整,然后生成更优的模型结构。对于基于强化学习的结构搜索策略来说,不同研究工作的差异主要集中在如何表示生成网络这个过程,以及如何对结构生成器进行优化\upcite{DBLP:conf/iclr/ZophL17,DBLP:conf/cvpr/ZophVSL18,DBLP:conf/iclr/BakerGNR17,DBLP:conf/cvpr/ZhongYWSL18}{\red{(下图转录时,主体改成智能体)}}
\item 强化学习:例如,将网络结构的设计看做是一种序列生成任务,使用字符序列对网络结构进行表述,通过使用强化学习训练的循环神经网络对该序列(目标任务网络结构)进行预测,从而为目标任务生成高效的网络结构\upcite{DBLP:conf/iclr/ZophL17}。基于强化学习的结构搜索方法过程如图\ref{fig:15-33}所示,其中智能体可以看做是一个用于生成模型结构的生成模型,该模型将产生智能体认为的最适用于当前任务的模型结构,强化学习中的动作在这里指的是由智能体产生一个模型结构,而环境对应着当前任务。当环境获得模型结构后,环境将输出当前任务下该模型的输出以及对输出结果的评价,二者分别对应强化学习中的状态和奖励,接下来这两个信息将反馈给智能体,让结构生成器更好地了解该状态下生成的模型结果,进而对结构生成的模式进行调整,然后生成更优的模型结构。对于基于强化学习的结构搜索策略来说,不同研究工作的差异主要集中在如何表示生成网络这个过程,以及如何对结构生成器进行优化\upcite{DBLP:conf/iclr/ZophL17,DBLP:conf/cvpr/ZophVSL18,DBLP:conf/iclr/BakerGNR17,DBLP:conf/cvpr/ZhongYWSL18}{\red{(下图转录时,主体改成智能体)}}
%----------------------------------------------
\begin{figure}[htp]
......@@ -1255,7 +1246,7 @@ a(\mathbi{x}) &=& \funp{P}(\cdot|\mathbi{x})
\vspace{0.5em}
\item 现有参数的继承及复用:另一类方法希望从训练过程的角度出发,在现有的模型参数基础上,继续优化中间过程产生的模型结构,快速达到收敛状态后进行性能评估\upcite{DBLP:conf/icml/RealMSSSTLK17,DBLP:conf/iclr/ElskenMH19,DBLP:conf/icml/CaiYZHY18,DBLP:conf/aaai/CaiCZYW18,DBLP:conf/iclr/ElskenMH18}。这种方式无需从头训练中间结构,通过“热启动”的方式对模型参数进行优化,大幅减少性能评估过程的时间消耗。此外对于前文提到的基于梯度的结构搜索方法,由于将众多候选模型结构建模在同一个超网络中,因此在完成超网络的参数优化时,其子模型的模型参数也得到了优化,通过这种共享参数的方式也能够快速对网络结构的性能进行评估\upcite{DBLP:conf/icml/PhamGZLD18,DBLP:conf/iclr/XieZLL19,DBLP:conf/iclr/LiuSY19,DBLP:conf/iclr/CaiZH19,DBLP:conf/nips/SaxenaV16,DBLP:conf/icml/BenderKZVL18}
\vspace{0.5em}
\item 模型性能的预测:从加速性能评估过程的角度来看,模型性能预测也是一个具有潜力的方法。这种方式使用少量训练过程中的性能变化曲线来预估模型是否具有潜力,从而快速终止低性能模型的训练过程,节约更多训练时间\upcite{DBLP:conf/ijcai/DomhanSH15,DBLP:conf/iclr/KleinFSH17,DBLP:conf/iclr/BakerGRN18}。除了根据性能变化曲线预测模型性能之外,也有研究人员根据局部结构的性能预测整体结构性能,这种方式也能更快速地了解结构搜索过程中中间结构的表示能力\upcite{DBLP:conf/eccv/LiuZNSHLFYHM18}
\item 模型性能的预测:从加速性能评估过程的角度来看,模型性能预测也是一个具有潜力的方法。这种方式使用训练过程中的性能变化曲线来预估模型是否具有潜力,从而快速终止低性能模型的训练过程,节约更多训练时间\upcite{DBLP:conf/ijcai/DomhanSH15,DBLP:conf/iclr/KleinFSH17,DBLP:conf/iclr/BakerGRN18}。除了根据性能变化曲线预测模型性能之外,也有研究人员根据局部结构的性能预测整体结构性能,这种方式也能更快速地了解结构搜索过程中中间结构的表示能力\upcite{DBLP:conf/eccv/LiuZNSHLFYHM18}
\vspace{0.5em}
\end{itemize}
......@@ -1265,7 +1256,7 @@ a(\mathbi{x}) &=& \funp{P}(\cdot|\mathbi{x})
\subsection{机器翻译任务下的结构搜索}
\parinterval 目前来说,网络结构搜索方法在包括图像、自然语言处理等领域中方兴未艾。对于自然语言处理的任务来说,网络结构搜索方法更多是在语言建模、命名实体识别等简单任务上进行的尝试\upcite{DBLP:conf/acl/LiHZXJXZLL20,DBLP:conf/emnlp/JiangHXZZ19}。其中,大多数工作是在基于循环神经网络的模型结构上进行探索,相较目前在机器翻译领域中广泛使用的Transformer模型结构来说,它们在性能上并没有体现出绝对优势。此外,由于机器翻译任务的复杂性,针对基于Transformer的机器翻译模型的结构搜索方法会更少一些。不过仍有部分工作在机器翻译任务上取得了很好的表现。例如,在WMT19机器翻译比赛中,神经网络结构优化方法在多个任务上取得了很好的成绩\upcite{DBLP:conf/nips/LuoTQCL18,DBLP:conf/wmt/XiaTTGHCFGLLWWZ19}。对于结构搜索在机器翻译领域的应用目前主要包括两个方面,分别是对模型性能的改进以及模型效率的优化:
\parinterval 对于自然语言处理的任务来说,网络结构搜索方法更多是在语言建模、命名实体识别等简单任务上进行的尝试\upcite{DBLP:conf/acl/LiHZXJXZLL20,DBLP:conf/emnlp/JiangHXZZ19}。其中,大多数工作是在基于循环神经网络的模型结构上进行探索,相较目前在机器翻译领域中广泛使用的Transformer模型结构来说,它们在性能上并没有体现出绝对优势。此外,由于机器翻译任务的复杂性,针对基于Transformer的机器翻译模型的结构搜索方法会更少一些。不过仍有部分工作在机器翻译任务上取得了很好的表现。例如,在WMT19机器翻译比赛中,神经网络结构优化方法在多个任务上取得了很好的成绩\upcite{DBLP:conf/nips/LuoTQCL18,DBLP:conf/wmt/XiaTTGHCFGLLWWZ19}。对于结构搜索在机器翻译领域的应用目前主要包括两个方面,分别是对模型性能的改进以及模型效率的优化:
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
......@@ -1288,21 +1279,13 @@ a(\mathbi{x}) &=& \funp{P}(\cdot|\mathbi{x})
\end{figure}
%-------------------------------------------
\noindent 此外,还有方法将为深层神经网络找到更合适的激活函数作为搜索的目标\upcite{DBLP:conf/iclr/RamachandranZL18},通过基于强化学习的搜索策略对激活函数空间进行探索,找到了若干新的激活函数,之后通过对这些激活函数在包括图像分类、机器翻译等任务上进行实验,确定了Swish激活函数在深层神经网络上的有效性,函数公式如下式所示,函数曲线如图\ref{fig:15-36}所示。
\noindent 此外,还有方法将为深层神经网络找到更合适的激活函数作为搜索的目标\upcite{DBLP:conf/iclr/RamachandranZL18},通过基于强化学习的搜索策略对激活函数空间进行探索,找到了若干新的激活函数,之后通过对这些激活函数在包括图像分类、机器翻译等任务上进行实验。例如,Swish激活函数就是一种被找到的新的激活函数,如下:
\begin{eqnarray}
f(x) &=& x \cdot \delta(\beta x) \\
\delta(z) &=& {(1 + \exp{(-z)})}^{-1}
\label{eq:15-60}
\end{eqnarray}
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter15/Figures/figure-swish-function-image}
\caption{Swish函数图像}
\label{fig:15-36}
\end{figure}
%-------------------------------------------
\noindent 相比传统人工设计的激活函数ReLU而言,Swish函数在多个机器翻译的测试集上具有更优的性能表现,同时使用该函数不要求对原本的模型结构进行更多修改,非常容易实现。
......@@ -1333,23 +1316,14 @@ f(x) &=& x \cdot \delta(\beta x) \\
\begin{itemize}
\vspace{0.5em}
\item 面向特定设备的模型结构优化:随着终端设备算力日益增强,在小设备上直接进行机器翻译的需求也日益增大。虽然简单地削减Transformer模型的超参数能够让翻译模型在低算力设备上运行,不过研究人员仍希望得到更适用于当前设备的翻译模型。因此一些研究人员开始尝试使用结构搜索方法改良Transformer模型,一些研究人员尝试在结构优化的过程中将设备的算力作为一个约束,为不同硬件设备(如CPU、GPU等设备)发现更加有效的结构\upcite{DBLP:conf/acl/WangWLCZGH20}。例如可以将搜索空间中各种基于Transformer结构的变体建模在同一个超网络中,通过权重共享的方式进行训练。使用设备算力约束子模型,并通过进化算法对子模型进行搜索,搜索到适用于目标设备的模型结构,整个过程如图\ref{fig:15-38}所示。该方法搜索到的模型能够在保证模型性能不变前提下获得较大的效率提升。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter15/Figures/figure-model-structure-optimization-framework-for-specific-equipment}
\caption{面向特定设备的模型结构优化框架}
\label{fig:15-38}
\end{figure}
%-------------------------------------------
\item 面向特定设备的模型结构优化:随着终端设备算力日益增强,在小设备上直接进行机器翻译的需求也日益增大。虽然简单地削减Transformer模型的超参数能够让翻译模型在低算力设备上运行,不过研究人员仍希望得到更适用于当前设备的翻译模型。因此一些研究人员开始尝试使用结构搜索方法改良Transformer模型,例如,可以在结构优化的过程中将设备的算力作为一个约束,为不同硬件设备(如CPU、GPU 等设备)发现更加有效的结构\upcite{DBLP:conf/acl/WangWLCZGH20}。具体来说,可以将搜索空间中各种基于Transformer结构的变体建模在同一个超网络中,通过权重共享的方式进行训练。使用设备算力约束子模型,并通过进化算法对子模型进行搜索,搜索到适用于目标设备的模型结构。该方法搜索到的模型能够在保证模型性能不变前提下获得较大的效率提升。
\vspace{0.5em}
\item 模型压缩:此外,在不考虑设备算力的情况下,也有一些研究人员通过结构搜索方法对基于Transformer的预训练模型进行压缩。例如,将Transformer模型拆分为若干小组件,然后通过基于采样的结构搜索方法对压缩后的模型结构进行搜索,尝试找到最优且高效的推断模型\upcite{DBLP:journals/corr/abs-2008-06808}。类似的,也有研究者在基于BERT的预训练模型上通过结构搜索方法进行模型压缩,通过基于梯度的结构搜索方法,针对不同的下游任务将BERT模型压缩为小模型\upcite{DBLP:conf/ijcai/ChenLQWLDDHLZ20}
\item 模型压缩:此外,在不考虑设备算力的情况下,也可以通过结构搜索方法对基于Transformer的预训练模型进行压缩。例如,将Transformer模型拆分为若干小组件,然后通过基于采样的结构搜索方法对压缩后的模型结构进行搜索,尝试找到最优且高效的推断模型\upcite{DBLP:journals/corr/abs-2008-06808}。类似的,也可以在基于BERT的预训练模型上通过结构搜索方法进行模型压缩,通过基于梯度的结构搜索方法,针对不同的下游任务将BERT模型压缩为小模型\upcite{DBLP:conf/ijcai/ChenLQWLDDHLZ20}
\vspace{0.5em}
\end{itemize}
\parinterval 虽然由于算力等条件的限制,导致目前很多网络结构搜索方法并没有直接在机器翻译任务中进行实验,但是这些方法并没有被限制在特定任务上。例如,可微分结构搜索方法被成功的用于学习更好的循环单元结构,这类方法完全可以应用在机器翻译任务上,不过大部分工作并没有在这个任务上进行尝试。此外,受到自然语言处理领域预训练模型的启发,一些研究人员也表示网络结构预搜索可能是一个极具潜力的方向,也有研究人员尝试在大规模语言模型上进行结构搜索\upcite{DBLP:conf/acl/LiHZXJXZLL20},然后将搜索到的模型结构应用于更多的自然语言处理任务中,这种方式有效提升了模型结构的可复用性。同时,相较于在特定任务下受限的数据集合中所得到的信息,从大规模单语数据中能获取到更加充分的信息,因此能够更好地指导模型结构的设计。此外,对于机器翻译任务而言,结构的预搜索同样是一个值得关注的研究方向。
\parinterval 虽然由于算力等条件的限制,导致目前很多网络结构搜索方法并没有直接在机器翻译任务中进行实验,但是这些方法并没有被限制在特定任务上。例如,可微分结构搜索方法被成功的用于学习更好的循环单元结构,这类方法完全可以应用在机器翻译任务上,不过大部分工作并没有在这个任务上进行尝试。此外,受到自然语言处理领域预训练模型的启发,一些研究人员也表示网络结构预搜索可能是一个极具潜力的方向,尝试在大规模语言模型上进行结构搜索\upcite{DBLP:conf/acl/LiHZXJXZLL20},然后将搜索到的模型结构应用于更多的自然语言处理任务中,这种方式有效提升了模型结构的可复用性。同时,相较于在特定任务下受限的数据集合中所得到的信息,从大规模单语数据中能获取到更加充分的信息,因此能够更好地指导模型结构的设计。此外,对于机器翻译任务而言,结构的预搜索同样是一个值得关注的研究方向。
%----------------------------------------------------------------------------------------
% NEW SECTION
......@@ -1358,10 +1332,12 @@ f(x) &=& x \cdot \delta(\beta x) \\
\sectionnewpage
\section{小结及深入阅读}
\parinterval 除了上述介绍的多分支网络,还可以通过多尺度的思想来对输入的特征表示进行分级表示,引入短语的信息\upcite{DBLP:conf/emnlp/HaoWSZT19}。此外,在对自注意力网络中的注意力权重分布进行修改时,同样可以根据不同的缩放比例对序列中的实词与虚词进行区分\upcite{DBLP:conf/emnlp/Lin0RLS18}
\parinterval 神经网络结构的设计一直是研究热点。本章节介绍了基于Transformer模型的结构优化工作,其中涉及了基于注意力机制的改进,网络连接优化,基于树结构的模型,以及神经网络结构的自动搜索。依靠自注意力机制的高并行化的计算特性,以及其全局建模能力,Transformer模型在各项自然语言处理任务中取得了优异的成绩。因此,该模型常被用来当作各项任务的基线模型。Transformer模型能够取得如此傲人的成绩,一定程度上受益于多头自注意力机制。多头机制可以让模型从更多维度的空间中提取相应的特征,与多分支思想有异曲同工之妙。研究人员针对编码端的多头进行分析,发现部分头在神经网络的学习过程中扮演至关重要的角色,并且蕴含语言学解释\upcite{DBLP:journals/corr/abs-1905-09418}。而另一部分头本身则不具备实质性的解释,可以通过剪枝的方式去除神经网络的冗余。然而在Transformer模型中,并不是头数越多,模型的性能就越强。{\red 一个有趣的发现是,在训练过程中利用多头,在推断过程中可以去除大部分头,性能没有明显变化,但却能够提高在CPU等串行计算单元的计算效率}\upcite{Michel2019AreSH}
\parinterval 为了进一步提高Transformer的性能,可以利用正则化训练手段,在训练过程中增大不同头之间的差异\upcite{DBLP:conf/emnlp/LiTYLZ18}。也可以通过多尺度的思想,对输入的特征进行分级表示,并引入短语的信息\upcite{DBLP:conf/emnlp/HaoWSZT19}。此外,在对自注意力网络中的注意力权重分布进行修改时,同样可以根据不同的缩放比例对序列中的实词与虚词进行区分\upcite{DBLP:conf/emnlp/Lin0RLS18}。除了上述基于编码端-解码端的建模范式,还可以定义隐变量模型来捕获句子中潜在的语义信息\upcite{Su2018VariationalRN,DBLP:conf/acl/SetiawanSNP20},或直接对源语言和目标语言进行联合的抽象表示\upcite{Li2020NeuralMT}
\parinterval 高效地Transformer:针对处理长文本数据时面临庞大的时间复杂度问题,除了上述章节介绍的方法,研究人员通过简化网络的结构来构建更高效地Transformer结构\upcite{DBLP:journals/corr/abs-2004-05150,DBLP:journals/corr/abs-2006-04768,DBLP:journals/corr/abs-2009-14794}
\parinterval Transformer的优越性能得益于自注意力机制与前馈神经网络的子层设计,同时残差连接{\red (引用)}与层正则化{\red (引用)}的引入让网络的训练变得更加稳定。此外,Transformer在训练过程中使用多种dropout来缓解过拟合问题\upcite{JMLR:v15:srivastava14a},同时在计算交叉熵损失时,也可以使用标签平滑(Label Smoothing)来提高模型的泛化能力\upcite{Szegedy_2016_CVPR}。有研究人员综合了上述的技术并提出了RNMT模型\upcite{Chen2018TheBO},即利用循环神经网络作为编码器和解码器,搭配上残差连接、层正则化、多头自注意力以及标签平滑等机制,构建了一个新模型。该模型能够取得与Transformer相媲美的性能,这也侧面反映了Transformer模型恰似一件艺术品,各个组件共同作用,缺一不可
\parinterval ODE工作(图像)
\parinterval 针对处理长文本数据时面临的复杂度较高的问题,一种比较直接的方式是优化自注意力机制,将复杂度减少到O(N),其中N代表输入序列的长度。例如采用基于滑动窗口的局部注意力的Longformer模型\upcite{DBLP:journals/corr/abs-2004-05150},基于正向的正价随机特征的Performer\upcite{DBLP:journals/corr/abs-2006-04768},应用低秩分解重新设计注意力计算的Linformer\upcite{DBLP:journals/corr/abs-2009-14794},应用星型拓扑排序的Star-Transformer模型(Star-Transformer)。
\parinterval 结构搜索技术是模型结构优化的一种方法,在近些年愈加得到广泛的关注。其中搜索策略作为衔接搜索空间和评价方法的关键步骤,在整个结构搜索方法中扮演着非常重要的角色,不同类型的搜索策略也决定了搜索过程能够在怎样的搜索空间中进行、性能评估如何帮助完成搜索等。除前文详细介绍的基于进化算法、强化学习以及梯度的方法外,基于贝叶斯优化以及随机搜索的方式同样能够有效对搜索空间进行探索。贝叶斯优化的方式已经在超参数优化领域中取得一定成绩,而对于结构搜索任务来说,也有相关研究人员尝试使用基于树的模型来对模型结构以及超参数进行协同优化\upcite{DBLP:conf/nips/BergstraBBK11,DBLP:conf/lion/HutterHL11,DBLP:conf/icml/BergstraYC13,DBLP:conf/ijcai/DomhanSH15,DBLP:conf/icml/MendozaKFSH16,DBLP:journals/corr/abs-1807-06906}。随机搜索的方法在很多工作中被作为基线,这种方式在搜索空间中随机对搜索单元进行选择及操作,最终通过组合或进化等方式找到适用于于当前任务的模型结构\upcite{li2020automated,DBLP:conf/cvpr/BenderLCCCKL20,DBLP:conf/uai/LiT19}。对于结构搜索任务来说如何提升目前搜索策略的稳定性\upcite{DBLP:conf/iccv/ChenXW019,DBLP:conf/icml/ChenH20,DBLP:conf/iclr/XuX0CQ0X20},如何在更大的搜索空间\upcite{DBLP:conf/iclr/XieZLL19,DBLP:conf/acl/LiHZXJXZLL20,DBLP:conf/iclr/CaiZH19}、更多的任务中进行搜索\upcite{DBLP:conf/emnlp/JiangHXZZ19,DBLP:conf/icml/SoLL19}等问题成为结构搜索方法中亟待解决的重要问题。
\parinterval 结构搜索技术是模型结构优化的一种方法,在近些年得到了愈加广泛的关注。其中搜索策略是衔接搜索空间和评价方法的关键步骤,在整个结构搜索方法中扮演着非常重要的角色,不同类型的搜索策略也决定了搜索过程能够在怎样的搜索空间中进行,以及性能评估如何帮助完成搜索等。除前文详细介绍的基于进化算法、强化学习以及基于梯度的方法外,基于贝叶斯优化以及随机搜索的方式同样能够有效地对搜索空间进行探索。贝叶斯优化的方式已经在超参数优化领域中取得一定成绩,而对于结构搜索任务来说,也有相关研究人员尝试使用基于树的模型来对模型结构以及超参数进行协同优化\upcite{DBLP:conf/nips/BergstraBBK11,DBLP:conf/lion/HutterHL11,DBLP:conf/icml/BergstraYC13,DBLP:conf/ijcai/DomhanSH15,DBLP:conf/icml/MendozaKFSH16,DBLP:journals/corr/abs-1807-06906}。随机搜索的方法在很多工作中被作为基线,这种方式在搜索空间中随机对搜索单元进行选择及操作,最终通过组合或进化等方式找到适用于当前任务的模型结构\upcite{li2020automated,DBLP:conf/cvpr/BenderLCCCKL20,DBLP:conf/uai/LiT19}。对于结构搜索任务来说如何提升目前搜索策略的稳定性\upcite{DBLP:conf/iccv/ChenXW019,DBLP:conf/icml/ChenH20,DBLP:conf/iclr/XuX0CQ0X20},如何在更大的搜索空间\upcite{DBLP:conf/iclr/XieZLL19,DBLP:conf/acl/LiHZXJXZLL20,DBLP:conf/iclr/CaiZH19}、如何在更多的任务中进行搜索\upcite{DBLP:conf/emnlp/JiangHXZZ19,DBLP:conf/icml/SoLL19}等等,已经成为结构搜索方法中亟待解决的重要问题。
......@@ -31,7 +31,7 @@
\draw [->,thick](node2-3.east)--(node2-6.west)node[pos=0.5,above,font=\scriptsize]{重排序};
\draw [->,thick](node2-6.north)--(node2-7.south);
\node [anchor=east] (node1) at ([xshift=-2.0em]node1-1.west) {\small{$x,y$:双语数据}};
\node [anchor=north](pos1) at ([yshift=0em]node1-4.south) {\small{(a)单任务学习}};
\node [anchor=west](pos2) at ([xshift=10.0em]pos1.east) {\small{(b)多任务学习}};
......
......@@ -34,7 +34,7 @@
\node [anchor=south,inner sep=2pt,minimum height=1.5em,minimum width=3.0em] (a20) at (a21.north) {\small{$P$}};
\node [anchor=south,inner sep=2pt] (a30) at (a41.north) {\scriptsize{丢弃的结果}};
\node [anchor=south,inner sep=2pt] (a30-2) at (a30.north) {\scriptsize{部分词随机}};
\node [anchor=north,inner sep=2pt] (pos1) at ([xshift=0.5em,yshift=-0.5em]a25.south) {\scriptsize{(a)部分词随机丢弃的加噪方法}};
\node [anchor=north,inner sep=2pt] (pos1) at ([xshift=0.5em,yshift=-0.5em]a25.south) {\small{(a)部分词随机丢弃的加噪方法}};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%mask
\node [anchor=west,inner sep=2pt,fill=blue!20,minimum height=1.5em,minimum width=3.0em] (b11) at ([xshift=2.0em]a41.east) {};
\node [anchor=north,inner sep=2pt,fill=blue!20,minimum height=1.5em,minimum width=3.0em] (b12) at ([yshift=-0.2em]b11.south) {};
......@@ -72,7 +72,7 @@
\node [anchor=south,inner sep=2pt,minimum height=1.5em,minimum width=3.0em] (b20) at (b21.north) {\small{$P$}};
\node [anchor=south,inner sep=2pt] (b30) at (b41.north) {\scriptsize{屏蔽的结果}};
\node [anchor=south,inner sep=2pt] (b30-2) at (b30.north) {\scriptsize{部分词随机}};
\node [anchor=north,inner sep=2pt] (pos2) at ([xshift=0.5em,yshift=-0.5em]b25.south) {\scriptsize{(b)部分词随机屏蔽的加噪方法}};
\node [anchor=north,inner sep=2pt] (pos2) at ([xshift=0.5em,yshift=-0.5em]b25.south) {\small{(b)部分词随机屏蔽的加噪方法}};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%打乱源语句子
\node [anchor=north,inner sep=2pt,fill=yellow!20,minimum height=1.5em,minimum width=3.0em] (c11) at ([yshift=-4.5em]a15.south) {};
\node [anchor=north,inner sep=2pt,fill=yellow!20,minimum height=1.5em,minimum width=3.0em] (c12) at ([yshift=-0.2em]c11.south) {};
......@@ -145,7 +145,7 @@
\node [anchor=south,inner sep=2pt] (c80) at (c81.north) {\scriptsize{后的结果}};
\node [anchor=south,inner sep=2pt] (c80-2) at (c80.north) {\scriptsize{打乱顺序}};
\node [anchor=north,inner sep=2pt] (pos3) at ([xshift=2.4em,yshift=-0.5em]c55.south) {\scriptsize{(c)轻微打乱单词顺序的加噪方法}};
\node [anchor=north,inner sep=2pt] (pos3) at ([xshift=2.4em,yshift=-0.5em]c55.south) {\small{(c)轻微打乱单词顺序的加噪方法}};
\end{tikzpicture}
......@@ -17,7 +17,7 @@
\node[anchor=north,circle,fill=red!20,minimum width=6.8em](node2) at ([xshift=-6.0em,yshift=-2.0em]remark1.south) {源语言句子$\seq{x}$};
\node[anchor=north,circle,fill=red!20,minimum width=6.8em](node2-2) at ([yshift=-0.2em]node2.south) {新生成句子$\seq{x'}$};
\draw [->,thick]([yshift=0.2em]node2.north).. controls (-1.93,-1.5) and (-2.0,-0.2)..([xshift=-0.2em]remark1.west);
\node[anchor=north,circle,fill=red!20](node3) at ([xshift=6.5em,yshift=-2.0em]remark1.south) {目标语言句子$\seq{x}$};
\node[anchor=north,circle,fill=red!20](node3) at ([xshift=6.5em,yshift=-2.0em]remark1.south) {目标语言句子$\seq{y}$};
\draw [->,thick]([xshift=0.2em]remark1.east).. controls (2.9,-0.25) and (2.9,-0.7) ..([yshift=0.2em]node3.north);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
\begin{tikzpicture}
\tikzstyle{layer}=[draw,rounded corners=2pt,font=\scriptsize,align=center,minimum width=5em]
\tikzstyle{word}=[font=\scriptsize]
\node[layer,fill=red!20] (en_sa) at (0,0){Multi-Head \\ Attention};
\node[layer,anchor=south,fill=green!20] (en_ffn) at ([yshift=1.4em]en_sa.north){Feed Forward \\ Network};
\node[draw,circle,inner sep=0pt, minimum size=1em,anchor=north] (en_add) at ([yshift=-1.4em]en_sa.south){};
\draw[] (en_add.90) -- (en_add.-90);
\draw[] (en_add.0) -- (en_add.180);
\node[layer,anchor=north,fill=yellow!20] (en_cnn) at ([yshift=-1.4em]en_add.south){CNN};
\node[draw,circle,inner sep=0pt, minimum size=1em,anchor=west] (de_add) at ([xshift=7em]en_add.east){};
\draw[] (de_add.90) -- (de_add.-90);
\draw[] (de_add.0) -- (de_add.180);
\node[layer,anchor=south,fill=red!20] (de_sa) at ([yshift=1.4em]de_add.north){Masked \\Multi-Head\\Attention};
\node[layer,anchor=south,fill=red!20] (de_ca) at ([yshift=1.4em]de_sa.north){Multi-Head \\ Attention};
\node[layer,anchor=south,fill=green!20] (de_ffn) at ([yshift=1.4em]de_ca.north){Feed Forward \\ Network};
\node[layer,anchor=south,fill=blue!20] (sf) at ([yshift=1.6em]de_ffn.north){Softmax};
\node[layer,anchor=south,fill=orange!20] (output) at ([yshift=1.4em]sf.north){STLoss};
\node[anchor=north,font=\scriptsize,align=center] (en_input) at ([yshift=-1em]en_cnn.south){Speech Feature\\(FilterBank/MFCC)};
\node[anchor=north,font=\scriptsize,align=center] (de_input) at ([yshift=-1.1em]de_add.south){Target Text\\(Embedding)};
\node[anchor=east,font=\scriptsize,align=center] (en_pos) at ([xshift=-2em]en_add.west){Position\\(Embedding)};
\node[anchor=west,font=\scriptsize,align=center] (de_pos) at ([xshift=2em]de_add.east){Position\\(Embedding)};
\draw[->] (en_input.90) -- ([yshift=-0.1em]en_cnn.-90);
\draw[->] ([yshift=0.1em]en_cnn.90) -- ([yshift=-0.1em]en_add.-90);
\draw[->] ([yshift=0.1em]en_add.90) -- ([yshift=-0.1em]en_sa.-90);
\draw[->] ([yshift=0.1em]en_sa.90) -- ([yshift=-0.1em]en_ffn.-90);
\draw[->] (de_input.90) -- ([yshift=-0.1em]de_add.-90);
\draw[->] ([yshift=0.1em]de_add.90) -- ([yshift=-0.1em]de_sa.-90);
\draw[->] ([yshift=0.1em]de_sa.90) -- ([yshift=-0.1em]de_ca.-90);
\draw[->] ([yshift=0.1em]de_ca.90) -- ([yshift=-0.1em]de_ffn.-90);
\draw[->] ([yshift=0.1em]de_ffn.90) -- ([yshift=-0.1em]sf.-90);
\draw[->] ([yshift=0.1em]sf.90) -- ([yshift=-0.1em]output.-90);
\draw[->] ([xshift=0.1em]en_pos.0) -- ([xshift=-0.1em]en_add.180);
\draw[->] ([xshift=-0.1em]de_pos.180) -- ([xshift=0.1em]de_add.0);
\draw[->,rounded corners=2pt] ([yshift=0.1em]en_ffn.90) -- ([yshift=2em]en_ffn.90) -- ([xshift=4em,yshift=2em]en_ffn.90) -- ([xshift=-1.5em]de_ca.west) -- ([xshift=-0.1em]de_ca.west);
\begin{pgfonlayer}{background}
\node[draw=ugreen,rounded corners=2pt,inner xsep=6pt,inner ysep=8pt,dashed,thick][fit=(en_sa)(en_ffn)]{};
\node[draw=red,rounded corners=2pt,inner xsep=6pt,inner ysep=8pt,dashed,thick][fit=(de_sa)(de_ca)(de_ffn)]{};
\end{pgfonlayer}
\node[anchor=east,font=\scriptsize,text=ugreen] at ([xshift=-0.1em]box1.west){$N \times$};
\node[anchor=west,font=\scriptsize,text=red] at ([xshift=0.1em]box2.east){$\times N$};
\node[anchor=east,font=\scriptsize] at ([xshift=-0.1em]en_cnn.west){$2 \times$};
\end{tikzpicture}
\ No newline at end of file
\tikzstyle{coder} = [rectangle,rounded corners,minimum height=2.2em,minimum width=4.3em,text centered,draw=black,fill=red!25]
\begin{tikzpicture}[node distance = 0,scale = 1]
\tikzstyle{every node}=[scale=1]
\node(x)[]{x};
\node(encoder)[coder, above of = x,yshift=4em]{{编码器}};
\node(decoder_left)[coder, above of = encoder, yshift=6em,fill=blue!25]{{解码器}};
\node(y_hat)[above of = decoder_left, yshift=4em]{{$\rm y'$}};
\node(y)[above of = decoder_left, xshift=-6em]{{$\rm y$}};
\node(decoder_right)[coder, above of = encoder, xshift=11em,fill=yellow!25]{{解码器}};
\node(figure)[draw=white,above of = decoder_right,yshift=6.5em,scale=0.25] {\includegraphics[width=0.62\textwidth]{./Chapter17/Figures/figure-bank-without-attention.png}};
\draw[->,thick](x)to(encoder);
\draw[->,thick](encoder)to(decoder_left)node[right,xshift=-0.1cm,yshift=-1.25cm,scale=1.0]{翻译};
\draw[->,thick](decoder_left)to(y_hat);
\draw[->,thick](y)to(decoder_left);
\draw[->,thick](encoder)to(decoder_right)node[left,xshift=-3.1em,yshift=0.25cm,scale=1.0]{生成图片};
\draw[->,thick](decoder_right)to(figure);
\end{tikzpicture}
\ No newline at end of file
\begin{tikzpicture}[node distance = 0,scale = 0.7]
\tikzstyle{every node}=[scale=0.7]
\node[draw=white] (input) at (0,0){\includegraphics[width=0.62\textwidth]{./Chapter17/Figures/figure-bank-without-attention.png}};(1.9,-1.4);
\node[draw=white] (input) at (10,0){\includegraphics[width=0.62\textwidth]{./Chapter17/Figures/figure-bank-with-attention.png}};(1.9,-1.4);
\end{tikzpicture}
\ No newline at end of file
\begin{tikzpicture}
\node[draw=white] (input) at (0,0){\includegraphics[width=0.62\textwidth]{./Chapter17/Figures/figure-hello-audio.png}};
\node[anchor=east,font=\scriptsize,align=center] (a1) at ([xshift=2.0em]input.west) {音频数据输入};
\node[minimum width=17.4em,minimum height=2.9em,draw=white,line width=3pt] at (0.3em,-0.02em){};
\node[anchor=north,draw,rounded corners=2pt,minimum width=16em, minimum height=2.2em,fill=yellow!20] (box) at ([xshift=0.4em]input.south){};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w1) at ([xshift=0.2em]box.west){{h}};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w2) at ([xshift=0.2em]w1.east){{e}};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w3) at ([xshift=0.2em]w2.east){{e}};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w4) at ([xshift=0.2em]w3.east){{$\epsilon$}};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w5) at ([xshift=0.2em]w4.east){{l}};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w6) at ([xshift=0.2em]w5.east){{$\epsilon$}};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w7) at ([xshift=0.2em]w6.east){{l}};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w8) at ([xshift=0.2em]w7.east){{l}};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w9) at ([xshift=0.2em]w8.east){{o}};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w10) at ([xshift=0.2em]w9.east){{o}};
\node[anchor=west,minimum width=1.2em,minimum height=2.2em] (w11) at ([xshift=0.2em]w10.east){{!}};
\draw[very thick] (w1.south west) -- (w1.south east);
\draw[very thick] (w2.south west) -- (w2.south east);
\draw[very thick] (w3.south west) -- (w3.south east);
\draw[very thick] (w5.south west) -- (w5.south east);
\draw[very thick] (w7.south west) -- (w7.south east);
\draw[very thick] (w8.south west) -- (w8.south east);
\draw[very thick] (w9.south west) -- (w9.south east);
\draw[very thick] (w10.south west) -- (w10.south east);
\draw[very thick] (w11.south west) -- (w11.south east);
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (m1) at ([yshift=-1em]w1.south){{h}};
\node[anchor=north,minimum width=2.64em,minimum height=1.4em,fill=gray!30] (m2) at ([yshift=-1em,xshift=0.72em]w2.south){{e}};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (m3) at ([yshift=-1em]w4.south){};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (m4) at ([yshift=-1em]w5.south){{l}};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (m5) at ([yshift=-1em]w6.south){};
\node[anchor=north,minimum width=2.64em,minimum height=1.4em,fill=gray!30] (m6) at ([yshift=-1em,xshift=0.72em]w7.south){{l}};
\node[anchor=north,minimum width=2.64em,minimum height=1.4em,fill=gray!30] (m7) at ([yshift=-1em,xshift=0.72em]w9.south){{o}};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (m8) at ([yshift=-1em]w11.south){{!}};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (o1) at ([yshift=-3.8em]w1.south){{h}};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (o2) at ([yshift=-3.8em]w2.south){{e}};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (o3) at ([yshift=-3.8em]w3.south){{l}};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (o4) at ([yshift=-3.8em]w4.south){{l}};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (o5) at ([yshift=-3.8em]w5.south){{o}};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] (o6) at ([yshift=-3.8em]w6.south){{!}};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] at ([yshift=-3.8em]w7.south){};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] at ([yshift=-3.8em]w8.south){};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] at ([yshift=-3.8em]w9.south){};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] at ([yshift=-3.8em]w10.south){};
\node[anchor=north,minimum width=1.2em,minimum height=1.4em,fill=gray!30] at ([yshift=-3.8em]w11.south){};
\draw[blue!40,fill=blue!30,opacity=0.7] (w1.south west) -- (w1.south east) -- (o1.south east) -- (o1.south west) -- (w1.south west);
\draw[blue!40,fill=blue!30,opacity=0.7] (w2.south west) -- (w3.south east) -- (m2.south east) .. controls ([yshift=-0.3em]m2.south east) and ([yshift=0.3em]o2.north east) .. (o2.north east) -- (o2.south east) -- (o2.south west) -- (w2.south west);
\draw[blue!40,fill=blue!30,opacity=0.7] (w5.south west) -- (w5.south east) -- (m4.south east) .. controls ([yshift=-0.3em]m4.south east) and ([yshift=0.3em]o3.north east) .. (o3.north east) -- (o3.south east) -- (o3.south west) -- (o3.north west) .. controls ([yshift=0.3em]o3.north west) and ([yshift=-0.3em]m4.south west) .. (m4.south west) -- (w5.south west);
\draw[blue!40,fill=blue!30,opacity=0.7] (w7.south west) -- (w8.south east) -- (m6.south east) .. controls ([yshift=-0.3em]m6.south east) and ([yshift=0.3em]o4.north east) .. (o4.north east) -- (o4.south east) -- (o4.south west) -- (o4.north west) .. controls ([yshift=0.3em]o4.north west) and ([yshift=-0.3em]m6.south west) .. (m6.south west) -- (w7.south west);
\draw[blue!40,fill=blue!30,opacity=0.7] (w9.south west) -- (w10.south east) -- (m7.south east) .. controls ([yshift=-0.1em]m7.south east) and ([yshift=0.2em]o5.north east) .. (o5.north east) -- (o5.south east) -- (o5.south west) -- (o5.north west) .. controls ([yshift=0.1em]o5.north west) and ([yshift=-0.5em]m7.south west) .. (m7.south west) -- (w9.south west);
\draw[blue!40,fill=blue!30,opacity=0.7] (w11.south west) -- (w11.south east) -- (m8.south east) .. controls ([yshift=-0.4em]m8.south east) and ([yshift=0.1em]o6.north east) .. (o6.north east) -- (o6.south east) -- (o6.south west) -- (o6.north west) .. controls ([yshift=0.1em]o6.north west) and ([yshift=-0.5em]m8.south west) .. (m8.south west) -- (w11.south west);
\node[anchor=north,font=\scriptsize,align=center] (a2) at ([yshift=-1.4em]a1.south) {预测字母序列};
\node[anchor=north,font=\scriptsize,align=center] (a3) at ([yshift=-1.8em]a2.south) {合并重复字母 \\ 并丢弃$\epsilon$};
\node[anchor=north,font=\scriptsize,align=center] (a4) at ([yshift=-0.6em]a3.south) {最终结果输出};
\end{tikzpicture}
\ No newline at end of file
\begin{tikzpicture}[scale=0.8]
\tikzstyle{every node}=[scale=0.8]
%figure 1
\coordinate (A1) at (0, 0);
\coordinate (B1) at ([xshift=1.5em,yshift=-0.4em]A1);
\coordinate (C1) at ([xshift=0.3em,yshift=-2.6em]A1);
\coordinate (D1) at ([xshift=2.7em,yshift=-2.6em]A1);
\coordinate (E1) at ([xshift=2.4em,yshift=-1.5em]A1);
\coordinate (F1) at ([xshift=0.3em]D1);
%figure 2
\coordinate (A2) at ([yshift=-15em]A1);
\coordinate (B2) at ([xshift=1.5em,yshift=-0.4em]A2);
\coordinate (C2) at ([xshift=0.3em,yshift=-2.6em]A2);
\coordinate (D2) at ([xshift=2.7em,yshift=-2.6em]A2);
\coordinate (E2) at ([xshift=2.4em,yshift=-1.5em]A2);
\coordinate (F2) at ([xshift=0.3em]D2);
\foreach \x in {1,2}{
\draw[-,line width=2pt] (A\x) -- ([xshift=3.6em]A\x) -- ([xshift=3.6em,yshift=-3em]A\x) -- ([yshift=-3em]A\x) -- (A\x) -- ([xshift=1em]A\x);
\draw[-, thick] (B\x) -- (C\x) -- (D\x) -- (B\x);
\draw[-, thick,fill=black] ([xshift=-0.6em,yshift=-1.2em]B\x) -- ([xshift=-0.3em,yshift=-1em]B\x) -- ([yshift=-1.2em]B\x) --([xshift=0.3em,yshift=-1em]B\x) -- ([xshift=0.6em,yshift=-1.2em]B\x) -- (D\x) -- (C\x) -- ([xshift=-0.6em,yshift=-1.2em]B\x);
\draw[-, thick,fill=black] (E\x) -- ([xshift=0.2em,yshift=0.3em]E\x) -- ([xshift=0.33em]F\x) -- (F\x) -- (E\x);
\node[circle,inner sep=0pt,minimum size=0.4em,fill=black] at ([xshift=-0.7em,yshift=-0.2em]B\x){};
\node[draw,rounded corners=2pt,fill=yellow!20,minimum height=2.2em,minimum width=4.3em](cnn\x) at ([xshift=9.5em,yshift=-1.5em]A\x){CNN};
\node[draw,circle,fill=green!20,font=\footnotesize,anchor=west,inner sep=3pt] (h\x_2) at ([xshift=3em,yshift=0.66em]cnn\x.east){$h_2$};
\node[draw,circle,fill=green!20,font=\footnotesize,anchor=south,inner sep=3pt] (h\x_1) at ([yshift=1em]h\x_2.north){$h_1$};
\node[font=\footnotesize,anchor=north] (h\x_c) at ([yshift=-0.6em]h\x_2.south){$\cdots$};
\node[draw,circle,fill=green!20,font=\footnotesize,anchor=north,inner sep=3pt] (h\x_n) at ([yshift=-0.6em]h\x_c.south){$h_n$};
}
\begin{pgfonlayer}{background}
\node[draw,thick,rounded corners=2pt,densely dashed,inner ysep=1.2em,inner xsep=0.4em,label={above:图像特征向量}][fit=(h1_1)(h1_2)(h1_n)](box1){};
\node[draw,thick,rounded corners=2pt,densely dashed,inner ysep=1.2em,inner xsep=0.4em,label={above:图像特征向量}][fit=(h2_1)(h2_2)(h2_n)](box2){};
\end{pgfonlayer}
\node[anchor=west,draw,rounded corners=2pt,fill=blue!20,minimum height=2.2em,minimum width=4.3em] (decoder1)at ([xshift=3em]box1.east){解码器};
\node[anchor=west,draw,circle,inner sep=0pt,minimum size=1.4em] (add)at ([xshift=2em,yshift=1.6em]box2.east){};
\draw[] (add.0) -- (add.180);
\draw[] (add.90) -- (add.-90);
\node[anchor=west,draw,rounded corners=2pt,fill=blue!20,minimum height=2.2em,minimum width=4.3em] (decoder2)at ([xshift=6em]box2.east){解码器};
\draw[->,thick] ([xshift=-2.7em]cnn1.180) -- ([xshift=-0.1em]cnn1.180);
\draw[->,thick] ([xshift=-2.7em]cnn2.180) -- ([xshift=-0.1em]cnn2.180);
\draw[->,thick] ([xshift=0.1em]cnn1.0) -- ([xshift=-0.1em]box1.180);
\draw[->,thick] ([xshift=0.1em]cnn2.0) -- ([xshift=-0.1em]box2.180);
\draw[->,thick] ([xshift=0.1em]box1.0) -- ([xshift=-0.1em]decoder1.180);
\draw[->,thick] ([xshift=0.1em]h2_1.0) -- (add.180);
\draw[->,thick] ([xshift=0.1em]h2_2.0) -- (add.180);
\draw[->,thick] ([xshift=0.1em]h2_c.0) -- (add.180);
\draw[->,thick] ([xshift=0.1em]h2_n.0) -- (add.180);
\draw[->,thick,out=20,in=130] ([xshift=0.1em]add.45) to ([xshift=-0em,yshift=0.1em]decoder2.north west);
\draw[->,thick,out=200,in=-45] ([xshift=-0.1em]decoder2.west) to ([yshift=-0.1em]add.-90);
\node [anchor=north](pos1) at ([yshift=-1.0em]box1.south) {(a)未引入注意力机制};
\node [anchor=north](pos2) at ([yshift=-1.0em]box2.south) {(b)引入注意力机制};
\end{tikzpicture}
%------------------------------------------------------------------------------------------------------------
\begin{tikzpicture}[scale=0.6]
\tikzstyle{every node}=[scale=0.6]
%figure 1
\coordinate (A1) at (0, 0);
\coordinate (B1) at ([xshift=1.5em,yshift=-0.4em]A1);
\coordinate (C1) at ([xshift=0.3em,yshift=-2.6em]A1);
\coordinate (D1) at ([xshift=2.7em,yshift=-2.6em]A1);
\coordinate (E1) at ([xshift=2.4em,yshift=-1.5em]A1);
\coordinate (F1) at ([xshift=0.3em]D1);
\coordinate (G1) at ([xshift=0.3em,yshift=-5em]A1);
\coordinate (H1) at ([xshift=0.4em,yshift=-1.6em]G1);
\coordinate (I1) at ([xshift=0.4em,yshift=-2.0em]G1);
\coordinate (J1) at ([xshift=0.4em,yshift=-2.5em]G1);
\coordinate (K1) at ([xshift=0.4em,yshift=-3.0em]G1);
\coordinate (L1) at ([xshift=0.4em,yshift=-3.5em]G1);
\coordinate (G2) at ([xshift=8em,yshift=-2.5em]A1);
\coordinate (H2) at ([xshift=0.4em,yshift=-1.6em]G2);
\coordinate (I2) at ([xshift=0.4em,yshift=-2.0em]G2);
\coordinate (J2) at ([xshift=0.4em,yshift=-2.5em]G2);
\coordinate (K2) at ([xshift=0.4em,yshift=-3.0em]G2);
\coordinate (L2) at ([xshift=0.4em,yshift=-3.5em]G2);
%figure 2
\coordinate (A2) at ([yshift=-0.5em,xshift=7em]G2);
\coordinate (B2) at ([xshift=1.5em,yshift=-0.4em]A2);
\coordinate (C2) at ([xshift=0.3em,yshift=-2.6em]A2);
\coordinate (D2) at ([xshift=2.7em,yshift=-2.6em]A2);
\coordinate (E2) at ([xshift=2.4em,yshift=-1.5em]A2);
\coordinate (F2) at ([xshift=0.3em]D2);
\coordinate (G3) at ([xshift=8em,yshift=0.5em]A2);
\coordinate (H3) at ([xshift=0.4em,yshift=-1.6em]G3);
\coordinate (I3) at ([xshift=0.4em,yshift=-2.0em]G3);
\coordinate (J3) at ([xshift=0.4em,yshift=-2.5em]G3);
\coordinate (K3) at ([xshift=0.4em,yshift=-3.0em]G3);
\coordinate (L3) at ([xshift=0.4em,yshift=-3.5em]G3);
%figure 3
\coordinate (A3) at ([yshift=-0.5em,xshift=7em]G3);
\coordinate (B3) at ([xshift=1.5em,yshift=-0.4em]A3);
\coordinate (C3) at ([xshift=0.3em,yshift=-2.6em]A3);
\coordinate (D3) at ([xshift=2.7em,yshift=-2.6em]A3);
\coordinate (E3) at ([xshift=2.4em,yshift=-1.5em]A3);
\coordinate (F3) at ([xshift=0.3em]D3);
\coordinate (A4) at ([xshift=8em]A3);
\coordinate (B4) at ([xshift=1.5em,yshift=-0.4em]A4);
\coordinate (C4) at ([xshift=0.3em,yshift=-2.6em]A4);
\coordinate (D4) at ([xshift=2.7em,yshift=-2.6em]A4);
\coordinate (E4) at ([xshift=2.4em,yshift=-1.5em]A4);
\coordinate (F4) at ([xshift=0.3em]D4);
%figure 4
\coordinate (G4) at ([xshift=7.6em,yshift=0.5em]A4);
\coordinate (H4) at ([xshift=0.4em,yshift=-1.6em]G4);
\coordinate (I4) at ([xshift=0.4em,yshift=-2.0em]G4);
\coordinate (J4) at ([xshift=0.4em,yshift=-2.5em]G4);
\coordinate (K4) at ([xshift=0.4em,yshift=-3.0em]G4);
\coordinate (L4) at ([xshift=0.4em,yshift=-3.5em]G4);
\coordinate (A5) at ([yshift=-0.5em,xshift=8em]G4);
\coordinate (B5) at ([xshift=1.5em,yshift=-0.4em]A5);
\coordinate (C5) at ([xshift=0.3em,yshift=-2.6em]A5);
\coordinate (D5) at ([xshift=2.7em,yshift=-2.6em]A5);
\coordinate (E5) at ([xshift=2.4em,yshift=-1.5em]A5);
\coordinate (F5) at ([xshift=0.3em]D5);
\foreach \x in {1,2,3,4,5}{
\draw[-,line width=2pt] (A\x) -- ([xshift=3.6em]A\x) -- ([xshift=3.6em,yshift=-3em]A\x) -- ([yshift=-3em]A\x) -- (A\x) -- ([xshift=1em]A\x);
\draw[-, very thick] (B\x) -- (C\x) -- (D\x) -- (B\x);
\draw[-, very thick,fill=black] ([xshift=-0.6em,yshift=-1.2em]B\x) -- ([xshift=-0.3em,yshift=-1em]B\x) -- ([yshift=-1.2em]B\x) --([xshift=0.3em,yshift=-1em]B\x) -- ([xshift=0.6em,yshift=-1.2em]B\x) -- (D\x) -- (C\x) -- ([xshift=-0.6em,yshift=-1.2em]B\x);
\draw[-, very thick,fill=black] (E\x) -- ([xshift=0.2em,yshift=0.3em]E\x) -- ([xshift=0.33em]F\x) -- (F\x) -- (E\x);
\node[circle,inner sep=0pt,minimum size=0.4em,fill=black] at ([xshift=-0.7em,yshift=-0.2em]B\x){};
}
\foreach \y in {1,2,3,4}{
\draw[-,line width=2pt] (G\y) -- ([xshift=1.6em]G\y) -- ([xshift=3em,yshift=-1.4em]G\y) -- ([xshift=3em,yshift=-4em]G\y) -- ([yshift=-4em]G\y) -- (G\y) -- ([xshift=1em]G\y);
\draw[-,line width=2pt] ([xshift=1.6em]G\y) -- ([xshift=1.5em,yshift=-1.4em]G\y) -- ([xshift=3em,yshift=-1.4em]G\y) ;
\draw[-,line width=1.6pt] (H\y) -- ([xshift=0.6em]H\y);
\draw[-,line width=1.6pt] (I\y) -- ([xshift=2em]I\y);
\draw[-,line width=1.6pt] (J\y) -- ([xshift=2em]J\y);
\draw[-,line width=1.6pt] (K\y) -- ([xshift=2em]K\y);
\draw[-,line width=1.6pt] (L\y) -- ([xshift=2em]L\y);
}
\draw[-,thick] ([yshift=4em,xshift=5em]G2) -- ([yshift=-8em,xshift=5em]G2);
\draw[-,thick] ([yshift=4em,xshift=5em]G3) -- ([yshift=-8em,xshift=5em]G3);
\draw[-,thick] ([yshift=4.5em,xshift=5.6em]A4) -- ([yshift=-7.5em,xshift=5.6em]A4);
\node [draw,single arrow,minimum height=2.4em,single arrow head extend=0.4em] (arrow1) at ([xshift=-2.4em,yshift=-2em]G2) {};
\node [draw,single arrow,minimum height=2.4em,single arrow head extend=0.4em] (arrow2) at ([xshift=-2.4em,yshift=-2em]G3) {};
\node [draw,single arrow,minimum height=2.4em,single arrow head extend=0.4em] (arrow3) at ([xshift=-2.4em,yshift=-1.5em]A4) {};
\node [draw,single arrow,minimum height=2.4em,single arrow head extend=0.4em] (arrow4) at ([xshift=-2.5em,yshift=-1.5em]A5) {};
\node[anchor=north,font=\small,scale=1.5] at ([yshift=-6em]arrow1.south){(a)多模态机器翻译};
\node[anchor=north,font=\small,scale=1.5] at ([yshift=-6em]arrow2.south){(b)图像到文本翻译};
\node[anchor=north,font=\small,scale=1.5] at ([yshift=-6em]arrow3.south){(c)图像到图像翻译};
\node[anchor=north,font=\small,scale=1.5] at ([yshift=-6em]arrow4.south){(d)文本到图像翻译};
\end{tikzpicture}
%------------------------------------------------------------------------------------------------------------
\begin{tikzpicture}
\begin{tikzpicture}[node distance = 0,scale = 0.8]
\tikzstyle{every node}=[scale=0.8]
\foreach \x in {1,2,3,4}
\node[inner sep=0pt,minimum size=1em,fill=ublue,circle] (c1_\x) at (0em+1.6em*\x, 0em){};
\node[draw,inner sep=0pt,minimum height=1em,minimum width=1.6em,fill=red!30,rounded corners=1pt] (c1_\x) at (0em+2em*\x, 0em){};
\foreach \x in {1,2,3,4,5,6}
\node[inner sep=0pt,minimum size=1em,fill=ublue,circle] (c2_\x) at (8.4em+1.6em*\x, 0em){};
\foreach \x in {1,2,3}
\node[draw,inner sep=0pt,minimum height=1em,minimum width=1.6em,fill=red!30,rounded corners=1pt] (c2_\x) at (11em+2em*\x, 0em){};
\foreach \x in {1,2,3,4,5}
\node[inner sep=0pt,minimum size=1em,fill=ublue,circle] (c3_\x) at (20em+1.6em*\x, 0em){};
\node[draw,inner sep=0pt,minimum height=1em,minimum width=1.6em,fill=red!30,rounded corners=1pt] (c3_\x) at (18.4em+2em*\x, 0em){};,minimum width=1em
\foreach \x in {1,2,3,4,5}
\node[inner sep=0pt,minimum size=1em,fill=orange,circle] (c4_\x) at (20em+1.6em*\x, 9.4em){};
\node[draw,inner sep=0pt,minimum height=1em,minimum width=1.6em,fill=blue!30,rounded corners=1pt] (c4_\x) at (18.4em+2em*\x, 10.4em){};
\node[inner sep=0pt,minimum size=1em,fill=ugreen,circle] (c5) at (9em, 7em){};
\node[inner sep=0pt,minimum size=1.2em,fill=ugreen,circle] (qs) at (18.6em, 5em){};
\node[inner sep=0pt,minimum size=1.2em,fill=ugreen,circle] (qw) at (18.6em, 3em){};
%\node[inner sep=0pt,minimum size=1em,fill=ugreen,circle] (c5) at (9em, 7em){};
\node[draw,inner sep=0pt,minimum size=1.2em,fill=green!20,circle] (qs) at (18.6em, 6.4em){};
\node[draw,inner sep=0pt,minimum size=1.2em,fill=green!20,circle] (qw) at (18.6em, 4.4em){};
\node[fill=orange,inner sep=0pt, minimum size=1.2em, circle, text=white] (sigma) at (24.8em, 7em){\small\bfnew{$\sigma$}};
\node[draw,thick,inner sep=0pt, minimum size=1.2em, circle] (sigma) at (24.4em, 8em){};
\draw[-,thick] (sigma.0) -- (sigma.180);
\draw[-,thick] (sigma.90) -- (sigma.-90);
\node[fill=ugreen,inner sep=0pt, minimum size=1.2em, circle, text=white] (add1) at (4em, 3em){\small\bfnew{+}};
\node[fill=ugreen,inner sep=0pt, minimum size=1.2em, circle, text=white] (add2) at (14em, 3em){\small\bfnew{+}};
\node[fill=ugreen,inner sep=0pt, minimum size=1.2em, circle, text=white] (add3) at (9em, 5em){\small\bfnew{+}};
\node[draw,fill=orange!30,inner sep=0pt, minimum size=1.2em, circle] (add1) at (5em, 3em){};
\node[draw,fill=orange!30,inner sep=0pt, minimum size=1.2em, circle] (add2) at (15em, 3em){};
\node[draw,fill=orange!30,inner sep=0pt, minimum size=1.2em, circle] (add3) at (10em, 5.2em){};
\begin{pgfonlayer}{background}
\node[draw,rounded corners=2pt,drop shadow,fill=white][fit=(c1_1)(c1_4)](box1){};
\node[draw,rounded corners=2pt,drop shadow,fill=white][fit=(c2_1)(c2_6)](box2){};
\node[draw,rounded corners=2pt,drop shadow,fill=white][fit=(c3_1)(c3_5)](box3){};
\node[draw,rounded corners=2pt,drop shadow,fill=white][fit=(c4_1)(c4_5)](box4){};
\node[draw,rounded corners=2pt,inner xsep=6pt,drop shadow,fill=white][fit=(c5)](box5){};
\node[draw,rounded corners=2pt,drop shadow,fill=white, minimum width=8.3em][fit=(c1_1)(c1_4)](box1){};
\node[draw,rounded corners=2pt,drop shadow,fill=white,minimum width=6.4em][fit=(c2_1)(c2_3)](box2){};
\node[draw,rounded corners=2pt,drop shadow,fill=white,minimum width=10.5em][fit=(c3_1)(c3_5)](box3){};
\node[draw,rounded corners=2pt,drop shadow,fill=white,minimum width=10.3em][fit=(c4_1)(c4_5)](box4){};
%\node[draw,rounded corners=2pt,inner xsep=6pt,drop shadow,fill=white][fit=(c5)](box5){};
\end{pgfonlayer}
\node[draw,dash pattern=on 3pt off 1pt,minimum width=1.6em, minimum height=2em,very thick] (n1) at (24.8em,0em){};
\node[draw,dash pattern=on 3pt off 1pt,minimum width=1.6em, minimum height=2em,very thick] (n2) at (24.8em,9.4em){};
\node[] at (24.8em, -1.5em){$\mathbi{x}_\mathbi{t}$};
\node[text=ublue] at (8.2em, 0em) {\small\bfnew{...}};
\draw[-latex, out=70, in=-120] (c1_1.90) node[xshift=-0.4em,yshift=1.2em]{$ \mathbi{h}_ \mathbi{i}^ \mathbi{j}$}to (add1.-90);
\draw[-latex, out=80, in=-100] (c1_2.90) to (add1.-90);
\draw[-latex, out=100, in=-80] (c1_3.90) to (add1.-90);
\draw[-latex, out=110, in=-60] (c1_4.90) to (add1.-90);
\draw[-latex, out=60, in=-140] (c2_1.90) to (add2.-90);
\draw[-latex, out=70, in=-120] (c2_2.90) to (add2.-90);
\draw[-latex, out=80, in=-100] (c2_3.90) to (add2.-90);
\draw[-latex, out=100, in=-80] (c2_4.90) to (add2.-90);
\draw[-latex, out=110, in=-60] (c2_5.90) to (add2.-90);
\draw[-latex, out=120, in=-40] (c2_6.90) to (add2.-90);
\draw[-latex, out=20, in=-150] (add1.90) node[xshift=-0.4em,yshift=1.2em]{$ \mathbi{s}^ \mathbi{j}$} to (add3.-90);
\draw[-latex, out=160, in=-30] (add2.90) to (add3.-90);
\draw[-latex] (add3.90) -- (box5.-90);
\draw[-latex] (box5.0) -- node[xshift=-3em,above]{$ \mathbi{d}_\mathbi{t}$}(sigma.180);
\draw[-latex, ugreen!60] (qs.180) node[xshift=-1em,above,text=black]{$ \mathbi{q}_\mathbi{s}$}-- (add3.0);
\draw[-, ugreen!60] (qw.180) node[xshift=-1em,above,text=black]{$ \mathbi{q}_\mathbi{w}$}-- (add2.0);
\draw[-latex, ugreen!60] (add2.180) -- (add1.0);
\draw[-latex] (n1.130) -- (qw.0);
\draw[-latex] (n1.120) -- (qs.0);
\draw[-latex] (n1.90) node[yshift=1em,right]{$ \mathbi{h}_\mathbi{t}$}-- (sigma.-90);
\draw[-latex] (sigma.90) -- (n2.-90);
\draw[-latex] (n2.90) -- node[right]{$ \widetilde{\mathbi{h}}_\mathbi{t}$}([yshift=2em]n2.90);
\node[draw=violet,densely dotted,minimum width=1.9em, minimum height=2.1em,very thick] (n1) at (24.4em,0em){};
\node[draw=violet,densely dotted,minimum width=1.8em, minimum height=2em,very thick] (n2) at (24.4em,10.4em){};
\node[] at (24.4em, -1.5em){$\mathbi{x}_\mathbi{t}$};
\node[text=ublue] at (10.5em, 0em) {\small\bfnew{...}};
\draw[->,thick, out=70, in=-120] ([yshift=0.1em]c1_1.90) node[xshift=-0.4em,yshift=1.2em]{$ \mathbi{h}_ \mathbi{i}^ \mathbi{j}$}to ([yshift=-0.1em]add1.-90);
\draw[->,thick, out=80, in=-100] ([yshift=0.1em]c1_2.90) to ([yshift=-0.1em]add1.-90);
\draw[->,thick, out=100, in=-80] ([yshift=0.1em]c1_3.90) to ([yshift=-0.1em]add1.-90);
\draw[->,thick, out=110, in=-60] ([yshift=0.1em]c1_4.90) to ([yshift=-0.1em]add1.-90);
\draw[->,thick, out=70, in=-110] ([yshift=0.1em]c2_1.90) to ([yshift=-0.1em]add2.-90);
\draw[->,thick, out=90, in=-90] ([yshift=0.1em]c2_2.90) to ([yshift=-0.1em]add2.-90);
\draw[->,thick, out=110, in=-70] ([yshift=0.1em]c2_3.90) to ([yshift=-0.1em]add2.-90);
\draw[->,thick, out=30, in=-130] ([yshift=0.1em]add1.90) node[xshift=-0.4em,yshift=1.1em]{$ \mathbi{s}^ \mathbi{j}$} to ([yshift=-0.1em]add3.-120);
\draw[->,thick, out=150, in=-50] ([yshift=0.1em]add2.90) to ([yshift=-0.1em]add3.-70);
\draw[->,thick, ugreen!60,out=160,in=-10] ([xshift=-0.1em]qs.160) node[xshift=-0.3em,yshift=0.1em,above,text=black]{$ \mathbi{q}_\mathbi{s}$} to ([xshift=0.1em]add3.0);
\draw[->,thick, ugreen!60,out=180,in=0] ([xshift=-0.1em]qw.180) node[xshift=-0.3em,yshift=0.4em,above,text=black]{$ \mathbi{q}_\mathbi{w}$} to ([xshift=0.1em]add2.0);
\draw[->,thick, ugreen!60,out=170,in=-10] ([xshift=-0.1em]qw.160) to ([xshift=0.1em]add1.0);
\draw[->,thick] ([yshift=0.1em]n1.135) .. controls ([xshift=-2em]n1.130) and ([xshift=2em]qw.0) .. ([xshift=0.1em]qw.0);
\draw[->,thick] ([yshift=0.1em]n1.120) .. controls ([xshift=-2em,yshift=1em]n1.120) and ([xshift=3em]qs.0) .. ([xshift=0.1em]qs.0);
\draw[->,thick] ([yshift=0.1em]n1.90) node[yshift=1em,right]{$ \mathbi{h}_\mathbi{t}$}-- ([yshift=-0.1em]sigma.-90);
\draw[->,thick] ([yshift=0.1em]sigma.90) -- ([yshift=-0.1em]n2.-90);
\draw[->,thick] ([yshift=0.1em]n2.90) -- node[right]{$ \widetilde{\mathbi{h}}_\mathbi{t}$}([yshift=2em]n2.90);
\draw[decorate,decoration={brace, mirror},gray, thick] ([yshift=-2em]box1.-180) -- node[font=\scriptsize,text=black,below]{前几句}([yshift=-2em]box2.0);
\draw[decorate,decoration={brace, mirror},gray, thick] ([yshift=-2em]box3.-180) -- node[font=\scriptsize,text=black,below]{当前句}([yshift=-2em]box3.0);
\draw[->, thick, rounded corners=2pt] ([yshift=0.1em]add3.90) -- ([yshift=2.1em]add3.90) -- ([xshift=-0.1em]sigma.180);
%annotation
\node[fill=ublue,rounded corners=1pt,inner sep=0pt,minimum size=1em] (a1) at (2em,-4.5em) {};
\node[fill=red!30,rounded corners=1pt,inner sep=0pt,minimum size=1em] (a1) at (2em,-4.5em) {};
\node[anchor=west,font=\footnotesize] (w1) at ([xshift=0.4em]a1.east) {编码表示};
\node[anchor=west,fill=ugreen,rounded corners=1pt,inner sep=0pt,minimum size=1em] (a2) at ([xshift=2em]w1.east) {};
\node[anchor=west,fill=orange!30,rounded corners=1pt,inner sep=0pt,minimum size=1em] (a2) at ([xshift=2em]w1.east) {};
\node[anchor=west,font=\footnotesize] (w2)at ([xshift=0.4em]a2.east) {层次注意力};
\node[anchor=west,fill=orange,rounded corners=1pt,inner sep=0pt,minimum size=1em] (a3) at ([xshift=2em]w2.east) {};
\node[anchor=west,fill=blue!30,rounded corners=1pt,inner sep=0pt,minimum size=1em] (a3) at ([xshift=2em]w2.east) {};
\node[anchor=west,font=\footnotesize] at ([xshift=0.4em]a3.east) {融合上下文信息的编码表示};
\end{tikzpicture}
......
\begin{tikzpicture}[scale=0.8]
\tikzstyle{every node}=[scale=0.8]
%figure 1
\coordinate (A1) at (0, 0);
\coordinate (B1) at ([xshift=1.5em,yshift=-0.4em]A1);
\coordinate (C1) at ([xshift=0.3em,yshift=-2.6em]A1);
\coordinate (D1) at ([xshift=2.7em,yshift=-2.6em]A1);
\coordinate (E1) at ([xshift=2.4em,yshift=-1.5em]A1);
\coordinate (F1) at ([xshift=0.3em]D1);
%figure 2
\coordinate (A2) at ([xshift=15em]A1);
\coordinate (B2) at ([xshift=1.5em,yshift=-0.4em]A2);
\coordinate (C2) at ([xshift=0.3em,yshift=-2.6em]A2);
\coordinate (D2) at ([xshift=2.7em,yshift=-2.6em]A2);
\coordinate (E2) at ([xshift=2.4em,yshift=-1.5em]A2);
\coordinate (F2) at ([xshift=0.3em]D2);
\foreach \x in {1,2}{
\draw[-,line width=2pt] (A\x) -- ([xshift=3.6em]A\x) -- ([xshift=3.6em,yshift=-3em]A\x) -- ([yshift=-3em]A\x) -- (A\x) -- ([xshift=1em]A\x);
\draw[-, very thick] (B\x) -- (C\x) -- (D\x) -- (B\x);
\draw[-, very thick,fill=black] ([xshift=-0.6em,yshift=-1.2em]B\x) -- ([xshift=-0.3em,yshift=-1em]B\x) -- ([yshift=-1.2em]B\x) --([xshift=0.3em,yshift=-1em]B\x) -- ([xshift=0.6em,yshift=-1.2em]B\x) -- (D\x) -- (C\x) -- ([xshift=-0.6em,yshift=-1.2em]B\x);
\draw[-, very thick,fill=black] (E\x) -- ([xshift=0.2em,yshift=0.3em]E\x) -- ([xshift=0.33em]F\x) -- (F\x) -- (E\x);
\node[circle,inner sep=0pt,minimum size=0.4em,fill=black] at ([xshift=-0.7em,yshift=-0.2em]B\x){};
\node[draw,rounded corners=2pt,fill=yellow!20,minimum width=2.3cm,minimum height=2.2em](cnn\x) at ([xshift=1.8em,yshift=3.6em]A\x){CNN};
}
\node[draw,anchor=south,rounded corners=2pt,minimum width=4.0cm,minimum height=2.2em,fill=red!20](encoder) at ([yshift=2.6em,xshift=2.2em]cnn1.north){编码器};
\node[anchor=north,font=\Large](x) at ([xshift=2.5em,yshift=-3.4em]encoder.south){$\seq{x}$};
\node[draw,anchor=south,rounded corners=2pt,minimum width=4.0cm,minimum height=2.2em,fill=blue!20](decoder) at ([yshift=2.6em,xshift=2.2em]cnn2.north){解码器};
\node[anchor=north,font=\Large](y) at ([xshift=2.5em,yshift=-3.4em]decoder.south){$\seq{y}$};
\node[anchor=south,font=\Large](y_1) at ([yshift=3em]decoder.north){$\seq{y}'$};
\draw[->,thick] ([yshift=-2.1em]cnn1.south) -- ([yshift=-0.1em]cnn1.south);
\draw[->,thick] ([yshift=-2.1em]cnn2.south) -- ([yshift=-0.1em]cnn2.south);
\draw[->,thick] ([yshift=0.1em]cnn1.north) -- ([yshift=2.4em]cnn1.north);
\draw[->,thick] ([yshift=0.1em]cnn2.north) -- ([yshift=2.4em]cnn2.north);
\draw[->,thick] ([yshift=0.3em]x.north) -- ([yshift=4.5em]x.south);
\draw[->,thick] ([yshift=0.3em]y.north) -- ([yshift=4.7em]y.south);
\draw[->,thick] ([xshift=0.1em]encoder.east) -- ([xshift=-0.1em]decoder.west);
\draw[->,thick] ([yshift=0.1em]decoder.north) -- ([yshift=-0.1em]y_1.south);
\node [anchor=south,scale=1.2] (node1) at ([xshift=-2.0em,yshift=2.5em]encoder.north) {{$x,y$:双语数据}};
\end{tikzpicture}
%------------------------------------------------------------------------------------------------------------
\begin{tikzpicture}[node distance = 0]
\tikzstyle{every node}=[scale=0.9]
\begin {scope}
\node[draw=white,scale=0.6] (input) at (0,0){\includegraphics[width=0.62\textwidth]{./Chapter17/Figures/figure-bank-without-attention.png}};(1.9,-1.4);
\node[anchor=south] (english1) at ([xshift=0em,yshift=-2.5em]input.south) {\begin{tabular}{l}{\large\bfnew{英语}}{\Large{:A medium sized child}}\end{tabular}};
\node[anchor=south] (english2) at ([xshift=1.9em,yshift=-1.2em]english1.south) {\begin{tabular}{l}{\Large{jumps off a dusty {\red{\underline{bank}}}.}} \end{tabular}};
\end {scope}
\node[draw,thick,inner sep=0pt,minimum height=16em,minimum width=19em,rounded corners=8pt][fit = (input) (english1)(english2)] (box1) at (0em,-1.5em){};
\begin {scope}[xshift=1.45in,yshift=-0.2in]
\draw[-,thick] (0,0.2) -- (1,0.2) -- (1,0.4) --(1.5,0) -- (1,-0.4) -- (1,-0.2) -- (0,-0.2) -- (0,0.2);
\end {scope}
\begin {scope}[xshift=4.4in,yshift=-0.2in]
\node[anchor=east] (de1) {\begin{tabular}{l}{\large\bfnew{汉语}}{\Large{:一个半大孩子从尘土}}\end{tabular}};
\node[anchor=south] (de2) at ([xshift=2em,yshift=-1.5em]de1.south) {\begin{tabular}{l}{\Large{飞扬的{\red{\underline{河床}}}上跳下来。}} \end{tabular}};
\end {scope}
\end{tikzpicture}
\ No newline at end of file
\begin{tikzpicture}
\tikzstyle{layer}=[draw,rounded corners=2pt,font=\scriptsize,align=center,minimum width=5em]
\tikzstyle{word}=[font=\scriptsize]
\node[layer,fill=red!20] (en_sa) at (0,0){Multi-Head \\ Attention};
\node[layer,anchor=south,fill=green!20] (en_ffn) at ([yshift=1.4em]en_sa.north){Feed Forward \\ Network};
\node[draw,circle,inner sep=0pt, minimum size=1em,anchor=north] (en_add) at ([yshift=-1.4em]en_sa.south){};
\draw[] (en_add.90) -- (en_add.-90);
\draw[] (en_add.0) -- (en_add.180);
\node[layer,anchor=north,fill=yellow!20] (en_cnn) at ([yshift=-1.4em]en_add.south){CNN};
\node[draw,circle,inner sep=0pt, minimum size=1em,anchor=west] (de_add) at ([xshift=7em]en_add.east){};
\draw[] (de_add.90) -- (de_add.-90);
\draw[] (de_add.0) -- (de_add.180);
\node[layer,anchor=south,fill=red!20] (de_sa) at ([yshift=1.4em]de_add.north){Masked \\Multi-Head\\Attention};
\node[layer,anchor=south,fill=red!20] (de_ca) at ([yshift=1.4em]de_sa.north){Multi-Head \\ Attention};
\node[layer,anchor=south,fill=green!20] (de_ffn) at ([yshift=1.4em]de_ca.north){Feed Forward \\ Network};
\node[layer,anchor=south,fill=blue!20] (sf) at ([yshift=1.6em]de_ffn.north){Softmax};
\node[layer,anchor=south,fill=orange!20] (output) at ([yshift=1.4em]sf.north){Output Probabilities};
\node[anchor=north,font=\scriptsize,align=center] (en_input) at ([yshift=-1em]en_cnn.south){Speech Feature\\(FilterBank/MFCC)};
\node[anchor=north,font=\scriptsize,align=center] (de_input) at ([yshift=-1.1em]de_add.south){Transcription\\(Embedding)};
\node[anchor=east,font=\scriptsize,align=center] (en_pos) at ([xshift=-2em]en_add.west){Position\\(Embedding)};
\node[anchor=west,font=\scriptsize,align=center] (de_pos) at ([xshift=2em]de_add.east){Position\\(Embedding)};
\draw[->] (en_input.90) -- ([yshift=-0.1em]en_cnn.-90);
\draw[->] ([yshift=0.1em]en_cnn.90) -- ([yshift=-0.1em]en_add.-90);
\draw[->] ([yshift=0.1em]en_add.90) -- ([yshift=-0.1em]en_sa.-90);
\draw[->] ([yshift=0.1em]en_sa.90) -- ([yshift=-0.1em]en_ffn.-90);
\draw[->] (de_input.90) -- ([yshift=-0.1em]de_add.-90);
\draw[->] ([yshift=0.1em]de_add.90) -- ([yshift=-0.1em]de_sa.-90);
\draw[->] ([yshift=0.1em]de_sa.90) -- ([yshift=-0.1em]de_ca.-90);
\draw[->] ([yshift=0.1em]de_ca.90) -- ([yshift=-0.1em]de_ffn.-90);
\draw[->] ([yshift=0.1em]de_ffn.90) -- ([yshift=-0.1em]sf.-90);
\draw[->] ([yshift=0.1em]sf.90) -- ([yshift=-0.1em]output.-90);
\draw[->] ([xshift=0.1em]en_pos.0) -- ([xshift=-0.1em]en_add.180);
\draw[->] ([xshift=-0.1em]de_pos.180) -- ([xshift=0.1em]de_add.0);
\draw[->,rounded corners=2pt] ([yshift=0.1em]en_ffn.90) -- ([yshift=2em]en_ffn.90) -- ([xshift=4em,yshift=2em]en_ffn.90) -- ([xshift=-1.5em]de_ca.west) -- ([xshift=-0.1em]de_ca.west);
\begin{pgfonlayer}{background}
\node[draw=ugreen,rounded corners=2pt,inner xsep=6pt,inner ysep=8pt,dashed,thick][fit=(en_sa)(en_ffn)](box1){};
\node[draw=red,rounded corners=2pt,inner xsep=6pt,inner ysep=8pt,dashed,thick][fit=(de_sa)(de_ca)(de_ffn)](box2){};
\end{pgfonlayer}
\node[anchor=east,font=\scriptsize,text=ugreen] at ([xshift=-0.1em]box1.west){$N \times$};
\node[anchor=west,font=\scriptsize,text=red] at ([xshift=0.1em]box2.east){$\times N$};
\node[anchor=east,font=\scriptsize] at ([xshift=-0.1em]en_cnn.west){$2 \times$};
\node[anchor=east,font=\scriptsize,align=center,text=ugreen] at ([xshift=-0.1em,yshift=3em]box1.west){ASR \\ Encoder};
\node[anchor=west,font=\scriptsize,align=center,text=red] at ([xshift=0.1em,yshift=5em]box2.east){ASR \\ Decoder};
\end{tikzpicture}
\ No newline at end of file
\begin{tikzpicture}
\tikzstyle{layer}=[draw,rounded corners=2pt,font=\scriptsize,align=center,minimum width=5em]
\tikzstyle{word}=[font=\scriptsize]
\node[layer,fill=red!20] (en_sa) at (0,0){Multi-Head \\ Attention};
\node[layer,anchor=south,fill=green!20] (en_ffn) at ([yshift=1.4em]en_sa.north){Feed Forward \\ Network};
\node[draw,circle,inner sep=0pt, minimum size=1em,anchor=north] (en_add) at ([yshift=-1.4em]en_sa.south){};
\draw[] (en_add.90) -- (en_add.-90);
\draw[] (en_add.0) -- (en_add.180);
\node[layer,anchor=north,fill=yellow!20] (en_cnn) at ([yshift=-1.4em]en_add.south){CNN};
\node[draw,circle,inner sep=0pt, minimum size=1em,anchor=west] (de_add) at ([xshift=7em]en_add.east){};
\draw[] (de_add.90) -- (de_add.-90);
\draw[] (de_add.0) -- (de_add.180);
\node[layer,anchor=south,fill=red!20] (de_sa) at ([yshift=1.4em]de_add.north){Masked \\Multi-Head\\Attention};
\node[layer,anchor=south,fill=red!20] (de_ca) at ([yshift=1.4em]de_sa.north){Multi-Head \\ Attention};
\node[layer,anchor=south,fill=green!20] (de_ffn) at ([yshift=1.4em]de_ca.north){Feed Forward \\ Network};
\node[layer,anchor=south,fill=blue!20] (en_sf) at ([yshift=3em]en_ffn.north){Softmax};
\node[layer,anchor=south,fill=blue!20] (sf) at ([yshift=2em]de_ffn.north){Softmax};
\node[layer,anchor=south,fill=orange!20] (en_output) at ([yshift=1.4em]en_sf.north){CTC Output};
\node[layer,anchor=south,fill=orange!20] (output) at ([yshift=1.4em]sf.north){ST Output};
\node[anchor=north,font=\scriptsize,align=center] (en_input) at ([yshift=-1em]en_cnn.south){Speech Feature\\(FilterBank/MFCC)};
\node[anchor=north,font=\scriptsize,align=center] (de_input) at ([yshift=-1em]de_add.south){Target Text\\(Embedding)};
\node[anchor=east,font=\scriptsize,align=center] (en_pos) at ([xshift=-2em]en_add.west){Position\\(Embedding)};
\node[anchor=west,font=\scriptsize,align=center] (de_pos) at ([xshift=2em]de_add.east){Position\\(Embedding)};
\draw[->] (en_input.90) -- ([yshift=-0.1em]en_cnn.-90);
\draw[->] ([yshift=0.1em]en_cnn.90) -- ([yshift=-0.1em]en_add.-90);
\draw[->] ([yshift=0.1em]en_add.90) -- ([yshift=-0.1em]en_sa.-90);
\draw[->] ([yshift=0.1em]en_sa.90) -- ([yshift=-0.1em]en_ffn.-90);
\draw[->] (de_input.90) -- ([yshift=-0.1em]de_add.-90);
\draw[->] ([yshift=0.1em]de_add.90) -- ([yshift=-0.1em]de_sa.-90);
\draw[->] ([yshift=0.1em]de_sa.90) -- ([yshift=-0.1em]de_ca.-90);
\draw[->] ([yshift=0.1em]de_ca.90) -- ([yshift=-0.1em]de_ffn.-90);
\draw[->] ([yshift=0.1em]en_ffn.90) -- ([yshift=-0.1em]en_sf.-90);
\draw[->] ([yshift=0.1em]en_sf.90) -- ([yshift=-0.1em]en_output.-90);
\draw[->] ([yshift=0.1em]de_ffn.90) -- ([yshift=-0.1em]sf.-90);
\draw[->] ([yshift=0.1em]sf.90) -- ([yshift=-0.1em]output.-90);
\draw[->] ([xshift=0.1em]en_pos.0) -- ([xshift=-0.1em]en_add.180);
\draw[->] ([xshift=-0.1em]de_pos.180) -- ([xshift=0.1em]de_add.0);
\draw[->,rounded corners=2pt] ([yshift=2em]en_ffn.90) -- ([xshift=4em,yshift=2em]en_ffn.90) -- ([xshift=-1.5em]de_ca.west) -- ([xshift=-0.1em]de_ca.west);
\begin{pgfonlayer}{background}
\node[draw=ugreen,rounded corners=2pt,inner xsep=6pt,inner ysep=8pt,dashed,thick][fit=(en_sa)(en_ffn)]{};
\node[draw=red,rounded corners=2pt,inner xsep=6pt,inner ysep=8pt,dashed,thick][fit=(de_sa)(de_ca)(de_ffn)]{};
\end{pgfonlayer}
\node[anchor=east,font=\scriptsize,text=ugreen] at ([xshift=-0.1em]box1.west){$N \times$};
\node[anchor=west,font=\scriptsize,text=red] at ([xshift=0.1em]box2.east){$\times N$};
\node[anchor=east,font=\scriptsize] at ([xshift=-0.1em]en_cnn.west){$2 \times$};
\node[anchor=east,font=\scriptsize,align=center,text=ugreen] at ([xshift=-0.1em,yshift=3em]box1.west){ST\\Encoder};
\node[anchor=west,font=\scriptsize,align=center,text=red] at ([xshift=0.1em,yshift=5em]box2.east){ST\\Decoder};
\end{tikzpicture}
\ No newline at end of file
\tikzstyle{word} = [rectangle,thick,minimum width=2cm,minimum height=0.7cm,text centered,]
\begin{tikzpicture}[node distance = 0,scale = 0.9]
\tikzstyle{every node}=[scale=0.9]
\node(figure)[draw=white,scale=0.4] {\includegraphics[width=0.62\textwidth]{./Chapter17/Figures/figure-bank-without-attention.png}};
\node(river)[word, right of = figure, xshift=5cm, yshift=0.35cm, fill=blue!45]{river};
\node(mountain)[word, above of = river, yshift=0.75cm, fill=blue!45]{mountain};
\node(child)[word, above of = mountain, yshift=0.75cm, fill=blue!15]{child};
\node(man)[word, above of = child, yshift=0.75cm, fill=blue!25]{man};
\node(jump)[word, below of = river, yshift=-0.75cm, fill=blue!30]{jump};
\node(bank)[word, below of = jump, yshift=-0.75cm, fill=blue!65]{bank};
\node(sky)[word, below of = bank, yshift=-0.75cm, fill=blue!30]{sky};
\node(tree)[word, below of = sky, yshift=-0.75cm, fill=blue!15]{tree};
\node(cir)[circle,thick, minimum width=0.6cm, xshift=8cm, draw=black]{};
\node(decoder)[rectangle, rounded corners, minimum height=2.2em,minimum width=4.3em, right of = cir,xshift=3cm, draw=black, fill=blue!25]{\large{解码器}};
\node(yn_1)[below of = decoder,yshift=-2cm,scale=1.2]{$\rm y_{n-1}$};
\node(yn_2)[above of = decoder,yshift=2cm,scale=1.2]{$\rm y'_{n-1}$(bank)};
\draw[->, thick]([xshift=0.1cm]figure.east)to([xshift=2cm]figure.east);
\draw[-,thick]([xshift=-0.03cm]cir.east)to([xshift=0.03cm]cir.west);
\draw[-,thick]([yshift=0.03cm]cir.south)to([yshift=-0.03cm]cir.north);
\draw[->, thick]([xshift=0.1cm]cir.east)to([xshift=-0.1cm]decoder.west);
\draw[->, thick](yn_1)to([yshift=-0.1cm]decoder.south);
\draw[->, thick]([yshift=0.1cm]decoder.north)to(yn_2);
\draw[->, thick, color=blue!45]([xshift=0.05cm]river.east)to([xshift=-0.05cm]cir.west);
\draw[->, thick, color=blue!45]([xshift=0.05cm]mountain.east)to([xshift=-0.05cm]cir.west);
\draw[->, thick, color=blue!15]([xshift=0.05cm]child.east)to([xshift=-0.05cm]cir.west);
\draw[->, thick, color=blue!25]([xshift=0.05cm]man.east)to([xshift=-0.05cm]cir.west);
\draw[->, thick, color=blue!30]([xshift=0.05cm]jump.east)to([xshift=-0.05cm]cir.west);
\draw[->, very thick, color=blue!65]([xshift=0.05cm]bank.east)to([xshift=-0.05cm]cir.west);
\draw[->, thick, color=blue!30]([xshift=0.05cm]sky.east)to([xshift=-0.05cm]cir.west);
\draw[->, thick, color=blue!15]([xshift=0.05cm]tree.east)to([xshift=-0.05cm]cir.west);
\end{tikzpicture}
\ No newline at end of file
\tikzstyle{coder} = [rectangle,thick,rounded corners,minimum width=2.3cm,minimum height=1cm,text centered,draw=black!70,fill=red!20]
\tikzstyle{coder} = [rectangle,thick,rounded corners,minimum height=2.2em,minimum width=4.3em,text centered,draw=black!70,fill=red!20]
\begin{tikzpicture}[node distance = 0,scale = 0.75]
\tikzstyle{every node}=[scale=0.75]
......@@ -15,9 +15,11 @@
\draw[->,thick](decoder_2.north)to(y.south);
\draw[->,thick](encoder.north)--([yshift=0.7cm]encoder.north)--([xshift=-4.16em,yshift=0.7cm]encoder.north)--(decoder_1.south);
\draw[->,thick](encoder.north)--([yshift=0.7cm]encoder.north)--([xshift=4.16em,yshift=0.7cm]encoder.north)--(decoder_2.south);
\node [anchor=north](pos1) at (s.south) {(a) 单编码器-双解码器方式};
\node [anchor=north,scale = 1.2](pos1) at (s.south) {(a) 单编码器-双解码器方式};
\node [anchor=south,scale=1.2] (node1) at ([xshift=-2.0em,yshift=6em]decoder_1.north) {{$x,y$:语言数据}};
\node [anchor=north,scale=1.2] (node2) at ([xshift=0.6em]node1.south){{$s$:语音数据}};
%%%%%%%%%%%%%%%%%%%%%%%%级联
\node(encoder-2)[coder]at ([xshift=10.0em]encoder.east){\large{编码器}};
\node(encoder-2)[coder]at ([xshift=12.0em]encoder.east){\large{编码器}};
\node(decoder_1-2)[coder,above of =encoder-2,yshift=1.4cm,fill=blue!20]{\large{解码器}};
\node(decoder_2-2)[coder,above of =decoder_1-2, yshift=1.4cm,fill=yellow!20]{\large{解码器}};
\node(s-2)[below of = encoder-2,yshift=-1.8cm,scale=1.6]{$s$};
......@@ -27,7 +29,7 @@
\draw[->,thick](encoder-2.north)to(decoder_1-2.south);
\draw[->,thick](decoder_1-2.north)to(decoder_2-2.south);
\draw[->,thick](decoder_2-2.north)to(y-2.south);
\node [anchor=north](pos2) at (s-2.south) {(b) 级联编码器方式};
\node [anchor=north,scale = 1.2](pos2) at (s-2.south) {(b) 级联编码器方式};
%%%%%%%%%%%%%%%%%%%%%%%%联合
\node(encoder-3)[coder]at([xshift=10.0em]encoder-2.east){\large{编码器}};
\node(decoder_1-3)[coder,above of =encoder-3,xshift=-1.6cm,yshift=2.8cm,fill=blue!20]{\large{解码器}};
......@@ -40,5 +42,5 @@
\draw[->,thick](decoder_2-3.north)to(y-3.south);
\draw[->,thick](encoder-3.north)--([yshift=0.7cm]encoder-3.north)--([xshift=-4.16em,yshift=0.7cm]encoder-3.north)--(decoder_1-3.south);
\draw[->,thick](encoder-3.north)--([yshift=0.7cm]encoder-3.north)--([xshift=4.16em,yshift=0.7cm]encoder-3.north)--(decoder_2-3.south);
\node [anchor=north](pos3) at (s-3.south) {(c) 联合编码器方式};
\node [anchor=north,scale = 1.2](pos3) at (s-3.south) {(c) 联合编码器方式};
\end{tikzpicture}
\ No newline at end of file
\definecolor{color_gray}{rgb}{0.278,0.337,0.426}
\definecolor{color_green}{rgb}{0.663,0.82,0.557}
\definecolor{color_orange}{rgb}{0.957,0.694,0.514}
\definecolor{color_blue}{rgb}{0.335,0.708,0.735}
\tikzstyle{description} = [rectangle,rounded corners=1mm, minimum width=3cm,minimum height=0.6cm,text centered]
\begin{tikzpicture}[node distance = 0,scale = 0.8]
\tikzstyle{every node}=[scale=0.8]
\node(figure-1)[draw=white,scale=0.25] at (0,0){\includegraphics[width=0.62\textwidth]{./Chapter17/Figures/figure-dog-with-hat.png}};
\node(ground-1)[rectangle,rounded corners, minimum width=5cm, minimum height=3.5cm,right of = figure-1, xshift=5cm,fill=blue!20]{};
\node(text-1)[right of = figure-1, xshift=3.6cm,yshift=2cm,scale=1.2]{\textcolor{color_gray}{描述候选池}};
\node(text_1-1)[description, right of = figure-1, xshift=4.2cm,yshift=1.2cm,fill=color_gray!50]{\textcolor{white}{天空中有很多鸟。}};
\node(text_2-1)[description, right of = figure-1, xshift=5.3cm,yshift=0.5cm,fill=color_green]{\textcolor{white}{孩子从河岸上跳下来。}};
\node(text_3-1)[description, right of = figure-1, xshift=4.5cm,yshift=-0.2cm,fill=color_orange]{\textcolor{white}{狗在吐舌头。}};
\node(surd-1)[right of = text_3-1, xshift=2cm,scale=1.5]{\textcolor{red}{$\surd$}};
\node(text_4-1)[description, right of = figure-1, xshift=5.2cm,yshift=-0.9cm,fill=color_blue]{\textcolor{white}{男人戴着眼镜。}};
\node(point-1)[right of = figure-1, xshift=5cm,yshift=-1.4cm,scale=1.5]{...};
\draw[->,thick](figure-1)to([xshift=-0.1cm]ground-1.west);
\node(figure)[draw=white,scale=0.25]at ([xshift=20.0em]figure-1.east){\includegraphics[width=0.62\textwidth]{./Chapter17/Figures/figure-dog-with-hat.png}};
\node(ground)[rectangle,rounded corners, minimum width=5cm, minimum height=1.5cm,right of = figure, xshift=5cm,yshift=-2.6em,fill=blue!20]{\large{图片中有\underline{\textcolor{red}{}}\underline{\textcolor{red}{帽子}}\underline{\quad\ }}};
\node(dog)[rectangle,rounded corners, minimum width=1cm, minimum height=0.7cm,right of = figure, xshift=3cm,yshift=1.5cm,thick, draw=color_orange,fill=color_orange!50]{};
\node(hat)[rectangle,rounded corners, minimum width=1.5cm, minimum height=0.7cm,right of = figure, xshift=4.5cm,yshift=1.5cm,thick, draw=color_green,fill=color_green!50]{帽子};
\draw[->, thick,color=black!60](figure.east)to([xshift=-0.1cm]dog.west)node[left,xshift=-0.2cm,yshift=-0.1cm,color=black]{图片检测};
\draw[->, thick,color=black!60]([yshift=-0.1cm]hat.south)to([yshift=0.1cm]ground.north)node[right,xshift=-0.2cm,yshift=0.5cm,color=black]{模板填充};
\node [anchor=north](pos1)at ([xshift=-3.8em,yshift=-0.5em]ground-1.south){(a)基于检索的图像描述生成范式};
\node [anchor=north](pos2)at ([xshift=-3.8em,yshift=-0.5em]ground.south){(b)基于模板的图像描述生成范式};
\end{tikzpicture}
\ No newline at end of file
\begin{tikzpicture}
\tikzstyle{node}=[circle,minimum size=1.2em,draw,inner sep=0pt,fill=yellow!20,font=\footnotesize,thick]
\tikzstyle{word}=[font=\scriptsize]
\node[node] (n0) at (0,0) {0};
\node[anchor=west,node] (n2) at ([xshift=3em]n0.east){2};
\node[anchor=west,node] (n6) at ([xshift=13em]n2.east){6};
\node[anchor=west,node] (n8) at ([xshift=2.4em]n6.east){8};
\node[anchor=west,node] (n9) at ([xshift=2.4em]n8.east){9};
\node[anchor=south,node] (n1) at ([xshift=0.6em,yshift=3.2em]n2.north){1};
\node[anchor=north,node] (n3) at ([xshift=2.2em,yshift=-1.6em]n2.south){3};
\node[anchor=north,node] (n7) at ([xshift=5.2em,yshift=-0.8em]n2.south){7};
\node[anchor=west,node] (n10) at ([xshift=4em]n7.east){10};
\node[anchor=south,node] (n11) at ([yshift=3.0em]n7.north){11};
\node[anchor=south,node] (n5) at ([yshift=3.0em]n10.north){5};
\node[anchor=north,node] (n4) at ([xshift=6em,yshift=-1.6em]n3.south){4};
\draw[->] (n0.0) -- node[word,above]{of /0.343}(n2.180);
\draw[->] (n0.60) -- node[word,above,rotate=40]{a /0.499}(n1.-150);
\draw[->] (n0.-50) -- node[word,above,rotate=-20]{their /0.116}(n3.150);
\draw[->] (n0.-70) .. controls ([xshift=-8em]n4.180) and ([xshift=-8em]n4.180) .. node[above,word,xshift=3em,yshift=-0.6em]{that /0.042} (n4.180);
\draw[->] (n4.0) .. node[word,above,xshift=-2em,yshift=-0.4em]{hospital /1} controls ([xshift=5em]n4.0) and ([yshift=-6em]n6.-90) .. (n6.-90);
\draw[->] (n2.-90) -- node[word,above,rotate=-18,pos=0.55]{house /0.127}(n7.180);
\draw[->] (n3.-10) node[word,above,xshift=3.6em,yshift=-0.8em]{conference /1} .. controls ([xshift=4.6em,yshift=-1.8em]n3.-10) and ([yshift=-1.6em,xshift=-3em]n10.-135) .. (n10.-135);
\draw[->] (n7.0) -- node[word,above]{which /1}(n10.180);
\draw[->] (n2.0) -- node[word,above,pos=0.5]{hospital /0.300}(n6.180);
\draw[->] (n2.45) -- node[word,above,rotate=18,pos=0.3]{a /0.573}(n11.-135);
\draw[->,rounded corners=1em] (n1.-45) node[word,above,xshift=1.4em,yshift=-1.3em,rotate=-43]{house /0.079} -- ([yshift=-0.4em,xshift=-1em]n11.-90) -- (n7.100);
\draw[->] (n1.20) node[word,above,xshift=4em]{conference /0.734} .. controls ([xshift=8em]n1.20) and ([xshift=-0.6em,yshift=2.2em]n5.110) .. (n5.110);
\draw[->] (n11.0) -- node[word,above]{conference /1}(n5.180);
\draw[->] (n5.-90) ..node[word,above,xshift=1.4em]{is /0.773} controls ([yshift=-1.6em]n5.-90) and ([xshift=-3em]n6.150]) .. (n6.150);
\draw[->] (n5.0) node[word, above,xshift=1.4em]{as /0.227}.. controls ([xshift=2.6em]n5.0) and ([xshift=-0.6em,yshift=2em]n6.120) .. (n6.120);
\coordinate (a) at ([xshift=6em,yshift=3em]n1);
\draw[->] (n1.60) .. controls ([xshift=3em,yshift=2em]n1.60) and ([xshift=-2em]a) .. (a) node[word,above,xshift=1em]{hospital /0.187}.. controls ([xshift=8em]a) and ([xshift=-0.6em,yshift=6em]n6.90) .. (n6.90);
\draw[->] (n10.0) -- node[above,word,pos=0.4,rotate=30]{is /1}(n6.-135);
\draw[->] (n6.0) -- node[above,word,yshift=0.2em]{being /1}(n8.180);
\draw[->] (n8.0) -- node[above,word,yshift=0.3em]{recorded /1}(n9.180);
\end{tikzpicture}
\ No newline at end of file
......@@ -35,11 +35,17 @@
\parinterval 长期以来,机器翻译的任务都是指句子级翻译。主要原因在于,句子级的翻译建模可以大大简化问题,使得机器翻译方法更容易进行实践和验证。但是人类使用语言的过程并不是孤立在一个个句子上进行的。这个问题可以类比于我们学习语言的过程:小孩成长过程中会接受视觉、听觉、触觉等多种信号,这些信号的共同作用使得他们产生对客观世界的“认识”,同时促使其使用“语言”进行表达。从这个角度说,语言能力并不是由单一因素形成的,它往往伴随着其他信息的相互作用,比如,当我们翻译一句话的时候,会用到看到的画面、听到的语调、甚至前面说过句子中的信息。
\parinterval 从广义上讲,当前句子以外的信息都可以被看作是一种上下文。比如,图XXX中,需要把英语句子“XXX”翻译为汉语。但是,其中的“bank”有多个含义,因此仅仅使用英语句子本身的信息可能会将其翻译为“银行”,而非正确的译文“河床”。但是,图XXX中也提供了这个英语句子所对应的图片,显然图片中直接展示了河床,这时“bank”是没有歧义的。通常也会把这种使用图片和文字一起进行机器翻译的任务称作多模态机器翻译(参考文献)
\parinterval 从广义上讲,当前句子以外的信息都可以被看作是一种上下文。比如,图\ref{fig:17-1}中,需要把英语句子“A medium sized child jumps off a dusty bank”翻译为汉语。但是,其中的“bank”有多个含义,因此仅仅使用英语句子本身的信息可能会将其翻译为“银行”,而非正确的译文“河床”。但是,图\ref{fig:17-1}中也提供了这个英语句子所对应的图片,显然图片中直接展示了河床,这时“bank”是没有歧义的。通常也会把这种使用图片和文字一起进行机器翻译的任务称作{\small\bfnew{多模态机器翻译}}\index{多模态机器翻译}(Multi-Modal Machine Translation)\index{Multi-Modal Machine Translation}
\parinterval 图图
\parinterval 所谓模态(Modality)是指某一种信息来源。例如,视觉、听觉、嗅觉、味觉都可以被看作是不同的模态。因此视频、语音、文字等都可以被看作是承载这些模态的媒介。在机器翻译中使用多模态这个概念,更多是为了区分某些不同于文字的信息。除了图像等视觉模态信息,机器翻译也可以利用语音模态信息。比如,直接对语音进行翻译,甚至直接用语音表达出翻译结果。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-picture-translation}
\caption{多模态机器翻译实例}
\label{fig:17-1}
\end{figure}
%-------------------------------------------
\parinterval {\small\bfnew{模态}}\index{模态}(Modality)\index{Modality}是指某一种信息来源。例如,视觉、听觉、嗅觉、味觉都可以被看作是不同的模态。因此视频、语音、文字等都可以被看作是承载这些模态的媒介。在机器翻译中使用多模态这个概念,更多是为了区分某些不同于文字的信息。除了图像等视觉模态信息,机器翻译也可以利用语音模态信息。比如,直接对语音进行翻译,甚至直接用语音表达出翻译结果。
\parinterval 此外,除了不同信息源所引入的上下文,机器翻译也可以利用文字本身的上下文。比如,翻译一篇文章中的某个句子时,可以根据整个篇章的内容进行翻译。显然这种篇章的语境是有助于机器翻译的。在本章后面的内容中,会就机器翻译中使用不同上下文(多模态和篇章信息)的方法展开讨论。
......@@ -56,30 +62,30 @@
\subsection{音频处理}
\parinterval 不同于文本,音频本质上是经过若干信号处理之后的{\small\bfnew{波形}}(Waveform)\index{Waveform}。具体来说,声音是一种空气的震动,因此可以被转换为模拟信号。模拟信号是一段连续的信号,经过采样变为离散数字信号。采样是每隔固定的时间记录一下声音的振幅,采样率表示每秒的采样点数,单位是赫兹(Hz)。采样率越高,结果的损失则越小。通常来说,采样的标准是能够通过离散化的数字信号重现原始语音。我们日常生活中使用的手机和电脑设备的采样率一般为16kHz,表示每秒16000个采样点;而音频CD的采样率可以达到44.1kHz。经过进一步的量化,将采样点的值转换为整型数值保存,从而减少占用的存储空间,通常采用的是16位量化。将采样率和量化位数相乘,就可以得到{\small\bfnew{比特率}}\index{比特率}(Bits Per Second,BPS)\index{Bits Per Second},表示音频每秒占用的位数。16kHz采样率和16位量化的音频,比特率为256kb/s。整体流程如图\ref{fig:17-1}所示\upcite{洪青阳2020语音识别原理与应用,陈果果2020语音识别实战}
\parinterval 不同于文本,音频本质上是经过若干信号处理之后的{\small\bfnew{波形}}(Waveform)\index{Waveform}。具体来说,声音是一种空气的震动,因此可以被转换为模拟信号。模拟信号是一段连续的信号,经过采样变为离散数字信号。采样是每隔固定的时间记录一下声音的振幅,采样率表示每秒的采样点数,单位是赫兹(Hz)。采样率越高,结果的损失则越小。通常来说,采样的标准是能够通过离散化的数字信号重现原始语音。我们日常生活中使用的手机和电脑设备的采样率一般为16kHz,表示每秒16000个采样点;而音频CD的采样率可以达到44.1kHz。经过进一步的量化,将采样点的值转换为整型数值保存,从而减少占用的存储空间,通常采用的是16位量化。将采样率和量化位数相乘,就可以得到{\small\bfnew{比特率}}\index{比特率}(Bits Per Second,BPS)\index{Bits Per Second},表示音频每秒占用的位数。16kHz采样率和16位量化的音频,比特率为256kb/s。整体流程如图\ref{fig:17-2}所示\upcite{洪青阳2020语音识别原理与应用,陈果果2020语音识别实战}
%----------------------------------------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-audio-processing}
\caption{音频处理过程}
\label{fig:17-1}
\label{fig:17-2}
\end{figure}
%----------------------------------------------------------------------------------------------------
\parinterval 经过上面的描述,音频的表示实际上是一个非常长的采样点序列,这导致了直接使用现有的深度学习技术处理音频序列较为困难。并且,原始的音频信号中可能包含着较多的噪声、环境声或冗余信息也会对模型产生干扰。因此,一般会对音频序列进行处理来提取声学特征,具体为将长序列的采样点序列转换为短序列的特征向量序列,再用于下游系统模块。虽然已有一些工作不依赖特征提取,直接在原始的采样点序列上进行声学建模和模型训练\upcite{DBLP:conf/interspeech/SainathWSWV15},但目前的主流方法仍然是基于声学特征进行建模\upcite{DBLP:conf/icassp/MohamedHP12}
\parinterval 声学特征提取的第一步是预处理。其流程主要是对音频进行预加重、分帧和加窗。预加重用来提升音频信号中的高频部分,目的是使频谱更加平滑。分帧是基于短时平稳假设,即根据生物学特征,语音信号是一个缓慢变化的过程,10ms~30ms的信号片段是相对平稳的。基于这个假设,一般将每25ms作为一帧来提取特征,这个时间称为{\small\bfnew{帧长}}\index{帧长}(Frame Length)\index{Frame Length}。同时,为了保证不同帧之间的信号平滑性,使每两个相邻帧之间存在一定的重合部分。一般每隔10ms取一帧,这个时长称为{\small\bfnew{帧移}}\index{帧移}(Frame Shift)\index{Frame Shift}。为了缓解分帧带来的频谱泄漏,对每帧的信号进行加窗处理使其幅度在两段渐变到0,一般采用的是{\small\bfnew{汉明窗}}\index{汉明窗}(Hamming)\index{Hamming}
\parinterval 声学特征提取的第一步是预处理。其流程主要是对音频进行预加重、分帧和加窗。预加重用来提升音频信号中的高频部分,目的是使频谱更加平滑。分帧(原理如图\ref{fig:17-3}是基于短时平稳假设,即根据生物学特征,语音信号是一个缓慢变化的过程,10ms~30ms的信号片段是相对平稳的。基于这个假设,一般将每25ms作为一帧来提取特征,这个时间称为{\small\bfnew{帧长}}\index{帧长}(Frame Length)\index{Frame Length}。同时,为了保证不同帧之间的信号平滑性,使每两个相邻帧之间存在一定的重合部分。一般每隔10ms取一帧,这个时长称为{\small\bfnew{帧移}}\index{帧移}(Frame Shift)\index{Frame Shift}。为了缓解分帧带来的频谱泄漏,对每帧的信号进行加窗处理使其幅度在两段渐变到0,一般采用的是{\small\bfnew{汉明窗}}\index{汉明窗}(Hamming)\index{Hamming}
%----------------------------------------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-framing-schematic}
\caption{分帧原理图}
\label{fig:17-2}
\label{fig:17-3}
\end{figure}
%----------------------------------------------------------------------------------------------------
\parinterval 经过了上述的预处理操作,可以得到音频对应的帧序列,之后通过不同的操作来提取不同类型的声学特征。常用的声学特征包括{\small\bfnew{Mel频率倒谱系数}}\index{Mel频率倒谱系数}(Mel-Frequency Cepstral Coefficient, MFCC)\index{Mel-Frequency Cepstral Coefficient}{\small\bfnew{感知线性预测系数}}\index{感知线性预测系数}(Perceptual Lienar Predictive, PLP)\index{Perceptual Lienar Predictive}{\small\bfnew{滤波器组}}\index{滤波器组}(Filter-bank, Fbank)\index{Filter-bank}等。MFCC、PLP和Fbank特征都需要对预处理后的音频做{\small\bfnew{短时傅里叶变换}}\index{短时傅里叶变换}(Short-time Fourier Tranform, STFT)\index{Short-time Fourier Tranform},得到具有规律的线性分辨率。之后再经过特定的操作,得到各种声学特征。不同声学特征的特点是不同的,MFCC去相关性较好,PLP抗噪性强,FBank可以保留更多的语音原始特征。在语音翻译中,比较常用的声学特征为FBank或MFCC\upcite{洪青阳2020语音识别原理与应用}
\parinterval 经过了上述的预处理操作,可以得到音频对应的帧序列,之后通过不同的操作来提取不同类型的声学特征。常用的声学特征包括{\small\bfnew{Mel频率倒谱系数}}\index{Mel频率倒谱系数}(Mel-Frequency Cepstral Coefficient,MFCC)\index{Mel-Frequency Cepstral Coefficient}{\small\bfnew{感知线性预测系数}}\index{感知线性预测系数}(Perceptual Lienar Predictive,PLP)\index{Perceptual Lienar Predictive}{\small\bfnew{滤波器组}}\index{滤波器组}(Filter-bank,Fbank)\index{Filter-bank}等。MFCC、PLP和Fbank特征都需要对预处理后的音频做{\small\bfnew{短时傅里叶变换}}\index{短时傅里叶变换}(Short-time Fourier Tranform,STFT)\index{Short-time Fourier Tranform},得到具有规律的线性分辨率。之后再经过特定的操作,得到各种声学特征。不同声学特征的特点是不同的,MFCC去相关性较好,PLP抗噪性强,FBank可以保留更多的语音原始特征。在语音翻译中,比较常用的声学特征为FBank或MFCC\upcite{洪青阳2020语音识别原理与应用}
\parinterval 某种程度上讲,提取到的声学特征可以理解计算机视觉中的像素特征,或者自然语言处理中的词嵌入表示。不同之处在于,声学特征更加复杂多变,可能存在着较多的噪声和冗余信息。此外,相比对应的文字序列,音频提取到的特征序列长度要大十倍以上。比如,人类正常交流中每秒钟一般可以说2-3个字,而每秒钟的语音可以提取得到100帧的特征序列。巨大的长度比差异也为语音翻译中对声学特征建模带来了困难。
......@@ -89,14 +95,14 @@
\subsection{级联式语音翻译}
\parinterval 实现语音翻译最简单的思路是基于级联的方式,即:先通过{\small\bfnew{自动语音识别}}\index{自动语音识别}(Automatic Speech Recognition,ASR)\index{Automatic Speech Recognition}系统将语音识别为源语言文本,然后利用机器翻译系统将源语言文本翻译为目标语言文本。这种做法的好处在于语音识别和机器翻译模型可以分别进行训练,有很多数据资源以及成熟技术可以分别运用到两个系统中。因此,级联语音翻译是很长时间以来的主流方法,深受工业界的青睐。级联语音翻译主要的流程如图\ref{fig:17-3}所示。
\parinterval 实现语音翻译最简单的思路是基于级联的方式,即:先通过{\small\bfnew{自动语音识别}}\index{自动语音识别}(Automatic Speech Recognition,ASR)\index{Automatic Speech Recognition}系统将语音识别为源语言文本,然后利用机器翻译系统将源语言文本翻译为目标语言文本。这种做法的好处在于语音识别和机器翻译模型可以分别进行训练,有很多数据资源以及成熟技术可以分别运用到两个系统中。因此,级联语音翻译是很长时间以来的主流方法,深受工业界的青睐。级联语音翻译主要的流程如图\ref{fig:17-4}所示。
%----------------------------------------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-cascading-speech-translation}
\caption{级联语音翻译}
\label{fig:17-3}
\label{fig:17-4}
\end{figure}
%----------------------------------------------------------------------------------------------------
......@@ -104,23 +110,25 @@
\parinterval 传统的语音识别模型和统计机器翻译相似,需要利用声学模型、语言模型和发音词典联合进行识别,系统较为复杂\upcite{DBLP:journals/ftsig/GalesY07,DBLP:journals/taslp/MohamedDH12,DBLP:journals/spm/X12a}。而近些年来,随着神经网络的发展,基于神经网络的端到端语音识别模型逐渐成为主流,大大简化了训练流程\upcite{DBLP:conf/nips/ChorowskiBSCB15,DBLP:conf/icassp/ChanJLV16}。目前的端到端语音识别模型主要基于序列到序列结构,编码器根据输入的声学特征进一步提取高级特征,解码器根据编码器提取的特征识别对应的文本。在后文中即将介绍的端到端语音翻译模型也是使用十分相似的结构。因此,从某种意义上说,语音识别和翻译的端到端方法与神经机器翻译是一致的。
\parinterval 语音识别目前广泛使用基于Transformer的模型结构(见{\chaptertwelve}),如图\ref{fig:17-2-3}所示。可以看出,相比文本翻译,模型结构上唯一的区别在于编码器的输入为声学特征,以及编码器底层会使用额外的卷积层来减小输入序列的长度,从而降低长序列带来的显存占用以及建模困难。通过大量的语音-标注平行数据对模型进行训练,可以得到高质量的语音识别模型。
\parinterval 语音识别目前广泛使用基于Transformer的模型结构(见{\chaptertwelve}),如图\ref{fig:17-5}所示。可以看出,相比文本翻译,模型结构上唯一的区别在于编码器的输入为声学特征,以及编码器底层会使用额外的卷积层来减小输入序列的长度,从而降低长序列带来的显存占用以及建模困难。通过大量的语音-标注平行数据对模型进行训练,可以得到高质量的语音识别模型。
%----------------------------------------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-speech-recognition-model-based-on-transformer}
\caption{基于Transformer的语音识别模型}
\label{fig:17-2-3}
\label{fig:17-5}
\end{figure}
%----------------------------------------------------------------------------------------------------
\parinterval 级联语音翻译模型利用翻译模型将语音识别结果翻译为目标语言文本,但存在的一个问题是语音识别模型只输出One-best,其中可能存在一些识别错误,这些错误在翻译过程中会被放大,导致最终翻译结果偏离原本意思,也就是错误传播问题。传统级联语音模型的一个主要方向是丰富语音识别模型的预测结果,为翻译模型提供更多的信息,具体做法是在语音识别模型中,声学模型解码得到{\small\bfnew{词格}}\index{词格}(Word Lattice)\index{Word Lattice}来取代One-best识别结果。词格是一种有向无环图,包含单个起点和终点,图中的每条边记录了每个词和对应的转移概率信息,如图\ref{fig:17-2-4}所示。
\parinterval 级联语音翻译模型利用翻译模型将语音识别结果翻译为目标语言文本,但存在的一个问题是语音识别模型只输出One-best,其中可能存在一些识别错误,这些错误在翻译过程中会被放大,导致最终翻译结果偏离原本意思,也就是错误传播问题。传统级联语音模型的一个主要方向是丰富语音识别模型的预测结果,为翻译模型提供更多的信息,具体做法是在语音识别模型中,声学模型解码得到{\small\bfnew{词格}}\index{词格}(Word Lattice)\index{Word Lattice}来取代One-best识别结果。词格是一种有向无环图,包含单个起点和终点,图中的每条边记录了每个词和对应的转移概率信息,如图\ref{fig:17-6}所示。
%----------------------------------------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-word-lattice.tex}
\caption{词格示例}
\label{fig:17-2-4}
\label{fig:17-6}
\end{figure}
%----------------------------------------------------------------------------------------------------
......@@ -162,13 +170,14 @@
\end{itemize}
%----------------------------------------------------------------------------------------------------
\parinterval 因此,端到端模型收到了研究人员的关注。目前比较火热的,基于Transformer的语音翻译模型架构如图\ref{fig:17-2-5}所示(下文中语音翻译模型均指端到端的模型)。该模型采用的也是序列到序列架构,编码器的输入是从语音中提取的特征(比如FBank特征)。由于语音对应的特征序列过长,在计算Attention的时候,会占用大量的内存/显存,从而降低计算效率,过长的序列也会增加模型训练的难度。因此,通常会先对语音特征做一个下采样,缩小语音的序列长度。目前一个常用的做法,是在输入的语音特征上进行两层步长为2的卷积操作,从而将输入序列的长度缩小为之前的1/4。之后的流程和标准的机器翻译是完全一致的,编码器对语音特征进行编码,解码器根据编码表示生成目标语言的翻译结果。
\parinterval 因此,端到端模型收到了研究人员的关注。目前比较火热的,基于Transformer的语音翻译模型架构如图\ref{fig:17-7}所示(下文中语音翻译模型均指端到端的模型)。该模型采用的也是序列到序列架构,编码器的输入是从语音中提取的特征(比如FBank特征)。由于语音对应的特征序列过长,在计算Attention的时候,会占用大量的内存/显存,从而降低计算效率,过长的序列也会增加模型训练的难度。因此,通常会先对语音特征做一个下采样,缩小语音的序列长度。目前一个常用的做法,是在输入的语音特征上进行两层步长为2的卷积操作,从而将输入序列的长度缩小为之前的1/4。之后的流程和标准的机器翻译是完全一致的,编码器对语音特征进行编码,解码器根据编码表示生成目标语言的翻译结果。
%----------------------------------------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-an-end-to-end-voice-translation-model-based-on-transformer}
\caption{基于Transformer的端到端语音翻译模型}
\label{fig:17-2-5}
\label{fig:17-7}
\end{figure}
%----------------------------------------------------------------------------------------------------
......@@ -189,13 +198,14 @@
%----------------------------------------------------------------------------------------------------
\noindent{\small\bfnew{1)多任务学习}}
\parinterval 针对语音翻译模型建模复杂度较高问题,常用的一个方法是进行多任务学习,使模型在训练过程中有更多的监督信息,从而使模型收敛地更加充分。语音语言中多任务学习主要借助语音对应的标注信息,也就是源语言文本。{\small\bfnew{连接时序分类}}\index{连接时序分类}(Connectionist Temporal Classification,CTC)\index{Connectionist Temporal Classification}\upcite{DBLP:conf/icml/GravesFGS06}是语音处理中最简单有效的一种多任务学习方法\upcite{DBLP:journals/jstsp/WatanabeHKHH17,DBLP:conf/icassp/KimHW17},也被广泛应用于文本识别任务中\upcite{DBLP:journals/pami/ShiBY17}。CTC可以将输入序列的每一位置都对应到标注文本中,学习语音和文字之间的软对齐关系。比如,对于下面的音频序列,CTC可以将每个位置分别对应到同一个词。需要注意的是,CTC会额外新增一个词$\epsilon$,类似于一个空白词,表示这个位置没有声音或者没有任何对应的预测结果。然后,将相同且连续的词合并,去除$\epsilon$,就可以得到预测结果,如图\ref{fig:17-2-6}所示。
\parinterval 针对语音翻译模型建模复杂度较高问题,常用的一个方法是进行多任务学习,使模型在训练过程中有更多的监督信息,从而使模型收敛地更加充分。语音语言中多任务学习主要借助语音对应的标注信息,也就是源语言文本。{\small\bfnew{连接时序分类}}\index{连接时序分类}(Connectionist Temporal Classification,CTC)\index{Connectionist Temporal Classification}\upcite{DBLP:conf/icml/GravesFGS06}是语音处理中最简单有效的一种多任务学习方法\upcite{DBLP:journals/jstsp/WatanabeHKHH17,DBLP:conf/icassp/KimHW17},也被广泛应用于文本识别任务中\upcite{DBLP:journals/pami/ShiBY17}。CTC可以将输入序列的每一位置都对应到标注文本中,学习语音和文字之间的软对齐关系。比如,对于下面的音频序列,CTC可以将每个位置分别对应到同一个词。需要注意的是,CTC会额外新增一个词$\epsilon$,类似于一个空白词,表示这个位置没有声音或者没有任何对应的预测结果。然后,将相同且连续的词合并,去除$\epsilon$,就可以得到预测结果,如图\ref{fig:17-8}所示。
%----------------------------------------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-examples-of-CTC-predictive-word-sequences}
\caption{CTC预测单词序列示例}
\label{fig:17-2-6}
\label{fig:17-8}
\end{figure}
%----------------------------------------------------------------------------------------------------
......@@ -211,23 +221,24 @@
\end{itemize}
%----------------------------------------------------------------------------------------------------
\parinterval 将CTC应用到语音翻译中的方法非常简单,只需要在编码器的顶层加上一个额外的输出层即可。通过这种方式,不需要增加过多的额外参数,就可以给模型加入一个较强的监督信息,提高模型的收敛性。
\parinterval 将CTC应用到语音翻译中的方法非常简单,只需要在编码器的顶层加上一个额外的输出层即可(图\ref{fig:17-9}。通过这种方式,不需要增加过多的额外参数,就可以给模型加入一个较强的监督信息,提高模型的收敛性。
%----------------------------------------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-speech-translation-model-based-on-CTC}
\caption{基于CTC的语音翻译模型}
\label{fig:17-2-7}
\label{fig:17-9}
\end{figure}
%----------------------------------------------------------------------------------------------------
\parinterval 另外一种多任务学习的思想是通过两个解码器,分别预测语音对应的源语言句子和目标语言句子,具体有图\ref{fig:17-9}展示的三种方式\upcite{DBLP:conf/naacl/AnastasopoulosC18,DBLP:conf/asru/BaharBN19}。图\ref{fig:17-9}(a)中采用单编码器-双解码器的方式,两个解码器根据编码器的表示,分别预测源语言句子和目标语言句子,从而使编码器训练地更加充分。这种做法的好处在于仅仅增加了训练代价,解码时只需要生成目标语言句子即可。图\ref{fig:17-9}(b)则通过使用两个级联的解码器,先利用第一个解码器生成源语言句子,然后再利用第一个解码器的表示,通过第二个解码器生成目标语言句子。这种方法通过增加一个中间输出,降低了模型的训练难度,但同时也会带来额外的解码耗时,因为两个解码器需要串行地进行生成。图\ref{fig:17-9}(c)中模型更进一步,第二个编码器联合编码器和第一个解码器的表示进行生成,更充分地利用了已有信息。
\parinterval 另外一种多任务学习的思想是通过两个解码器,分别预测语音对应的源语言句子和目标语言句子,具体有图\ref{fig:17-10}展示的三种方式\upcite{DBLP:conf/naacl/AnastasopoulosC18,DBLP:conf/asru/BaharBN19}。图\ref{fig:17-10}(a)中采用单编码器-双解码器的方式,两个解码器根据编码器的表示,分别预测源语言句子和目标语言句子,从而使编码器训练地更加充分。这种做法的好处在于仅仅增加了训练代价,解码时只需要生成目标语言句子即可。图\ref{fig:17-10}(b)则通过使用两个级联的解码器,先利用第一个解码器生成源语言句子,然后再利用第一个解码器的表示,通过第二个解码器生成目标语言句子。这种方法通过增加一个中间输出,降低了模型的训练难度,但同时也会带来额外的解码耗时,因为两个解码器需要串行地进行生成。图\ref{fig:17-10}(c)中模型更进一步,第二个编码器联合编码器和第一个解码器的表示进行生成,更充分地利用了已有信息。
%----------------------------------------------------------------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-three-ways-of-dual-decoder-speech-translation}
\caption{双解码器语音翻译的三种方式}
\label{fig:17-9}
\label{fig:17-10}
\end{figure}
%----------------------------------------------------------------------------------------------------
......@@ -241,7 +252,7 @@
%----------------------------------------------------------------------------------------------------
\parinterval 此外,研究人员还探索了很多其他方法来提高语音翻译模型的性能。利用在海量的无标注语音数据上预训练的{\small\bfnew{自监督}}\index{自监督}(Self-supervised)\index{Self-supervised}模型作为一个特征提取器,将从语音中提取的特征作为语音翻译模型的输入,可以有效提高模型的性能\upcite{DBLP:conf/interspeech/WuWPG20}。相比语音翻译模型,文本翻译模型任务更加简单,因此一种思想是利用文本翻译模型来指导语音翻译模型,比如通过知识蒸馏\upcite{DBLP:conf/interspeech/LiuXZHWWZ19}、正则化\upcite{DBLP:conf/emnlp/AlinejadS20}等方法。为了简化语音翻译模型的学习,可以通过课程学习的策略,使模型从语音识别任务,逐渐过渡到语音翻译任务,这种由易到难的训练策略可以使模型训练更加充分\upcite{DBLP:journals/corr/abs-1802-06003,DBLP:conf/acl/WangWLZY20}
\parinterval 此外,研究人员还探索了很多其他方法来提高语音翻译模型的性能。利用在海量的无标注语音数据上预训练的{\small\bfnew{自监督}}\index{自监督}(Self-supervised)\index{Self-supervised}模型作为一个特征提取器,将从语音中提取的特征作为语音翻译模型的输入,可以有效提高模型的性能\upcite{DBLP:conf/interspeech/WuWPG20}。相比语音翻译模型,文本翻译模型任务更加简单,因此一种思想是利用文本翻译模型来指导语音翻译模型,比如通过知识蒸馏\upcite{DBLP:conf/interspeech/LiuXZHWWZ19}、正则化\upcite{DBLP:conf/emnlp/AlinejadS20}等方法。为了简化语音翻译模型的学习,可以通过课程学习的策略,使模型从语音识别任务,逐渐过渡到语音翻译任务,这种由易到难的训练策略可以使模型训练更加充分\upcite{DBLP:journals/corr/abs-1802-06003,DBLP:conf/acl/WangWLZY20}
%----------------------------------------------------------------------------------------
% NEW SECTION
......@@ -249,14 +260,15 @@
\section{图像翻译}
\parinterval 人类所接受的信息中视觉信息的比重往往不亚于语言信息,甚至更多。视觉信息通常以图像的形式存在,近几年,结合图像的多模态机器翻译任务受到了广泛的研究。多模态机器翻译(图a)简单来说就是结合源语言和其他模态(例如图像等)的信息生成目标语言的过程。这种结合图像的机器翻译还是一种狭义上的“翻译”,它本质上还是从源语言到目标语言或者说从文本到文本的翻译。那么从图像到文本上(图b)的转换,例如,{\small\bfnew{图片描述生成}}\index{图片描述生成}(Image Captioning)\index{Image Captioning},即给定图像生成与图像内容相关的描述,也可以被称为广义上的“翻译”,当然,这种广义上的翻译形式不仅仅包括图像到文本,还应该包括从图像到图像(图c),甚至是从文本到图像(图d)等等。这里将这些与图像相关的翻译任务统称为图像翻译。
\parinterval 人类所接受的信息中视觉信息的比重往往不亚于语言信息,甚至更多。视觉信息通常以图像的形式存在,近几年,结合图像的多模态机器翻译任务受到了广泛的研究。多模态机器翻译(图\ref{fig:17-11}(a))简单来说就是结合源语言和其他模态(例如图像等)的信息生成目标语言的过程。这种结合图像的机器翻译还是一种狭义上的“翻译”,它本质上还是从源语言到目标语言或者说从文本到文本的翻译。那么从图像到文本上(图\ref{fig:17-11}(b))的转换,例如,{\small\bfnew{图片描述生成}}\index{图片描述生成}(Image Captioning)\index{Image Captioning},即给定图像生成与图像内容相关的描述,也可以被称为广义上的“翻译”,当然,这种广义上的翻译形式不仅仅包括图像到文本,还应该包括从图像到图像(图\ref{fig:17-11}(c)),甚至是从文本到图像(图\ref{fig:17-11}(d))等等。这里将这些与图像相关的翻译任务统称为图像翻译。
%----------------------------------------------------------------------------------------------------
\begin{table}[htp]
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-image-translation-task.tex}
\caption{图像翻译任务}
\label{tab:17-2-1-c}
\end{table}
\label{fig:17-11}
\end{figure}
%----------------------------------------------------------------------------------------------------
%----------------------------------------------------------------------------------------
......@@ -265,7 +277,7 @@
\subsection{基于图像增强的文本翻译}
\parinterval 在文本翻译中引入图像信息是最典型的多模态机器翻译任务。虽然多模态机器翻译还是一种从源语言文字到目标语言文字的转换,但是在转换的过程中,融入了其他模态的信息减少了歧义的产生。例如前文提到的通过与源语言相关的图像信息,将“A medium sized child jumps off of a dusty bank”中“bank”译为“河岸”而不是“银行”,通过给定一张相关的图片,机器翻译模型就可以利用视觉信息更好的理解歧义词,避免产生歧义。换句话说,对于同一图像或者视觉场景的描述,源语言和目标语言描述的本质意义是一致的,只不过,体现在语言上会有表达方法上的差异。那么,图像就会存在一些源语言和目标语言的隐含对齐“约束”,将这种“约束”融入到机器翻译系统,会让模型加深对某些歧义词语上下文的理解,从而进一步提高机器翻译质量。
\parinterval 在文本翻译中引入图像信息是最典型的多模态机器翻译任务。虽然多模态机器翻译还是一种从源语言文字到目标语言文字的转换,但是在转换的过程中,融入了其他模态的信息减少了歧义的产生。例如前文提到的通过与源语言相关的图像信息,将“A medium sized child jumps off of a dusty bank”中“bank”译为“河岸”而不是“银行”,通过给定一张相关的图片,机器翻译模型就可以利用视觉信息更好的理解歧义词,避免产生歧义。换句话说,对于同一图像或者视觉场景的描述,源语言和目标语言描述的本质意义是一致的,只不过,体现在语言上会有表达方法上的差异。那么,图像就会存在一些源语言和目标语言的隐含对齐“约束”,将这种“约束”融入到机器翻译系统,会让模型加深对某些歧义词语上下文的理解,从而进一步提高机器翻译质量。
\parinterval WMT机器翻译评测在2016年首次将融合图像和文本的多模态机器翻译作为机器翻译和跨语言图像描述的共享任务\upcite{DBLP:conf/wmt/SpeciaFSE16},这项任务也受到了广泛的研究\upcite{DBLP:conf/wmt/CaglayanABGBBMH17,DBLP:conf/wmt/LibovickyHTBP16}。如何融入视觉信息,更好的理解多模态上下文语义是多模态机器翻译研究的热点,大体的研究方向包括基于特征融合的方法\upcite{DBLP:conf/emnlp/CalixtoL17,DBLP:journals/corr/abs-1712-03449,DBLP:conf/wmt/HelclLV18}、基于多任务学习的方法\upcite{DBLP:conf/ijcnlp/ElliottK17,DBLP:conf/acl/YinMSZYZL20}。接下来将从这两个方向,对多模态机器翻译的研究展开介绍。
......@@ -275,22 +287,23 @@
\subsubsection{1. 基于特征融合的方法}
\parinterval 较为早期的研究工作通常将图像信息作为输入句子的一部分\upcite{DBLP:conf/emnlp/CalixtoL17,DBLP:conf/wmt/HuangLSOD16},或者用其对编码器、解码器的状态进行初始化\upcite{DBLP:conf/emnlp/CalixtoL17,Elliott2015MultilingualID,DBLP:conf/wmt/MadhyasthaWS17}。如图2所示,对图像特征的提取通常是基于卷积神经网络,有关卷积神经网络的内容,请参考{\chaptereleven}内容。通过卷积神经网络得到全局视觉特征,在进行维度变换后,将其作为源语言输入的一部分或者初始化状态引入到模型当中。但是,这种图像信息的引入方式有以下两个缺点:
\parinterval 较为早期的研究工作通常将图像信息作为输入句子的一部分\upcite{DBLP:conf/emnlp/CalixtoL17,DBLP:conf/wmt/HuangLSOD16},或者用其对编码器、解码器的状态进行初始化\upcite{DBLP:conf/emnlp/CalixtoL17,Elliott2015MultilingualID,DBLP:conf/wmt/MadhyasthaWS17}。如图\ref{fig:17-12}所示,对图像特征的提取通常是基于卷积神经网络,有关卷积神经网络的内容,请参考{\chaptereleven}内容。通过卷积神经网络得到全局视觉特征,在进行维度变换后,将其作为源语言输入的一部分或者初始化状态引入到模型当中。但是,这种图像信息的引入方式有以下两个缺点:
\begin{itemize}
\vspace{0.5em}
\item 图像信息不全都是有用的,往往存在一些与源语言或目标语言无关的信息,作为全局特征会引入噪音
\item 图像信息不全都是有用的,往往存在一些与源语言或目标语言无关的信息,作为全局特征会引入噪音
\vspace{0.5em}
\item 图像信息作为源语言的一部分或者初始化状态,间接参与目标语言单词的生成,在循环神经网络信息传递的过程中,图像信息会有一定的损失。
\vspace{0.5em}
\end{itemize}
%----------------------------------------------------------------------------------------------------
\begin{table}[htp]
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-modeling-a-global-approach-to-visual-characteristics}
\caption{建模全局的视觉特征方法}
\label{tab:17-2-2-c}
\end{table}
\label{fig:17-12}
\end{figure}
%----------------------------------------------------------------------------------------------------
\parinterval 说到噪音问题就不得不提到注意力机制的引入,前面章节中提到过这样的一个例子:
......@@ -302,11 +315,12 @@
\parinterval 想在横线处填写“吃饭”,“吃东西”的原因是我们在读句子的过程中,关注到了“没/吃饭”,“很/饿”等关键息。这是在自然语言处理中注意力机制解决的问题,即对于要生成的目标语言单词时,相关性更高的源语言片段应该在源语言句子的表示中体现出来,而不是将所有的源语言单词一视同仁。同样的,注意力机制也用在多模态机器翻译中,即在生成目标单词时,对于图像而言,更应该关注与目标单词相关的图像部分,而弱化对其他部分的关注,这样就达到了降噪的目的,另外,注意力机制的引入,也使图像信息直接参与目标语言的生成,解决了在编码器中,图像信息传递损失的问题。
%----------------------------------------------------------------------------------------------------
\begin{table}[htp]
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-comparison-of-attention-mechanism-of-target-word-bank}
\caption{目标词“bank”注意力机制前后对比}
\label{tab:17-2-3-c}
\end{table}
\end{figure}
%----------------------------------------------------------------------------------------------------
\parinterval 那么,多模态机器翻译是如何计算上下文向量的呢?这里仿照第十章的内容给出具体解释(参考图10.19):
......@@ -314,12 +328,12 @@
\parinterval 编码器输出的状态序列${\mathbi{h}_1,\mathbi{h}_2,...\mathbi{h}_m}$,m为状态序列的长度,需要注意的是,这里的状态序列不是源语言的状态序列,而是通过基于卷积循环网络提取到的图像的状态序列。假设图像的特征维度16×16×512,其中前两个维度分别表示图像的高和宽,这里会将图像的维度映射为256×512的状态序列,512为每个状态的维度,对于目标语位置$j$,上下文向量$\mathbi{C}_{j}$被定义为对序列的编码器输出进行加权求和,如下:
\begin{eqnarray}
\mathbi{C}_{j}&=& \sum_{i}{{\alpha}_{i,j}{\mathbi{h}}_{i}}
\label{eq:17-2-1}
\label{fig:17-13}
\end{eqnarray}
\noindent 其中,${\alpha}_{i,j}$是注意力权重,它表示目标语言第j个位置与图片编码状态序列第i个位置的相关性大小,计算方式与{\chapterten}描述的注意力函数一致。
\parinterval 这里,将每个时间步编码器的输出$\mathbi{h}_{i}$看作源图像序列位置$i$的表示结果。图3说明了模型在生成目标词“man”时,图像经过注意力机制对图像区域关注度的可视化效果,可以看到,经过注意力机制后,模型更注重的是与目标词相关的图像部分。当然,多模态机器翻译的输入还包括源语言文字序列。通常,源语言文字对于翻译的作用比图像更大\upcite{DBLP:conf/acl/YaoW20}。从这个角度说,图像信息更多的是作为文字信息的补充,而不是替代。除此之外,注意力机制在多模态机器翻译中也有很多研究,不仅仅在解码器端将经过注意力机制的文本特征和视觉特征作为解码输入的一部分,还有的工作在编码端将源语言与图像信息进行注意力建模\upcite{DBLP:journals/corr/abs-1712-03449,DBLP:conf/acl/YaoW20},得到更好的源语言特征表示。
\parinterval 这里,将每个时间步编码器的输出$\mathbi{h}_{i}$看作源图像序列位置$i$的表示结果。图\ref{fig:17-13}说明了模型在生成目标词“bank”时,图像经过注意力机制对图像区域关注度的可视化效果,可以看到,经过注意力机制后,模型更注重的是与目标词相关的图像部分。当然,多模态机器翻译的输入还包括源语言文字序列。通常,源语言文字对于翻译的作用比图像更大\upcite{DBLP:conf/acl/YaoW20}。从这个角度说,图像信息更多的是作为文字信息的补充,而不是替代。除此之外,注意力机制在多模态机器翻译中也有很多研究,不仅仅在解码器端将经过注意力机制的文本特征和视觉特征作为解码输入的一部分,还有的工作在编码器端将源语言与图像信息进行注意力建模\upcite{DBLP:journals/corr/abs-1712-03449,DBLP:conf/acl/YaoW20},得到更好的源语言特征表示。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
......@@ -329,14 +343,15 @@
\parinterval 基于多任务学习的方法通常是把翻译任务与其他视觉任务结合,进行联合训练。在{\chapterfifteen}{\chaptersixteen}已经提到过多任务学习。一种常见的多任务学习框架是针对多个相关的任务,共享模型的部分参数来学习不同任务之间相似的部分,并通过特定的模块来学习每个任务特有的部分。在多模态机器翻译中,应用多任务学习的主要策略就是将翻译作为主任务,同时设置一些与其他模态相关的子任务,通过这些子任务来辅助源语言理解自身的语言知识。
\parinterval 如图4所示,可以将多模态机器翻译任务分解为两个子任务:机器翻译和图片生成\upcite{DBLP:conf/ijcnlp/ElliottK17}。其中机器翻译作为主任务,图片生成作为子任务,图片生成这里指的是从一个图片描述生成对应图片,对于图片生成任务在后面叙述。通过单个编码器对源语言数据进行建模,然后通过两个解码器(翻译解码器和图像解码器)来学习翻译任务和图像生成任务。顶层任务学习每个任务的独立特征,底层共享参数层能够学习到更丰富的文本特征表示。另外在视觉问答领域有研究表明\upcite{DBLP:conf/nips/LuYBP16},在多模态任务中,不宜引入多层的注意力,因为多层注意力会导致模型严重的过拟合,从另一角度来说,利用多任务学习的方式,提高模型的泛化能力,也是一种有效防止过拟合现象的方式。类似的思想,也大量使用在多模态自然语言处理中,例如图像描述生成、视觉问答\upcite{DBLP:conf/iccv/AntolALMBZP15}等。
\parinterval 如图\ref{fig:17-14}所示,可以将多模态机器翻译任务分解为两个子任务:机器翻译和图片生成\upcite{DBLP:conf/ijcnlp/ElliottK17}。其中机器翻译作为主任务,图片生成作为子任务,图片生成这里指的是从一个图片描述生成对应图片,对于图片生成任务在后面叙述。通过单个编码器对源语言数据进行建模,然后通过两个解码器(翻译解码器和图像解码器)来学习翻译任务和图像生成任务。顶层任务学习每个任务的独立特征,底层共享参数层能够学习到更丰富的文本特征表示。另外在视觉问答领域有研究表明\upcite{DBLP:conf/nips/LuYBP16},在多模态任务中,不宜引入过多层的注意力机制,因为过多层的注意力机制会导致模型严重的过拟合,从另一角度来说,利用多任务学习的方式,提高模型的泛化能力,也是一种有效防止过拟合现象的方式。类似的思想,也大量使用在多模态自然语言处理中,例如图像描述生成、视觉问答\upcite{DBLP:conf/iccv/AntolALMBZP15}等。
%----------------------------------------------------------------------------------------------------
\begin{table}[htp]
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-application-of-multimodal-machine-translation-to-multitask-learning.tex}
\caption{多模态机器翻译多任务学习的应用}
\label{tab:17-2-4-c}
\end{table}
\label{fig:17-14}
\end{figure}
%----------------------------------------------------------------------------------------------------
%----------------------------------------------------------------------------------------
......@@ -348,14 +363,15 @@
\parinterval 图像到文本的转换也可以看作是广义上的翻译,简单来说,就是把源语言的形式替换成了图像。其中,图像描述生成是最典型的任务。虽然,这部分内容并不是本书的重点,不过为了保证多模态翻译内容的完整性,这里对相关技术进行简要介绍。图像描述生成是指给定图像生成文字描述,有时也被称作图说话、图像字幕生成。如何理解图像信息、在理解图像信息基础上生成描述是图像描述任务要解决的问题,可以发现,该任务涉及到自然语言处理和计算机视觉两个领域,是一项很有挑战的任务。同时,图像描述在图像检索、智能导盲、人机交互等领域有着广泛的应用场景,有很大的研究价值。
%----------------------------------------------------------------------------------------------------
\begin{table}[htp]
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-traditional-methods-of-image-description}
\caption{图像描述传统方法}
\label{tab:17-2-5-c}
\end{table}
\label{fig:17-15}
\end{figure}
%----------------------------------------------------------------------------------------------------
\parinterval 传统图像描述生成有两种范式:基于检索的方法和基于模板的方法。其中基于检索的方法(图5左)是指在指定的图像描述候选句子中选择其中的句子作为图像的描述,这种方法的弊端是所选择的句子可能会和图像很大程度上不相符。而基于模板的方法(图5右)是指在图像上检测视觉特征,然后把内容填在实现设计好的模板当中,这种方法的缺点是生成的图像描述过于呆板,‘像是在一个模子中刻出来的’说的就是这个意思。近几年来 ,由于卷积神经网络在计算机视觉领域效果显著,而循环神经网络在自然语言处理领域卓有成效,受到机器翻译领域编码器-解码器框架的启发,逐渐的,这种基于卷积神经网络作为编码器编码图像,循环神经网络作为解码器解码描述的编码器-解码器框架成了图像描述任务的基础范式。本章节,从基础的图像描述范式编码器-解码器框架展开\upcite{DBLP:conf/cvpr/VinyalsTBE15,DBLP:conf/icml/XuBKCCSZB15},从编码器的改进、解码器的改进展开介绍。
\parinterval 传统图像描述生成有两种范式:基于检索的方法和基于模板的方法。其中\ref{fig:17-15}(a)是指在指定的图像描述候选句子中选择其中的句子作为图像的描述,这种方法的弊端是所选择的句子可能会和图像很大程度上不相符。而\ref{fig:17-15}(b)是指在图像上检测视觉特征,然后把内容填在实现设计好的模板当中,这种方法的缺点是生成的图像描述过于呆板,“像是在一个模子中刻出来的”说的就是这个意思。近几年来 ,由于卷积神经网络在计算机视觉领域效果显著,而循环神经网络在自然语言处理领域卓有成效,受到机器翻译领域编码器-解码器框架的启发,逐渐的,这种基于卷积神经网络作为编码器编码图像,循环神经网络作为解码器解码描述的编码器-解码器框架成了图像描述任务的基础范式。本章节,从基础的图像描述范式编码器-解码器框架展开\upcite{DBLP:conf/cvpr/VinyalsTBE15,DBLP:conf/icml/XuBKCCSZB15},从编码器的改进、解码器的改进展开介绍。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
......@@ -363,14 +379,15 @@
\subsubsection{1. 基础框架}
\parinterval 受到神经机器翻译的启发,编码器-解码器框架也应用到图像描述任务当中。其中,编码器将输入的图像转换为一种新的“表示”形式,这种表示包含了输入图像的所有信息。之后解码器把这种“表示”重新转换为输出的描述。图XX中(上)是编码器-解码器框架在图像描述生成的应用\upcite{DBLP:conf/cvpr/VinyalsTBE15}。首先,通过卷积神经网络提取图像特征到一个合适的长度向量表示。然后,利用长短时记忆网络(LSTM)解码生成文字描述,这个过程中与机器翻译解码过程类似。这种建模方式存在一定的短板:生成的描述单词不一定需要所有的图像信息,将全局的图像信息送入模型中,可能会引入噪音,使这种“表示”形式不准确。针对这个问题,图XX(下\upcite{DBLP:conf/icml/XuBKCCSZB15}为了弥补这种建模的局限性,引入了注意力机制。利用注意力机制在生成不同单词时,使模型不再只关注图像的全局特征,而是关注“应该”关注的图像特征。
\parinterval 受到神经机器翻译的启发,编码器-解码器框架也应用到图像描述任务当中。其中,编码器将输入的图像转换为一种新的“表示”形式,这种表示包含了输入图像的所有信息。之后解码器把这种“表示”重新转换为输出的描述。图\ref{fig:17-16}(a)是编码器-解码器框架在图像描述生成的应用\upcite{DBLP:conf/cvpr/VinyalsTBE15}。首先,通过卷积神经网络提取图像特征到一个合适的长度向量表示。然后,利用长短时记忆网络(LSTM)解码生成文字描述,这个过程中与机器翻译解码过程类似。这种建模方式存在一定的短板:生成的描述单词不一定需要所有的图像信息,将全局的图像信息送入模型中,可能会引入噪音,使这种“表示”形式不准确。针对这个问题,图\ref{fig:17-16}(b\upcite{DBLP:conf/icml/XuBKCCSZB15}为了弥补这种建模的局限性,引入了注意力机制。利用注意力机制在生成不同单词时,使模型不再只关注图像的全局特征,而是关注“应该”关注的图像特征。
%----------------------------------------------------------------------------------------------------
\begin{table}[htp]
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-image-description-of-encoder-decoder-framework}
\caption{图像描述的编码器-解码器框架}
\label{tab:17-2-6-c}
\end{table}
\label{fig:17-16}
\end{figure}
%----------------------------------------------------------------------------------------------------
\parinterval 图像描述生成基本上沿用了编码器-解码器框架。接下来,分别从编码器端的改进和解码器端的改进展开介绍。这些改进总体来说是在解决以下两个问题:
......@@ -391,17 +408,18 @@
\parinterval 要想使编码器-解码器框架在图像描述中充分发挥作用,编码器也要更好的表示图像信息。对于编码器的改进,大多也是从这个方向出发。通常,体现在向编码器中添加图像的语义信息\upcite{DBLP:conf/cvpr/YouJWFL16,DBLP:conf/cvpr/ChenZXNSLC17,DBLP:journals/pami/FuJCSZ17}和位置信息\upcite{DBLP:conf/cvpr/ChenZXNSLC17,DBLP:conf/ijcai/LiuSWWY17}
\parinterval 图像的语义信息一般是指图像中存在的实体、属性、场景等等。如图XX所示,从图像中利用属性或实体检测器提取出“child”、“river”、“bank”等等的属性词和实体词作为图像的语义信息,提取全局的图像特征初始化循环神经网络,再利用注意力机制计算目标词与属性词或实体词之间的注意力权重,根据该权重计算上下文向量,从而将编码语义信息送入解码端\upcite{DBLP:conf/cvpr/YouJWFL16},在解码‘bank’单词时,会更关注图像语义信息中的‘bank’。当然,除了图像中的实体和属性作为语义信息外,也可以将图片的场景信息也加入到编码器当中\upcite{DBLP:journals/pami/FuJCSZ17}。有关如何做属性、实体和场景的检测,涉及到目标检测任务的工作,例如Faster-RCNN\upcite{DBLP:journals/pami/RenHG017}、YOLO\upcite{DBLP:journals/corr/abs-1804-02767,DBLP:journals/corr/abs-2004-10934}等等,这里不过多赘述。
\parinterval 图像的语义信息一般是指图像中存在的实体、属性、场景等等。如图\ref{fig:17-17}所示,从图像中利用属性或实体检测器提取出“child”、“river”、“bank”等等的属性词和实体词作为图像的语义信息,提取全局的图像特征初始化循环神经网络,再利用注意力机制计算目标词与属性词或实体词之间的注意力权重,根据该权重计算上下文向量,从而将编码语义信息送入解码器端\upcite{DBLP:conf/cvpr/YouJWFL16},在解码‘bank’单词时,会更关注图像语义信息中的‘bank’。当然,除了图像中的实体和属性作为语义信息外,也可以将图片的场景信息加入到编码器当中\upcite{DBLP:journals/pami/FuJCSZ17}。有关如何做属性、实体和场景的检测,涉及到目标检测任务的工作,例如Faster-RCNN\upcite{DBLP:journals/pami/RenHG017}、YOLO\upcite{DBLP:journals/corr/abs-1804-02767,DBLP:journals/corr/abs-2004-10934}等等,这里不过多赘述。
%----------------------------------------------------------------------------------------------------
\begin{table}[htp]
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-the-encoder-explicitly-incorporates-semantic-information}
\caption{编码器“显式”融入语义信息}
\label{tab:17-2-6-c}
\end{table}
\label{fig:17-17}
\end{figure}
%----------------------------------------------------------------------------------------------------
\parinterval 以上的方法大都是将图像中的实体、属性、场景等映射到文字上,并把这些信息显式地添加到编码器端。令一种方式,把图像中的语义特征隐式地作用到编码器端\upcite{DBLP:conf/cvpr/ChenZXNSLC17}。例如,可以图像数据可以分解为三个通道(红、绿、蓝),简单来说,就是将图像的每一个像素点按照红色、绿色、蓝色分成三个部分,这样就将图像分成了三个通道。在很多图像中,不同通道随伴随的特征是不一样的,可以将其作用于编码器端。另一种方法是基于位置信息的编码器增强。位置信息指的是图像中对象(物体)的位置。利用目标检测技术检测系统获得图中的对象和对应的特征,这样就确定了图中的对象位置。显然,这些信息也可以加入到编码端,以加强编码器的表示能力\upcite{DBLP:conf/eccv/YaoPLM18}
\parinterval 以上的方法大都是将图像中的实体、属性、场景等映射到文字上,并把这些信息显式地添加到编码器端。另一种方式,把图像中的语义特征隐式地作用到编码器端\upcite{DBLP:conf/cvpr/ChenZXNSLC17}。例如,图像数据可以分解为三个通道(红、绿、蓝),简单来说,就是将图像的每一个像素点按照红色、绿色、蓝色分成三个部分,这样就将图像分成了三个通道。在很多图像中,不同通道伴随的特征是不一样的,可以将其作用于编码器端。另一种方法是基于位置信息的编码器增强。位置信息指的是图像中对象(物体)的位置。利用目标检测技术检测系统获得图中的对象和对应的特征,这样就确定了图中的对象位置。显然,这些信息也可以加入到编码器端,以加强编码器的表示能力\upcite{DBLP:conf/eccv/YaoPLM18}
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
......@@ -409,8 +427,9 @@
\subsubsection{3. 解码器的改进}
\parinterval 由于解码器输出的是语言文字序列,因此需要考虑语言的特点对其进行改进。 例如,解码过程中, “the”,“on”,“at”这种介词或者冠词与图像的相关性较低,这时图像信息的引入就会产生负面影响\upcite{DBLP:conf/cvpr/LuXPS17}。因此,可以通过门等结构,控制视觉信号作用于文字生成的程度。另外,在解码过程中,生成的每个单词对应着图像的区域可能是不同的。因此也可以设计更为有效的注意力机制来捕捉解码端对不同图像局部信息的关注程度\upcite{DBLP:conf/cvpr/00010BT0GZ18}
\parinterval 除了在解码端更好的使生成文本与图像特征相互作用以外,还有一些其他的解码器端改进的方向。例如:用其它结构(如卷积神经网络或者Transformer)代替解码器端循环神经网络\upcite{DBLP:conf/cvpr/AnejaDS18}。或者使用更深层的神经网络学习动词或者名词等视觉中不易表现出来的单词\upcite{DBLP:journals/mta/FangWCT18},其思想与深层神经机器翻译模型有相通之处({\chapterfifteen})。
\parinterval 由于解码器输出的是语言文字序列,因此需要考虑语言的特点对其进行改进。 例如,解码过程中, “the”,“on”,“at”这种介词或者冠词与图像的相关性较低,这时图像信息的引入就会产生负面影响\upcite{DBLP:conf/cvpr/LuXPS17}。因此,可以通过门等结构,控制视觉信号作用于文字生成的程度。另外,在解码过程中,生成的每个单词对应着图像的区域可能是不同的。因此也可以设计更为有效的注意力机制来捕捉解码器端对不同图像局部信息的关注程度\upcite{DBLP:conf/cvpr/00010BT0GZ18}
\parinterval 除了在解码器端更好的使生成文本与图像特征相互作用以外,还有一些其他的解码器端改进的方向。例如:用其它结构(如卷积神经网络或者Transformer)代替解码器端循环神经网络\upcite{DBLP:conf/cvpr/AnejaDS18}。或者使用更深层的神经网络学习动词或者名词等视觉中不易表现出来的单词\upcite{DBLP:journals/mta/FangWCT18},其思想与深层神经机器翻译模型有相通之处({\chapterfifteen})。
%----------------------------------------------------------------------------------------
% NEW SUB-SECTION
......@@ -422,9 +441,9 @@
\parinterval 计算机视觉领域,图像风格转移、图像语义分割、图像超分辨率等任务,都可以被视为{\small\bfnew{图像到图像的翻译}}\index{图像到图像的翻译}(Image-to-Image Translation)\index{Image-to-Image Translation}问题。与机器翻译类似,这些问题的共同目标是学习从一个对象到另一个对象的映射,只不过这里的对象是指图像,而非机器翻译中的文字。例如,给定物体的轮廓生成真实物体照片或者给定白天照片生成夜晚的照片等。图像到图像的翻译有广阔的应用场景,如图片补全、风格迁移等。
\parinterval 对抗神经网络被广泛地应用图像到图像的翻译任务当中\upcite{DBLP:conf/nips/GoodfellowPMXWOCB14,DBLP:conf/nips/ZhuZPDEWS17,DBLP:journals/corr/abs-1908-06616}。实际上,这类方法非常适合图像生成类的任务。简单来说,对抗生成网络包括两个部分分别是:生成器和判别器。基于输入生成器生成一个结果,而判别器要判别生成的结果和真实结果是否是相同的,对抗的思想是,通过强化生成器的生成能力和判别器的判别能力,当生成器生成的结果可以“骗”过判别器时,即判别器无法分清真实结果和生成结果,认为模型学到了这种映射关系。在图像到图像的翻译中,根据输入图像,生成器生成预测图像,判别器判别是否为目标图像,多次迭代后,生成图像被判别为目标图像时,则模型学习到了“翻译能力”。以上的工作都是有监督的,即基于对齐的图像对数据集,但是,这种数据的标注是极为费时费力的,所以有很多的工作也基于无监督的方法展开\upcite{DBLP:conf/iccv/ZhuPIE17,DBLP:conf/iccv/YiZTG17,DBLP:conf/nips/LiuBK17},这里不过多赘述。
\parinterval 对抗神经网络被广泛地应用图像到图像的翻译任务当中\upcite{DBLP:conf/nips/GoodfellowPMXWOCB14,DBLP:conf/nips/ZhuZPDEWS17,DBLP:journals/corr/abs-1908-06616}。实际上,这类方法非常适合图像生成类的任务。简单来说,对抗生成网络包括两个部分分别是:生成器和判别器。基于输入生成器生成一个结果,而判别器要判别生成的结果和真实结果是否是相同的,对抗的思想是,通过强化生成器的生成能力和判别器的判别能力,当生成器生成的结果可以“骗”过判别器时,即判别器无法分清真实结果和生成结果,认为模型学到了这种映射关系。在图像到图像的翻译中,根据输入图像,生成器生成预测图像,判别器判别是否为目标图像,多次迭代后,生成图像被判别为目标图像时,则模型学习到了“翻译能力”。以上的工作都是有监督的,即基于对齐的图像对数据集,但是,这种数据的标注是极为费时费力的,所以有很多的工作也基于无监督的方法展开\upcite{DBLP:conf/iccv/ZhuPIE17,DBLP:conf/iccv/YiZTG17,DBLP:conf/nips/LiuBK17},这里不过多赘述。
\parinterval {\small\bfnew{文本到图像的翻译}}\index{文本到图像的翻译}(Text-to-Image Translation)\index{Text-to-Image Translation}是指给定描述物体颜色和形状等细节的自然语言文字,生成对应的图像。该任务也可以看作是图像描述任务的逆任务。目前方法上大部分基于对抗神经网络\upcite{DBLP:conf/icml/ReedAYLSL16,DBLP:journals/corr/DashGALA17,DBLP:conf/nips/ReedAMTSL16}。基本流程为:首先利用自然语言处理技术提取出文本信息,然后再用文本特征作为后面生成图像的约束,在对抗神经网络中生成器(Generator)中根据文本特征生成图像的约束,从而别鉴别器(Discriminator)鉴定其生成效果。
\parinterval {\small\bfnew{文本到图像的翻译}}\index{文本到图像的翻译}(Text-to-Image Translation)\index{Text-to-Image Translation}是指给定描述物体颜色和形状等细节的自然语言文字,生成对应的图像。该任务也可以看作是图像描述任务的逆任务。目前方法上大部分基于对抗神经网络\upcite{DBLP:conf/icml/ReedAYLSL16,DBLP:journals/corr/DashGALA17,DBLP:conf/nips/ReedAMTSL16}。基本流程为:首先利用自然语言处理技术提取出文本信息,然后再用文本特征作为后面生成图像的约束,在对抗神经网络中生成器(Generator)中根据文本特征生成图像的约束,从而别鉴别器(Discriminator)鉴定其生成效果。
%----------------------------------------------------------------------------------------
% NEW SECTION
......@@ -440,15 +459,19 @@
\subsection{什么是篇章级翻译}
\parinterval “篇章”在这里指一系列连续的段落或者句子所构成的整体,其中各个句子间从形式和内容上都具有一定的连贯性和一致性\upcite{jurafsky2000speech}。这些联系主要体现在{\small\sffamily\bfseries{衔接}}\index{衔接}(Cohesion \index{Cohesion})以及{\small\sffamily\bfseries{连贯}}\index{连贯}(Coherence \index{Coherence})两个方面。其中衔接体现在显性的语言成分和结构上,包括篇章中句子间语法和词汇上的联系,而连贯体现在各个句子之间逻辑和语义上的联系。因此,篇章级翻译的目的就是要考虑到这些上下文之间的联系,从而生成相比句子级翻译更连贯和准确的翻译结果(如\ref{tab:17-3-1})。但是由于不同语言的特性多种多样,上下文信息在篇章级翻译中的作用也不尽相同。比如在德语中名词是分词性的,因此在代词翻译的过程中需要根据其先行词的词性进行区分,而这种现象在其它不区分词性的语言中是不存在的。这导致篇章级翻译在不同的语种中可能对应多种不同的上下文现象。
\parinterval “篇章”在这里指一系列连续的段落或者句子所构成的整体,其中各个句子间从形式和内容上都具有一定的连贯性和一致性\upcite{jurafsky2000speech}。这些联系主要体现在{\small\sffamily\bfseries{衔接}}\index{衔接}(Cohesion \index{Cohesion})以及{\small\sffamily\bfseries{连贯}}\index{连贯}(Coherence \index{Coherence})两个方面。其中衔接体现在显性的语言成分和结构上,包括篇章中句子间语法和词汇上的联系,而连贯体现在各个句子之间逻辑和语义上的联系。因此,篇章级翻译的目的就是要考虑到这些上下文之间的联系,从而生成相比句子级翻译更连贯和准确的翻译结果(如实例\ref{eg:17-1})。但是由于不同语言的特性多种多样,上下文信息在篇章级翻译中的作用也不尽相同。比如在德语中名词是分词性的,因此在代词翻译的过程中需要根据其先行词的词性进行区分,而这种现象在其它不区分词性的语言中是不存在的。这导致篇章级翻译在不同的语种中可能对应多种不同的上下文现象。
%----------------------------------------------------------------------------------------------------
\begin{table}[htp]
\centering
\caption{篇章级翻译中时态一致性的问题}
\label{tab:17-3-1}
\end{table}
%----------------------------------------------------------------------------------------------------
\begin{example}
上下文句子:我上周针对这个问题做出解释并咨询了他的意见。
\hspace{2em} 待翻译句子:他也同意我的看法。
\hspace{2em} 句子级翻译结果:He also agrees with me.
\hspace{2em} 篇章级翻译结果:{\red{And}} he {\red{agreed}} with me.
\label{eg:17-1}
\end{example}
\parinterval 正是由于这种上下文现象的多样性,使得篇章级翻译模型的性能评价相对困难。目前篇章级机器翻译主要针对一些常见上下文的现象,比如代词翻译、省略、连接和词汇衔接等,而{\chapterfour}介绍的BLEU等通用自动评价指标通常对这些上下文现象不敏感,篇章级翻译需要采用一些专用方法来对这些具体的现象进行评价。之前已经有一些研究工作针对具体的上下文现象提出了相应的评价标准并且在篇章级翻译中得到应用\upcite{DBLP:conf/naacl/BawdenSBH18,DBLP:conf/acl/VoitaST19},但是目前并没有达成共识,这也在一定程度上阻碍了篇章级机器翻译的进一步发展。我们将在ref{sec:17-3-2}节中对这些评价标准进行介绍。
......@@ -514,7 +537,7 @@ D_i&\subseteq&\{X_{-i},Y_{-i}\} \label{eq:17-3-2}
\label{eg:17-3-1}
\end{example}
\parinterval 其他改进输入的做法相比于拼接的方法要复杂一些,首先需要对篇章进行处理,得到词汇链(Lexical Chain)\footnote{词汇链指篇章中语义相关的词所构成的序列}\upcite{DBLP:conf/wmt/GonzalesMS17}或者篇章嵌入\upcite{DBLP:journals/corr/abs-1910-07481}等信息,然后融入到当前句子的序列表示中,送入模型进行翻译。这种方式中上下文信息来自于预先提取的篇章表示,但是这种表示是否适合机器翻译还有待论证。
\parinterval 其他改进输入的做法相比于拼接的方法要复杂一些,首先需要对篇章进行处理,得到词汇链\footnote{词汇链指篇章中语义相关的词所构成的序列}\upcite{DBLP:conf/wmt/GonzalesMS17}或者篇章嵌入\upcite{DBLP:journals/corr/abs-1910-07481}等信息,然后融入到当前句子的序列表示中,送入模型进行翻译。这种方式中上下文信息来自于预先提取的篇章表示,但是这种表示是否适合机器翻译还有待论证。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
......@@ -526,11 +549,11 @@ D_i&\subseteq&\{X_{-i},Y_{-i}\} \label{eq:17-3-2}
\centering
\input{./Chapter17/Figures/figure-multiencoder}
\caption{多编码器结构\upcite{DBLP:conf/acl/LiLWJXZLL20}}
\label{fig:17-3-1}
\label{fig:17-18}
\end{figure}
%----------------------------------------------
\parinterval 区别于在输入上进行改进,另一种思路是对传统的编码器-解码器框架进行更改,采用额外的编码器来编码上下文句子,称之为多编码器结构\upcite{DBLP:conf/acl/LiLWJXZLL20,DBLP:conf/acl/LiLWJXZLL20,DBLP:conf/discomt/SugiyamaY19}。这种结构最早被应用在基于循环神经网络的篇章级翻译模型\upcite{DBLP:journals/corr/JeanLFC17,DBLP:conf/coling/KuangX18,DBLP:conf/naacl/BawdenSBH18,DBLP:conf/pacling/YamagishiK19},并且在Transformer模型上同样适用\upcite{DBLP:journals/corr/abs-1805-10163,DBLP:conf/emnlp/ZhangLSZXZL18}。图\ref{fig:17-3-1}展示了一个基于Transformer模型的多编码器结构,基于源语言当前待翻译句子的编码表示$\mathbi{h}$和上下文句子的编码表示$\mathbi{h}_{pre}$,模型首先通过注意力机制提取句子间上下文信息$\mathbi{d}$
\parinterval 区别于在输入上进行改进,另一种思路是对传统的编码器-解码器框架进行更改,采用额外的编码器来编码上下文句子,称之为多编码器结构\upcite{DBLP:conf/acl/LiLWJXZLL20,DBLP:conf/acl/LiLWJXZLL20,DBLP:conf/discomt/SugiyamaY19}。这种结构最早被应用在基于循环神经网络的篇章级翻译模型\upcite{DBLP:journals/corr/JeanLFC17,DBLP:conf/coling/KuangX18,DBLP:conf/naacl/BawdenSBH18,DBLP:conf/pacling/YamagishiK19},并且在Transformer模型上同样适用\upcite{DBLP:journals/corr/abs-1805-10163,DBLP:conf/emnlp/ZhangLSZXZL18}。图\ref{fig:17-18}展示了一个基于Transformer模型的多编码器结构,基于源语言当前待翻译句子的编码表示$\mathbi{h}$和上下文句子的编码表示$\mathbi{h}_{pre}$,模型首先通过注意力机制提取句子间上下文信息$\mathbi{d}$
\begin{eqnarray}
\mathbi{d}&=&Attention(\mathbi{h},\mathbi{h}_{pre},\mathbi{h}_{pre})
......@@ -561,13 +584,13 @@ D_i&\subseteq&\{X_{-i},Y_{-i}\} \label{eq:17-3-2}
\centering
\input{./Chapter17/Figures/figure-layer}
\caption{层次注意力结构\upcite{Werlen2018DocumentLevelNM}}
\label{fig:17-3-2}
\label{fig:17-19}
\end{figure}
%----------------------------------------------
\parinterval 多编码器结构通过额外的编码器对前一句进行编码,但是无法处理多个上下文句子的情况。为了能够捕捉到更充分的上下文信息,可以采用层次结构来对更多的上下文句子进行建模。层次结构可以有效的处理更长的上下文序列,以及序列内不同单元之间的相互作用。类似的思想也成功的应用在基于树的翻译模型中({\chaptereight}{\chapterfifteen})。
\parinterval\ref{fig:17-3-2}描述了一个基于层次注意力的模型结构\upcite{DBLP:conf/emnlp/WerlenRPH18}。首先通过翻译模型的编码器获取前文$k$个句子的序列编码表示$(\mathbi{h}^k,\dots,\mathbi{h}^2,\mathbi{h}^1)$,然后使用层次注意力机制从这些编码表示中提取上下文信息$\mathbi{d}$,进而可以和当前句子的编码表示$\mathbi{h}$融合,得到一个上下文相关的当前句子表示$\widetilde{\mathbi{h}}$。其中层次注意力的计算过程也是分为两步,第一步针对前文每个句子的词序列表示$\mathbi{h}^{j}$,使用词级注意力提取从各个句子的上下文信息$\mathbi{s}^{j}$,然后在这$k$个句子级上下文表示$\mathbi{s}=(\mathbi{s}^k,\dots,\mathbi{s}^2,\mathbi{s}^1)$基础上,使用句子级注意力提取最终的上下文信息。具体计算过程如下所示:
\parinterval\ref{fig:17-19}描述了一个基于层次注意力的模型结构\upcite{DBLP:conf/emnlp/WerlenRPH18}。首先通过翻译模型的编码器获取前文$k$个句子的序列编码表示$(\mathbi{h}^k,\dots,\mathbi{h}^2,\mathbi{h}^1)$,然后使用层次注意力机制从这些编码表示中提取上下文信息$\mathbi{d}$,进而可以和当前句子的编码表示$\mathbi{h}$融合,得到一个上下文相关的当前句子表示$\widetilde{\mathbi{h}}$。其中层次注意力的计算过程也是分为两步,第一步针对前文每个句子的词序列表示$\mathbi{h}^{j}$,使用词级注意力提取从各个句子的上下文信息$\mathbi{s}^{j}$,然后在这$k$个句子级上下文表示$\mathbi{s}=(\mathbi{s}^k,\dots,\mathbi{s}^2,\mathbi{s}^1)$基础上,使用句子级注意力提取最终的上下文信息。具体计算过程如下所示:
\begin{eqnarray}
\mathbi{q}_{w}&=&f_w(\mathbi{h}_t)
......@@ -590,7 +613,7 @@ D_i&\subseteq&\{X_{-i},Y_{-i}\} \label{eq:17-3-2}
\subsubsection{4. 基于缓存的方法}
\parinterval 除了以上提到的建模方法,还有一类基于缓存的方法\upcite{DBLP:journals/tacl/TuLSZ18,DBLP:conf/coling/KuangXLZ18}。这种方法最大的特点在于将篇章翻译看作一个连续的过程,然后在这个过程中通过一个额外的缓存来记录一些相关信息,最后在每个句子解码的过程中使用这个缓存来提供上下文信息。图\ref{fig:17-3-3}描述了一种基于缓存的篇章级翻译模型结构\upcite{DBLP:journals/tacl/TuLSZ18}。在这里,翻译模型基于循环神经网络(参考{\chapterten}),但是这种方法同样适用于包括Transformer在内的其他神经机器翻译模型。模型中篇章上下文的建模依赖于缓存的读和写操作。其中读操作以及与目标端表示的融合方法和层次结构中提到的方法类似,同样使用注意力机制以及门控机制来获取最终的目标端表示$\widetilde{\mathbi{s}_{t}}$。而缓存的写操作则是在每个句子翻译结束后,将句子中每个词${y}_{t}$对应的表示对$<\mathbi{c}_{t},\mathbi{s}_{t}>$作为注意力的键和值按照一定规则写入缓存。其中,$\mathbi{c}_{t}$$\mathbi{s}_{t}$分别表示第$t$个目标词所对应的源语表示和解码器隐层状态。如果${y}_{t}$不存在于缓存,则写入其中的空槽或者替换最久未使用的键值对;如果${y}_{t}$存在于缓存,则将对应的键值对进行更新:
\parinterval 除了以上提到的建模方法,还有一类基于缓存的方法\upcite{DBLP:journals/tacl/TuLSZ18,DBLP:conf/coling/KuangXLZ18}。这种方法最大的特点在于将篇章翻译看作一个连续的过程,然后在这个过程中通过一个额外的缓存来记录一些相关信息,最后在每个句子解码的过程中使用这个缓存来提供上下文信息。图\ref{fig:17-20}描述了一种基于缓存的篇章级翻译模型结构\upcite{DBLP:journals/tacl/TuLSZ18}。在这里,翻译模型基于循环神经网络(参考{\chapterten}),但是这种方法同样适用于包括Transformer在内的其他神经机器翻译模型。模型中篇章上下文的建模依赖于缓存的读和写操作。其中读操作以及与目标端表示的融合方法和层次结构中提到的方法类似,同样使用注意力机制以及门控机制来获取最终的目标端表示$\widetilde{\mathbi{s}_{t}}$。而缓存的写操作则是在每个句子翻译结束后,将句子中每个词${y}_{t}$对应的表示对$<\mathbi{c}_{t},\mathbi{s}_{t}>$作为注意力的键和值按照一定规则写入缓存。其中,$\mathbi{c}_{t}$$\mathbi{s}_{t}$分别表示第$t$个目标词所对应的源语表示和解码器隐层状态。如果${y}_{t}$不存在于缓存,则写入其中的空槽或者替换最久未使用的键值对;如果${y}_{t}$存在于缓存,则将对应的键值对进行更新:
\begin{eqnarray}
\mathbi{k}_{i}&=&(\mathbi{k}_{i}+\mathbi{c}_{t})/2
......@@ -606,7 +629,7 @@ D_i&\subseteq&\{X_{-i},Y_{-i}\} \label{eq:17-3-2}
\centering
\input{./Chapter17/Figures/figure-cache}
\caption{基于Cache的解码器结构\upcite{DBLP:journals/tacl/TuLSZ18}}
\label{fig:17-3-3}
\label{fig:17-20}
\end{figure}
%----------------------------------------------
......@@ -635,14 +658,14 @@ D_i&\subseteq&\{X_{-i},Y_{-i}\} \label{eq:17-3-2}
通过这种生成式模型,只需要使用句子级的翻译模型以及目标端的篇章级翻译模型,避免了对篇章级双语数据的依赖。
\parinterval 另一种改进方法不影响句子级翻译模型的推断过程,而是在完成翻译后使用额外的模块进行第二阶段的解码,通过两阶段的解码来引入上下文信息\upcite{DBLP:conf/aaai/XiongH0W19,DBLP:conf/acl/VoitaST19}。如图\ref{fig:17-3-4}所示,这种两阶段解码的做法相当于将篇章级翻译的问题进行了分离和简化,适用于篇章级双语数据稀缺的场景。基于类似的思想,有研究人员使用后编辑的做法对翻译结果进行修正\upcite{DBLP:conf/emnlp/VoitaST19}。区别于两阶段解码的方法,后编辑的方法无需参考源语信息,只是基于目标语言端的连续翻译结果来提供上下文信息。通过这种方式,可以降低对篇章级双语数据的需求。
\parinterval 另一种改进方法不影响句子级翻译模型的推断过程,而是在完成翻译后使用额外的模块进行第二阶段的解码,通过两阶段的解码来引入上下文信息\upcite{DBLP:conf/aaai/XiongH0W19,DBLP:conf/acl/VoitaST19}。如图\ref{fig:17-21}所示,这种两阶段解码的做法相当于将篇章级翻译的问题进行了分离和简化,适用于篇章级双语数据稀缺的场景。基于类似的思想,有研究人员使用后编辑的做法对翻译结果进行修正\upcite{DBLP:conf/emnlp/VoitaST19}。区别于两阶段解码的方法,后编辑的方法无需参考源语信息,只是基于目标语言端的连续翻译结果来提供上下文信息。通过这种方式,可以降低对篇章级双语数据的需求。
%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter17/Figures/figure-twodecoding}
\caption{两阶段解码}
\label{fig:17-3-4}
\label{fig:17-21}
\end{figure}
%----------------------------------------------
......
......@@ -23,9 +23,9 @@
\chapter{机器翻译应用技术}
\parinterval 近几年,随着翻译品质的不断提升,越来越多的机器翻译需求被挖掘出来。但是,仅凭一个翻译引擎无法满足如此多样的需求。应用机器翻译技术时,需要“额外”考虑很多因素,例如,数据加工方式、交互方式、应用的领域等,甚至机器翻译模型也要经过改造才能适应到不同的场景中。
\parinterval 随着机器翻译品质的不断提升,越来越多的应用需求被挖掘出来。但是,一个优秀的机器翻译引擎并不意味着机器翻译可以被成功应用。机器翻译技术落地需要“额外”考虑很多因素,例如,数据加工方式、交互方式、应用的领域等,甚至机器翻译模型也要经过改造才能适应到不同的场景中。
\parinterval 本章将重点介绍机器翻译应用中所面临的问题,以及解决这些问题可以采用的策略。本章所涉及的内容较为广泛,一方面会大量使用本书前十七章的模型和方法,另一方面也会介绍新的技术手段。最终,本章会结合机器翻译的特点展示机器翻译可能的应用场景,并进行一些对机器翻译未来的思考
\parinterval 本章将重点介绍机器翻译应用中所面临的问题,以及解决这些问题可以采用的策略。本章所涉及的内容较为广泛,一方面会大量使用本书前十七章的模型和方法,另一方面也会介绍新的技术手段。最终,本章会结合机器翻译的特点展示一些机器翻译可能的应用场景
%----------------------------------------------------------------------------------------
% NEW SECTION
......@@ -37,7 +37,7 @@
\begin{itemize}
\vspace{0.5em}
\item {\small\bfnew{机器翻译模型很脆弱}}。实验环境下,给定翻译任务,甚至给定训练和测试数据,机器翻译模型可以表现的很好。但是,应用场景是不断变化的。经常会出现训练数据缺乏、应用领域与训练数据不匹配、用户的测试方法与开发者不同等等一系列问题。特别是,对于不同的任务,神经机器翻译模型需要进行非常细致的调整,理想中“一套包打天下”的模型和设置是不存在的。这些都导致一个结果:直接使用既有机器翻译模型很难满足不断变化的应用场景
\item {\small\bfnew{机器翻译模型很脆弱}}。实验环境下,给定翻译任务,甚至给定训练和测试数据,机器翻译模型可以表现得很好。但是,应用场景是不断变化的。经常会出现训练数据缺乏、应用领域与训练数据不匹配、用户的测试方法与开发者不同等等一系列问题。特别是,对于不同的任务,神经机器翻译模型需要进行非常细致的调整,理想中“一套包打天下”的模型和设置是不存在的。这些都导致一个结果:直接使用既有机器翻译模型很难满足不断变化的应用需求
\vspace{0.5em}
\item {\small\bfnew{机器翻译缺少针对场景的应用技术}}。目前为止,机器翻译的研究进展已经为我们提供很好的机器翻译基础模型。但是,用户并不是简单的与这些模型“打交道”,他们更加关注如何解决自身的业务需求,例如,机器翻译应用的交互方式、系统是否可以自己预估翻译可信度等等。甚至,在某些场景中,用户对翻译模型的体积和速度都有非常严格的要求。
......@@ -47,7 +47,7 @@
\vspace{0.5em}
\end{itemize}
\parinterval 下面本章将重点对机器翻译应用中的若干技术问题展开讨论,旨在给机器翻译应用提供一些可落地的思路。之后,本章也会结合笔者的经验,对机器翻译的发展方向展开一些讨论。
\parinterval 下面本章将重点对机器翻译应用中的若干技术问题展开讨论,旨在给机器翻译应用提供一些可落地的思路。
%----------------------------------------------------------------------------------------
% NEW SECTION
......@@ -67,9 +67,9 @@
\parinterval 这时就产生一个问题,能否使用新的数据让系统变得更好?简单直接的方式是,将新的数据和原始数据混合重新训练系统,但是使用全量数据训练模型的周期很长,这种方法的成本很高。而且,新的数据可能是不断产生的,甚至是流式的。这时就需要一种快速、低成本的方式对模型进行更新。
\parinterval 增量训练就是满足上述需求的一种方法。本质上来说,神经机器翻译中使用的随机梯度下降方法就是典型的增量训练方法,其基本思想是:每次选择一个样本对模型进行更新,这个过程反复不断执行,每次模型更新都是一次增量训练。当多个样本构成了一个新数据集时,可以把这些新样本作为训练数据,把当前的模型作为初始模型,之后正常执行机器翻译的训练过程即可。如果新增加的数据量不大(比如,几万句对),训练的代价非常低。
\parinterval 增量训练就是满足上述需求的一种方法。{\chapterthirteen}已经就增量训练这个概念展开了一些讨论,这里重点介绍一些具体的实践手段。本质上,神经机器翻译中使用的随机梯度下降方法就是典型的增量训练方法,其基本思想是:每次选择一个样本对模型进行更新,这个过程反复不断执行,每次模型更新都是一次增量训练。当多个样本构成了一个新数据集时,可以把这些新样本作为训练数据,把当前的模型作为初始模型,之后正常执行机器翻译的训练过程即可。如果新增加的数据量不大(比如,几万句对),训练的代价非常低。
\parinterval 这里面的一个问题是,新的数据虽然能代表一部分的翻译现象,但是如果仅仅依赖新数据进行更新,会使模型对新数据过分拟合,进而造成无法很好地处理新数据之外的样本。这也可以被看做是一种灾难性遗忘的问题\upcite{DBLP:conf/coling/GuF20},即:模型过分注重对新样本的拟合,丧失了旧模型的一部分能力。解决这个问题,有几种思路
\parinterval 这里面的一个问题是,新的数据虽然能代表一部分的翻译现象,但是如果仅仅依赖新数据进行更新,会使模型对新数据过分拟合,进而造成无法很好地处理新数据之外的样本。这也可以被看做是一种灾难性遗忘的问题\upcite{DBLP:conf/coling/GuF20},即:模型过分注重对新样本的拟合,丧失了旧模型的一部分能力。在应用系统开发中,有几种常用的增量训练方法
\begin{itemize}
\vspace{0.5em}
......@@ -79,7 +79,7 @@
\item 模型插值\upcite{DBLP:conf/emnlp/WangULCS17}。在增量训练之后,将新模型与旧模型进行插值。
\vspace{0.5em}
\item 多目标训练\upcite{barone2017regularization,DBLP:conf/aclnmt/KhayrallahTDK18,DBLP:conf/naacl/ThompsonGKDK19}。在增量训练时,除了在新数据上定义损失函数之外,可以再定义一个在旧数据上的损失函数,这样确保模型可以在两个数据上都有较好的表现。另一种方案是引入正则化项,使新模型的参数不会偏离旧模型的参数太远。
\item 多目标训练\upcite{barone2017regularization,DBLP:conf/aclnmt/KhayrallahTDK18,DBLP:conf/naacl/ThompsonGKDK19}。在增量训练时,除了在新数据上定义损失函数之外,可以再定义一个在旧数据上的损失函数,这样确保模型可以在两个数据上都有较好的表现。也可以引入正则化项,使新模型的参数不会偏离旧模型的参数太远。
\vspace{0.5em}
\end{itemize}
......@@ -106,11 +106,11 @@
\section{交互式机器翻译}
\parinterval 机器翻译的结果会存在错误,因此很多时候需要人工的修改才能被使用。例如,在{\small\bfnew 译后编辑}\index{译后编辑}(Post-editing)\index{Post-editing}中,译员对机器翻译的译文进行修改,最终使译文达到要求。但是,译后编辑的成本仍然很高,因为它需要译员阅读机器翻译的结果,同时做出修改的动作。有时候,由于译文修改的内容较为复杂,译后编辑的时间甚至比人工直接翻译源语言句子的时间都长。因此在机器翻译应用中,需要更高效的方式调整机器翻译的结果,使其达到可用。比如,可以使用质量评估方法({\chapterfour}),选择模型置信度较高的译文进行译后编辑,对置信度低的译文直接进行人工翻译。而另一种思路是,让人的行为直接影响机器翻译生成译文的过程,让人和机器翻译系统进行交互,在不断的修正中生成更好的译文。这个过程也被称作{\small\bfnew 交互式机器翻译}\index{交互式机器翻译}(Interactive Machine Translation,,IMT)\index{Interactive Machine Translation,,IMT}
\parinterval 机器翻译的结果会存在错误,因此很多时候需要人工的修改才能被使用。例如,在{\small\bfnew 译后编辑}\index{译后编辑}(Post-editing)\index{Post-editing}中,译员对机器翻译的译文进行修改,最终使译文达到要求。但是,译后编辑的成本仍然很高,因为它需要译员阅读机器翻译的结果,同时做出修改的动作。有时候,由于译文修改的内容较为复杂,译后编辑的时间甚至比人工直接翻译源语言句子的时间都长。因此在机器翻译应用中,需要更高效的方式调整机器翻译的结果,使其达到可用。比如,可以使用质量评估方法({\chapterfour}),选择模型置信度较高的译文进行译后编辑,对置信度低的译文直接进行人工翻译。而另一种思路是,让人的行为直接影响机器翻译生成译文的过程,让人和机器翻译系统进行交互,在不断的修正中生成更好的译文。这种方法也被称作{\small\bfnew 交互式机器翻译}\index{交互式机器翻译}(Interactive Machine Translation,,IMT)\index{Interactive Machine Translation,,IMT}
\parinterval 交互式机器翻译的大致流程如下:机器翻译系统根据用户输入的源语言句子预测出可能的译文交给用户,然后用户在现有翻译的基础上进行接受、修改或者删除等操作,然后翻译系统根据用户的反馈信息再次生成比前一次更好的翻译并提交给用户。以此循环,直到得到最终的译文。
\parinterval\ref{fig:18-2}给出了一个使用TranSmart系统\footnote{TranSmart:\url{https://transmart.qq.com/index}}进行交互式机器翻译的例子,在这里我们要将一个汉语句子“疼痛/也/可能/会在/夜间/使/你/醒来。”翻译成英语“The pain may also wake you up during the night .”。在开始交互之前,系统首先推荐一个可能的译文“The pain may also wake you up at night .”。在第一次交互中,用户将单词at替换成during,然后系统根据用户修改后的译文立即给出新的译文候选,提供给用户选择。循环往复,直到用户接受了系统当前推荐的译文。
\parinterval\ref{fig:18-2}给出了一个使用TranSmart系统进行交互式机器翻译的例子,在这里我们要将一个汉语句子“疼痛/也/可能/会在/夜间/使/你/醒来。”翻译成英语“The pain may also wake you up during the night .”。在开始交互之前,系统首先推荐一个可能的译文“The pain may also wake you up at night .”。在第一次交互中,用户将单词at替换成during,然后系统根据用户修改后的译文立即给出新的译文候选,提供给用户选择。循环往复,直到用户接受了系统当前推荐的译文。
%----------------------------------------------
\begin{figure}[htp]
......@@ -124,14 +124,19 @@
\parinterval 交互式机器翻译系统主要通过用户的反馈来提升译文的质量,不同类型的反馈信息则影响着系统最终的性能。根据反馈形式的不同,可以将交互式机器翻译分为以下几种:
\begin{itemize}
\vspace{0.5em}
\item {\small\bfnew 基于前缀的交互式机器翻译}。早期的交互式机器翻译系统都是采用基于前缀的方式。基于翻译系统生成的初始译文,翻译人员从左到右检查翻译的正确性,并在第一个错误的位置进行更正。这为系统提供了一种双重信号:表明该位置上单词必须是译员修改过后的单词,并且该位置之前的单词都是正确的。之后系统根据已经检查过的前缀再生成后面的译文\upcite{DBLP:conf/acl/WuebkerGDHL16,Zens2003EfficientSF,DBLP:journals/coling/BarrachinaBCCCKLNTVV09,DBLP:journals/csl/PerisC19}
\vspace{0.5em}
\item {\small\bfnew 基于片段的交互式机器翻译}。根据用户提供的反馈来生成更好的翻译结果是交互式翻译系统的关键。而基于前缀的系统则存在一个严重的缺陷,当翻译系统获得确定的翻译前缀之后,再重新生成译文时会将原本正确的翻译后缀遗漏了,因此会引入新的错误。在基于片段的交互式机器翻译系统中,翻译人员除了纠正第一个错误的单词,还可以指定在未来迭代中保留的单词序列。之后系统根据这些反馈信号再生成新的译文\upcite{Peris2017InteractiveNM,DBLP:journals/mt/DomingoPC17}
\vspace{0.5em}
\item {\small\bfnew 基于评分的交互式机器翻译}。随着计算机算力的提升,有时会出现“机器等人”的现象,因此需要提升人参与交互的效率也是需要考虑的。与之前的系统不同,基于评分的交互式机器翻译系统不需要译员选择、纠正或删除某个片段,而是使用译员对译文的评分来强化机器翻译的学习\upcite{DBLP:journals/corr/abs-1805-01553,DBLP:conf/emnlp/NguyenDB17}
\vspace{0.5em}
\end{itemize}
\parinterval 除此之外,基于在线学习的框架越来越引发人们的关注。在学习过程中,用户希望翻译系统能从反馈中自动纠正以前的错误。当用户最终确认一个修改过后的译文后,翻译系统将源语与该修正后的译文作为训练语料继续训练\upcite{DBLP:conf/acl/DomingoGEBHPCH19}。实际上,交互式机器翻译是机器翻译大规模应用的重要路径之一,它为打通译员和机器翻译系统之间的障碍提供了手段。不过,交互式机器翻译也有许多挑战等待解决。一个是如何设计交互方式?理想的交互方式应该式更加贴近译员输入文字的习惯,比如,利用输入法完成交互;另一个是如何把交互式翻译嵌入到翻译的生产流程里?这本身不完全是一个技术问题,可能需要更多的产品手段来求解。
\parinterval 除此之外,基于在线学习的方法也受到了关注,这类方法也可以被看作是交互式翻译与增量训练的一种结合。用户总是希望翻译系统能从反馈中自动纠正以前的错误。当用户最终确认一个修改过后的译文后,翻译系统将源语与该修正后的译文作为训练语料继续训练\upcite{DBLP:conf/acl/DomingoGEBHPCH19}。实际上,交互式机器翻译是机器翻译大规模应用的重要路径之一,它为打通译员和机器翻译系统之间的障碍提供了手段。不过,交互式机器翻译也有许多挑战等待解决。一个是如何设计交互方式?理想的交互方式应该式更加贴近译员输入文字的习惯,比如,利用输入法完成交互;另一个是如何把交互式翻译嵌入到翻译的生产流程里?这本身不完全是一个技术问题,可能需要更多的产品手段来求解。
%----------------------------------------------------------------------------------------
......@@ -140,12 +145,12 @@
\section{翻译结果可干预性}
\parinterval 交互式机器翻译体现了一种用户的行为“干预”机器翻译结果的思想。实际上,在机器翻译出现错误时,人们总是希望用一种直接有效的方式“改变”译文,到达改善翻译质量的目的。比如,如果机器翻译系统可以输出多个候选译文,用户可以在其中挑选最好的译文进行输出。也就是,人干预了译文候选的排序过程。另一个例子是使用{\small\bfnew{翻译记忆}}\index{翻译记忆}(Translation Memory\index{Translation Memory})改善机器翻译系统的性能。翻译记忆记录了高质量的源语言-目标语言句对,有时也可以被看作是一种先验知识或“记忆”。因此,当进行机器翻译(包括统计机器翻译和神经机器翻译)时,使用翻译记忆指导翻译过程也可以被看作是一种干预手段\upcite{DBLP:conf/acl/WangZS13,DBLP:conf/aaai/XiaHLS19}
\parinterval 交互式机器翻译体现了一种用户的行为“干预”机器翻译结果的思想。实际上,在机器翻译出现错误时,人们总是希望用一种直接有效的方式“改变”译文,最短时间内达到改善翻译质量的目的。比如,如果机器翻译系统可以输出多个候选译文,用户可以在其中挑选最好的译文进行输出。也就是,人干预了译文候选的排序过程。另一个例子是使用{\small\bfnew{翻译记忆}}\index{翻译记忆}(Translation Memory\index{Translation Memory})改善机器翻译系统的性能。翻译记忆记录了高质量的源语言-目标语言句对,有时也可以被看作是一种先验知识或“记忆”。因此,当进行机器翻译时,使用翻译记忆指导翻译过程也可以被看作是一种干预手段\upcite{DBLP:conf/acl/WangZS13,DBLP:conf/aaai/XiaHLS19}
\parinterval 虽然干预机器翻译系统的方式很多,最常用的还是对源语言特定片段翻译的干预,以期望最终句子的译文中满足某些对片段翻译的约束。这个问题也被称作{\small\bfnew{基于约束的翻译}}\index{基于约束的翻译} (Constraint-based Translation\index{Constraint-based Translation})。比如,在翻译网页时,需要保持译文中的网页标签与源文一致。另一个典型例子是术语翻译。在实际应用中,经常会遇到公司名称、品牌名称、产品名称等专有名词和行业术语,以及不同含义的缩写,比如,对于“小牛翻译”这个专有术语,不同的机器翻译系统给出的结果不一样:“Maverick translation”、“Calf translation”、“The mavericks translation”…… 而它正确的翻译应该为“NiuTrans”。 对于这些类似的特殊词汇,大多数机器翻译引擎很难翻译得准确。一方面,因为模型大多是在通用数据集上训练出来的,并不能保证数据集能涵盖所有的语言现象。另一方面,即使是这些术语在训练数据中出现,它们通常也是低频的,模型比较难学到。为了保证翻译的准确性,对术语翻译进行干预是十分有必要的,这对领域适应等问题的求解也是非常有意义的。
\parinterval 虽然干预机器翻译系统的方式很多,最常用的还是对源语言特定片段翻译的干预,以期望最终句子的译文满足某些约束。这个问题也被称作{\small\bfnew{基于约束的翻译}}\index{基于约束的翻译} (Constraint-based Translation\index{Constraint-based Translation})。比如,在翻译网页时,需要保持译文中的网页标签与源文一致。另一个典型例子是术语翻译。在实际应用中,经常会遇到公司名称、品牌名称、产品名称等专有名词和行业术语,以及不同含义的缩写,比如,对于“小牛翻译”这个专有名词,不同的机器翻译系统给出的结果不一样:“Maverick translation”、“Calf translation”、“The mavericks translation”…… 而它正确的翻译应该为“NiuTrans”。 对于这些类似的特殊词汇,大多数机器翻译引擎很难翻译得准确。一方面,因为模型大多是在通用数据集上训练出来的,并不能保证数据集能涵盖所有的语言现象。另一方面,即使是这些术语在训练数据中出现,它们通常也是低频的,模型不容易捕捉它们的规律。为了保证翻译的准确性,对术语翻译进行干预是十分有必要的,这对领域适应等问题的求解也是非常有意义的。
\parinterval{\small\bfnew 术语翻译}\index{术语翻译}(Lexically Constrained Translation)\index{Lexically Constrained Translation}而言,在不干预的情况下让模型直接翻译出正确术语是很难的,因为目标术语翻译词很可能是未登录词,因此必须人为提供额外的术语词典,那么我们的目标就是让模型的翻译输出遵守用户提供的术语约束。这个过程如图\ref{fig:18-3}所示。
\parinterval{\small\bfnew 词汇约束翻译}\index{词汇约束翻译}(Lexically Constrained Translation)\index{Lexically Constrained Translation}而言,在不干预的情况下让模型直接翻译出正确术语是很难的,因为目标术语翻译词很可能是未登录词,因此必须人为提供额外的术语词典,那么我们的目标就是让模型的翻译输出遵守用户提供的术语约束。这个过程如图\ref{fig:18-3}所示。
%----------------------------------------------
\begin{figure}[htp]
\centering
......@@ -156,11 +161,11 @@
\end{figure}
%----------------------------------------------
\parinterval 在统计机器翻译中,翻译本质上是由短语和规则构成的推导,因此修改译文比较容易,比如,可以在一个源语言片段所对应的翻译候选集中添加希望得到的译文即可。而神经机器翻译是一个端到端模型,内部基于连续空间的实数向量表示,翻译过程本质上是连续空间中元素的一系列映射、组合和代数运算,因此无法像修改符号系统那样直接修改模型并加入离散化的约束来影响译文生成。目前主要有两种解决思路:
\parinterval 在统计机器翻译中,翻译本质上是由短语和规则构成的推导,因此修改译文比较容易,比如,可以在一个源语言片段所对应的翻译候选集中添加希望得到的译文即可。而神经机器翻译是一个端到端模型,翻译过程本质上是连续空间中元素的一系列映射、组合和代数运算,因此无法像修改符号系统那样直接修改模型并加入离散化的约束来影响译文生成。目前主要有两种解决思路:
\begin{itemize}
\vspace{0.5em}
\item 强制生成。这种方法并不改变模型,而是在解码过程中按照一定的策略来实施约束,一般是修改束搜索算法以确保输出必须包含指定的词或者短语\upcite{DBLP:conf/acl/HokampL17,DBLP:conf/naacl/PostV18,DBLP:conf/wmt/ChatterjeeNTFSB17,DBLP:conf/naacl/HaslerGIB18},例如,在获得译文输出后,利用注意力机制获取词对齐,之后通过词对齐对指定部分译文进行强制替换。或者,对包含正确术语翻译的翻译候选进行额外的加分,以确保解码时这样的翻译候选的排名足够靠前。
\item 强制生成。这种方法并不改变模型,而是在解码过程中按照一定的策略来实施约束,一般是修改束搜索算法以确保输出必须包含指定的词或者短语\upcite{DBLP:conf/acl/HokampL17,DBLP:conf/naacl/PostV18,DBLP:conf/wmt/ChatterjeeNTFSB17,DBLP:conf/naacl/HaslerGIB18},例如,在获得译文输出后,利用注意力机制获取词对齐,之后通过词对齐得到源语言和目标语言片段的对应关系,最后对指定译文片段进行强制替换。或者,对包含正确术语翻译的翻译候选进行额外的加分,以确保解码时这样的翻译候选的排名足够靠前。
\vspace{0.5em}
\item 数据增强。这类方法通过修改机器翻译模型的数据和训练过程来实现约束。通常是根据术语词典对源语言句子进行一定的修改,例如,将术语的译文编辑到源语言句子中,之后将原始语料库和合成语料库进行混合训练,期望模型能够自动利用术语信息来指导解码,或者是利用占位符来替换源语中的术语,待翻译完成后再进行还原\upcite{DBLP:conf/naacl/SongZYLWZ19,DBLP:conf/acl/DinuMFA19,DBLP:journals/corr/abs-1912-00567,DBLP:conf/ijcai/ChenCWL20}
......@@ -168,7 +173,7 @@
\vspace{0.5em}
\end{itemize}
\parinterval 强制生成的方法是在搜索策略上进行限制,与模型无关,这类方法能保证输出满足约束,但是会影响翻译速度。数据增强的方法是通过构造特定格式的数据让模型训练,从而让模型具有一定的泛化能力,这类方法需要进行译前译后编辑,通常不会影响翻译速度,但并不能保证输出能满足约束。
\parinterval 强制生成的方法是在搜索策略上进行限制,与模型无关,这类方法能保证输出满足约束,但是会影响翻译速度。数据增强的方法是通过构造特定格式的数据让模型训练,从而让模型具有一定的泛化能力,通常不会影响翻译速度,但并不能保证输出能满足约束。
\parinterval 此外,机器翻译在应用时通常还需要进行译前译后的处理,译前处理指的是在翻译前对源语言句子进行修改和规范,从而能生成比较顺畅的译文,提高译文的可读性和准确率。在实际应用时,由于用户输入的形式多样,可能会包含比如术语、缩写、数学公式等,有些甚至可能还包含网页标签,因此对源文进行预处理是很有必要的。常见的处理工作包括格式转换、标点符号检査、术语编辑、标签识别等,待翻译完成后,则需要对机器译文进行进一步的编辑和修正,从而使其符合使用规范,比如进行标点、格式检查,术语、标签还原等,这些过程通常都是按照设定的处理策略自动完成的。另外,译文长度的控制、译文多样性的控制等也可以丰富机器翻译系统干预的手段(见{\chapterfourteen})。
......@@ -178,13 +183,13 @@
\section{小设备机器翻译}
\parinterval 在机器翻译研究中,一般会假设计算资源是充足的。但是,在很多应用场景中,机器翻译使用的计算资源非常有限,比如,一些离线设备上没有GPU处理器,而且CPU的处理能力也很弱,甚至内存也非常有限。这时,让模型变得更小、系统变得更快就成为了一个重要的需求。
\parinterval 在机器翻译研究中,一般会假设计算资源是充足的。但是,在很多应用场景中,机器翻译使用的计算资源非常有限,比如,一些离线设备上没有GPU处理器,而且CPU的处理能力也很弱,甚至内存也非常有限。这时,让模型变得更小、系统变得更快就成为了重要的需求。
\parinterval 本书中已经讨论了大量的可用于小设备上的机器翻译技术方法,例如:
\begin{itemize}
\vspace{0.5em}
\item 知识蒸馏({\chapterthirteen})。这种方法可以有效地翻译能力从大模型迁移到小模型。
\item 知识蒸馏({\chapterthirteen})。这种方法可以有效地翻译能力从大模型迁移到小模型。
\vspace{0.5em}
\item 低精度存储及计算({\chapterfourteen})。可以使用量化的方式将模型压缩,同时整数型计算也非常适合在CPU等设备上执行。
......@@ -243,14 +248,15 @@
\vspace{0.5em}
\end{itemize}
\parinterval 除了上述问题,如何对多设备环境下进行负载均衡、容灾处理等都是大规模机器翻译系统部署中需要考虑的。有时候,甚至统计机器翻译系统也可以与神经机器翻译系统混合使用。由于统计机器翻译系统对GPU设备的要求较低,纯CPU部署的方案也相对成熟。因此,可以作为GPU机器翻译服务的灾备。此外,在有些任务,特别是低资源翻译任务上,统计机器翻译仍然具有优势。
\parinterval 除了上述问题,如何对多设备环境下进行负载均衡、容灾处理等都是大规模机器翻译系统部署中需要考虑的。有时候,甚至统计机器翻译系统也可以与神经机器翻译系统混合使用。由于统计机器翻译系统对GPU资源的要求较低,纯CPU部署的方案也相对成熟。因此,可以作为GPU机器翻译服务的灾备。此外,在有些任务,特别是某些低资源翻译任务上,统计机器翻译仍然具有优势。
%----------------------------------------------------------------------------------------
% NEW SECTION
%----------------------------------------------------------------------------------------
\section{机器翻译的应用场景}
\parinterval 机器翻译有着十分广泛的应用,下面看一下机器翻译在生活中的具体应用形式:
\parinterval 机器翻译有着十分广泛的应用,这里列举了一些常见的应用场景:
\parinterval (一)网页翻译
......@@ -272,23 +278,19 @@
\parinterval 在一些国际会议中,与会者来自许多不同的国家,为了保证会议的流畅,通常需要专业译员进行同声传译。同声传译需要在不打断演讲的同时,不间断地将讲话内容进行口译,对翻译人员的素质要求极高,成本高昂。现在,一些会议开始采用语音识别来将语音转换成文本,同时使用机器翻译技术进行翻译的方式,达到同步翻译的目的。这项技术已经得到了多个企业的关注,并在很多重要会议上进行尝试,取得了很好的反响。不过同声传译达到真正的使用还需一定时间的打磨,特别是会议场景下,准确进行语音识别和翻译仍然具有挑战性。
\parinterval (六)医药领域翻译
\parinterval 在医药领域中,从药品研发、临床试验到药品注册,都有着大量的翻译需求。比如,在新药注册阶段,限定申报时间的同时,更是对翻译质量有着极高的要求。由于医药领域专业词汇量庞大、单词冗长复杂、术语准确且文体专业性强,翻译难度明显高于其他领域,人工翻译的方式代价大且很难满足效率的要求。为此,机器翻译近几年在医药领域取得广泛应用。在针对医药领域进行优化后,机器翻译质量可以很好地满足翻译的要求。
\parinterval (七)中国传统语言文化的翻译
\parinterval (六)中国传统语言文化的翻译
\parinterval 中国几千年的历史留下了极为宝贵的文化遗产,而其中,文言文作为古代书面语,具有言文分离、行文简练的特点,易于流传。言文分离的特点使得文言文和现在的标准汉语具有一定的区别。为了更好发扬中国传统文化,我们需要对文言文进行翻译。而文言文古奥难懂,人们需要具备一定的文言文知识背景才能准确翻译。机器翻译技术也可以帮助人们快速完成文言文的翻译。除此之外,机器翻译技术同样可以用于古诗生成和对联生成等任务。
\parinterval)全球化
\parinterval)全球化
\parinterval 在经济全球化的今天,很多企业都有国际化的需求,企业员工或多或少地会遇到一些跨语言阅读和交流的情况,比如阅读进口产品的说明书,跨国公司之间的邮件、说明文件等等。相比于成本较高的人工翻译,机器翻译往往是一种很好的选择。在一些质量要求不高的翻译场景中,机器翻译可以得到应用。
\parinterval九)翻译机
\parinterval八)翻译机/翻译笔
\parinterval 出于商务、学术交流或者旅游的目的,人们在出国时会面临着跨语言交流的问题。近几年,随着出境人数的增加,不少企业推出了翻译机产品。通过结合机器翻译、语音识别和图像识别技术,翻译机实现了图像翻译和语音翻译的功能。用户可以很便捷地获取一些外语图像文字和语音信息,同时可以通过翻译机进行对话,降低跨语言交流门槛。
\parinterval 出于商务、学术交流或者旅游的目的,人们在出国时会面临着跨语言交流的问题。近几年,随着出境人数的增加,不少企业推出了翻译机产品。通过结合机器翻译、语音识别和图像识别技术,翻译机实现了图像翻译和语音翻译的功能。用户可以很便捷地获取一些外语图像文字和语音信息,同时可以通过翻译机进行对话,降低跨语言交流门槛。类似的,翻译笔等应用产品可以通过划词翻译的方式,对打印材料中的外语文字进行翻译。
\parinterval)翻译结果后编辑
\parinterval)翻译结果后编辑
\parinterval 翻译结果后编辑是指在机器翻译的结果之上,通过少量的人工编辑来进一步完善机器译文。在传统的人工翻译过程中,翻译人员完全依靠人工的方式进行翻译,这虽然保证了翻译质量,但是时间成本高。相对应的,机器翻译具有速度快和成本低的优势。在一些领域,目前的机器翻译质量已经可以很大程度上减小翻译人员的工作量,翻译人员可以在机器翻译的辅助下,花费相对较小的代价来完成翻译。
......
......@@ -34,8 +34,8 @@
%----------------------------------------------
\begin{figure}[htp]
\centering
\subfigure[机器翻译系统被看作一个黑盒] {\input{./Chapter3/Figures/figure-mt-system-as-a-black-box} }
\subfigure[机器翻译系统 = 前/后处理 + 核心引擎] {\input{./Chapter3/Figures/figure-mt=language-analysis+translation-engine}}
\subfigure[\small{机器翻译系统被看作一个黑盒}] {\input{./Chapter3/Figures/figure-mt-system-as-a-black-box} }
\subfigure[\small{机器翻译系统 = 前/后处理 + 核心引擎}] {\input{./Chapter3/Figures/figure-mt=language-analysis+translation-engine}}
\caption{机器翻译系统的结构}
\label{fig:3.1-1}
\end{figure}
......@@ -253,8 +253,8 @@ $计算这种切分的概率值。
%----------------------------------------------
\begin{figure}[htp]
\centering
\subfigure[BIO格式标注命名实体] {\input{./Chapter3/Figures/figure-labeling-named-entities-in-bio-format} }
\subfigure[BIOES格式标注命名实体] {\input{./Chapter3/Figures/figure-labeling-named-entities-in-bioes-format}}
\subfigure[\small{BIO格式标注命名实体}] {\input{./Chapter3/Figures/figure-labeling-named-entities-in-bio-format} }
\subfigure[\small{BIOES格式标注命名实体}] {\input{./Chapter3/Figures/figure-labeling-named-entities-in-bioes-format}}
\caption{BIO和BIOES格式对比}
\label{fig:3.3-1}
\end{figure}
......@@ -514,7 +514,7 @@ Z(\seq{x})&=&\sum_{\seq{y}}\exp(\sum_{i=1}^m\sum_{j=1}^k\lambda_{j}F_{j}(y_{i-1}
\begin{figure}[htp]
\centering
\begin{tabular}{l l l}
\subfigure[HMM处理序列标注]{\input{./Chapter3/Figures/figure-process-sequence-labeling-by-hmm}} & \subfigure[CRF处理序列标注]{\input{./Chapter3/Figures/figure-process-sequence-labeling-by-crf}} & \subfigure[分类模型处理序列标注]{\input{./Chapter3/Figures/figure-process-sequence-labeling-by-classfication}}
\subfigure[\small{HMM处理序列标注}]{\input{./Chapter3/Figures/figure-process-sequence-labeling-by-hmm}} & \subfigure[\small{CRF处理序列标注}]{\input{./Chapter3/Figures/figure-process-sequence-labeling-by-crf}} & \subfigure[\small{分类模型处理序列标注}]{\input{./Chapter3/Figures/figure-process-sequence-labeling-by-classfication}}
\end{tabular}
\caption{HMM、CRF、分类算法三种方法对比}
\label{fig:3.3-7}
......
......@@ -149,7 +149,7 @@
\item {\small\sffamily\bfseries{根据冲突次数进行排序}}\upcite{DBLP:conf/wmt/Lopez12}。第一种排序策略中存在冲突现象:例如在每次两两比较中,系统${S}_j$胜过系统${S}_k$ 的次数比系统${S}_j$不敌系统${S}_k$的次数多,若待评价系统仅有系统${S}_j$${S}_k$,显然系统${S}_j$的排名高于系统${S}_k$。但当待评价系统很多时,可能系统${S}_j$在所有比较中获胜的次数低于系统${S}_k$,此时就出现了总体排序与局部排序不一致的冲突。因此,有研究者提出,能够与局部排序冲突最少的总体排序才是最合理的。令$O$表示一个对若干个系统的排序,该排序所对应的冲突定义为:
\begin{eqnarray}
\textrm{conflict}(O) &=& \sum\limits_{{{S}_j} \in O,{{S}_k} \in O,j \ne k} {{\textrm{max}}(0,\textrm{count}_{\textrm{win}}({{S}_j},{{S}_k}) - \textrm{count}_{\textrm{loss}}({{S}_j},{{S}_k}))}
\textrm{conflict}(O) =\sum\limits_{{{S}_j},{{S}_k} \in O,j \ne k} {{\textrm{max}}(0,\textrm{count}_{\textrm{win}}({{S}_j},{{S}_k}) - \textrm{count}_{\textrm{loss}}({{S}_j},{{S}_k}))}
\label{eq:4-1}
\end{eqnarray}
......@@ -297,8 +297,8 @@
%----------------------------------------------
\begin{figure}[htp]
\centering
\subfigure[“绝对”匹配词对齐-1]{\input{./Chapter4/Figures/figure-absolute-match-word-alignment-1}}
\subfigure[“绝对”匹配词对齐-2]{\input{./Chapter4/Figures/figure-absolute-match-word-alignment-2}}
\subfigure[\small{“绝对”匹配词对齐-1}]{\input{./Chapter4/Figures/figure-absolute-match-word-alignment-1}}
\subfigure[\small{“绝对”匹配词对齐-2}]{\input{./Chapter4/Figures/figure-absolute-match-word-alignment-2}}
\caption{“绝对”匹配模型}
\label{fig:4-3}
\end{figure}
......@@ -490,8 +490,8 @@ His house is on the south bank of the river.
%----------------------------------------------
\begin{figure}[htp]
\centering
\subfigure[英语参考答案集表示]{\input{./Chapter4/Figures/figure-representation-of-english-reference-answer-set}}
\subfigure[捷克语参考答案集表示]{\input{./Chapter4/Figures/figure-representation-of-czech-reference-answer-set}}
\subfigure[\small{英语参考答案集表示}]{\input{./Chapter4/Figures/figure-representation-of-english-reference-answer-set}}
\subfigure[\small{捷克语参考答案集表示}]{\input{./Chapter4/Figures/figure-representation-of-czech-reference-answer-set}}
\caption{使用HyTER构造的参考答案集}
\label{fig:4-8}
\end{figure}
......@@ -815,11 +815,11 @@ d&=&t \frac{s}{\sqrt{n}}
\begin{example}
文档级质量评估任务
Candidate: A {\red housewife} won the first prize in the supermarket's anniversary
上文信息:A {\red housewife} won the first prize in the supermarket's anniversary
\hspace{5em}celebration.
Reference: A few days ago, {\red he} contacted the News Channel and said that the
机器译文:A few days ago, {\red he} contacted the News Channel and said that the
\hspace{5em}supermarket owner refused to give {\red him} the prize.
\label{eg:4-9}
......
......@@ -1082,7 +1082,7 @@ c_{\mathbb{E}}(s_u|t_v)&=&\sum\limits_{k=1}^{K} c_{\mathbb{E}}(s_u|t_v;s^{[k]},
\begin{itemize}
\vspace{0.5em}
\item 在IBM基础模型之上,有很多改进的工作。例如,对空对齐、低频词进行额外处理\upcite{DBLP:conf/acl/Moore04};考虑源语言-目标语言和目标语言-源语言双向词对齐进行更好地词对齐对称化\upcite{肖桐1991面向统计机器翻译的重对齐方法研究};使用词典、命名实体等多种信息对模型进行改进\upcite{2005Improvin};通过引入短语增强IBM基础模型\upcite{1998Grammar};引入相邻单词对齐之间的依赖关系增加模型鲁棒\upcite{DBLP:conf/acl-vlc/DaganCG93}等;也可以对IBM模型的正向和反向结果进行对称化处理,以得到更加准确词对齐结果\upcite{och2003systematic}
\item 在IBM基础模型之上,有很多改进的工作。例如,对空对齐、低频词进行额外处理\upcite{DBLP:conf/acl/Moore04};考虑源语言-目标语言和目标语言-源语言双向词对齐进行更好地词对齐对称化\upcite{肖桐1991面向统计机器翻译的重对齐方法研究};使用词典、命名实体等多种信息对模型进行改进\upcite{2005Improvin};通过引入短语增强IBM基础模型\upcite{1998Grammar};引入相邻单词对齐之间的依赖关系增加模型健壮\upcite{DBLP:conf/acl-vlc/DaganCG93}等;也可以对IBM模型的正向和反向结果进行对称化处理,以得到更加准确词对齐结果\upcite{och2003systematic}
\item 随着词对齐概念的不断深入,也有很多词对齐方面的工作并不依赖IBM模型。比如,可以直接使用判别式模型利用分类器解决词对齐问题\upcite{ittycheriah2005maximum};使用带参数控制的动态规划方法来提高词对齐准确率\upcite{DBLP:conf/naacl/GaleC91};甚至可以把对齐的思想用于短语和句法结构的双语对应\upcite{xiao2013unsupervised};无监督的对称词对齐方法,正向和反向模型联合训练,结合数据的相似性\upcite{DBLP:conf/naacl/LiangTK06};除了GIZA++,研究人员也开发了很多优秀的自动对齐工具,比如,FastAlign\upcite{DBLP:conf/naacl/DyerCS13}、Berkeley Word Aligner\upcite{taskar2005a}等,这些工具现在也有很广泛的应用。
......
......@@ -7,7 +7,7 @@
\foreach \y in {1.0,0.5}{\draw(0,\y)--(0.05,\y)node[left,outer sep=2pt,font=\scriptsize]at(0,\y){\y};}
\draw[color=red ,domain=-1.4:1, line width=1pt]plot(\x,{ln(1+(exp(\x))});
\node[black,anchor=south] at (0,1.4) {\small $y = \ln(1+{\textrm e}^x)$};
\node [anchor=south east,inner sep=1pt] (labela) at (0.8,-2) {\footnotesize{(a) Softplus}};
\node [anchor=south east,inner sep=1pt] (labela) at (0.8,-2) {\small{(a) Softplus}};
\end{scope}
%%%------------------------------------------------------------------------------------------------------------
......@@ -22,7 +22,7 @@
\foreach \y in {0.5,1.0}{\draw(0,\y)--(0.05,\y)node[left,outer sep=2pt,font=\scriptsize]at(-0.15,\y){\y};}
\draw[color=red,domain=-1.4:1.4, line width=1pt]plot(\x,{1/(1+(exp(-5*\x)))});
\node[black,anchor=south] at (0,1.4) {\small $y = \frac{1}{1+{\textrm e}^{-x}}$};
\node [anchor=south east,inner sep=1pt] (labelb) at (0.8,-2) {\footnotesize{(b) Sigmoid}};
\node [anchor=south east,inner sep=1pt] (labelb) at (0.8,-2) {\small{(b) Sigmoid}};
\end{scope}
%%%------------------------------------------------------------------------------------------------------------
......@@ -35,7 +35,7 @@
\foreach \y in {,-1.0-0.5,0.5,1.0}{\draw(0,\y)--(0.05,\y)node[left,outer sep=2pt,font=\scriptsize]at(0,\y){\y};}
\draw[color=red ,domain=-1.4:1.4, line width=1pt]plot(\x,{tanh(\x)});
\node[black,anchor=south] at (0,1.4) {\small $y = \frac{{\textrm e}^{x}-{\textrm e}^{-x}}{{e}^{x}+e^{-x}}$};
\node [anchor=south east,inner sep=1pt] (labelc) at (0.8,-2) {\footnotesize{(c) Tanh}};
\node [anchor=south east,inner sep=1pt] (labelc) at (0.8,-2) {\small{(c) Tanh}};
\end{scope}
%%%------------------------------------------------------------------------------------------------------------
......@@ -47,7 +47,7 @@
\foreach \y in {0.5,1.0}{\draw(0,\y)--(0.05,\y)node[left,outer sep=2pt,font=\scriptsize]at(0,\y){\y};}
\draw[color=red ,domain=-1.4:1.4, line width=1pt]plot(\x,{max(\x,0)});
\node[black,anchor=south] at (0,1.4) {\small $y =\max (0, x)$};
\node [anchor=south east,inner sep=1pt] (labeld) at (0.8,-2) {\footnotesize{(d) ReLU}};
\node [anchor=south east,inner sep=1pt] (labeld) at (0.8,-2) {\small{(d) ReLU}};
\end{scope}
%%%------------------------------------------------------------------------------------------------------------
......@@ -58,7 +58,7 @@
\foreach \y in {0.5,1.0}{\draw(0,\y)--(0.05,\y)node[left,outer sep=2pt,font=\scriptsize]at(-0.15,\y){\y};}
\draw[color=red ,domain=-1.4:1.4, line width=1pt]plot(\x,{exp(-1*((\x)^2))});
\node[black,anchor=south] at (0,1.4) {\small $y =e^{-x^2}$};
\node [anchor=south east,inner sep=1pt] (labele) at (0.8,-2) {\footnotesize{(e) Gaussian}};
\node [anchor=south east,inner sep=1pt] (labele) at (0.8,-2) {\small{(e) Gaussian}};
\end{scope}
%%%------------------------------------------------------------------------------------------------------------
......@@ -69,7 +69,7 @@
\foreach \y in {0.5,1.0}{\draw(0,\y)--(0.05,\y)node[left,outer sep=2pt,font=\scriptsize]at(0,\y){\y};}
\draw[color=red ,domain=-1:1, line width=1pt]plot(\x,\x);
\node[black,anchor=south] at (0,1.4) {\small $y =x$};
\node [anchor=south east,inner sep=1pt] (labelf) at (0.8,-2) {\footnotesize{(f) Identity}};
\node [anchor=south east,inner sep=1pt] (labelf) at (0.8,-2) {\small{(f) Identity}};
\end{scope}
\end{tikzpicture}
%%%------------------------------------------------------------------------------------------------------------
\ No newline at end of file
......@@ -8,7 +8,7 @@
\draw [-] (-0.05,1) -- (0.05,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] (labela) at (0.2,-0.5) {\footnotesize{(a)}};
\node [anchor=south east,inner sep=1pt] (labela) at (0.2,-0.5) {\small{(a)}};
}
{\node [anchor=north west,align=left] (wblabel) at (-1.8,2) {{\scriptsize{\ $w_{11}=100$}}\\[-0ex] \scriptsize{\ $b_1=0$}};}
{\draw [-,very thick,ublue,rounded corners=0.1em] (-1.5,0) -- (0,0) -- (0,1) -- (1.5,1);}
......@@ -21,7 +21,7 @@
\draw [-] (-0.05,1) -- (0.05,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] (labelb) at (0.2,-0.5) {\footnotesize{(b)}};
\node [anchor=south east,inner sep=1pt] (labelb) at (0.2,-0.5) {\small{(b)}};
}
{\node [anchor=north west,align=left] (wblabel) at (-1.8,2) {\scriptsize{\ $w_{11}=100$}\\[-0ex] {\scriptsize{\ $b_1=-2$}}};}
{\draw [-,very thick,ublue,rounded corners=0.1em] (-1.5,0) -- (0.25,0) -- (0.25,1) -- (1.5,1);}
......@@ -34,7 +34,7 @@
\draw [-] (-0.05,1) -- (0.05,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] (labelc) at (0.2,-0.5) {\footnotesize{(c)}};
\node [anchor=south east,inner sep=1pt] (labelc) at (0.2,-0.5) {\small{(c)}};
}
{\node [anchor=north west,align=left] (wblabel) at (-1.8,2) {\scriptsize{\ $w_{11}=100$}\\[-0ex] {\scriptsize{\ $b_1=-4$}}};}
{\draw [-,very thick,ublue,rounded corners=0.1em] (-1.5,0) -- (0.5,0) -- (0.5,1) -- (1.5,1);}
......
......@@ -9,7 +9,7 @@
\addtocounter{mycount1}{1};
}
\node [anchor=south] (varlabel) at (0,0.6) {$\mathbi{s}$};
\node [anchor=north] (labelc) at (0,-0.7) {\footnotesize{(a)}};
\node [anchor=north] (labelc) at (0,-0.7) {\small{(a)}};
\end{scope}
\begin{scope}[xshift=2.1in]
......@@ -21,7 +21,7 @@
\addtocounter{mycount1}{1};
}
\node [anchor=south] (varlabel) at (0,0.1) {$\mathbi{b}$};
\node [anchor=north] (labelc) at (0,-0.7) {\footnotesize{(b)}};
\node [anchor=north] (labelc) at (0,-0.7) {\small{(b)}};
\end{scope}
......@@ -51,7 +51,7 @@
}
\node [anchor=center] (plabel) at (-4.5em,0) {\huge{$\mathbf{+}$}};
\node [anchor=south] (varlabel) at (0,0.6) {$\mathbi{b}$};
\node [anchor=north] (labelc) at (0,-0.7) {\footnotesize{(c)}};
\node [anchor=north] (labelc) at (0,-0.7) {\small{(c)}};
\end{scope}
\begin{scope}[yshift=-1in,xshift=3in]
\setcounter{mycount1}{2}
......
......@@ -10,7 +10,7 @@
\draw [-,ublue] (n10.west) -- (n10.east);
\draw [-,ublue] (n11.west) -- (n11.east);
\node [anchor=north] (x1) at ([yshift=-6em]n11.south) {$x_1$};
\node [anchor=north] (labela) at ([xshift=3.5em,yshift=-0.5em]x1.south) {\footnotesize{(a) 拟合一小段函数}};
\node [anchor=north] (labela) at ([xshift=3.5em,yshift=-0.5em]x1.south) {\small{(a) 拟合一小段函数}};
\node [anchor=north] (b) at ([yshift=-6em]n10.south) {$\mathbi{b}$};
{
\draw [->,thick,red] (b.north) -- ([yshift=-0.1em]n10.south);
......@@ -92,7 +92,7 @@
\draw [-,ublue] (n10.west) -- (n10.east);
\draw [-,ublue] (n11.west) -- (n11.east);
\node [anchor=north] (x1) at ([yshift=-6em]n11.south) {$x_1$};
\node [anchor=north] (labelb) at ([xshift=6em,yshift=-0.5em]x1.south) {\footnotesize{(b) 拟合更大一段函数}};
\node [anchor=north] (labelb) at ([xshift=6em,yshift=-0.5em]x1.south) {\small{(b) 拟合更大一段函数}};
\node [anchor=north] (b) at ([yshift=-6em]n10.south) {$\mathbi{b}$};
{
\draw [->,thick,red] (b.north) -- ([yshift=-0.1em]n10.south);
......
......@@ -32,13 +32,13 @@
}
{
\draw[->,very thick,red] ([xshift=-0.5em,yshift=2pt]processor2.north) -- ([xshift=-0.5em,yshift=-2pt]serverbox.south) node [pos=0.5,align=right,xshift=-2em] (pushlabel) {\footnotesize{$\frac{\partial J}{\partial{\bm \theta}}$}};;
\draw[<-,very thick,blue] ([xshift=0.5em,yshift=2pt]processor2.north) -- ([xshift=0.5em,yshift=-2pt]serverbox.south) node [pos=0.5,align=left,xshift=2.2em] (fetchlabel) {\footnotesize{${\bm \theta}_{\textrm{new}}$}};;;
\draw[->,very thick,red] ([xshift=-0.5em,yshift=2pt]processor3.north) --
\draw[->,very thick,red!70] ([xshift=-0.5em,yshift=2pt]processor2.north) -- ([xshift=-0.5em,yshift=-2pt]serverbox.south) node [pos=0.5,align=right,xshift=-2em] (pushlabel) {\footnotesize{$\frac{\partial J}{\partial{\bm \theta}}$}};;
\draw[<-,very thick,ublue!90] ([xshift=0.5em,yshift=2pt]processor2.north) -- ([xshift=0.5em,yshift=-2pt]serverbox.south) node [pos=0.5,align=left,xshift=2.2em] (fetchlabel) {\footnotesize{${\bm \theta}_{\textrm{new}}$}};;;
\draw[->,very thick,red!70] ([xshift=-0.5em,yshift=2pt]processor3.north) --
([xshift=3em,yshift=-2pt]serverbox.south);
\draw[<-,very thick,blue] ([xshift=0.5em,yshift=2pt]processor3.north) -- ([xshift=4em,yshift=-2pt]serverbox.south) node [pos=0.49,align=left,xshift=2.2em] (fetchlabel) {\footnotesize{Fetch($\cdot$)}};
\draw[->,very thick,red] ([xshift=-0.5em,yshift=2pt]processor1.north) -- ([xshift=-4em,yshift=-2pt]serverbox.south) node [pos=0.5,align=right,xshift=-2em] (pushlabel) {\footnotesize{Push($\cdot$)}};
\draw[<-,very thick,blue] ([xshift=0.5em,yshift=2pt]processor1.north) -- ([xshift=-3em,yshift=-2pt]serverbox.south);
\draw[<-,very thick,ublue!90] ([xshift=0.5em,yshift=2pt]processor3.north) -- ([xshift=4em,yshift=-2pt]serverbox.south) node [pos=0.49,align=left,xshift=2.2em] (fetchlabel) {\footnotesize{Fetch($\cdot$)}};
\draw[->,very thick,red!70] ([xshift=-0.5em,yshift=2pt]processor1.north) -- ([xshift=-4em,yshift=-2pt]serverbox.south) node [pos=0.5,align=right,xshift=-2em] (pushlabel) {\footnotesize{Push($\cdot$)}};
\draw[<-,very thick,ublue!90] ([xshift=0.5em,yshift=2pt]processor1.north) -- ([xshift=-3em,yshift=-2pt]serverbox.south);
}
%%%%%%%%%%%
......@@ -110,13 +110,13 @@
}
{
\draw[->,very thick,red] ([xshift=-0.5em,yshift=2pt]processor2.north) -- ([xshift=-0.5em,yshift=-2pt]serverbox.south) node [pos=0.5,align=right,xshift=-2em] (pushlabel) {\footnotesize{$\frac{\partial J}{\partial {\bm \theta}}$}};;
\draw[<-,very thick,blue] ([xshift=0.5em,yshift=2pt]processor2.north) -- ([xshift=0.5em,yshift=-2pt]serverbox.south) node [pos=0.5,align=left,xshift=2.2em] (fetchlabel) {\footnotesize{${\bm \theta}_{\textrm{new}}$}};;;
\draw[->,very thick,red] ([xshift=-0.5em,yshift=2pt]processor3.north) --
\draw[->,very thick,red!70] ([xshift=-0.5em,yshift=2pt]processor2.north) -- ([xshift=-0.5em,yshift=-2pt]serverbox.south) node [pos=0.5,align=right,xshift=-2em] (pushlabel) {\footnotesize{$\frac{\partial J}{\partial {\bm \theta}}$}};;
\draw[<-,very thick,ublue] ([xshift=0.5em,yshift=2pt]processor2.north) -- ([xshift=0.5em,yshift=-2pt]serverbox.south) node [pos=0.5,align=left,xshift=2.2em] (fetchlabel) {\footnotesize{${\bm \theta}_{\textrm{new}}$}};;;
\draw[->,very thick,red!70] ([xshift=-0.5em,yshift=2pt]processor3.north) --
([xshift=3em,yshift=-2pt]serverbox.south);
\draw[<-,very thick,blue] ([xshift=0.5em,yshift=2pt]processor3.north) -- ([xshift=4em,yshift=-2pt]serverbox.south) node [pos=0.49,align=left,xshift=2.2em] (fetchlabel) {\footnotesize{Fetch($\cdot$)}};
\draw[->,very thick,red] ([xshift=-0.5em,yshift=2pt]processor1.north) -- ([xshift=-4em,yshift=-2pt]serverbox.south) node [pos=0.5,align=right,xshift=-2em] (pushlabel) {\footnotesize{Push($\cdot$)}};
\draw[<-,very thick,blue] ([xshift=0.5em,yshift=2pt]processor1.north) -- ([xshift=-3em,yshift=-2pt]serverbox.south);
\draw[<-,very thick,ublue] ([xshift=0.5em,yshift=2pt]processor3.north) -- ([xshift=4em,yshift=-2pt]serverbox.south) node [pos=0.49,align=left,xshift=2.2em] (fetchlabel) {\footnotesize{Fetch($\cdot$)}};
\draw[->,very thick,red!70] ([xshift=-0.5em,yshift=2pt]processor1.north) -- ([xshift=-4em,yshift=-2pt]serverbox.south) node [pos=0.5,align=right,xshift=-2em] (pushlabel) {\footnotesize{Push($\cdot$)}};
\draw[<-,very thick,ublue] ([xshift=0.5em,yshift=2pt]processor1.north) -- ([xshift=-3em,yshift=-2pt]serverbox.south);
}
%%%%%%%%%%%
......
......@@ -10,7 +10,7 @@
\draw [->,thick] (-2.2,0) -- (2.2,0);
\draw [->,thick] (0,0) -- (0,2);
\draw [-] (-0.05,1) -- (0.05,1);
\node [anchor=north,inner sep=1pt] (labelb) at (0,-0.2) {\footnotesize{(b)}};
\node [anchor=north,inner sep=1pt] (labelb) at (0,-0.2) {\small{(b)}};
}
{
\draw [->,thick] (-2.2,0) -- (2.2,0);
......@@ -35,7 +35,7 @@
\draw [-] (-0.05,1) -- (0.05,1);
\node [anchor=east,inner sep=1pt] (label1) at (0,1.18) {\tiny{1}};
\node [anchor=south east,inner sep=1pt] (label2) at (0,0) {\tiny{0}};
\node [anchor=north,inner sep=1pt] (labela) at (0,-0.2) {\footnotesize{(a)}};
\node [anchor=north,inner sep=1pt] (labela) at (0,-0.2) {\small{(a)}};
}
{
\draw [->,thick] (-2.2,0) -- (2.2,0);
......
\begin{tikzpicture}
\begin{scope}
\tikzstyle{rnnnode} = [draw,inner sep=5pt,minimum width=4em,minimum height=1.5em,fill=green!30!white,blur shadow={shadow xshift=1pt,shadow yshift=-1pt}]
\tikzstyle{rnnnode} = [draw,inner sep=5pt,minimum width=4em,minimum height=1.5em,fill=green!20!white,blur shadow={shadow xshift=1pt,shadow yshift=-1pt}]
{
\node [anchor=west,rnnnode] (node11) at (0,0) {\scriptsize{RNN Cell}};
\node [anchor=west,rnnnode] (node12) at ([xshift=2em]node11.east) {\scriptsize{RNN Cell}};
\node [anchor=west,rnnnode] (node13) at ([xshift=2em]node12.east) {\scriptsize{RNN Cell}};
\node [anchor=west,rnnnode] (node14) at ([xshift=2em]node13.east) {\scriptsize{RNN Cell}};
}
\node [anchor=north,rnnnode,fill=red!30!white] (e1) at ([yshift=-1.2em]node11.south) {\tiny{${\mathbi{e}}_1={\mathbi{o}}_1{\mathbi{C}}$}};
\node [anchor=north,rnnnode,fill=red!30!white] (e2) at ([yshift=-1.2em]node12.south) {\tiny{${\mathbi{e}}_2={\mathbi{o}}_2{\mathbi{C}}$}};
\node [anchor=north,rnnnode,fill=red!30!white] (e3) at ([yshift=-1.2em]node13.south) {\tiny{${\mathbi{e}}_3={\mathbi{o}}_3{\mathbi{C}}$}};
\node [anchor=north,rnnnode,fill=red!30!white] (e4) at ([yshift=-1.2em]node14.south) {\tiny{${\mathbi{e}}_4={\mathbi{o}}_4{\mathbi{C}}$}};
\node [anchor=north,rnnnode,fill=red!20!white] (e1) at ([yshift=-1.2em]node11.south) {\tiny{${\mathbi{e}}_1={\mathbi{o}}_1{\mathbi{C}}$}};
\node [anchor=north,rnnnode,fill=red!20!white] (e2) at ([yshift=-1.2em]node12.south) {\tiny{${\mathbi{e}}_2={\mathbi{o}}_2{\mathbi{C}}$}};
\node [anchor=north,rnnnode,fill=red!20!white] (e3) at ([yshift=-1.2em]node13.south) {\tiny{${\mathbi{e}}_3={\mathbi{o}}_3{\mathbi{C}}$}};
\node [anchor=north,rnnnode,fill=red!20!white] (e4) at ([yshift=-1.2em]node14.south) {\tiny{${\mathbi{e}}_4={\mathbi{o}}_4{\mathbi{C}}$}};
\node [anchor=north] (w1) at ([yshift=-1em]e1.south) {\footnotesize{${\mathbi{o}}_1$}};
\node [anchor=north] (w2) at ([yshift=-1em]e2.south) {\footnotesize{${\mathbi{o}}_2$}};
\node [anchor=north] (w3) at ([yshift=-1em]e3.south) {\footnotesize{${\mathbi{o}}_3$}};
......@@ -32,10 +32,10 @@
\node [anchor=south,rnnnode] (node23) at ([yshift=1.5em]node13.north) {\scriptsize{RNN Cell}};
\node [anchor=south,rnnnode] (node24) at ([yshift=1.5em]node14.north) {\scriptsize{RNN Cell}};
\node [anchor=south,rnnnode,fill=blue!30!white] (node31) at ([yshift=1.5em]node21.north) {\scriptsize{Softmax($\cdot$)}};
\node [anchor=south,rnnnode,fill=blue!30!white] (node32) at ([yshift=1.5em]node22.north) {\scriptsize{Softmax($\cdot$)}};
\node [anchor=south,rnnnode,fill=blue!30!white] (node33) at ([yshift=1.5em]node23.north) {\scriptsize{Softmax($\cdot$)}};
\node [anchor=south,rnnnode,fill=blue!30!white] (node34) at ([yshift=1.5em]node24.north) {\scriptsize{Softmax($\cdot$)}};
\node [anchor=south,rnnnode,fill=blue!20!white] (node31) at ([yshift=1.5em]node21.north) {\scriptsize{Softmax($\cdot$)}};
\node [anchor=south,rnnnode,fill=blue!20!white] (node32) at ([yshift=1.5em]node22.north) {\scriptsize{Softmax($\cdot$)}};
\node [anchor=south,rnnnode,fill=blue!20!white] (node33) at ([yshift=1.5em]node23.north) {\scriptsize{Softmax($\cdot$)}};
\node [anchor=south,rnnnode,fill=blue!20!white] (node34) at ([yshift=1.5em]node24.north) {\scriptsize{Softmax($\cdot$)}};
}
{
......
\begin{tikzpicture}
\begin{scope}
\tikzstyle{rnnnode} = [draw,inner sep=5pt,minimum width=4em,minimum height=1.5em,fill=green!30!white,blur shadow={shadow xshift=1pt,shadow yshift=-1pt}]
\tikzstyle{rnnnode} = [draw,inner sep=5pt,minimum width=4em,minimum height=1.5em,fill=green!20!white,blur shadow={shadow xshift=1pt,shadow yshift=-1pt}]
\node [anchor=west,rnnnode] (node11) at (0,0) {\scriptsize{RNN Cell}};
\node [anchor=west,rnnnode] (node12) at ([xshift=2em]node11.east) {\scriptsize{RNN Cell}};
\node [anchor=west,rnnnode] (node13) at ([xshift=2em]node12.east) {\scriptsize{RNN Cell}};
\node [anchor=west,rnnnode] (node14) at ([xshift=2em]node13.east) {\scriptsize{RNN Cell}};
\node [anchor=north,rnnnode,fill=red!30!white] (e1) at ([yshift=-1.2em]node11.south) {\scriptsize{embedding}};
\node [anchor=north,rnnnode,fill=red!30!white] (e2) at ([yshift=-1.2em]node12.south) {\scriptsize{embedding}};
\node [anchor=north,rnnnode,fill=red!30!white] (e3) at ([yshift=-1.2em]node13.south) {\scriptsize{embedding}};
\node [anchor=north,rnnnode,fill=red!30!white] (e4) at ([yshift=-1.2em]node14.south) {\scriptsize{embedding}};
\node [anchor=north,rnnnode,fill=red!20!white] (e1) at ([yshift=-1.2em]node11.south) {\scriptsize{embedding}};
\node [anchor=north,rnnnode,fill=red!20!white] (e2) at ([yshift=-1.2em]node12.south) {\scriptsize{embedding}};
\node [anchor=north,rnnnode,fill=red!20!white] (e3) at ([yshift=-1.2em]node13.south) {\scriptsize{embedding}};
\node [anchor=north,rnnnode,fill=red!20!white] (e4) at ([yshift=-1.2em]node14.south) {\scriptsize{embedding}};
\node [anchor=north] (w1) at ([yshift=-1em]e1.south) {\footnotesize{亚伦}};
\node [anchor=north] (w2) at ([yshift=-1em]e2.south) {\footnotesize{任职}};
\node [anchor=north] (w3) at ([yshift=-1em]e3.south) {\footnotesize{}};
......
......@@ -7,7 +7,7 @@
\node [fill=green!15,inner sep=0pt,minimum height=0.49cm,minimum width=0.49cm](vector1) at (\x,0.25) {$\number\value{mycount1}$};
\addtocounter{mycount1}{1};
}
\node [anchor=north] (labela) at ([xshift=-1.2em,yshift=-0em]vector1.south) {\footnotesize{(a) }};
\node [anchor=north] (labela) at ([xshift=-1.2em,yshift=-0em]vector1.south) {\small{(a) }};
\end{scope}
\begin{scope}[xshift=1.2in]
......@@ -21,7 +21,7 @@
\node [fill=red!15,inner sep=0pt,minimum height=0.49cm,minimum width=0.49cm] at (\x,0.25) {$\number\value{mycount2}$};
\addtocounter{mycount2}{1};
}
\node [anchor=north] (labelb) at ([xshift=0.3em,yshift=-0em]vector2.south) {\footnotesize{(b) }};
\node [anchor=north] (labelb) at ([xshift=0.3em,yshift=-0em]vector2.south) {\small{(b) }};
\end{scope}
\begin{scope}[yshift=-0.6in]
......@@ -47,7 +47,7 @@
\draw[decorate,thick,decoration={brace,mirror,raise=0.2em}] (3.05,-0.2) -- (6,-0.2);
\node [anchor=north] (subtensor1) at (1.5,-0.4) {\footnotesize{$3 \times 2$ sub-tensor}};
\node [anchor=north] (subtensor1) at (4.5,-0.4) {\footnotesize{$3 \times 2$ sub-tensor}};
\node [anchor=north] (labelc) at (3,-0.8) {\footnotesize{(c)}};
\node [anchor=north] (labelc) at (3,-0.8) {\small{(c)}};
\end{scope}
\end{tikzpicture}
......
......@@ -40,7 +40,7 @@
\draw[-,ublue](0,-0.8)..controls(0.5,-0.8) and (0.6,-0.85)..(0.6,-0.9)..controls(0.6,-0.93)and (0.5,-0.91)..(0.3,-0.88)..controls(0.2,-0.87)and (0.1,-0.86)..(0,-0.86)..controls(-0.1,-0.86)and(-0.2,-0.87)..(-0.3,-0.88)..controls(-0.5,-0.91) and(-0.6,-0.93) ..(-0.6,-0.9)..controls(-0.6,-0.85)and (-0.5,-0.8)..(0,-0.8);
\node [anchor=north] (labela) at (0,-2.7) {\footnotesize{(a)梯度下降算法中的``锯齿''现象}};
\node [anchor=north] (labela) at (0,-2.7) {\small{(a)梯度下降算法中的``锯齿''现象}};
\end{scope}
......@@ -78,7 +78,7 @@
\draw[-,ublue](0,-0.8)..controls(0.5,-0.8) and (0.6,-0.85)..(0.6,-0.9)..controls(0.6,-0.93)and (0.5,-0.91)..(0.3,-0.88)..controls(0.2,-0.87)and (0.1,-0.86)..(0,-0.86)..controls(-0.1,-0.86)and(-0.2,-0.87)..(-0.3,-0.88)..controls(-0.5,-0.91) and(-0.6,-0.93) ..(-0.6,-0.9)..controls(-0.6,-0.85)and (-0.5,-0.8)..(0,-0.8);
\node [anchor=north] (labelb) at (0,-3) {\footnotesize{(b)Momentum梯度下降算法更加``平滑''地更新}};
\node [anchor=north] (labelb) at (0,-3) {\small{(b)Momentum梯度下降算法更加``平滑''地更新}};
\end{scope}
\end{tikzpicture}
......
%%%------------------------------------------------------------------------------------------------------------
\begin{tikzpicture}
\tikzstyle{neuron} = [rectangle,draw,thick,fill=red!30,red!35,minimum height=2em,minimum width=2em,font=\small]
\tikzstyle{neuron} = [rectangle,draw,thick,fill=red!25,red!30,minimum height=2em,minimum width=2em,font=\small]
\node[neuron,anchor=north] (a1) at (0,0) {};
\draw[->,thick] ([xshift=-2em,yshift=0em]a1.south) to ([xshift=3em,yshift=0em]a1.south);
\draw[->,thick] ([xshift=0em,yshift=-4em]a1.west) to ([xshift=0em,yshift=2em]a1.west);
......@@ -11,7 +11,7 @@
\node [anchor=west] (x) at ([xshift=-0.7em,yshift=1em]a1.south) {\Large{$\textbf{F}$}};
{
\tikzstyle{neuron} = [rectangle,draw,thick,fill=red!30,red!35,minimum height=2em,minimum width=2em,font=\small]
\tikzstyle{neuron} = [rectangle,draw,thick,fill=red!25,red!30,minimum height=2em,minimum width=2em,font=\small]
\node[neuron,anchor=north] (a2) at ([xshift=10em,yshift=0em]a1.south) {};
\draw[->,thick] ([xshift=-2em,yshift=0em]a2.north) to ([xshift=3em,yshift=0em]a2.north);
\draw[->,thick] ([xshift=0em,yshift=-2em]a2.west) to ([xshift=0em,yshift=4em]a2.west);
......@@ -33,7 +33,7 @@
}
{
\tikzstyle{neuron} = [rectangle,draw,thick,fill=red!30,red!35,minimum height=2em,minimum width=2em,font=\small]
\tikzstyle{neuron} = [rectangle,draw,thick,fill=red!25,red!30,minimum height=2em,minimum width=2em,font=\small]
\node[neuron,anchor=north] (a3) at ([xshift=11em,yshift=2.05em]a2.south) {};
\draw[->,thick] ([xshift=-3em,yshift=0em]a3.north) to ([xshift=2em,yshift=0em]a3.north);
\draw[->,thick] ([xshift=-1em,yshift=-2em]a3.west) to ([xshift=-1em,yshift=4em]a3.west);
......
......@@ -8,7 +8,7 @@
\draw [-] (-0.05,1) -- (0.05,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] (labela) at (0.2,-0.5) {\footnotesize{(a)}};
\node [anchor=south east,inner sep=1pt] (labela) at (0.2,-0.5) {\small{(a)}};
}
{\node [anchor=north west,align=left] (wblabel) at (-1.8,2) {\scriptsize{\ $w_{11}=100$}\\[-0ex] {\scriptsize{\ $b_1=-4$}}};}
{\draw [-,very thick,ublue,rounded corners=0.1em] (-1.5,0) -- (0.5,0) -- (0.5,1) -- (1.5,1);}
......@@ -21,7 +21,7 @@
\draw [-] (-0.05,1) -- (0.05,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] (labelb) at (0.2,-0.5) {\footnotesize{(b)}};
\node [anchor=south east,inner sep=1pt] (labelb) at (0.2,-0.5) {\small{(b)}};
}
{\node [anchor=north west,align=left] (wblabel) at (-1.8,2) {{\scriptsize{\ $w'_{11}=0.9$}}};}
{\draw [-,very thick,ublue,rounded corners=0.1em] (-1.8,0) -- (0.5,0) -- (0.5,0.9) -- (1.8,0.9);}
......@@ -35,7 +35,7 @@
\draw [-] (-0.05,1) -- (0.05,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] (labelc) at (0.2,-0.5) {\footnotesize{(c)}};
\node [anchor=south east,inner sep=1pt] (labelc) at (0.2,-0.5) {\small{(c)}};
}
{\node [anchor=north west,align=left] (wblabel) at (-1.8,2) {{\scriptsize{\ $w'_{11}=0.7$}}};}
{\draw [-,very thick,ublue,rounded corners=0.1em] (-1.5,0) -- (0.5,0) -- (0.5,0.7) -- (1.5,0.7);}
......
......@@ -8,7 +8,7 @@
\draw [-] (-0.05,1) -- (0.05,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] (labela) at (0.2,-0.5) {\footnotesize{(a)}};
\node [anchor=south east,inner sep=1pt] (labela) at (0.2,-0.5) {\small{(a)}};
}
{\node [anchor=north west,align=left] (wblabel) at (-1.8,2) {\scriptsize{\ $w_{11}=1$}\\[-0ex] \scriptsize{\ $b_1=0$}};}
{\draw [-,very thick,ublue,domain=-1.5:1.5,samples=100] plot (\x,{1/(1+exp(-2*\x))});}
......@@ -21,7 +21,7 @@
\draw [-] (-0.05,1) -- (0.05,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] (labelb) at (0.2,-0.5) {\footnotesize{(b)}};
\node [anchor=south east,inner sep=1pt] (labelb) at (0.2,-0.5) {\small{(b)}};
}
{\node [anchor=north west,align=left] (wblabel) at (-1.8,2) {{\scriptsize{\ $w_{11}=10$}}\\[-0ex] \scriptsize{\ $b_1=0$}};}
{\draw [-,very thick,ublue,domain=-1.5:1.5,samples=100] plot (\x,{1/(1+exp(-4*\x))});}
......@@ -34,7 +34,7 @@
\draw [-] (-0.05,1) -- (0.05,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] (labelc) at (0.2,-0.5) {\footnotesize{(c)}};
\node [anchor=south east,inner sep=1pt] (labelc) at (0.2,-0.5) {\small{(c)}};
}
{\node [anchor=north west,align=left] (wblabel) at (-1.8,2) {{\scriptsize{\ $w_{11}=100$}}\\[-0ex] \scriptsize{\ $b_1=0$}};}
{\draw [-,very thick,ublue,rounded corners=0.1em] (-1.5,0) -- (0,0) -- (0,1) -- (1.5,1);}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论