Commit c6f7a368 by zengxin

合并分支 'caorunzhe' 到 'zengxin'

Caorunzhe

查看合并请求 !522
parents d9550b40 485ac716
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
\end{figure} \end{figure}
%------------------------------------------ %------------------------------------------
\parinterval 在此之后,更多的翻译工作在文化和知识传播中开展。其中一个典型代表是宗教文献的翻译。宗教是人类意识形态的一个重要载体,为了宣传教义,人们编写了大量的宗教文献。在西方,一项最早被记录的翻译活动是将旧约圣经(希伯来文及埃兰文)翻译为希腊文版本。迄今为止人类历史上翻译版本最多的书就是圣经。在中国唐代,有一位世界性的文化人物\ \dash \ 玄奘,他不仅是佛学家、旅行家,还是翻译家。玄奘西行求法归来后把全部的心血和智慧奉献给了译经事业,在助手们的帮助下,共翻译佛教经论74部,1335卷,每卷万字左右,合计1335万字,占去整个唐代译经总数的一半以上\upcite{慧立彦宗1983大慈恩寺三藏法师传},树立了我国古代翻译思想的光辉典范。 \parinterval 在此之后,更多的翻译工作在文化和知识传播中开展。其中一个典型代表是宗教文献的翻译。宗教是人类意识形态的一个重要载体,为了宣传教义,人们编写了大量的宗教文献。在西方,一项最早被记录的翻译活动是将旧约圣经(希伯来文及埃兰文)翻译为希腊文版本。迄今为止人类历史上翻译版本最多的书就是圣经。在中国唐代,有一位世界性的文化人物\ \dash \ 玄奘,他不仅是佛学家、旅行家,还是翻译家。玄奘西行求法归来后把全部的心血和智慧奉献给了译经事业,在助手们的帮助下,共翻译佛教经论74部,1335卷,每卷万字左右,合计1335万字,占去整个唐代译经总数的一半以上\upcite{慧立2000大慈恩寺三藏法師傳},树立了我国古代翻译思想的光辉典范。
\parinterval 翻译在人类历史长河中起到了重要的作用。一方面,由于语言文字、文化和地理位置的差异性,使得翻译成为一个重要的需求;另一方面,翻译也加速了不同文明的融会贯通,促进了世界的发展。今天,翻译已经成为重要的行业之一,包括各个高校也都设立了翻译及相关专业,相关人才不断涌现。据《2019年中国语言服务行业发展报告》\upcite{2019cns}统计:全球语言服务产值预计将首次接近500亿美元;中国涉及语言服务的在营企业360,000余家,语言服务为主营业务的在营企业近万家,总产值超过300亿元,年增长3\%以上;全国开设外语类专业的高校数量多达上千所,其中设立有翻译硕士(MTI)和翻译本科(BTI)专业的院校分别有250余所和280余所,其中仅MTI的累计招生数就高达6万余人\upcite{赵军峰2019深化改革}。当然,面对着巨大的需求,如何使用机器辅助翻译等技术手段提高人工翻译效率,也是人工翻译和机器翻译领域需要共同探索的方向。 \parinterval 翻译在人类历史长河中起到了重要的作用。一方面,由于语言文字、文化和地理位置的差异性,使得翻译成为一个重要的需求;另一方面,翻译也加速了不同文明的融会贯通,促进了世界的发展。今天,翻译已经成为重要的行业之一,包括各个高校也都设立了翻译及相关专业,相关人才不断涌现。据《2019年中国语言服务行业发展报告》\upcite{2019cns}统计:全球语言服务产值预计将首次接近500亿美元;中国涉及语言服务的在营企业360,000余家,语言服务为主营业务的在营企业近万家,总产值超过300亿元,年增长3\%以上;全国开设外语类专业的高校数量多达上千所,其中设立有翻译硕士(MTI)和翻译本科(BTI)专业的院校分别有250余所和280余所,其中仅MTI的累计招生数就高达6万余人\upcite{赵军峰2019深化改革}。当然,面对着巨大的需求,如何使用机器辅助翻译等技术手段提高人工翻译效率,也是人工翻译和机器翻译领域需要共同探索的方向。
......
\tikzstyle{yy} = [circle,minimum height=1cm,text centered,draw=black] \tikzstyle{yy} = [circle,minimum height=1cm,text centered,draw=black,thick,drop shadow={shadow xshift=0.3em,yshift=0.8em},fill=white]
\begin{tikzpicture}[node distance = 0,scale = 1] \begin{tikzpicture}[node distance = 0,scale = 1]
\begin{scope}[xshift=0.2in] \begin{scope}[xshift=0.2in]
\tikzstyle{every node}=[scale=1] \tikzstyle{every node}=[scale=1]
...@@ -8,22 +8,22 @@ ...@@ -8,22 +8,22 @@
\node (y4)[yy,right of = y3,xshift=1.5cm]{\large$y_4$}; \node (y4)[yy,right of = y3,xshift=1.5cm]{\large$y_4$};
\node (y5)[yy,right of = y4,xshift=1.5cm]{\large$y_5$}; \node (y5)[yy,right of = y4,xshift=1.5cm]{\large$y_5$};
\node (y6)[yy,right of = y5,xshift=1.5cm]{\large$y_6$}; \node (y6)[yy,right of = y5,xshift=1.5cm]{\large$y_6$};
\node [anchor=north,font=\scriptsize] (labela) at ([xshift=1.8em,yshift=-3em]y3.south) {(a) 自回归模型}; \node [anchor=north,font=\scriptsize] (labela) at ([xshift=1.8em,yshift=-2em]y3.south) {(a) 自回归模型};
\draw[->,thick] (y1.north) .. controls ([yshift=2em]y1.north) and ([yshift=2em]y3.north).. (y3.north); \draw[->,thick] (y1.north) .. controls ([yshift=1.5em]y1.north) and ([yshift=1.5em]y3.north).. (y3.north);
\draw[->,thick] (y1.north) .. controls ([yshift=3em]y1.north) and ([yshift=3em]y4.north).. (y4.north); \draw[->,thick] (y1.north) .. controls ([yshift=2em]y1.north) and ([yshift=2em]y4.north).. (y4.north);
\draw[->,thick] (y1.south) .. controls ([yshift=-2em]y1.south) and ([yshift=-2em]y5.south).. (y5.south); \draw[->,thick] (y1.south) .. controls ([yshift=-1.5em]y1.south) and ([yshift=-1.5em]y5.south).. (y5.south);
\draw[->,thick] (y1.south) .. controls ([yshift=-3em]y1.south) and ([yshift=-3em]y6.south).. (y6.south); \draw[->,thick] (y1.south) .. controls ([yshift=-2em]y1.south) and ([yshift=-2em]y6.south).. (y6.south);
\draw[->,thick] (y2.north) .. controls ([yshift=2em]y2.north) and ([yshift=2em]y4.north).. (y4.north); \draw[->,thick] (y2.north) .. controls ([yshift=1.5em]y2.north) and ([yshift=1.5em]y4.north).. (y4.north);
\draw[->,thick] (y2.south) .. controls ([yshift=-2em]y2.south) and ([yshift=-2em]y5.south).. (y5.south); \draw[->,thick] (y2.south) .. controls ([yshift=-1.5em]y2.south) and ([yshift=-1.6em]y5.south).. (y5.south);
\draw[->,thick] (y2.south) .. controls ([yshift=-3em]y2.south) and ([yshift=-3em]y6.south).. (y6.south); \draw[->,thick] (y2.south) .. controls ([yshift=-2em]y2.south) and ([yshift=-2em]y6.south).. (y6.south);
\draw[->,thick] (y3.south) .. controls ([yshift=-2em]y3.south) and ([yshift=-2em]y5.south).. (y5.south); \draw[->,thick] (y3.south) .. controls ([yshift=-1.5em]y3.south) and ([yshift=-1.5em]y5.south).. (y5.south);
\draw[->,thick] (y3.south) .. controls ([yshift=-3em]y3.south) and ([yshift=-3em]y6.south).. (y6.south); \draw[->,thick] (y3.south) .. controls ([yshift=-2em]y3.south) and ([yshift=-2em]y6.south).. (y6.south);
\draw[->,thick] (y4.south) .. controls ([yshift=-2em]y4.south) and ([yshift=-2em]y6.south).. (y6.south); \draw[->,thick] (y4.south) .. controls ([yshift=-1.5em]y4.south) and ([yshift=-1.5em]y6.south).. (y6.south);
\draw[->,red,very thick](y1.east)to(y2.west); \draw[->,red,very thick](y1.east)to(y2.west);
\draw[->,red,very thick](y2.east)to(y3.west); \draw[->,red,very thick](y2.east)to(y3.west);
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
\draw[->,red,very thick](y5.east)to(y6.west); \draw[->,red,very thick](y5.east)to(y6.west);
\end{scope} \end{scope}
\begin{scope}[yshift=-1.6in] \begin{scope}[yshift=-1.45in]
\tikzstyle{rec} = [rectangle,minimum width=2.8cm,minimum height=1.5cm,text centered,draw=black,dashed] \tikzstyle{rec} = [rectangle,minimum width=2.8cm,minimum height=1.5cm,text centered,draw=black,dashed]
\tikzstyle{every node}=[scale=1] \tikzstyle{every node}=[scale=1]
\node (y1)[yy]{\large$y_1$}; \node (y1)[yy]{\large$y_1$};
...@@ -49,9 +49,9 @@ ...@@ -49,9 +49,9 @@
\draw[->,red,very thick](rec1.east)to(rec2.west); \draw[->,red,very thick](rec1.east)to(rec2.west);
\draw[->,red,very thick](rec2.east)to(rec3.west); \draw[->,red,very thick](rec2.east)to(rec3.west);
\draw[->,thick] (rec1.north) .. controls ([yshift=3em]rec1.north) and ([yshift=3em]rec3.north).. (rec3.north); \draw[->,thick] (rec1.north) .. controls ([yshift=2.5em]rec1.north) and ([yshift=2.5em]rec3.north).. (rec3.north);
\end{scope} \end{scope}
\begin{scope}[xshift=0.3in,yshift=-2.5in] \begin{scope}[xshift=0.3in,yshift=-2.35in]
\tikzstyle{every node}=[scale=1] \tikzstyle{every node}=[scale=1]
\node (y1)[yy]{\large$y_1$}; \node (y1)[yy]{\large$y_1$};
\node (y2)[yy,right of = y1,xshift=1.5cm]{\large$y_2$}; \node (y2)[yy,right of = y1,xshift=1.5cm]{\large$y_2$};
......
\begin{tikzpicture} \begin{tikzpicture}
\tikzstyle{snode} = [draw,inner sep=1pt,minimum width=3em,minimum height=0.5em,rounded corners=1pt,fill=green!30!white] \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] \tikzstyle{pnode} = [draw,inner sep=1pt,minimum width=1em,minimum height=0.5em,rounded corners=1pt]
\node [anchor=west,snode] (s1) at (0,0) {\tiny{}}; \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=6.3em] (s2) at ([yshift=-0.3em]s1.south west) {\tiny{}};
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
\node [anchor=west,pnode,minimum width=3em] (p6) at ([xshift=0.3em]s6.east) {\tiny{}}; \node [anchor=west,pnode,minimum width=3em] (p6) at ([xshift=0.3em]s6.east) {\tiny{}};
\node [rectangle,inner sep=0.5em,rounded corners=2pt,very thick,dotted,draw=ugreen!80] [fit = (s1) (s6) (p1) (p6)] (box0) {}; \node [rectangle,inner sep=0.5em,rounded corners=2pt,very thick,dotted,draw=ugreen!80] [fit = (s1) (s6) (p1) (p6)] (box0) {};
\node[rectangle,inner sep=0.5em,rounded corners=1pt,draw,fill=blue!15] (model) at ([xshift=4em]box0.east){{模型}}; \node[rectangle,inner sep=0.5em,rounded corners=1pt,draw,fill=blue!20] (model) at ([xshift=3.5em]box0.east){{模型}};
% big batch % big batch
\node [anchor=west,snode] (sbi1) at ([xshift=3em,yshift=6em]model.east) {\tiny{}}; \node [anchor=west,snode] (sbi1) at ([xshift=3em,yshift=6em]model.east) {\tiny{}};
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
\node [rectangle,inner sep=0.5em,rounded corners=2pt,very thick,dotted,draw=ugreen!80] [fit = (sma1) (sma3) (pma1) (pma2)] (box2) {}; \node [rectangle,inner sep=0.5em,rounded corners=2pt,very thick,dotted,draw=ugreen!80] [fit = (sma1) (sma3) (pma1) (pma2)] (box2) {};
% small batch % small batch
\node [anchor=west,snode,minimum width=2em] (sma4) at ([xshift=4em,yshift=0em]sma1.east) {\tiny{}}; \node [anchor=west,snode,minimum width=2em] (sma4) at ([xshift=3.5em,yshift=0em]sma1.east) {\tiny{}};
\node [anchor=north west,snode,minimum width=3em] (sma5) at ([yshift=-0.3em]sma4.south west) {\tiny{}}; \node [anchor=north west,snode,minimum width=3em] (sma5) at ([yshift=-0.3em]sma4.south west) {\tiny{}};
\node [anchor=north west,snode,minimum width=3em] (sma6) at ([yshift=-0.3em]sma5.south west) {\tiny{}}; \node [anchor=north west,snode,minimum width=3em] (sma6) at ([yshift=-0.3em]sma5.south west) {\tiny{}};
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
\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]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); \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=10em]sbi1.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} \begin{tabular}{l}
$m$: 显存 \\ $m$: 显存 \\
$t$: 时间 \\ $t$: 时间 \\
......
\definecolor{cocoabrown}{rgb}{0.82, 0.41, 0.12}
\centering \centering
...@@ -10,19 +10,19 @@ ...@@ -10,19 +10,19 @@
\tikzstyle{output} = [rectangle,very thick,rounded corners=3pt,minimum width=1cm,align=center,font=\tiny]; \tikzstyle{output} = [rectangle,very thick,rounded corners=3pt,minimum width=1cm,align=center,font=\tiny];
\begin{scope} \begin{scope}
\node [system,draw=orange,text=orange] (model3) at (0,0) {模型 $3$}; \node [system,draw=orange!70,text=orange] (model3) at (0,0) {模型 $3$};
\node [system,draw=ugreen,text=ugreen,anchor=south] (model2) at ([yshift=0.3cm]model3.north) {模型 $2$}; \node [system,draw=ugreen!70,text=ugreen,anchor=south] (model2) at ([yshift=0.3cm]model3.north) {模型 $2$};
\node [system,draw=red,text=red,anchor=south] (model1) at ([yshift=0.3cm]model2.north) {模型 $1$}; \node [system,draw=red!70,text=red,anchor=south] (model1) at ([yshift=0.3cm]model2.north) {模型 $1$};
\node [output,draw=orange,text=orange,anchor=west] (output3) at ([xshift=0.5cm]model3.east) {输出 $3$}; \node [output,draw=orange!70,text=orange,anchor=west] (output3) at ([xshift=0.5cm]model3.east) {输出 $3$};
\node [output,draw=ugreen,text=ugreen,anchor=west] (output2) at ([xshift=0.5cm]model2.east) {输出 $2$}; \node [output,draw=ugreen!70,text=ugreen,anchor=west] (output2) at ([xshift=0.5cm]model2.east) {输出 $2$};
\node [output,draw=red,text=red,anchor=west] (output1) at ([xshift=0.5cm]model1.east) {输出 $1$}; \node [output,draw=red!70,text=red,anchor=west] (output1) at ([xshift=0.5cm]model1.east) {输出 $1$};
\begin{pgfonlayer}{background} \begin{pgfonlayer}{background}
\node [draw,thick,dashed,rounded corners=3pt,inner sep=2pt,fit=(output1) (output2) (output3)] (output) {}; \node [draw,thick,dashed,rounded corners=3pt,inner sep=2pt,fit=(output1) (output2) (output3)] (output) {};
\end{pgfonlayer} \end{pgfonlayer}
\node [output,draw=ublue,text=ublue,minimum width=1cm,right=1cm of output] (final) {最终\\输出}; \node [output,draw=cocoabrown!70,text=cocoabrown,minimum width=1cm,right=1cm of output] (final) {最终\\输出};
\draw [->,very thick] (model1) to (output1); \draw [->,very thick] (model1) to (output1);
\draw [->,very thick] (model2) to (output2); \draw [->,very thick] (model2) to (output2);
...@@ -40,17 +40,17 @@ ...@@ -40,17 +40,17 @@
\tikzstyle{output} = [rectangle,very thick,rounded corners=3pt,minimum width=1cm,align=center,font=\tiny]; \tikzstyle{output} = [rectangle,very thick,rounded corners=3pt,minimum width=1cm,align=center,font=\tiny];
\begin{scope} \begin{scope}
\node [system,draw=orange,text=orange] (model3) at (0,0) {模型 $3$}; \node [system,draw=orange!70,text=orange] (model3) at (0,0) {模型 $3$};
\node [system,draw=ugreen,text=ugreen,anchor=south] (model2) at ([yshift=0.3cm]model3.north) {模型 $2$}; \node [system,draw=ugreen!70,text=ugreen,anchor=south] (model2) at ([yshift=0.3cm]model3.north) {模型 $2$};
\node [system,draw=red,text=red,anchor=south] (model1) at ([yshift=0.3cm]model2.north) {模型 $1$}; \node [system,draw=red!70,text=red,anchor=south] (model1) at ([yshift=0.3cm]model2.north) {模型 $1$};
\begin{pgfonlayer}{background} \begin{pgfonlayer}{background}
\node [draw,thick,dashed,inner sep=2pt,fit=(model3) (model2) (model1)] (ensemble) {}; \node [draw,thick,dashed,inner sep=2pt,fit=(model3) (model2) (model1)] (ensemble) {};
\end{pgfonlayer} \end{pgfonlayer}
\node [system,draw=ugreen,text=ugreen,right=1cm of ensemble] (model) {模型}; \node [system,draw=ugreen!70,text=ugreen,right=1cm of ensemble] (model) {模型};
\node [output,draw=ublue,text=ublue,minimum width=1cm,anchor=west] (final) at ([xshift=0.5cm]model.east) {最终\\输出}; \node [output,draw=cocoabrown!70,text=cocoabrown,minimum width=1cm,anchor=west] (final) at ([xshift=0.5cm]model.east) {最终\\输出};
\draw [->,very thick] (ensemble) to node [above,pos=0.5,font=\tiny] {融合} (model); \draw [->,very thick] (ensemble) to node [above,pos=0.5,font=\tiny] {融合} (model);
...@@ -68,13 +68,13 @@ ...@@ -68,13 +68,13 @@
\tikzstyle{dot} = [circle,fill=blue!40!white,minimum size=5pt,inner sep=0pt]; \tikzstyle{dot} = [circle,fill=blue!40!white,minimum size=5pt,inner sep=0pt];
\begin{scope} \begin{scope}
\node [system,draw=orange,text=orange] (model3) at (0,0) {模型 $3$}; \node [system,draw=orange!70,text=orange] (model3) at (0,0) {模型 $3$};
\node [system,draw=ugreen,text=ugreen,anchor=south] (model2) at ([yshift=0.3cm]model3.north) {模型 $2$}; \node [system,draw=ugreen!70,text=ugreen,anchor=south] (model2) at ([yshift=0.3cm]model3.north) {模型 $2$};
\node [system,draw=red,text=red,anchor=south] (model1) at ([yshift=0.3cm]model2.north) {模型 $1$}; \node [system,draw=red!70,text=red,anchor=south] (model1) at ([yshift=0.3cm]model2.north) {模型 $1$};
\node [output,draw=orange,text=orange,anchor=west] (output3) at ([xshift=0.5cm]model3.east) {输出 $3$}; \node [output,draw=orange!70,text=orange,anchor=west] (output3) at ([xshift=0.5cm]model3.east) {输出 $3$};
\node [output,draw=ugreen,text=ugreen,anchor=west] (output2) at ([xshift=0.5cm]model2.east) {输出 $2$}; \node [output,draw=ugreen!70,text=ugreen,anchor=west] (output2) at ([xshift=0.5cm]model2.east) {输出 $2$};
\node [output,draw=red,text=red,anchor=west] (output1) at ([xshift=0.5cm]model1.east) {输出 $1$}; \node [output,draw=red!70,text=red,anchor=west] (output1) at ([xshift=0.5cm]model1.east) {输出 $1$};
\draw [->,very thick] (model1) to (output1); \draw [->,very thick] (model1) to (output1);
\draw [->,very thick] (model2) to (output2); \draw [->,very thick] (model2) to (output2);
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
\node [system,draw=purple,text=purple,anchor=west] (model) at ([xshift=5.3cm]output1.east) {模型}; \node [system,draw=purple,text=purple,anchor=west] (model) at ([xshift=5.3cm]output1.east) {模型};
\node [output,draw=ublue,text=ublue,minimum width=1cm,right=1.3cm of lattice] (final) {最终输出}; \node [output,draw=cocoabrown!70,text=cocoabrown,minimum width=1cm,right=1.3cm of lattice] (final) {最终输出};
\draw [->,very thick] (model) |- (final); \draw [->,very thick] (model) |- (final);
\draw [->,very thick] (lattice) -- (final); \draw [->,very thick] (lattice) -- (final);
......
\definecolor{cocoabrown}{rgb}{0.82, 0.41, 0.12}
\begin{tikzpicture} \begin{tikzpicture}
\tikzstyle{system} = [rectangle,very thick,minimum width=1.5cm,font=\scriptsize]; \tikzstyle{system} = [rectangle,very thick,minimum width=1.5cm,font=\scriptsize];
\tikzstyle{output} = [rectangle,very thick,rounded corners=3pt,minimum width=1.5cm,align=center,font=\scriptsize]; \tikzstyle{output} = [rectangle,very thick,rounded corners=3pt,minimum width=1.5cm,align=center,font=\scriptsize];
\begin{scope}[local bounding box=MULTIPLE] \begin{scope}[local bounding box=MULTIPLE]
\node [system,draw=orange,text=orange] (engine3) at (0,0) {系统 $n$}; \node [system,draw=orange!70,text=orange] (engine3) at (0,0) {系统 $n$};
\node [system,draw=ugreen,text=ugreen,anchor=south] (engine2) at ([yshift=0.6cm]engine3.north) {系统 $2$}; \node [system,draw=ugreen!70,text=ugreen,anchor=south] (engine2) at ([yshift=0.6cm]engine3.north) {系统 $2$};
\node [system,draw=red,text=red,anchor=south] (engine1) at ([yshift=0.3cm]engine2.north) {系统 $1$}; \node [system,draw=red!70,text=red,anchor=south] (engine1) at ([yshift=0.3cm]engine2.north) {系统 $1$};
\node [output,draw=orange,text=orange,anchor=west] (output3) at ([xshift=0.5cm]engine3.east) {输出 $n$}; \node [output,draw=orange!70,text=orange,anchor=west] (output3) at ([xshift=0.5cm]engine3.east) {输出 $n$};
\node [output,draw=ugreen,text=ugreen,anchor=west] (output2) at ([xshift=0.5cm]engine2.east) {输出 $2$}; \node [output,draw=ugreen!70,text=ugreen,anchor=west] (output2) at ([xshift=0.5cm]engine2.east) {输出 $2$};
\node [output,draw=red,text=red,anchor=west] (output1) at ([xshift=0.5cm]engine1.east) {输出 $1$}; \node [output,draw=red!70,text=red,anchor=west] (output1) at ([xshift=0.5cm]engine1.east) {输出 $1$};
\draw [very thick,decorate,decoration={brace}] ([xshift=3pt]output1.north east) to node [midway,name=final] {} ([xshift=3pt]output3.south east); \draw [very thick,decorate,decoration={brace}] ([xshift=3pt]output1.north east) to node [midway,name=final] {} ([xshift=3pt]output3.south east);
\node [output,draw=ublue,text=ublue,minimum width=1cm,right=0pt of final,minimum height=2.5em] () {最终\\输出}; \node [output,draw=cocoabrown!70,text=cocoabrown,minimum width=1cm,right=0pt of final,minimum height=2.5em] () {最终\\输出};
\draw [->,very thick] (engine1) to (output1); \draw [->,very thick] (engine1) to (output1);
\draw [->,very thick] (engine2) to (output2); \draw [->,very thick] (engine2) to (output2);
...@@ -25,15 +25,15 @@ ...@@ -25,15 +25,15 @@
\end{scope} \end{scope}
\begin{scope}[local bounding box=SINGLE] \begin{scope}[local bounding box=SINGLE]
\node [output,draw=ugreen,text=ugreen,anchor=west] (output3) at ([xshift=4cm]output3.east) {输出 $n$}; \node [output,draw=ugreen!70,text=ugreen,anchor=west] (output3) at ([xshift=4cm]output3.east) {输出 $n$};
\node [output,draw=ugreen,text=ugreen,anchor=west] (output2) at ([xshift=4cm]output2.east) {输出 $2$}; \node [output,draw=ugreen!70,text=ugreen,anchor=west] (output2) at ([xshift=4cm]output2.east) {输出 $2$};
\node [output,draw=ugreen,text=ugreen,anchor=west] (output1) at ([xshift=4cm]output1.east) {输出 $1$}; \node [output,draw=ugreen!70,text=ugreen,anchor=west] (output1) at ([xshift=4cm]output1.east) {输出 $1$};
\node [system,draw=ugreen,text=ugreen,anchor=east,align=center,inner sep=1.9pt] (engine) at ([xshift=-0.5cm]output2.west) {单系统}; \node [system,draw=ugreen!70,text=ugreen,anchor=east,align=center,inner sep=1.9pt] (engine) at ([xshift=-0.5cm]output2.west) {单系统};
\draw [very thick,decorate,decoration={brace}] ([xshift=3pt]output1.north east) to node [midway,name=final] {} ([xshift=3pt]output3.south east); \draw [very thick,decorate,decoration={brace}] ([xshift=3pt]output1.north east) to node [midway,name=final] {} ([xshift=3pt]output3.south east);
\node [output,draw=ublue,text=ublue,minimum width=1cm,right=0pt of final,minimum height=2.5em] () {最终\\输出}; \node [output,draw=cocoabrown!70,text=cocoabrown,minimum width=1cm,right=0pt of final,minimum height=2.5em] () {最终\\输出};
\draw [->,very thick] (engine.east) to (output1.west); \draw [->,very thick] (engine.east) to (output1.west);
\draw [->,very thick] (engine.east) to (output2.west); \draw [->,very thick] (engine.east) to (output2.west);
......
\tikzstyle{er} = [rectangle,minimum width=2.5cm,minimum height=1.5cm,text centered,draw=black] \definecolor{taupegray}{rgb}{0.55, 0.52, 0.54}
\definecolor{babyblueeyes}{rgb}{0.63, 0.79, 0.95}
\tikzstyle{er} = [rectangle,minimum width=2.5cm,minimum height=1.5cm,rounded corners,text centered,draw=taupegray,drop shadow]
\begin{tikzpicture}[node distance = 0,scale = 0.75] \begin{tikzpicture}[node distance = 0,scale = 0.75]
\tikzstyle{every node}=[scale=0.75] \tikzstyle{every node}=[scale=0.75]
\node (encoder)[er,very thick,draw=black!70,fill=ugreen!20]{\Large{编码器}}; \node (encoder)[er,very thick,draw=taupegray,fill=ugreen!20]{\Large{编码器}};
\node (decoder_1)[er,very thick,draw=black!70,right of=encoder,xshift=4cm,fill=red!20]{\Large{解码器1}}; \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=black!70,right of=decoder_1,xshift=4cm,fill=red!20]{\Large{解码器2}}; \node (decoder_2)[er,very thick,draw=taupegray,right of=decoder_1,xshift=4cm,fill=red!20]{\Large{解码器2}};
\node (point)[right of=decoder_2,xshift=2.5cm,]{\LARGE{...}}; \node (point)[right of=decoder_2,xshift=2.5cm,]{\LARGE{...}};
\node (decoder_3)[er,very thick,draw=black!70,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{解码器3}};
\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]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_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); \draw [->,very thick,draw=black!70]([xshift=0.2cm]decoder_2.east) -- ([xshift=-0.1cm]point.west);
......
\begin{tikzpicture} \begin{tikzpicture}
%左 %左
\node [anchor=west,draw=black,very thick,minimum width=6em,minimum height=3.5em,fill=blue!15,align=center,text=black] (part1) at (0,0) {\scriptsize{预测模块} \\ \tiny{(RNN/Transsformer)}}; \node [anchor=west,draw=black!70,rounded corners,drop shadow,very thick,minimum width=6em,minimum height=3.5em,fill=blue!15,align=center,text=black] (part1) at (0,0) {\scriptsize{预测模块} \\ \tiny{(RNN/Transsformer)}};
\node [anchor=south] (text) at ([xshift=0.5em,yshift=-3.5em]part1.south) {\scriptsize{源语言句子(编码)}}; \node [anchor=south] (text) at ([xshift=0.5em,yshift=-3.5em]part1.south) {\scriptsize{源语言句子(编码)}};
\node [anchor=east,draw=black,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=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{预测当前位置的单词分布}}; \node [anchor=south] (text2) at ([xshift=0.5em,yshift=2.2em]part2.north) {\scriptsize{预测当前位置的单词分布}};
......
\tikzstyle{er} = [rectangle,minimum width=7cm,minimum height=2.5cm,text centered,draw=black] \definecolor{taupegray}{rgb}{0.55, 0.52, 0.54}
\tikzstyle{er} = [rectangle,minimum width=7cm,minimum height=2.5cm,text centered,draw=taupegray,drop shadow,rounded corners]
\begin{tikzpicture}[node distance = 0,scale = 0.55] \begin{tikzpicture}[node distance = 0,scale = 0.55]
\tikzstyle{every node}=[scale=0.55] \tikzstyle{every node}=[scale=0.55]
\node (encoder)[er,very thick,minimum width=5cm,draw=black!70,fill=ugreen!20]{\huge{编码器}}; \node (encoder)[er,very thick,minimum width=5.5cm,fill=ugreen!20]{\huge{编码器}};
\node (decoder)[er,very thick,right of=encoder,xshift=7.75cm,draw=black!70,fill=red!20]{\huge{解码器}}; \node (decoder)[er,very thick,right of=encoder,xshift=7.75cm,fill=red!20]{\huge{解码器}};
\node (decoder_1)[er,very thick,right of=decoder,xshift=8.75cm,draw=black!70,fill=red!20]{\huge{解码器}}; \node (decoder_1)[er,very thick,right of=decoder,xshift=8.75cm,fill=red!20]{\huge{解码器}};
\draw [->,very thick,draw=black!70]([xshift=0.2cm]encoder.east) -- ([xshift=-0.2cm]decoder.west); \draw [->,very thick,draw=black!70]([xshift=0.2cm]encoder.east) -- ([xshift=-0.2cm]decoder.west);
\draw [->,very thick,draw=black!70]([xshift=0.2cm]decoder.east) -- ([xshift=-0.2cm]decoder_1.west); \draw [->,very thick,draw=black!70]([xshift=0.2cm]decoder.east) -- ([xshift=-0.2cm]decoder_1.west);
\foreach \x in {-1.8cm,-0.9cm,...,1.9cm} \foreach \x in {-2.2cm,-1.1cm,...,2.2cm}
\draw [->,very thick,draw=black!70]([xshift=\x,yshift=-1cm]encoder.south) -- ([xshift=\x,yshift=-0.2cm]encoder.south); \draw [->,very thick,draw=black!70]([xshift=\x,yshift=-1cm]encoder.south) -- ([xshift=\x,yshift=-0.2cm]encoder.south);
\node [below of = encoder,xshift=-1.8cm,yshift=-2.95cm,scale=1.2]{[cls]}; \node [below of = encoder,xshift=-2.3cm,yshift=-2.95cm,scale=1.2]{\large{[LEN]}};
\node [below of = encoder,xshift=-0.7cm,yshift=-2.9cm,scale=1.2]{hello}; \node [below of = encoder,xshift=-1.05cm,yshift=-2.9cm,scale=1.2]{\large{hello}};
\node [below of = encoder,xshift=0cm,yshift=-3.05cm,scale=1.2]{,}; \node [below of = encoder,xshift=0cm,yshift=-3.05cm,scale=1.2]{,};
\node [below of = encoder,xshift=0.9cm,yshift=-2.9cm,scale=1.2]{world}; \node [below of = encoder,xshift=1.1cm,yshift=-2.9cm,scale=1.2]{\large{world}};
\node [below of = encoder,xshift=1.8cm,yshift=-2.9cm,scale=1.2]{!}; \node [below of = encoder,xshift=2.2cm,yshift=-2.9cm,scale=1.2]{!};
\draw [->,very thick,draw=black!70]([xshift=-1.8cm,yshift=0.2cm]encoder.north) -- ([xshift=-1.8cm,yshift=1cm]encoder.north); \draw [->,very thick,draw=black!70]([xshift=-2.2cm,yshift=0.2cm]encoder.north) -- ([xshift=-2.2cm,yshift=1cm]encoder.north);
\node [below of = encoder,xshift=-1.8cm,yshift=2.9cm,scale=1.5]{length:6}; \node [below of = encoder,xshift=-2.2cm,yshift=2.9cm,scale=1.5]{4};
\foreach \x in {-2.8cm,-1.7cm,...,2.9cm} \foreach \x in {-2.7cm,-0.9cm,...,2.8cm}
{\draw [->,very thick,draw=black!70]([xshift=\x,yshift=-1cm]decoder.south) -- ([xshift=\x,yshift=-0.2cm]decoder.south); {\draw [->,very thick,draw=black!70]([xshift=\x,yshift=-1cm]decoder.south) -- ([xshift=\x,yshift=-0.2cm]decoder.south);
\draw [->,very thick,draw=black!70]([xshift=\x,yshift=0.2cm]decoder.north) -- ([xshift=\x,yshift=1cm]decoder.north);} \draw [->,very thick,draw=black!70]([xshift=\x,yshift=0.2cm]decoder.north) -- ([xshift=\x,yshift=1cm]decoder.north);}
\node [below of = decoder,xshift=0cm,yshift=-2.9cm,scale=1.2]{{Mask\ Mask\ Mask\ Mask\ Mask\ Mask}}; \node [below of = decoder,xshift=-2.7cm,yshift=-2.9cm,scale=1.6]{\small{[Mask]}};
\node [below of = decoder,xshift=-2.8cm,yshift=2.9cm,scale=1.6]{}; \node [below of = decoder,xshift=-0.9cm,yshift=-2.9cm,scale=1.6]{\small{[Mask]}};
\node [below of = decoder,xshift=-1.7cm,yshift=2.9cm,scale=1.6]{}; \node [below of = decoder,xshift=0.9cm,yshift=-2.9cm,scale=1.6]{\small{[Mask]}};
\node [below of = decoder,xshift=-0.6cm,yshift=2.7cm,scale=1.6]{}; \node [below of = decoder,xshift=2.7cm,yshift=-2.9cm,scale=1.6]{\small{[Mask]}};
\node [below of = decoder,xshift=0.5cm,yshift=2.7cm,scale=1.6]{}; \node [below of = decoder,xshift=-2.7cm,yshift=2.9cm,scale=1.6]{你好};
\node [below of = decoder,xshift=1.6cm,yshift=2.9cm,scale=1.6]{}; \node [below of = decoder,xshift=-0.9cm,yshift=2.7cm,scale=1.6]{};
\node [below of = decoder,xshift=2.7cm,yshift=2.75cm,scale=1.6]{}; \node [below of = decoder,xshift=0.9cm,yshift=2.9cm,scale=1.6]{你好};
\node [below of = decoder,xshift=2.6cm,yshift=2.9cm,scale=1.6]{};
\foreach \x in {-2.8cm,-1.7cm,...,2.9cm}
\foreach \x in {-2.7cm,-0.9cm,...,2.8cm}
{\draw [->,very thick,draw=black!70]([xshift=\x,yshift=-1cm]decoder_1.south) -- ([xshift=\x,yshift=-0.2cm]decoder_1.south); {\draw [->,very thick,draw=black!70]([xshift=\x,yshift=-1cm]decoder_1.south) -- ([xshift=\x,yshift=-0.2cm]decoder_1.south);
\draw [->,very thick,draw=black!70]([xshift=\x,yshift=0.2cm]decoder_1.north) -- ([xshift=\x,yshift=1cm]decoder_1.north);} \draw [->,very thick,draw=black!70]([xshift=\x,yshift=0.2cm]decoder_1.north) -- ([xshift=\x,yshift=1cm]decoder_1.north);}
\node [below of = decoder_1,xshift=-2.8cm,yshift=2.9cm,scale=1.6]{}; \node [below of = decoder_1,xshift=-2.7cm,yshift=2.9cm,scale=1.6]{你好};
\node [below of = decoder_1,xshift=-1.7cm,yshift=2.9cm,scale=1.6]{}; \node [below of = decoder_1,xshift=-0.9cm,yshift=2.7cm,scale=1.6]{};
\node [below of = decoder_1,xshift=-0.6cm,yshift=2.75cm,scale=1.6]{}; \node [below of = decoder_1,xshift=0.9cm,yshift=2.9cm,scale=1.6]{世界};
\node [below of = decoder_1,xshift=0.5cm,yshift=2.9cm,scale=1.6]{}; \node [below of = decoder_1,xshift=2.7cm,yshift=2.9cm,scale=1.6]{};
\node [below of = decoder_1,xshift=1.6cm,yshift=2.9cm,scale=1.6]{};
\node [below of = decoder_1,xshift=2.7cm,yshift=2.75cm,scale=1.6]{}; \node [below of = decoder_1,xshift=-2.7cm,yshift=-2.9cm,scale=1.6]{你好};
\node [below of = decoder_1,xshift=-2.8cm,yshift=-2.9cm,scale=1.2]{Mask}; \node [below of = decoder_1,xshift=-0.9cm,yshift=-3cm,scale=1.6]{};
\node [below of = decoder_1,xshift=-1.7cm,yshift=-2.9cm,scale=1.3]{}; \node [below of = decoder_1,xshift=0.9cm,yshift=-2.9cm,scale=1.6]{\small{[Mask]}};
\node [below of = decoder_1,xshift=-0.6cm,yshift=-3cm,scale=1.3]{}; \node [below of = decoder_1,xshift=2.7cm,yshift=-2.9cm,scale=1.6]{};
\node [below of = decoder_1,xshift=0.5cm,yshift=-2.9cm,scale=1.2]{Mask};
\node [below of = decoder_1,xshift=1.6cm,yshift=-2.9cm,scale=1.2]{};
\node [below of = decoder_1,xshift=2.7cm,yshift=-3cm,scale=1.3]{};
\end{tikzpicture} \end{tikzpicture}
\ No newline at end of file
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
\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{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] \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[ 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=1cm]encoder.east) {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 解码器};
\node[anchor=north,word] (en1) 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]encoder.south) {}; \node[anchor=north,word] (en2) at ([yshift=-1.3em]encoder.south) {};
......
...@@ -4,48 +4,48 @@ ...@@ -4,48 +4,48 @@
%%% outline %%% outline
%------------------------------------------------------------------------- %-------------------------------------------------------------------------
\begin{tikzpicture} \begin{tikzpicture}
\tikzstyle{word} = [draw=ugreen!20,minimum size=1.8em, fill=ugreen!40, font=\scriptsize, rounded corners=1pt] \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=12em,minimum height=4em] (encoder) at (0,0) {Transformer 编码器 }; \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[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=14em,minimum height=4em] (decoder) at ([xshift=0.8cm]attention.east) {Transformer 解码器}; \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.6em,xshift=-4.8em]encoder.south) {hello}; \node[anchor=north,word] (en1) at ([yshift=-1.4em,xshift=-3.6em]encoder.south) {hello};
\node[anchor=north,word] (en2) at ([yshift=-1.6em,xshift=-1.6em]encoder.south) {,}; \node[anchor=north,word] (en2) at ([yshift=-1.4em,xshift=-1.2em]encoder.south) {,};
\node[anchor=north,word] (en3) at ([yshift=-1.6em,xshift=1.6em]encoder.south) {world}; \node[anchor=north,word] (en3) at ([yshift=-1.4em,xshift=1.2em]encoder.south) {world};
\node[anchor=north,word] (en4) at ([yshift=-1.6em,xshift=4.8em]encoder.south) {!}; \node[anchor=north,word] (en4) at ([yshift=-1.4em,xshift=3.6em]encoder.south) {!};
\node[anchor=north,word] (de1) at ([yshift=-1.6em,xshift=-5.75em]decoder.south) {1}; \node[anchor=north,word] (de1) at ([yshift=-1.4em,xshift=-5em]decoder.south) {1};
\node[anchor=north,word] (de2) at ([yshift=-1.6em,xshift=-3.45em]decoder.south) {2}; \node[anchor=north,word] (de2) at ([yshift=-1.4em,xshift=-3em]decoder.south) {2};
\node[anchor=north,word] (de3) at ([yshift=-1.6em,xshift=-1.15em]decoder.south) {3}; \node[anchor=north,word] (de3) at ([yshift=-1.4em,xshift=-1 em]decoder.south) {3};
\node[anchor=north,word] (de4) at ([yshift=-1.6em,xshift=1.15em]decoder.south) {4}; \node[anchor=north,word] (de4) at ([yshift=-1.4em,xshift=1em]decoder.south) {4};
\node[anchor=north,word] (de5) at ([yshift=-1.6em,xshift=3.45em]decoder.south) {5}; \node[anchor=north,word] (de5) at ([yshift=-1.4em,xshift=3em]decoder.south) {5};
\node[anchor=north,word] (de6) at ([yshift=-1.6em,xshift=5.75em]decoder.south) {6}; \node[anchor=north,word] (de6) at ([yshift=-1.4em,xshift=5em]decoder.south) {6};
\node[anchor=south,word] (out1) at ([yshift=1.6em,xshift=-5.75em]decoder.north) {}; \node[anchor=south,word] (out1) at ([yshift=1.4em,xshift=-5em]decoder.north) {};
\node[anchor=south,word] (out2) at ([yshift=1.6em,xshift=-3.45em]decoder.north) {}; \node[anchor=south,word] (out2) at ([yshift=1.4em,xshift=-3em]decoder.north) {};
\node[anchor=south,word] (out3) at ([yshift=1.6em,xshift=-1.15em]decoder.north) {}; \node[anchor=south,word] (out3) at ([yshift=1.4em,xshift=-1em]decoder.north) {};
\node[anchor=south,word] (out4) at ([yshift=1.6em,xshift=1.15em]decoder.north) {}; \node[anchor=south,word] (out4) at ([yshift=1.4em,xshift=1em]decoder.north) {};
\node[anchor=south,word] (out5) at ([yshift=1.6em,xshift=3.45em]decoder.north) {}; \node[anchor=south,word] (out5) at ([yshift=1.4em,xshift=3em]decoder.north) {};
\node[anchor=south,word] (out6) at ([yshift=1.6em,xshift=5.75em]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=-4.8em,yshift=-0.1em]encoder.south); \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.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.6em,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=4.8em,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=-5.75em]decoder.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=-3.45em]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=-1.15em]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=1.15em]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=3.45em]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=5.75em]decoder.south); \draw[-latex, very thick,ublue] ([yshift=0.1em]de6.north) -- ([xshift=5em]decoder.south);
\draw[-latex, very thick,ublue] ([xshift=-5.75em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out1.south); \draw[-latex, very thick,ublue] ([xshift=-5em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out1.south);
\draw[-latex, very thick,ublue] ([xshift=-3.45em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out2.south); \draw[-latex, very thick,ublue] ([xshift=-3em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out2.south);
\draw[-latex, very thick,ublue] ([xshift=-1.15em,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]out3.south);
\draw[-latex, very thick,ublue] ([xshift=1.15em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out4.south); \draw[-latex, very thick,ublue] ([xshift=1em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out4.south);
\draw[-latex, very thick,ublue] ([xshift=3.45em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out5.south); \draw[-latex, very thick,ublue] ([xshift=3em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out5.south);
\draw[-latex, very thick,ublue] ([xshift=5.75em,yshift=0.1em]decoder.north) -- ([yshift=-0.1em]out6.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] (encoder.east) -- (attention.west);
\draw[-latex, very thick, ublue] (attention.east) -- (decoder.west); \draw[-latex, very thick, ublue] (attention.east) -- (decoder.west);
......
\definecolor{ublue}{rgb}{0.152,0.250,0.545} \definecolor{taupegray}{rgb}{0.55, 0.52, 0.54}
\definecolor{ugreen}{rgb}{0,0.5,0} \definecolor{bananamania}{rgb}{0.98, 0.91, 0.71}
%%% outline %%% outline
%------------------------------------------------------------------------- %-------------------------------------------------------------------------
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}
\tikzstyle{every node}=[scale=0.7] \tikzstyle{layer} = [draw=black!70,thick, minimum width=7.5em,rounded corners=2pt,inner ysep=6pt,font=\footnotesize,align=center]
\tikzstyle{emb} = [draw,very thick, minimum height=2.4em,minimum width=3.6em,rounded corners=2pt,font=\footnotesize] \tikzstyle{line} = [line width=1pt,->]
\tikzstyle{attention} = [fill=blue!15,draw,very thick, minimum width=19.6em,minimum height=2.4em, rounded corners=2pt,font=\footnotesize] \tikzstyle{cir} = [draw,circle,minimum size=1em, thick,inner sep=0pt]
\tikzstyle{line} = [line width=1.6pt,->]
%encoder
\foreach \x in {1,2,3,4,5} \node[layer,fill=red!15] (src_emb) at (0,0){\scriptsize\textbf{Input Embedding}};
\node[emb,fill=gray!30] (enemb_\x) at (0+4em*\x,0){\small\bfnew{Emb}}; \node[anchor=south,layer,fill=yellow!20] (src_sa) at ([yshift=3.7em]src_emb.north){\scriptsize\textbf{Self-attention}};
\node[anchor=south,layer,fill=orange!20] (src_ff) at ([yshift=1em]src_sa.north){\scriptsize\textbf{Feed Forward}};
\foreach \x in {1,2,3,4,5} \node[anchor=south,layer,fill=blue!20] (src_sf) at ([yshift=2.4em]src_ff.north){\scriptsize\textbf{Softmax}};
\node[emb,fill=gray!30] (deemb_\x) at (24em+4em*\x,0){\small\bfnew{Emb}};
%decoder
\node[attention] (a1) at (12em, 5em) {\small\bfnew{Multi-Head Self-Attention}}; \node[anchor=west,layer,fill=red!15] (tgt_emb) at ([xshift=4.4em]src_emb.east){\scriptsize\textbf{Output Embedding}};
\node[attention] (a2) at (36em, 5em) {\small\bfnew{Multi-Head Self-Attention}}; \node[anchor=south,layer,fill=yellow!20] (tgt_sa) at ([yshift=3.7em]tgt_emb.north){\scriptsize\textbf{Self-attention}};
\node[attention] (a3) at (36em, 9em) {\small\bfnew{Multi-Head Self-Attention}}; \node[anchor=south,layer,fill=yellow!20] (tgt_pa) at ([yshift=1.1em]tgt_sa.north){\scriptsize\textbf{Positional Attention}};
\node[attention] (a4) at (36em, 13em) {\small\bfnew{Multi-Head Self-Attention}}; \node[anchor=south,layer,fill=yellow!20] (tgt_eda) at ([yshift=1.5em]tgt_pa.north){\scriptsize\textbf{Encoder-Decoder} \\ \scriptsize\textbf{Attention}};
\node[anchor=south,layer,fill=orange!20] (tgt_ff) at ([yshift=1em]tgt_eda.north){\scriptsize\textbf{Feed Forward}};
\foreach \x in {1,2,3,4,5} \node[anchor=south,layer,fill=green!20] (tgt_linear) at ([yshift=1.4em]tgt_ff.north){\scriptsize\textbf{Linear}};
\node[emb,fill=cyan!35] (enmlp_\x) at (0+4em*\x,9em){\small\bfnew{MLP}}; \node[anchor=south,layer,fill=blue!20] (tgt_sf) at ([yshift=1em]tgt_linear.north){\scriptsize\textbf{Softmax}};
\foreach \x in {1,2,3,4,5} \node[font=\footnotesize,anchor=south] (w3) at ([yshift=0.8em]src_sf.north){\scriptsize\textbf{2}};
\node[emb,fill=cyan!35] (demlp_\x) at (24em+4em*\x,17em){\small\bfnew{MLP}}; \node[font=\footnotesize,anchor=east] (w2) at ([xshift=-0.5em]w3.west){\scriptsize\textbf{1}};
\node[font=\footnotesize,anchor=east] (w1) at ([xshift=-0.5em]w2.west){\scriptsize\textbf{1}};
\foreach \x in {1,2,3,4,5} \node[font=\footnotesize,anchor=west] (w4) at ([xshift=0.5em]w3.east){\scriptsize\textbf{0}};
\node[emb,fill=red!25,inner sep=1pt] (ensf_\x) at (0+4em*\x,17em){\small\bfnew{SoftMax}}; \node[font=\footnotesize,anchor=west] (w5) at ([xshift=0.5em]w4.east){\scriptsize\textbf{1}};
\node[font=\footnotesize,anchor=south] (output) at ([yshift=1em]tgt_sf.north){\scriptsize\textbf{Wir akzeptieren das voll und ganz}};
\foreach \x in {1,2,3,4,5} \node[font=\footnotesize,anchor=north] (src) at ([yshift=-1em]src_emb.south){\scriptsize\textbf{We totally accept it .}};
\node[emb,fill=ugreen!25!white,inner sep=1pt, font=\scriptsize] (desf_\x) at (24em+4em*\x,22em){\small\bfnew{SoftMax}}; \node[font=\footnotesize,anchor=north] (tgt) at ([yshift=-1em]tgt_emb.south){\scriptsize\textbf{We totally accept accept .}};
\node[minimum height=2.4em,minimum width=3.6em] (enout_1) at (0+4em*1,21em){\small\bfnew{1}}; \node[cir] (src_add) at (0,2.5em) {};
\node[minimum height=2.4em,minimum width=3.6em] (enout_2) at (0+4em*2,21em){\small\bfnew{1}}; \node[cir,fill=orange!7] (src_pos) at (-2.5em,2.5em) {};
\node[minimum height=2.4em,minimum width=3.6em] (enout_3) at (0+4em*3,21em){\small\bfnew{2}};
\node[minimum height=2.4em,minimum width=3.6em] (enout_4) at (0+4em*4,21em){\small\bfnew{0}}; \node[cir] (tgt_add) at (12em,2.5em) {};
\node[minimum height=2.4em,minimum width=3.6em] (enout_5) at (0+4em*5,21em){\small\bfnew{1}}; \node[cir,fill=orange!7] (tgt_pos) at (14.5em,2.5em) {};
\node[minimum height=2.4em,minimum width=3.6em,inner sep=0pt,font=\footnotesize] (deout_1) at (24em+4em*1,26em){\small\bfnew{I}}; \draw[-,thick] (src_add.90) -- (src_add.-90);
\node[minimum height=2.4em,minimum width=3.6em,inner sep=0pt,font=\footnotesize] (deout_2) at (24em+4em*2,26em){\small\bfnew{love}}; \draw[-,thick] (src_add.0) -- (src_add.180);
\node[minimum height=2.4em,minimum width=3.6em,inner sep=0pt,font=\footnotesize] (deout_3) at (24em+4em*3,26em){\small\bfnew{my}}; \draw[-,thick,] (src_pos.180) .. controls ([xshift=0.8em,yshift=0.8em]src_pos.180) and ([xshift=-0.8em,yshift=-0.8em]src_pos.0) ..(src_pos.0);
\node[minimum height=2.4em,minimum width=3.6em,inner sep=0pt,font=\footnotesize] (deout_4) at (24em+4em*4,26em){\small\bfnew{dog}}; \draw[-,thick] (tgt_add.90) -- (tgt_add.-90);
\node[minimum height=2.4em,minimum width=3.6em,inner sep=0pt,font=\footnotesize] (deout_5) at (24em+4em*5,26em){\small\bfnew{.}}; \draw[-,thick] (tgt_add.0) -- (tgt_add.180);
\draw[-,thick,] (tgt_pos.180) .. controls ([xshift=0.8em,yshift=0.8em]tgt_pos.180) and ([xshift=-0.8em,yshift=-0.8em]tgt_pos.0) ..(tgt_pos.0);
\foreach \x in {1,2,3,4,5}{
\draw[line] (enemb_\x.north) -- ([yshift=2.6em]enemb_\x.north); \draw[line] (src_emb.north) -- (src_add.south);
\draw[line] ([yshift=4.9em]enemb_\x.north) -- (enmlp_\x.south); \draw[line] (src_add.north) -- (src_sa.south);
\draw[line] (enmlp_\x.north) -- (ensf_\x.south); \draw[line] (src_sa.north) -- (src_ff.south);
\draw[line,dotted] (ensf_\x.north) -- (enout_\x.south); \draw[line] (src_ff.north) -- (src_sf.south);
\draw[line] (deemb_\x.north) -- ([yshift=2.6em]deemb_\x.north); \draw[line] (tgt_emb.north) -- (tgt_add.south);
\draw[line] ([yshift=4.9em]deemb_\x.north) -- ([yshift=6.5em]deemb_\x.north); \draw[line] (tgt_add.north) -- (tgt_sa.south);
\draw[line] ([yshift=8.8em]deemb_\x.north) -- ([yshift=10.4em]deemb_\x.north); \draw[line] (tgt_sa.north) -- (tgt_pa.south);
\draw[line] ([yshift=12.9em]deemb_\x.north) -- (demlp_\x.south); \draw[line] (tgt_eda.north) -- (tgt_ff.south);
\draw[line] (demlp_\x.north) -- (desf_\x.south); \draw[line] (tgt_ff.north) -- (tgt_linear.south);
\draw[line,dotted] (desf_\x.north) -- (deout_\x.south); \draw[line] (tgt_linear.north) -- (tgt_sf.south);
} \draw[line] (src_pos.0) -- (src_add.180);
\draw[line] (tgt_pos.180) -- (tgt_add.0);
\draw[line] (src_sf.north) -- (w3.south);
\draw[line] (tgt_sf.north) -- (output.south);
\draw[line] (src.north) -- (src_emb.south);
\draw[line,<->,out=-35,in=-145] ([xshift=-2em]src_sa.south) to ([xshift=2em]src_sa.south);
\draw[line, rounded corners=2pt] (src_ff.north) -- ([yshift=0.9em]src_ff.north) -- ([xshift=-2.4em,yshift=-0.8em]tgt_eda.south) -- ([xshift=-2.4em]tgt_eda.south);
\draw[line, rounded corners=2pt] (src_ff.north) -- ([yshift=0.9em]src_ff.north) -- ([yshift=-0.8em]tgt_eda.south) -- (tgt_eda.south);
\draw[line, rounded corners=2pt] (tgt_pa.north) -- ([yshift=0.5em]tgt_pa.north) -- ([yshift=0.5em,xshift=2.4em]tgt_pa.north) -- ([xshift=2.4em]tgt_eda.south);
\draw[line,<->,out=-35,in=-145] ([xshift=-2em]tgt_sa.south) to ([xshift=2em]tgt_sa.south);
\draw[line,<->,out=-35,in=-145] ([xshift=-2em]tgt_pa.south) to ([xshift=2em]tgt_pa.south);
\begin{pgfonlayer}{background} \begin{pgfonlayer}{background}
{ {
\node[draw=blue!25,very thick,fill=blue!5,rounded corners=6pt,minimum height=12em,minimum width=21em,yshift=-1em] at (12em,9em) (box1){}; \node[draw=taupegray,thick,fill=ugreen!10,inner sep=0pt,minimum height=6.7em,minimum width=9.5em,rounded corners=4pt,drop shadow] (box1) at (0em,6.8em){};
\node[draw=red!25,very thick,fill=red!10,rounded corners=6pt,minimum height=7.4em,minimum width=21em,yshift=-1em] at (12em,19.2em) (box2){}; \node[draw=taupegray,thick,fill=yellow!10,inner sep=0pt,minimum height=4.5em,minimum width=9.5em,rounded corners=4pt,drop shadow] (box2) at (0em,13em){};
\node[draw=cyan!25,very thick,fill=cyan!15,rounded corners=6pt,minimum height=17.5em,minimum width=22.6em,yshift=-1em] at (36em,11.8em) (box3){}; \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){};
\node[draw=ugreen!25,very thick,fill=green!15!white,rounded corners=6pt,minimum height=7em,minimum width=22.6em,yshift=-1em] at (36em,24.5em) (box4){};
} }
\draw[line] (enmlp_1.north) .. controls ([yshift=3.6em]enmlp_1.north) and ([xshift=-2em]a4.west) .. (a4.west);
\draw[line] (enmlp_2.north) .. controls ([yshift=3.6em]enmlp_2.north) and ([xshift=-2em]a4.west) .. (a4.west);
\draw[line] (enmlp_3.north) .. controls ([yshift=3.6em]enmlp_3.north) and ([xshift=-2em]a4.west) .. (a4.west);
\draw[line] (enmlp_4.north) .. controls ([yshift=3.6em]enmlp_4.north) and ([xshift=-2em]a4.west) .. (a4.west);
\draw[line] (enmlp_5.north) .. controls ([yshift=3.6em]enmlp_5.north) and ([xshift=-2em]a4.west) .. (a4.west);
\end{pgfonlayer} \end{pgfonlayer}
\node[] at ([xshift=-2em]box1.west){{$M \times$}};
\node[] at ([xshift=2em]box3.east){{$\times N$}};
\node[anchor=east,draw,circle,minimum size=2em,thick,inner sep=0pt,fill=gray!40] at ([xshift=-2em]enemb_1.west) (pos1){\Large$\sim$}; \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);
\node[anchor=west,draw,circle,minimum size=2em,thick,inner sep=0pt,fill=gray!40] at ([xshift=2.4em]deemb_5.east) (pos2){\Large$\sim$}; \draw[line,-,dotted,rounded corners=4pt,violet,] (src_emb.east) -- ([xshift=-2em]tgt_emb.west);
\node[anchor=west,draw,circle,minimum size=2em,thick,inner sep=0pt,fill=gray!40] at ([xshift=2.4em]a3.east) (pos3){\Large$\sim$};
\draw[line] (pos1.0) -- (enemb_1.180);
\draw[line] (pos2.180) -- (deemb_5.0);
\draw[line] (pos3.180) -- (a3.0);
\draw[violet,dotted,rounded corners=4pt,very thick,->] (box2.north) -- ([yshift=2em]box2.north) -- ([yshift=2em,xshift=11.5em]box2.north) -- ([xshift=1.9em]enemb_5.east) -- (deemb_1.west);
\draw[violet,dotted,very thick,->] (enemb_5.east) -- node[below,violet,font=\footnotesize]{\emph{Copy}}(deemb_1.west);
\node[] at ([xshift=-1em,yshift=-4em]box1.west){{$N \times$}};
\node[] at ([xshift=1em,yshift=-7em]box3.east){{$\times N$}};
\node[font=\footnotesize,align=left] at ([xshift=-2em,yshift=2em]box1.west) {\small\bfnew{Encoder} \\ \small\bfnew{Stack}};
\node[font=\footnotesize,align=left] at ([xshift=-2em]box2.west) {\small\bfnew{Fertility} \\ \small\bfnew{Predictor}};
\node[font=\footnotesize,align=left] at ([xshift=0.4em,yshift=-1.2em]pos3.south) {\small\bfnew{Positional} \\ \small\bfnew{Encoding}};
\node[font=\footnotesize,align=left] at ([xshift=2em,yshift=2em]box3.east) {\small\bfnew{Decoder} \\ \small\bfnew{Stack}};
\node[font=\footnotesize,align=left] at ([xshift=2.5em]box4.east) {\small\bfnew{Translation} \\ \small\bfnew{Predictor}};
\node[font=\footnotesize] at ([yshift=-1em]enemb_1.south) {\small\bfnew{}};
\node[font=\footnotesize] at ([yshift=-1em]enemb_2.south) {\small\bfnew{}};
\node[font=\footnotesize] at ([yshift=-1em]enemb_3.south) {\small\bfnew{我的}};
\node[font=\footnotesize] at ([yshift=-1em]enemb_4.south) {\small\bfnew{}};
\node[font=\footnotesize] at ([yshift=-1em]enemb_5.south) {\small\bfnew{}};
\end{tikzpicture} \end{tikzpicture}
......
\definecolor{beige}{rgb}{0.96, 0.96, 0.86}
\definecolor{aliceblue}{rgb}{0.94, 0.97, 1.0}
\definecolor{brown(traditional)}{rgb}{0.59, 0.29, 0.0}
\definecolor{taupegray}{rgb}{0.55, 0.52, 0.54}
\definecolor{bananamania}{rgb}{0.98, 0.91, 0.71}
\definecolor{beaublue}{rgb}{0.74, 0.83, 0.9}
%%% outline
%-------------------------------------------------------------------------
\begin{tikzpicture}
\tikzstyle{module} = [draw=taupegray,very thick,rounded corners=2pt,inner ysep=8pt,font=\footnotesize,align=center,fill=yellow!15]
\tikzstyle{box} = [draw=taupegray,very thick,rounded corners=4pt,inner ysep=4pt,inner xsep=8pt,fill=ugreen!10,drop shadow];
\tikzstyle{line} = [very thick,-latex];
\node[module, minimum width=8em] (encoder) at (0,0) {编码器组件};
\node[module,anchor=west, minimum width=8em] (decoder) at ([xshift=4em]encoder.east){解码器组件};
\node[module,anchor=west, minimum width=8em] (decoder2) at ([xshift=4em]decoder.east){解码器组件};
\node[module,anchor=north, minimum width=6em,font=\scriptsize,inner ysep=4pt] (deinput) at ([yshift=-2em]decoder2.south){解码端输入};
\node[anchor=south,font=\footnotesize] (mod1) at ([yshift=0.4em]encoder.north){\small\bfnew{编码器模块}};
\node[anchor=south,font=\footnotesize] (mod2) at ([yshift=0.4em]decoder.north){\small\bfnew{重排序模块}};
\node[anchor=south,font=\footnotesize] (mod3) at ([yshift=0.4em]decoder2.north){\small\bfnew{解码端}};
\begin{pgfonlayer}{background}
{
\node[box][fit=(encoder)(mod1)] (box1) {};
\node[box][fit=(decoder)(mod2)] (box2) {};
\node[box][fit=(decoder2)(mod3)] (box3) {};
}
\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=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$};
\node[font=\tiny] at ([xshift=-0.8em,yshift=-0.6em]decoder.east) {$1\times$};
\node[font=\tiny] at ([xshift=-1em,yshift=-0.6em]decoder2.east) {$N$-1$\times$};
\draw[line] (w1.north) -- (box1.south);
\draw[line] (w2.north) -- (box2.south);
\draw[line] (box2.north) -- (w4.south);
\draw[line] (box3.north) -- (w5.south);
\draw[line] (deinput.north) -- (box3.south);
\draw[line] (box1.east) -- (box2.west);
\draw[line] (box2.east) -- (box3.west);
\draw[line,rounded corners=2pt,dotted,brown(traditional)] (w1.south) -- ([yshift=-1.6em]w1.south) -- ([yshift=-2.3em]deinput.south) -- (deinput.south);
\draw[line,rounded corners=2pt,dotted,brown(traditional)] (w4.east) -- ([xshift=0.9em]w4.east) -- ([xshift=-3em]deinput.west) -- (deinput.west);
\end{tikzpicture}
...@@ -2,13 +2,14 @@ ...@@ -2,13 +2,14 @@
\definecolor{Goldenrod}{rgb}{0.85, 0.65, 0.13} \definecolor{Goldenrod}{rgb}{0.85, 0.65, 0.13}
\definecolor{Cerulean}{rgb}{0, 0.48, 0.65} \definecolor{Cerulean}{rgb}{0, 0.48, 0.65}
\definecolor{Gray}{rgb}{0.5, 0.5, 0.5} \definecolor{Gray}{rgb}{0.5, 0.5, 0.5}
\tikzstyle{emb} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=0.85cm,text centered,draw=black!70,fill=Melon!25] \definecolor{aliceblue}{rgb}{0.94, 0.97, 1.0}
\tikzstyle{sa} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=1cm,text centered,draw=black!70,fill=Goldenrod!25] \tikzstyle{emb} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=0.85cm,text centered,draw=black!70,fill=red!15]
\tikzstyle{edsa} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=1.5cm,text centered,align=center,draw=black!70,fill=Goldenrod!25] \tikzstyle{sa} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=1cm,text centered,draw=black!70,fill=yellow!20]
\tikzstyle{an} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=0.7cm,text centered,draw=black!70,fill=ugreen!20] \tikzstyle{edsa} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=1.5cm,text centered,align=center,draw=black!70,fill=yellow!20]
\tikzstyle{ff} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=1cm,text centered,align=center,draw=black!70,fill=Cerulean!10] \tikzstyle{an} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=0.7cm,text centered,draw=black!70,fill=aliceblue]
\tikzstyle{linear} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=0.7cm,text centered,draw=black!70,fill=Gray!20] \tikzstyle{ff} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=1cm,text centered,align=center,draw=black!70,fill=orange!20]
\tikzstyle{softmax} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=0.7cm,text centered,draw=black!70,fill=Melon!40] \tikzstyle{linear} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=0.7cm,text centered,draw=black!70,fill=green!20]
\tikzstyle{softmax} = [rectangle,very thick,rounded corners,minimum width=3cm,minimum height=0.7cm,text centered,draw=black!70,fill=blue!20]
\begin{tikzpicture}[node distance = 0,scale = 0.7] \begin{tikzpicture}[node distance = 0,scale = 0.7]
\tikzstyle{every node}=[scale=0.7] \tikzstyle{every node}=[scale=0.7]
%left %left
...@@ -23,7 +24,7 @@ ...@@ -23,7 +24,7 @@
\node(left_Add_bottom)[an,above of = left_Self,yshift=1.1cm]{\textbf{Add$\&\&$Norm}}; \node(left_Add_bottom)[an,above of = left_Self,yshift=1.1cm]{\textbf{Add$\&\&$Norm}};
\node(left_Feed)[ff,above of = left_Add_bottom,yshift=1.2cm]{\textbf{Feed}\\\textbf{Forward}}; \node(left_Feed)[ff,above of = left_Add_bottom,yshift=1.2cm]{\textbf{Feed}\\\textbf{Forward}};
\node(left_Add_top)[an,above of = left_Feed,yshift=1.1cm]{\textbf{Add$\&\&$Norm}}; \node(left_Add_top)[an,above of = left_Feed,yshift=1.1cm]{\textbf{Add$\&\&$Norm}};
\node(left_text_bottom)[below of = left_Emb,xshift=0cm,yshift=-1.2cm,scale=1]{\small\sffamily\bfseries{爱我的}}; \node(left_text_bottom)[below of = left_Emb,xshift=0cm,yshift=-1.2cm,scale=1]{\small\sffamily\bfseries{\quad\quad 我的\quad }};
\draw [->,very thick,draw=black!70]([yshift=-0.5cm]left_Emb.south)--(left_Emb.south); \draw [->,very thick,draw=black!70]([yshift=-0.5cm]left_Emb.south)--(left_Emb.south);
\draw [->,very thick,draw=black!70](left_Emb.north)--(left_cir.south); \draw [->,very thick,draw=black!70](left_Emb.north)--(left_cir.south);
\draw [->,very thick,draw=black!70](left_cir.north)--(left_Self.south); \draw [->,very thick,draw=black!70](left_cir.north)--(left_Self.south);
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
\begin{tabular}{C{.20\textwidth}C{.20\textwidth}C{.20\textwidth}C{.20\textwidth}} \begin{tabular}{C{.20\textwidth}C{.20\textwidth}C{.20\textwidth}C{.20\textwidth}}
\setlength{\tabcolsep}{0pt} \setlength{\tabcolsep}{0pt}
\subfigure [\footnotesize{自注意力}] { \subfigure [\footnotesize{自注意力}] {
\begin{tabular}{cc} \begin{tabular}{ccC{1em}}
\setlength{\tabcolsep}{0pt} \setlength{\tabcolsep}{0pt}
~ ~
& &
...@@ -57,24 +57,27 @@ ...@@ -57,24 +57,27 @@
0.5531 & 0.0332 & 0.0296 & 0.0552 & 0.0389 & 0.0000 \\ 0.5531 & 0.0332 & 0.0296 & 0.0552 & 0.0389 & 0.0000 \\
\end{tabular} \end{tabular}
&
\end{tabular} \end{tabular}
} }
& &
\subfigure [\footnotesize{编码-解码注意力}] { \subfigure [\footnotesize{编码-解码注意力}] {
\setlength{\tabcolsep}{0pt} \setlength{\tabcolsep}{0pt}
\begin{tabular}{cc} \begin{tabular}{ccC{1em}}
\setlength{\tabcolsep}{0pt} \setlength{\tabcolsep}{0pt}
~ ~
& &
\begin{tikzpicture} \begin{tikzpicture}
\begin{scope} \begin{scope}
\node [inner sep=1.5pt] (w1) at (0,0) {\small{$1$} }; \node [inner sep=1.5pt] (w1) at (0,0) {\small{$1$} };
\foreach \x/\y/\z in {2/1/$2$, 3/2/$3$, 4/3/$4$, 5/4/$5$, 6/5/$6$} \foreach \x/\y/\z in {2/1/$2$, 3/2/$3$, 4/3/$4$, 5/4/$5$, 6/5/$6$}
{ {
\node [inner sep=1.5pt,anchor=south west] (w\x) at ([xshift=1.15em]w\y.south west) {\small{\z} }; \node [inner sep=1.5pt,anchor=south west] (w\x) at ([xshift=1.15em]w\y.south west) {\small{\z} };
} }
\end{scope} \end{scope}
\end{tikzpicture} \end{tikzpicture}
\\ \\
\renewcommand\arraystretch{1} \renewcommand\arraystretch{1}
...@@ -102,6 +105,7 @@ ...@@ -102,6 +105,7 @@
0.3603 & 0.3324 & 0.4163 & 0.2022 & 0.0658 & 0.0000 \\ 0.3603 & 0.3324 & 0.4163 & 0.2022 & 0.0658 & 0.0000 \\
\end{tabular} \end{tabular}
&
\end{tabular} \end{tabular}
} }
\end{tabular} \end{tabular}
......
...@@ -49,11 +49,11 @@ ...@@ -49,11 +49,11 @@
\vspace{0.5em} \vspace{0.5em}
\end{itemize} \end{itemize}
\parinterval 这个过程与统计机器翻译中自左向右翻译是一样的(见{\chapterseven}),即,在每一个目标语位置,根据已经生成的译文和源语言的信息,生成下一个译文单词\upcite{Koehn2007Moses,DBLP:conf/amta/Koehn04}。它可以由两个模块实现\upcite{DBLP:conf/emnlp/StahlbergHSB17} \parinterval 这个过程与统计机器翻译中自左向右翻译是一样的(见{\chapterseven}),即,在目标语言的每个位置,根据已经生成的译文和源语言的信息,生成下一个译文单词\upcite{Koehn2007Moses,DBLP:conf/amta/Koehn04}。它可以由两个模块实现\upcite{DBLP:conf/emnlp/StahlbergHSB17}
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\item 预测模块,也就是根据已经翻译的历史和源语言句子,预测下一个要生成单词的概率\footnote{在统计机器翻译中,翻译的每一步也可以预测短语。在神经机器翻译中也有类似于生成短语的方 \item 预测模块,也就是根据已经翻译的历史和源语言句子,预测下一个要生成单词的概率分布\footnote{在统计机器翻译中,翻译的每一步也可以预测短语。在神经机器翻译中也有类似于生成短语的方
法,但是主流的方法还是按单词为单位进行生成。}。因此预测模块实际上就是一个模型打分装置; 法,但是主流的方法还是按单词为单位进行生成。}。因此预测模块实际上就是一个模型打分装置;
\vspace{0.5em} \vspace{0.5em}
\item 搜索模块,它会利用预测结果,对当前的翻译假设进行打分,并根据模型得分对翻译假设进行排序和剪枝。 \item 搜索模块,它会利用预测结果,对当前的翻译假设进行打分,并根据模型得分对翻译假设进行排序和剪枝。
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
\parinterval 这是一个非常通用的框架,同样适用基于统计的机器翻译模型。因此,神经机器翻译推断中的很多问题与统计机器翻译是一致的,比如:束搜索的宽度、解码终止条件等等。 \parinterval 这是一个非常通用的框架,同样适用基于统计的机器翻译模型。因此,神经机器翻译推断中的很多问题与统计机器翻译是一致的,比如:束搜索的宽度、解码终止条件等等。
\parinterval 一般来说,机器翻译推断系统的设计要考虑三个因素:搜索的准确性、搜索的时延、搜索所需要的存储。通常,准确性是研究人员最关心的问题,比如可以通过增大搜索空间来找到模型得分更高的结果。而搜索的延时和存储消耗是实践中必须要考虑的问题,比如,可以设计合理的搜索终止条件降低延时 \parinterval 一般来说,机器翻译推断系统的设计要考虑三个因素:搜索的准确性、搜索的时延、搜索所需要的存储。通常,准确性是研究人员最关心的问题,比如可以通过增大搜索空间来找到模型得分更高的结果。而搜索的时延和存储消耗是实践中必须要考虑的问题,比如,可以设计合理的搜索终止条件降低搜索时延
\parinterval 虽然,上述问题在统计机器翻译中都有讨论,但是在神经机器翻译中又面临着新的挑战。 \parinterval 虽然,上述问题在统计机器翻译中都有讨论,但是在神经机器翻译中又面临着新的挑战。
...@@ -81,13 +81,13 @@ ...@@ -81,13 +81,13 @@
\vspace{0.5em} \vspace{0.5em}
\item 搜索的基本问题在神经机器翻译中有着特殊的现象。比如,在统计机器翻译中,降低搜索错误是提升翻译效果的一种手段。但是神经机器翻译中,简单的降低搜索错误可能无法带来性能的提升,甚至造成翻译品质的下降\upcite{li-etal-2018-simple,Stahlberg2019OnNS} \item 搜索的基本问题在神经机器翻译中有着特殊的现象。比如,在统计机器翻译中,降低搜索错误是提升翻译效果的一种手段。但是神经机器翻译中,简单的降低搜索错误可能无法带来性能的提升,甚至造成翻译品质的下降\upcite{li-etal-2018-simple,Stahlberg2019OnNS}
\vspace{0.5em} \vspace{0.5em}
\item 搜索的延时很高,系统实际部署的成本很高。与统计机器翻译系统不同的是,神经机器翻译依赖大量的浮点预算。这也造成神经机器翻译系统的推断会比统计机器翻译系统慢很多。虽然可以使用GPU来加速神经机器翻译的推断速度,但是也大大增加了成本; \item 搜索的时延很高,系统实际部署的成本很高。与统计机器翻译系统不同的是,神经机器翻译依赖大量的浮点预算。这也造成神经机器翻译系统的推断会比统计机器翻译系统慢很多。虽然可以使用GPU来加速神经机器翻译的推断速度,但是也大大增加了成本;
\vspace{0.5em} \vspace{0.5em}
\item 神经机器翻译优化容易陷入局部最优,单模型的表现并不稳定。由于神经机器翻译优化的目标函数非常不光滑,每次训练得到的模型往往只是一个局部最优解。在新数据上,使用这个局部最优模型进行推断时模型的表现可能不稳定。 \item 神经机器翻译在优化过程中容易陷入局部最优,单模型的表现并不稳定。由于神经机器翻译优化的目标函数非常不光滑,每次训练得到的模型往往只是一个局部最优解。在新数据上使用这个局部最优模型进行推断时,模型的表现可能不稳定。
\vspace{0.5em} \vspace{0.5em}
\end{itemize} \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 % NEW SECTION
...@@ -103,7 +103,7 @@ ...@@ -103,7 +103,7 @@
\subsection{推断的方向} \subsection{推断的方向}
\parinterval 机器翻译有两种常用的推断方式\ \dash \ 自左向右翻译和自右向左翻译。自左向右翻译符合现实世界中人类的语言使用规律,因为在人为翻译一个句子时,人们总是习惯从句子开始的部分往后生成\footnote{有些语言中,文字是自右向左书写,这时自右向左翻译更符合人类使用这种语言的习惯。}。不过,有时候人也会使用当前单词后面的译文信息。也就是说,翻译也需要“未来” 的文字信息。于是很容易想到使用自右向左的方法对译文进行生成。 \parinterval 机器翻译有两种常用的推断方式\ \dash \ 自左向右推断和自右向左推断。自左向右推断符合现实世界中人类的语言使用规律,因为在人为翻译一个句子时,人们总是习惯从句子开始的部分往后生成\footnote{有些语言中,文字是自右向左书写,这时自右向左推断更符合人类使用这种语言的习惯。}。不过,有时候人也会使用当前单词后面的译文信息。也就是说,翻译也需要“未来” 的文字信息。于是很容易想到使用自右向左的方法对译文进行生成。
\parinterval 以上两种推断方式在神经机器翻译中都有应用,对于源语言句子$\seq{x}=\{x_1,x_2,\dots,x_m\}$和目标语句子$\seq{y}=\{y_1,y_2,\dots,y_n\}$,用自左向右的方式可以将翻译概率$\funp{P}(\seq{y}\vert\seq{x})$描述为公式\eqref{eq:14-1} \parinterval 以上两种推断方式在神经机器翻译中都有应用,对于源语言句子$\seq{x}=\{x_1,x_2,\dots,x_m\}$和目标语句子$\seq{y}=\{y_1,y_2,\dots,y_n\}$,用自左向右的方式可以将翻译概率$\funp{P}(\seq{y}\vert\seq{x})$描述为公式\eqref{eq:14-1}
...@@ -119,7 +119,7 @@ ...@@ -119,7 +119,7 @@
\end{eqnarray} \end{eqnarray}
\parinterval 其中,$\seq{y}_{<j}=\{y_1,y_2,\dots,y_{j-1}\}$$\seq{y}_{>j}=\{y_{j+1},y_{j+2},\dots,y_n\}$ \parinterval 其中,$\seq{y}_{<j}=\{y_1,y_2,\dots,y_{j-1}\}$$\seq{y}_{>j}=\{y_{j+1},y_{j+2},\dots,y_n\}$
\parinterval 可以看到,自左向右推断和自右向左推断本质上是一样的。第十章$\sim$第十二章均使用了自左向右的推断方法。自右向左推断比较简单的实现方式是:直接将训练用双语数据中的目标语句子进行反向,之后仍然使用原始的模型进行训练即可。在推断的时候,生成的目标语词串也需要进行反向得到最终的译文。有时候,使用自右向左的翻译方式会取得更好的效果\upcite{DBLP:conf/wmt/SennrichHB16}。不过更多情况下需要同时使用词串左端(历史)和右端(未来)的信息。有多种思路 \parinterval 可以看到,自左向右推断和自右向左推断本质上是一样的。\chapterten$\sim$\chaptertwelve均使用了自左向右的推断方法。自右向左推断比较简单的实现方式是:在训练过程中直接将双语数据中的目标语句子进行反向,之后仍然使用原始的模型进行训练即可。在推断的时候,生成的目标语词串也需要进行反向得到最终的译文。有时候,使用自右向左的推断方式会取得更好的效果\upcite{DBLP:conf/wmt/SennrichHB16}。不过更多情况下需要同时使用词串左端(历史)和右端(未来)的信息。有多种思路可以融合左右两端信息
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
...@@ -127,13 +127,13 @@ ...@@ -127,13 +127,13 @@
\vspace{0.5em} \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} \vspace{0.5em}
\item {\small\sffamily\bfseries{多阶段推断}}\index{多阶段推断}(Multi-stage Inference)\index{Multi-stage Inference}。在第一阶段,通过一个基础模型生成一个初步的翻译结果。在第二阶段,同时使用第一阶段生成的翻译结果和源语言句子,进一步生成更好的译文\upcite{Li2017EnhancedNM,ElMaghraby2018EnhancingTF,Geng2018AdaptiveMD}。由于第一阶段的结果已经包含了完整的译文,因此在第二阶段中,系统实际上已经同时使用了整个译文串的两端信息。上述过程可以扩展为迭代式的译文生成方法,配合掩码等技术,可以在生成每个译文单词时,同时考虑左右两端的上下文信息\upcite{Lee2018DeterministicNN,Gu2019LevenshteinT,Guo2020JointlyMS} \item {\small\sffamily\bfseries{多阶段推断}}\index{多阶段推断}(Multi-stage Inference)\index{Multi-stage Inference}。在第一阶段,通过一个基础模型生成一个初步的翻译结果。在第二阶段,同时使用第一阶段生成的翻译结果和源语言句子,进一步生成更好的译文\upcite{Li2017EnhancedNM,ElMaghraby2018EnhancingTF,Geng2018AdaptiveMD}。由于第一阶段的结果已经包含了完整的译文信息,因此在第二阶段中,系统实际上已经同时使用了整个译文串的两端信息。上述过程可以扩展为迭代式的译文生成方法,配合掩码等技术,可以在生成每个译文单词时,同时考虑左右两端的上下文信息\upcite{Lee2018DeterministicNN,Gu2019LevenshteinT,Guo2020JointlyMS}
\vspace{0.5em} \vspace{0.5em}
\end{itemize} \end{itemize}
\parinterval 不论是自左向右还是自右向左翻译,本质上都是在对上下文信息进行建模。除了自左向右和自右向左的翻译策略,研究者们也提出了许多新的译文生成策略,比如,{\small\sffamily\bfseries{从中部向外生成}}\index{从中部向外生成}(Middle-Out Decoding)\index{Middle-Out Decoding}、按源语言顺序生成\upcite{Stahlberg2018AnOS}、基于插入的方式生成\upcite{Stern2019InsertionTF,stling2017NeuralMT}等。或者将翻译问题松弛化为一个连续空间模型的优化问题,进而在推断的过程中同时使用译文串左右两端的信息\upcite{Geng2018AdaptiveMD} \parinterval 不论是自左向右还是自右向左推断,本质上都是在对上下文信息进行建模。除了自左向右和自右向左的推断策略,研究者们也提出了许多新的译文生成策略,比如,{\small\sffamily\bfseries{从中部向外生成}}\index{从中部向外生成}(Middle-Out Decoding)\index{Middle-Out Decoding}、按源语言顺序生成\upcite{Stahlberg2018AnOS}、基于插入的方式生成\upcite{Stern2019InsertionTF,stling2017NeuralMT}等。或者将翻译问题松弛化为一个连续空间模型的优化问题,进而在推断的过程中同时使用译文串左右两端的信息\upcite{Geng2018AdaptiveMD}
\parinterval 最近,以BERT 为代表的预训练语言模型已经证明,一个单词的“历史” 和“未来” 信息对于生成当前单词都是有帮助的\upcite{devlin2019bert}。类似的观点也在神经机器翻译编码器设计中得到验证。比如,在基于循环神经网络的模型中,经常同时使用自左向右和自右向左的方式对源语言句子进行编码。还有,Transformer 编码会使用整个句子的信息对每一个源语言位置进行表示。因此,在神经机器翻译的解码端采用类似的策略是有其合理性的。 \parinterval 最近,以BERT 为代表的预训练语言模型已经证明,一个单词的“历史” 和“未来” 信息对于生成当前单词都是有帮助的\upcite{devlin2019bert}。类似的观点也在神经机器翻译编码器设计中得到验证。比如,在基于循环神经网络的模型中,经常同时使用自左向右和自右向左的方式对源语言句子进行编码。还有,Transformer 编码会使用整个句子的信息对每一个源语言位置进行表示。因此,在神经机器翻译的解码端采用类似的策略是有其合理性的。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION % NEW SUBSUB-SECTION
...@@ -521,7 +521,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4} ...@@ -521,7 +521,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\item 基于层级知识蒸馏的方法\upcite{Li2019HintBasedTF}。由于自回归模型和非自回归模型的结构相差不大,因此可以将翻译质量更高的自回归模型作为“教师”,通过给非自回归模型提供监督信号,使其逐块的学习前者的分布。研究者发现了两点非常有意思的现象:1)非自回归模型输出的重复单词的位置的隐藏状态非常相似。2)非自回归模型的注意力分布比自回归模型的分布更加分散。这两点发现启发了研究者使用自回归模型中的隐层状态来指导非自回归模型学习。通过计算两个模型隐层状态的距离以及注意力矩阵的{\red{KL散度}}作为额外的损失来帮助非自回归模型的训练过程。 \item 基于层级知识蒸馏的方法\upcite{Li2019HintBasedTF}。由于自回归模型和非自回归模型的结构相差不大,因此可以将翻译质量更高的自回归模型作为“教师”,通过给非自回归模型提供监督信号,使其逐块的学习前者的分布。研究者发现了两点非常有意思的现象:1)非自回归模型输出的重复单词的位置的隐藏状态非常相似。2)非自回归模型的注意力分布比自回归模型的分布更加分散。这两点发现启发了研究者使用自回归模型中的隐层状态来指导非自回归模型学习。通过计算两个模型隐层状态的距离以及注意力矩阵的KL散度\footnote{KL散度即相对熵}作为额外的损失来帮助非自回归模型的训练过程。
\vspace{0.5em} \vspace{0.5em}
\item 基于模仿学习的方法\upcite{Wei2019ImitationLF}。这种观点认为非自回归模型可以从性能优越的自回归模型中学得知识。模仿学习是强化学习中的一个概念,即从专家那里学习正确的行为,与监督学习很相似\upcite{Ho2016ModelFreeIL,Ho2016GenerativeAI,Duan2017OneShotIL}。与其不同的是,模仿学习不是照搬专家的行为,而是学习专家为什么要那样做。换句话说,学习的不是专家的镜像,而是一个专家的行为分布。这里,可以将自回归模型作为专家,非自回归模型学习不同时间步和不同层的中的解码状态,最后将模仿学习的损失与交叉熵损失加权求和后作为最终的优化目标。 \item 基于模仿学习的方法\upcite{Wei2019ImitationLF}。这种观点认为非自回归模型可以从性能优越的自回归模型中学得知识。模仿学习是强化学习中的一个概念,即从专家那里学习正确的行为,与监督学习很相似\upcite{Ho2016ModelFreeIL,Ho2016GenerativeAI,Duan2017OneShotIL}。与其不同的是,模仿学习不是照搬专家的行为,而是学习专家为什么要那样做。换句话说,学习的不是专家的镜像,而是一个专家的行为分布。这里,可以将自回归模型作为专家,非自回归模型学习不同时间步和不同层的中的解码状态,最后将模仿学习的损失与交叉熵损失加权求和后作为最终的优化目标。
\vspace{0.5em} \vspace{0.5em}
...@@ -564,7 +564,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4} ...@@ -564,7 +564,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
%---------------------------------------------------------------------- %----------------------------------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
% \input{} \input{./Chapter14/Figures/figure-reranking}
\caption{引入重排序模块的非自回归模型} \caption{引入重排序模块的非自回归模型}
\label{fig:14-22} \label{fig:14-22}
\end{figure} \end{figure}
...@@ -578,7 +578,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4} ...@@ -578,7 +578,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\parinterval 如果一次并行生成整个序列,往往会导致单词之间的关系很难捕捉,因此也限制了这类方法的能力。即使生成了错误的译文单词,这类方法也无法修改。针对这些问题,也可以使用迭代式的生成方式\upcite{Lee2018DeterministicNN,Ghazvininejad2019MaskPredictPD,Kasai2020NonAutoregressiveMT}。这种方法放弃了一次生成最终的目标句子,而是将解码出的文本再重新送给解码器,在每次迭代中来改进之前生成的单词,可以理解为句子级上的自回归模型。这样做的好处在于,每次迭代的过程中可以利用已经生成的部分翻译结果,来指导其它部分的生成。 \parinterval 如果一次并行生成整个序列,往往会导致单词之间的关系很难捕捉,因此也限制了这类方法的能力。即使生成了错误的译文单词,这类方法也无法修改。针对这些问题,也可以使用迭代式的生成方式\upcite{Lee2018DeterministicNN,Ghazvininejad2019MaskPredictPD,Kasai2020NonAutoregressiveMT}。这种方法放弃了一次生成最终的目标句子,而是将解码出的文本再重新送给解码器,在每次迭代中来改进之前生成的单词,可以理解为句子级上的自回归模型。这样做的好处在于,每次迭代的过程中可以利用已经生成的部分翻译结果,来指导其它部分的生成。
\parinterval\ref{fig:14-18}展示了这种方法的简单示例。它拥有一个解码器和$N$个编码器。解码器首先预测出目标句子的长度,然后将输入$\seq{x}$按照长度复制出$\seq{x'}$作为第一个解码器的输入,之后生成$\seq{y'}$出作为第一轮迭代的输出。接下来再把$\seq{y'}$输入给解码器2输出$\seq{y''}$,以此类推。那么迭代到什么时候结束呢?一种简单的做法是提前制定好迭代次数,这种方法能够自主地对生成句子的质量和效率进行平衡。另一种称之为“自适应”的方法,具体是通过计算当前生成的句子上一次生成的变化量来自动停止,例如,使用{\red 杰卡德相似系数}作为变化量函数。 \parinterval\ref{fig:14-18}展示了这种方法的简单示例。它拥有一个解码器和$N$个编码器。解码器首先预测出目标句子的长度,然后将输入$\seq{x}$按照长度复制出$\seq{x'}$作为第一个解码器的输入,之后生成$\seq{y'}$出作为第一轮迭代的输出。接下来再把$\seq{y'}$输入给解码器2输出$\seq{y''}$,以此类推。那么迭代到什么时候结束呢?一种简单的做法是提前制定好迭代次数,这种方法能够自主地对生成句子的质量和效率进行平衡。另一种称之为“自适应”的方法,具体是通过计算当前生成的句子上一次生成的变化量来自动停止,例如,使用杰卡德相似系数\footnote{杰卡德相似系数是衡量有限样本集之间的相似性与差异性的一种指标,杰卡德相似系数值越大,样本相似度越高。}作为变化量函数。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -593,7 +593,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4} ...@@ -593,7 +593,7 @@ b &=& \omega_{\textrm{high}}\cdot |\seq{x}| \label{eq:14-4}
\parinterval 另一种方法借鉴了BERT的思想\upcite{devlin2019bert},提出了一种新的解码方法:Mask-Predict\upcite{Ghazvininejad2019MaskPredictPD} \parinterval 另一种方法借鉴了BERT的思想\upcite{devlin2019bert},提出了一种新的解码方法:Mask-Predict\upcite{Ghazvininejad2019MaskPredictPD}
\parinterval 类似于BERT的[CLS],该方法在源语句子的最前面加上了一个特殊符号[LENGTH]作为输入,用来预测目标句的长度$n$。之后,将特殊符[MASK](与BERT中的[MASK]有相似的含义)复制$n$次作为解码器的输入,然后用非自回归的方式生成目标端所有的词。这样生成的翻译可能是比较差的,因此可以将第一次生成出的这些词中不确定(即生成概率比较低)的一些词再“擦”掉,依据目标端剩余的单词以及源语言句子重新进行预测,不断迭代,直到满足停止条件为止。图\ref{fig:14-19}给出了一个示例。 \parinterval 类似于BERT的[CLS],该方法在源语句子的最前面加上了一个特殊符号[LEN]作为输入,用来预测目标句的长度$n$。之后,将特殊符[Mask](与BERT中的[Mask]有相似的含义)复制$n$次作为解码器的输入,然后用非自回归的方式生成目标端所有的词。这样生成的翻译可能是比较差的,因此可以将第一次生成出的这些词中不确定(即生成概率比较低)的一些词再“擦”掉,依据目标端剩余的单词以及源语言句子重新进行预测,不断迭代,直到满足停止条件为止。图\ref{fig:14-19}给出了一个示例。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
......
...@@ -4,21 +4,21 @@ ...@@ -4,21 +4,21 @@
\node [anchor=north,rectangle, inner sep=0mm,minimum height=1.2em,minimum width=2em,rounded corners=5pt,thick] (n1) at (0, 0) {编码端}; \node [anchor=north,rectangle, inner sep=0mm,minimum height=1.2em,minimum width=2em,rounded corners=5pt,thick] (n1) at (0, 0) {编码端};
\node [anchor=west,rectangle, inner sep=0mm,minimum height=1.2em,minimum width=0em,rounded corners=5pt,thick] (n2) at ([xshift=3.5em,yshift=-0.5em]n1.east) {$z_0$}; \node [anchor=west,rectangle, inner sep=0mm,minimum height=1.2em,minimum width=0em,rounded corners=5pt,thick] (n2) at ([xshift=3.5em,yshift=-0.5em]n1.east) {$\mathbi{X}$};
\node [anchor=west,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=3em,fill=orange!20,rounded corners=5pt,thick] (n3) at ([xshift=3.5em,yshift=0em]n2.east) {$z_1$}; \node [anchor=west,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=3em,fill=orange!20,rounded corners=5pt,thick] (n3) at ([xshift=3.5em,yshift=0em]n2.east) {$\mathbi{x}_1$};
\node [anchor=west,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=3em,fill=orange!20,rounded corners=5pt,thick] (n4) at ([xshift=3.5em,yshift=0em]n3.east) {$z_2$}; \node [anchor=west,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=3em,fill=orange!20,rounded corners=5pt,thick] (n4) at ([xshift=3.5em,yshift=0em]n3.east) {$\mathbi{x}_2$};
\node [anchor=west,rectangle, inner sep=0mm,minimum height=1.2em,minimum width=1em,rounded corners=5pt,thick] (n6) at ([xshift=1.5em,yshift=0em]n4.east) {$\ldots$}; \node [anchor=west,rectangle, inner sep=0mm,minimum height=1.2em,minimum width=1em,rounded corners=5pt,thick] (n6) at ([xshift=1.5em,yshift=0em]n4.east) {$\ldots$};
\node [anchor=west,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=3em,fill=orange!20,rounded corners=5pt,thick] (n5) at ([xshift=3.5em,yshift=0em]n6.east) {$z_{l}$}; \node [anchor=west,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=3em,fill=orange!20,rounded corners=5pt,thick] (n5) at ([xshift=3.5em,yshift=0em]n6.east) {$\mathbi{x}_l$};
\node [anchor=west,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=3em,fill=orange!20,rounded corners=5pt,thick] (n7) at ([xshift=1.5em,yshift=0em]n5.east) {$z_{l+1}$}; \node [anchor=west,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=3em,fill=orange!20,rounded corners=5pt,thick] (n7) at ([xshift=1.5em,yshift=0em]n5.east) {$\mathbi{x}_{l+1}$};
\node [anchor=north,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=15em,fill=teal!17,rounded corners=5pt,thick] (n8) at ([xshift=0em,yshift=-3em]n4.south) {层正则化}; \node [anchor=north,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=15em,fill=teal!17,rounded corners=5pt,thick] (n8) at ([xshift=0em,yshift=-3em]n4.south) {层正则化};
\node [anchor=north,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=15em,fill=purple!17,rounded corners=5pt,thick] (n9) at ([xshift=0em,yshift=-1em]n8.south) {$L_0\ \quad L_1\ \quad L_2\quad \ldots \quad\ L_l$}; \node [anchor=north,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=15em,fill=purple!17,rounded corners=5pt,thick] (n9) at ([xshift=0em,yshift=-1em]n8.south) {$\mathbi{X}\ \quad \mathbi{h}_1\ \quad \mathbi{h}_2\quad \ldots \quad\ \mathbi{h}_l$};
\node [anchor=north,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=15em,fill=teal!17,rounded corners=5pt,thick] (n10) at ([xshift=0em,yshift=-2em]n9.south) {权重累加}; \node [anchor=north,rectangle,draw, inner sep=0mm,minimum height=1.2em,minimum width=15em,fill=teal!17,rounded corners=5pt,thick] (n10) at ([xshift=0em,yshift=-2em]n9.south) {权重累加};
......
%%% outline
%-------------------------------------------------------------------------
\begin{tikzpicture}[scale=0.6]
\tikzstyle{every node}=[scale=0.6]
\tikzstyle{cell} = [draw,circle,inner sep=0pt,minimum size=1.4em]
\tikzstyle{point} = [circle,fill=white,minimum size=0.46em,inner sep=0pt]
\tikzstyle{point_line} = [-,white,line width=1.4pt]
\tikzstyle{cell_line} = [-,thick]
\tikzstyle{background} = [rounded corners=4pt,minimum width=44em,fill=gray!20]
%figure 1
\node[inner sep=0pt,minimum size=4em,fill=black,rounded corners=6pt] (n1) at (-1.6em,0) {};
\node[circle,fill=white,minimum size=2em] at (-1.6em,0){};
\node[circle,fill=black,minimum size=1.4em] (n2) at (1.8em,0){};
\draw[line width=4pt,-] ([xshift=-0.1em]n1.east) -- ([xshift=0.1em]n2.west);
\draw[line width=4pt,-, out=-45,in=45] ([xshift=0.2em,yshift=1em]n2.east) to ([xshift=0.2em,yshift=-1em]n2.east);
\draw[line width=4pt,-, out=-45,in=45] ([xshift=0.8em,yshift=1.4em]n2.east) to ([xshift=0.8em,yshift=-1.4em]n2.east);
\draw[line width=4pt,-, out=-45,in=45] ([xshift=1.4em,yshift=1.8em]n2.east) to ([xshift=1.4em,yshift=-1.8em]n2.east);
%figure 2
\node[inner sep=0pt,minimum size=6em,fill=black,rounded corners=6pt] (n3) at (14em,0) {};
\node[inner sep=0pt,minimum size=5em,fill=white,rounded corners=8pt] (n4) at (14em,0) {};
\node[inner sep=0pt,minimum size=4.4em,fill=black,rounded corners=6pt] (n5) at (14em,0) {};
\node[point] (dot1) at (12.7em,-1em){};
\node[point] (dot2) at (12.8em,1.2em){};
\node[point] (dot3) at (14.8em,-0.9em){};
\node[point] (dot4) at (15.2em,-0.2em){};
\node[point] (dot5) at (13.5em,0.3em){};
\node[point] (dot6) at (14em,0.8em){};
\draw[point_line] ([yshift=-1em]dot1.south) -- ([yshift=0.1em]dot1.south);
\draw[point_line] ([yshift=-1.1em,xshift=-1.6em]dot3.south) -- ([yshift=-0.5em,xshift=-1.6em]dot3.south)-- ([yshift=-0.5em]dot3.south) -- ([yshift=0.1em]dot3.south);
\draw[point_line] ([xshift=-0.1em]dot4.east) -- ([xshift=1em]dot4.east);
\draw[point_line] ([xshift=-1em,yshift=-1.3em]dot2.south) -- ([yshift=-1.3em]dot2.south) -- ([yshift=0.1em]dot2.south);
\draw[point_line] ([xshift=-0.1em]dot5.east) -- ([xshift=0.9em]dot5.east) --([xshift=0.9em,yshift=0.8em]dot5.east) -- ([xshift=2.6em,yshift=0.8em]dot5.east);
\draw[point_line] ([yshift=-0.1em]dot6.north) -- ([yshift=0.6em]dot6.north) -- ([yshift=0.6em,xshift=1em]dot6.north) -- ([yshift=1.2em,xshift=1em]dot6.north);
\foreach \x in {1,2,3,4}{
\node[fill=black,inner sep=0pt,minimum width=1.2em,minimum height=0.6em] at (17.8em,-3em+1.2em*\x){};
\node[inner sep=0pt,circle,minimum size=0.6em,fill=black] at (18.4em,-3em+1.2em*\x){};}
\foreach \x in {1,2,3,4}{
\node[fill=black,inner sep=0pt,minimum width=1.2em,minimum height=0.6em] at (10.2em,-3em+1.2em*\x){};
\node[inner sep=0pt,circle,minimum size=0.6em,fill=black] at (9.6em,-3em+1.2em*\x){};}
\foreach \x in {1,2,3,4}{
\node[fill=black,inner sep=0pt,minimum width=0.6em,minimum height=1.2em] at (10.9em+1.2em*\x,3.8em){};
\node[inner sep=0pt,circle,minimum size=0.6em,fill=black] at (10.9em+1.2em*\x,4.2em){};}
\foreach \x in {1,2,3,4}{
\node[fill=black,inner sep=0pt,minimum width=0.6em,minimum height=1.2em] at (10.9em+1.2em*\x,-3.8em){};
\node[inner sep=0pt,circle,minimum size=0.6em,fill=black] at (10.9em+1.2em*\x,-4.2em){};}
%figure 3
\node[circle,line width=2pt,minimum size=3.8em,draw,fill=white] (f1) at (26em,0){};
\node[circle,line width=2pt,minimum size=1em,draw,fill=white] (c1) at (26em,0){};
\node[circle,line width=2pt,minimum size=3.8em,draw,fill=white] (f2)at (30.4em,0){};
\node[circle,line width=2pt,minimum size=1em,draw,fill=white] (c2) at (30.4em,0){};
\draw[line width=2pt,out=90,in=90] ([xshift=0.1em]c1.180) to ([xshift=0.1em]f1.180);
\draw[line width=2pt,out=45,in=45] ([xshift=0.1em,yshift=-0.1em]c1.135) to ([xshift=0.1em,yshift=-0.1em]f1.135);
\draw[line width=2pt,out=0,in=0] ([yshift=-0.1em]c1.90) to ([yshift=-0.1em]f1.90);
\draw[line width=2pt,out=-45,in=-45] ([xshift=-0.1em,yshift=-0.1em]c1.45) to ([xshift=-0.1em,yshift=-0.1em]f1.45);
\draw[line width=2pt,out=-90,in=-90] ([xshift=-0.1em]c1.0) to ([xshift=-0.1em]f1.0);
\draw[line width=2pt,out=-135,in=-135] ([xshift=-0.1em,yshift=0.1em]c1.-45) to ([xshift=-0.1em,yshift=0.1em]f1.-45);
\draw[line width=2pt,out=-180,in=-180] ([yshift=0.1em]c1.-90) to ([yshift=0.1em]f1.-90);
\draw[line width=2pt,out=-225,in=-225] ([xshift=0.1em,yshift=0.1em]c1.-135) to ([xshift=0.1em,yshift=0.1em]f1.-135);
\draw[line width=2pt,out=90,in=90] ([xshift=0.1em]c2.180) to ([xshift=0.1em]f2.180);
\draw[line width=2pt,out=45,in=45] ([xshift=0.1em,yshift=-0.1em]c2.135) to ([xshift=0.1em,yshift=-0.1em]f2.135);
\draw[line width=2pt,out=0,in=0] ([yshift=-0.1em]c2.90) to ([yshift=-0.1em]f2.90);
\draw[line width=2pt,out=-45,in=-45] ([xshift=-0.1em,yshift=-0.1em]c2.45) to ([xshift=-0.1em,yshift=-0.1em]f2.45);
\draw[line width=2pt,out=-90,in=-90] ([xshift=-0.1em]c2.0) to ([xshift=-0.1em]f2.0);
\draw[line width=2pt,out=-135,in=-135] ([xshift=-0.1em,yshift=0.1em]c2.-45) to ([xshift=-0.1em,yshift=0.1em]f2.-45);
\draw[line width=2pt,out=-180,in=-180] ([yshift=0.1em]c2.-90) to ([yshift=0.1em]f2.-90);
\draw[line width=2pt,out=-225,in=-225] ([xshift=0.1em,yshift=0.1em]c2.-135) to ([xshift=0.1em,yshift=0.1em]f2.-135);
\draw[line width=2pt,-] (22.8em,2.6em) -- (23.4em,2.6em) -- (23.4em,-3em);
\draw[line width=2pt,-] (23.4em,1.6em) -- (23em,1.6em) -- (23em,0.8em) -- (23.4em,0.8em);
\draw[line width=2pt,-] (23.4em,0.4em) -- (23em,0.4em) -- (23em,-2em) -- (23.4em,-2em);
\draw[line width=2pt,-] (23.4em,2em) -- (24.4em,2em) -- (25em,2.6em) -- (30.4em,2.6em);
\draw[line width=2pt,-] (23.4em,-2.5em) -- (30.8em,-2.5em);
\draw[line width=2pt,-] (25em,-2.5em) -- (25em,-3em) -- (26em,-3em) -- (26em,-2.5em);
\draw[line width=2pt,-] (26.5em,-2.5em) -- (26.5em,-3em) -- (29.4em, -3em) -- (29.4em,-2.5em) ;
\draw[line width=2pt,-,out=0,in=120] (30.4em,2.6em) to (32.8em,1em);
\draw[line width=2pt,-,out=0,in=-70] (30.8em,-2.5em) to (33.2em,1em);
\draw[line width=2pt,-] (32.8em,1em) to (33.2em,1em);
\draw[line width=2pt,-] (27.4em,2.6em) -- (28.4em,1.6em) -- (29.6em,1.6em);
\node[] at (0em,4.6em) {\huge\bfnew{Different Hardware}};
\node[] at (6.4em,22em) {\huge\bfnew{SubTransformers(Weight-Sharing)}};
\node[] at (-0.4em,37.6em) {\huge\bfnew{SuperTransformer}};
\node[] at (0.4em,-6.2em) {\huge\bfnew{IOT}};
\node[] at (14em,-6.2em) {\huge\bfnew{CPU}};
\node[] at (28em,-6.2em) {\huge\bfnew{GPU}};
\begin{pgfonlayer}{background}
{
\draw[line width=3pt,-] (23.4em,-1.6em) -- (28.2em,-1.6em) -- (28.6em,-2.5em);
\node[background,minimum height=14em] (bg1) at (13.4em,-0.8em){};
\node[background,minimum height=11.4em] (bg2) at (13.4em,17.8em){};
\node[background,minimum height=10em] (bg3) at (13.4em,34em){};
\draw[thick,out=45,in=-45,-latex] (bg1.north east) to (bg2.north east);
}
\end{pgfonlayer}
\node[cell,fill=red!60] (c1_1) at (-1.5em,18.5em){};
\node[cell,fill=red!60] (c1_2) at (1.5em,18.5em){};
\node[cell,fill=ublue!60] (c1_3) at (-1.5em,15.5em){};
\node[cell,fill=ublue!60] (c1_4) at (1.5em,15.5em){};
\node[cell,fill=red!60] (c2_1) at (12.5em,20em){};
\node[cell,fill=red!60] (c2_2) at (15.5em,20em){};
\node[cell,fill=ublue!60] (c2_3) at (12.5em,17em){};
\node[cell,fill=ublue!60] (c2_4) at (15.5em,17em){};
\node[cell,fill=orange!60] (c2_5) at (9.5em,14em){};
\node[cell,fill=orange!60] (c2_6) at (12.5em,14em){};
\node[cell,fill=orange!60] (c2_7) at (15.5em,14em){};
\node[cell,fill=orange!60] (c2_8) at (18.5em,14em){};
\node[cell,fill=red!60] (c3_1) at (23.5em,19em){};
\node[cell,fill=red!60] (c3_2) at (26.5em,19em){};
\node[cell,fill=red!60] (c3_3) at (29.5em,19em){};
\node[cell,fill=red!60] (c3_4) at (32.5em,19em){};
\node[cell,fill=ublue!60] (c3_5) at (23.5em,15em){};
\node[cell,fill=ublue!60] (c3_6) at (26.5em,15em){};
\node[cell,fill=ublue!60] (c3_7) at (29.5em,15em){};
\node[cell,fill=ublue!60] (c3_8) at (32.5em,15em){};
\draw[-,thick] (c1_1.-90) -- (c1_3.90);
\draw[-,thick] (c1_1.-45) -- (c1_4.135);
\draw[-,thick] (c1_2.-90) -- (c1_4.90);
\draw[-,thick] (c1_2.-135) -- (c1_3.45);
\draw[-,thick] (c2_1.-90) -- (c2_3.90);
\draw[-,thick] (c2_1.-45) -- (c2_4.135);
\draw[-,thick] (c2_2.-90) -- (c2_4.90);
\draw[-,thick] (c2_2.-135) -- (c2_3.45);
\draw[-,thick] (c2_3.-90) -- (c2_6.90);
\draw[-,thick] (c2_3.-135) -- (c2_5.45);
\draw[-,thick] (c2_3.-45) -- (c2_7.135);
\draw[-,thick] (c2_3.-30) -- (c2_8.150);
\draw[-,thick] (c2_4.-150) -- (c2_5.30);
\draw[-,thick] (c2_4.-135) -- (c2_6.45);
\draw[-,thick] (c2_4.-90) -- (c2_7.90);
\draw[-,thick] (c2_4.-45) -- (c2_8.135);
\draw[-,thick] (c3_1.-90) -- (c3_5.90);
\draw[-,thick] (c3_1.-45) -- (c3_6.135);
\draw[-,thick] (c3_1.-30) -- (c3_7.150);
\draw[-,thick] (c3_1.-15) -- (c3_8.165);
\draw[-,thick] (c3_2.-90) -- (c3_6.90);
\draw[-,thick] (c3_2.-135) -- (c3_5.45);
\draw[-,thick] (c3_2.-45) -- (c3_7.135);
\draw[-,thick] (c3_2.-30) -- (c3_8.150);
\draw[-,thick] (c3_3.-150) -- (c3_5.30);
\draw[-,thick] (c3_3.-135) -- (c3_6.45);
\draw[-,thick] (c3_3.-90) -- (c3_7.90);
\draw[-,thick] (c3_3.-45) -- (c3_8.135);
\draw[-,thick] (c3_4.-165) -- (c3_5.15);
\draw[-,thick] (c3_4.-150) -- (c3_6.30);
\draw[-,thick] (c3_4.-135) -- (c3_7.45);
\draw[-,thick] (c3_4.-90) -- (c3_8.90);
\node[cell,fill=red!60] (c4_1) at (9.5em,37em){};
\node[cell,fill=red!60] (c4_2) at (12.5em,37em){};
\node[cell,fill=red!60] (c4_3) at (15.5em,37em){};
\node[cell,fill=red!60] (c4_4) at (18.5em,37em){};
\node[cell,fill=ublue!60] (c4_5) at (9.5em,34em){};
\node[cell,fill=ublue!60] (c4_6) at (12.5em,34em){};
\node[cell,fill=ublue!60] (c4_7) at (15.5em,34em){};
\node[cell,fill=ublue!60] (c4_8) at (18.5em,34em){};
\node[cell,fill=orange!60] (c4_9) at (9.5em,31em){};
\node[cell,fill=orange!60] (c4_10) at (12.5em,31em){};
\node[cell,fill=orange!60] (c4_11) at (15.5em,31em){};
\node[cell,fill=orange!60] (c4_12) at (18.5em,31em){};
\draw[-,thick] (c4_1.-90) -- (c4_5.90);
\draw[-,thick] (c4_1.-45) -- (c4_6.135);
\draw[-,thick] (c4_1.-30) -- (c4_7.150);
\draw[-,thick] (c4_1.-15) -- (c4_8.165);
\draw[-,thick] (c4_2.-90) -- (c4_6.90);
\draw[-,thick] (c4_2.-135) -- (c4_5.45);
\draw[-,thick] (c4_2.-45) -- (c4_7.135);
\draw[-,thick] (c4_2.-30) -- (c4_8.150);
\draw[-,thick] (c4_3.-150) -- (c4_5.30);
\draw[-,thick] (c4_3.-135) -- (c4_6.45);
\draw[-,thick] (c4_3.-90) -- (c4_7.90);
\draw[-,thick] (c4_3.-45) -- (c4_8.135);
\draw[-,thick] (c4_4.-165) -- (c4_5.15);
\draw[-,thick] (c4_4.-150) -- (c4_6.30);
\draw[-,thick] (c4_4.-135) -- (c4_7.45);
\draw[-,thick] (c4_4.-90) -- (c4_8.90);
\draw[-,thick] (c4_5.-90) -- (c4_9.90);
\draw[-,thick] (c4_5.-45) -- (c4_10.135);
\draw[-,thick] (c4_5.-30) -- (c4_11.150);
\draw[-,thick] (c4_5.-15) -- (c4_12.165);
\draw[-,thick] (c4_6.-90) -- (c4_10.90);
\draw[-,thick] (c4_6.-135) -- (c4_9.45);
\draw[-,thick] (c4_6.-45) -- (c4_11.135);
\draw[-,thick] (c4_6.-30) -- (c4_12.150);
\draw[-,thick] (c4_7.-150) -- (c4_9.30);
\draw[-,thick] (c4_7.-135) -- (c4_10.45);
\draw[-,thick] (c4_7.-90) -- (c4_11.90);
\draw[-,thick] (c4_7.-45) -- (c4_12.135);
\draw[-,thick] (c4_8.-165) -- (c4_9.15);
\draw[-,thick] (c4_8.-150) -- (c4_10.30);
\draw[-,thick] (c4_8.-135) -- (c4_11.45);
\draw[-,thick] (c4_8.-90) -- (c4_12.90);
\draw[line width=2pt,-latex] ([xshift=0.5em,yshift=-0.6em]bg3.south) -- ([xshift=0.5em,yshift=0.6em]bg2.north);
\draw[line width=2pt,-latex] ([xshift=-2.5em,yshift=-0.6em]bg3.south) -- ([xshift=-9.5em,yshift=0.6em]bg2.north);
\draw[line width=2pt,-latex] ([xshift=3.5em,yshift=-0.6em]bg3.south) -- ([xshift=9.5em,yshift=0.6em]bg2.north);
\draw[line width=2pt,-latex] (0em, 10.4em) -- (0em, 7em);
\draw[line width=2pt,-latex] (14em, 10.4em) -- (14em, 7em);
\draw[line width=2pt,-latex] (28em, 10.4em) -- (28em, 7em);
\node[align=center] at (0.5em,-9em){\Large\bfnew{TinyML}};
\node[align=center] at (14em,-9em){\Large\bfnew{Deeper}};
\node[align=center] at (28em,-9em){\Large\bfnew{Wider}};
\node[font=\footnotesize,align=center] at (30em,26em){\Large\bfnew{Evolutionary Search with} \\ \Large\bfnew{Hardware Constraints}};
\node[font=\footnotesize,align=center] at ([yshift=-1em]bg2.south){\Large\bfnew{Specialized Deployment is Efficient}};
\node[font=\footnotesize,align=center] at ([xshift=3em,yshift=5em]bg1.east){\Large\bfnew{Hardware}\\\Large\bfnew{Latency}\\\Large\bfnew{Feedback}};
\node[circle,inner sep=0pt,minimum size=3em,draw,fill=white] (clock) at ([xshift=3.4em,yshift=-2.4em]bg2.east){};
\node[circle,inner sep=0pt,minimum size=0.4em,draw,fill=black] (clock2)at ([xshift=3.4em,yshift=-2.4em]bg2.east){};
\draw[] ([xshift=-0.3em]clock.0) arc (1:180:1.2em);
\draw[fill=black] (clock2.90) -- ([xshift=0.6em,yshift=-0.6em]clock.135) -- (clock2.180) -- (clock2.90);
\end{tikzpicture}
...@@ -5,25 +5,25 @@ ...@@ -5,25 +5,25 @@
\begin{scope}[minimum height = 20pt] \begin{scope}[minimum height = 20pt]
\node [anchor=east] (x1) at (-0.5em, 0) {$x_l$}; \node [anchor=east] (x1) at (-0.5em, 0) {$\mathbi{x}_l$};
\node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (F1) at ([xshift=2em]x1.east){\small{$\mathcal{F}$}}; \node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (F1) at ([xshift=2em]x1.east){\small{$F$}};
\node [anchor=west,circle,draw,minimum size=1em] (n1) at ([xshift=2em]F1.east) {}; \node [anchor=west,circle,draw,minimum size=1em] (n1) at ([xshift=2em]F1.east) {};
\node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (ln1) at ([xshift=2em]n1.east){\small{\textrm{LN}}}; \node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (ln1) at ([xshift=2em]n1.east){\small{\textrm{LN}}};
\node [anchor=west] (x2) at ([xshift=2em]ln1.east) {$x_{l+1}$}; \node [anchor=west] (x2) at ([xshift=2em]ln1.east) {$\mathbi{x}_{l+1}$};
\node [anchor=north] (x3) at ([yshift=-5em]x1.south) {$x_l$}; \node [anchor=north] (x3) at ([yshift=-5em]x1.south) {$\mathbi{x}_l$};
\node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (F2) at ([xshift=2em]x3.east){\small{\textrm{LN}}}; \node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (F2) at ([xshift=2em]x3.east){\small{\textrm{LN}}};
\node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (ln2) at ([xshift=2em]F2.east){\small{$\mathcal{F}$}}; \node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (ln2) at ([xshift=2em]F2.east){\small{$F$}};
\node [anchor=west,circle,draw,,minimum size=1em] (n2) at ([xshift=2em]ln2.east){}; \node [anchor=west,circle,draw,,minimum size=1em] (n2) at ([xshift=2em]ln2.east){};
\node [anchor=west] (x4) at ([xshift=2em]n2.east) {$x_{l+1}$}; \node [anchor=west] (x4) at ([xshift=2em]n2.east) {$\mathbi{x}_{l+1}$};
\draw[->, line width=1pt] ([xshift=-0.1em]x1.east)--(F1.west); \draw[->, line width=1pt] ([xshift=-0.1em]x1.east)--(F1.west);
\draw[->, line width=1pt] ([xshift=-0.1em]F1.east)--(n1.west); \draw[->, line width=1pt] ([xshift=-0.1em]F1.east)--(n1.west);
\draw[->, line width=1pt] (n1.east)--node[above]{$y_l$}(ln1.west); \draw[->, line width=1pt] (n1.east)--node[above]{$\mathbi{y}_l$}(ln1.west);
\draw[->, line width=1pt] ([xshift=-0.1em]ln1.east)--(x2.west); \draw[->, line width=1pt] ([xshift=-0.1em]ln1.east)--(x2.west);
\draw[->, line width=1pt] ([xshift=-0.1em]x3.east)--(F2.west); \draw[->, line width=1pt] ([xshift=-0.1em]x3.east)--(F2.west);
\draw[->, line width=1pt] ([xshift=-0.1em]F2.east)--(ln2.west); \draw[->, line width=1pt] ([xshift=-0.1em]F2.east)--(ln2.west);
\draw[->, line width=1pt] ([xshift=0.1em]ln2.east)--node[above]{$y_l$}(n2.west); \draw[->, line width=1pt] ([xshift=0.1em]ln2.east)--node[above]{$\mathbi{y}_l$}(n2.west);
\draw[->, line width=1pt] (n2.east)--(x4.west); \draw[->, line width=1pt] (n2.east)--(x4.west);
\draw[->,rounded corners,line width=1pt] ([yshift=-0.2em]x1.north) -- ([yshift=1em]x1.north) -- ([yshift=1.4em]n1.north) -- (n1.north); \draw[->,rounded corners,line width=1pt] ([yshift=-0.2em]x1.north) -- ([yshift=1em]x1.north) -- ([yshift=1.4em]n1.north) -- (n1.north);
\draw[->,rounded corners,line width=1pt] ([yshift=-0.2em]x3.north) -- ([yshift=1em]x3.north) -- ([yshift=1.4em]n2.north) -- (n2.north); \draw[->,rounded corners,line width=1pt] ([yshift=-0.2em]x3.north) -- ([yshift=1em]x3.north) -- ([yshift=1.4em]n2.north) -- (n2.north);
......
...@@ -4,22 +4,22 @@ ...@@ -4,22 +4,22 @@
\begin{tikzpicture} \begin{tikzpicture}
\begin{scope} \begin{scope}
\node [anchor=east,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s11) at (-0.5em, 0) {\footnotesize{$\times h$}}; \node [anchor=east,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s11) at (-0.5em, 0) {\footnotesize{$\times l$}};
\node [rectangle,anchor=west,fill=blue!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s12) at ([xshift=1.2em]s11.east) {}; \node [rectangle,anchor=west,fill=blue!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s12) at ([xshift=1.2em]s11.east) {};
\node [anchor=north,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s21) at ([yshift=-1.2em]s11.south) {\footnotesize{$\times h$}}; \node [anchor=north,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s21) at ([yshift=-1.2em]s11.south) {\footnotesize{$\times l$}};
\node [anchor=west,fill=orange!20,draw=red,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em,dashed] (s22) at ([xshift=1.2em]s21.east) {\footnotesize{$\times h$}}; \node [anchor=west,fill=orange!20,draw=red,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em,dashed] (s22) at ([xshift=1.2em]s21.east) {\footnotesize{$\times l$}};
\node [anchor=west,fill=blue!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s23) at ([xshift=1.2em]s22.east) {}; \node [anchor=west,fill=blue!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s23) at ([xshift=1.2em]s22.east) {};
\node [anchor=north,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s31) at ([yshift=-1.2em]s21.south) {\footnotesize{$\times h$}}; \node [anchor=north,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s31) at ([yshift=-1.2em]s21.south) {\footnotesize{$\times l$}};
\node [anchor=west,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s32) at ([xshift=1.2em]s31.east) {\footnotesize{$\times h$}}; \node [anchor=west,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s32) at ([xshift=1.2em]s31.east) {\footnotesize{$\times l$}};
\node [anchor=west,fill=orange!20,draw=red,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em,dashed] (s33) at ([xshift=1.2em]s32.east) {\footnotesize{$\times h$}}; \node [anchor=west,fill=orange!20,draw=red,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em,dashed] (s33) at ([xshift=1.2em]s32.east) {\footnotesize{$\times l$}};
\node [anchor=west,fill=blue!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s34) at ([xshift=1.2em]s33.east) {}; \node [anchor=west,fill=blue!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s34) at ([xshift=1.2em]s33.east) {};
\node [anchor=north,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s41) at ([yshift=-1.2em]s31.south) {\footnotesize{$\times h$}}; \node [anchor=north,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s41) at ([yshift=-1.2em]s31.south) {\footnotesize{$\times l$}};
\node [anchor=west,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s42) at ([xshift=1.2em]s41.east) {\footnotesize{$\times h$}}; \node [anchor=west,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s42) at ([xshift=1.2em]s41.east) {\footnotesize{$\times l$}};
\node [anchor=west,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s43) at ([xshift=1.2em]s42.east) {\footnotesize{$\times h$}}; \node [anchor=west,fill=orange!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s43) at ([xshift=1.2em]s42.east) {\footnotesize{$\times l$}};
\node [anchor=west,fill=orange!20,draw=red,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em,dashed] (s44) at ([xshift=1.2em]s43.east) {\footnotesize{$\times h$}}; \node [anchor=west,fill=orange!20,draw=red,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em,dashed] (s44) at ([xshift=1.2em]s43.east) {\footnotesize{$\times l$}};
\node [anchor=west,fill=blue!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s45) at ([xshift=1.2em]s44.east) {}; \node [anchor=west,fill=blue!20,draw,rounded corners=3pt,minimum height=1.6em,minimum width=1.6em] (s45) at ([xshift=1.2em]s44.east) {};
\node [anchor=east] (p1) at ([xshift=-2em]s11.west) {\footnotesize{step 1}}; \node [anchor=east] (p1) at ([xshift=-2em]s11.west) {\footnotesize{step 1}};
......
...@@ -5,29 +5,29 @@ ...@@ -5,29 +5,29 @@
\begin{scope}[minimum height = 20pt] \begin{scope}[minimum height = 20pt]
\node [anchor=east] (x1) at (-0.5em, 0) {$x_l$}; \node [anchor=east] (x1) at (-0.5em, 0) {$\mathbi{x}_l$};
\node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (ln1) at ([xshift=1em]x1.east){\small{\textrm{LN}}}; \node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (ln1) at ([xshift=1em]x1.east){\small{\textrm{LN}}};
\node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (f1) at ([xshift=0.6em]ln1.east){\small{$\mathcal{F}$}}; \node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (f1) at ([xshift=0.6em]ln1.east){\small{$F$}};
\node [anchor=west,circle,draw,,minimum size=1em] (n1) at ([xshift=3em]f1.east){}; \node [anchor=west,circle,draw,,minimum size=1em] (n1) at ([xshift=3em]f1.east){};
\node [anchor=west] (x2) at ([xshift=1em]n1.east) {$x_{l+1}$}; \node [anchor=west] (x2) at ([xshift=1em]n1.east) {$\mathbi{x}_{l+1}$};
\node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (ln12) at ([xshift=1em]x2.east){\small{\textrm{LN}}}; \node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (ln12) at ([xshift=1em]x2.east){\small{\textrm{LN}}};
\node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (f12) at ([xshift=0.6em]ln12.east){\small{$\mathcal{F}$}}; \node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (f12) at ([xshift=0.6em]ln12.east){\small{$F$}};
\node [anchor=west,circle,draw,,minimum size=1em] (n12) at ([xshift=3em]f12.east){}; \node [anchor=west,circle,draw,,minimum size=1em] (n12) at ([xshift=3em]f12.east){};
\node [anchor=west] (x22) at ([xshift=1em]n12.east) {$x_{l+2}$}; \node [anchor=west] (x22) at ([xshift=1em]n12.east) {$\mathbi{x}_{l+2}$};
\node [anchor=north] (x3) at ([yshift=-5em]x1.south) {$x_l$}; \node [anchor=north] (x3) at ([yshift=-5em]x1.south) {$\mathbi{x}_l$};
\node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (ln2) at ([xshift=1em]x3.east){\small{\textrm{LN}}}; \node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (ln2) at ([xshift=1em]x3.east){\small{\textrm{LN}}};
\node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (f2) at ([xshift=0.6em]ln2.east){\small{$\mathcal{F}$}}; \node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (f2) at ([xshift=0.6em]ln2.east){\small{$F$}};
\node [anchor=west,minimum size=1em] (p1) at ([xshift=1em]f2.east){}; \node [anchor=west,minimum size=1em] (p1) at ([xshift=1em]f2.east){};
\node [anchor=north] (m1) at ([yshift=0.6em]p1.south){\tiny{\red{$M=1$}}}; \node [anchor=north] (m1) at ([yshift=0.6em]p1.south){\footnotesize{\red{Mask=1}}};
\node [anchor=west,circle,draw,,minimum size=1em] (n2) at ([xshift=3em]f2.east){}; \node [anchor=west,circle,draw,,minimum size=1em] (n2) at ([xshift=3em]f2.east){};
\node [anchor=west] (x4) at ([xshift=1em]n2.east) {$x_{l+1}$}; \node [anchor=west] (x4) at ([xshift=1em]n2.east) {$\mathbi{x}_{l+1}$};
\node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (ln22) at ([xshift=1em]x4.east){\small{\textrm{LN}}}; \node [anchor=west,draw,fill=red!20,inner xsep=5pt,rounded corners=2pt] (ln22) at ([xshift=1em]x4.east){\small{\textrm{LN}}};
\node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (f22) at ([xshift=0.6em]ln22.east){\small{$\mathcal{F}$}}; \node [anchor=west,draw,fill=green!20,inner xsep=5pt,rounded corners=2pt] (f22) at ([xshift=0.6em]ln22.east){\small{$F$}};
\node [anchor=west,minimum size=1em] (p2) at ([xshift=1em]f22.east){}; \node [anchor=west,minimum size=1em] (p2) at ([xshift=1em]f22.east){};
\node [anchor=north] (m2) at ([yshift=0.6em]p2.south){\tiny{\red{$M=0$}}}; \node [anchor=north] (m2) at ([yshift=0.6em]p2.south){\footnotesize{\red{Mask=0}}};
\node [anchor=west,circle,draw,,minimum size=1em] (n22) at ([xshift=3em]f22.east){}; \node [anchor=west,circle,draw,,minimum size=1em] (n22) at ([xshift=3em]f22.east){};
\node [anchor=west] (x42) at ([xshift=1em]n22.east) {$x_{l+2}$}; \node [anchor=west] (x42) at ([xshift=1em]n22.east) {$\mathbi{x}_{l+2}$};
\draw[->, line width=1pt] ([xshift=-0.1em]x1.east)--(ln1.west); \draw[->, line width=1pt] ([xshift=-0.1em]x1.east)--(ln1.west);
\draw[->, line width=1pt] ([xshift=-0.1em]ln1.east)--(f1.west); \draw[->, line width=1pt] ([xshift=-0.1em]ln1.east)--(f1.west);
......
...@@ -21,17 +21,26 @@ ...@@ -21,17 +21,26 @@
% CHAPTER 15 % CHAPTER 15
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\chapter{面向神经机器翻译的网络结构设计} \chapter{神经机器翻译结构优化}
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SECTION % NEW SECTION
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\section{深层网络} \section{基于自注意力机制的改进}
\parinterval {\chapterthirteen}已经指出:增加神经网络的深度有助于对句子进行更充分的表示、同时增加模型的容量。但是,简单地堆叠很多层Transformer网络并不能带来性能上的提升,反而会面临更加严重的梯度消失/梯度爆炸的问题。这是由于伴随神经网络变深,梯度无法有效地从输出层回传到底层网络,造成网络浅层部分的参数无法得到充分训练\upcite{Wang2019LearningDT,DBLP:conf/cvpr/YuYR18}。针对这些问题,已经有研究者开始尝试进行求解,并取得了很好的效果。比如,设计更有利于深层信息传递的网络连接和恰当的参数初始化方法等\upcite{Bapna2018TrainingDN,Wang2019LearningDT,DBLP:conf/emnlp/ZhangTS19} %----------------------------------------------------------------------------------------
% NEW SECTION
%----------------------------------------------------------------------------------------
\section{网络连接优化及深层网络建模}
\parinterval 除了对Transformer模型中的局部组件进行改进,改进不同层之间的连接方式也十分重要。常见的做法是融合编码/解码的中间层表示得到更丰富的编码/解码输出\upcite{Wang2018MultilayerRF,Wang2019ExploitingSC,Dou2018ExploitingDR,Dou2019DynamicLA}。同时,可以利用稠密连接等更复杂的层间连接方式来强化或替换残差连接,这类方法在图像识别\upcite{DBLP:journals/corr/HeZRS15,DBLP:conf/cvpr/HuangLMW17}、机器翻译\upcite{Bapna2018TrainingDN,Wang2018MultilayerRF,Dou2018ExploitingDR,WangLearning,Dou2019DynamicLA}
等任务上取得了很好的效果。
\parinterval 与此同时,宽网络(如Transformer-Big)在机器翻译、语言模型等任务上表现十分出色,但伴随而来的是快速增长的参数量与更大的训练代价。同时受限于任务的复杂度与计算设备的算力,进一步探索更宽的网络显然不是特别高效的手段。在本书第十三章已经指出:增加神经网络的深度同样有助于对句子进行更充分的表示、同时增加模型的容量。但是,简单地堆叠很多层Transformer网络并不能带来性能上的提升,反而会面临更加严重的梯度消失/梯度爆炸的问题。这是由于伴随神经网络变深,梯度无法有效地从输出层回传到底层网络,造成网络浅层部分的参数无法得到充分训练\upcite{Bapna2018TrainingDN,WangLearning,DBLP:journals/corr/abs-2002-04745,DBLP:conf/emnlp/LiuLGCH20}。针对这些问题,已经有研究者开始尝试求解,并取得了很好的效果。比如,设计更有利于深层信息传递的网络连接\upcite{Bapna2018TrainingDN,WangLearning,Wei2020MultiscaleCD,DBLP:conf/acl/WuWXTGQLL19,li2020shallow,DBLP:journals/corr/abs-2007-06257}和恰当的参数初始化方法\upcite{huang2020improving,DBLP:conf/emnlp/ZhangTS19,DBLP:conf/acl/XuLGXZ20,DBLP:conf/emnlp/LiuLGCH20}等。
\parinterval 但是,如何设计一个足够“深”的机器翻译模型仍然是业界关注的热点问题之一。此外,伴随着网络的继续变深,将会面临一些新的问题,例如,如何加速深层网络的训练,如何解决深层网络的过拟合问题等。下面将会对以上问题展开讨论。 \parinterval 但是,如何设计一个足够“深”的机器翻译模型仍然是业界关注的热点问题之一。此外,伴随着网络的继续变深,将会面临一些新的问题,例如,如何加速深层网络的训练,如何解决深层网络的过拟合问题等。下面将会对以上问题展开讨论。首先对Transformer模型的内部信息流进行详细的讨论。之后分别从模型结构和参数初始化两个角度求解为什么深层网络难以训练,并介绍相应的解决手段。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
...@@ -39,7 +48,7 @@ ...@@ -39,7 +48,7 @@
\subsection{Post-Norm vs Pre-Norm} \subsection{Post-Norm vs Pre-Norm}
\parinterval 为了探究为何深层的Transformer模型很难直接训练,首先对Transformer的模型结构进行简单的回顾。以Transformer的编码端为例,在多头自注意力网络和前馈神经网络中间,Transformer模型利用残差连接和层正则化操作来提高信息的传递效率。Transformer模型大致分为图\ref{fig:15-1}中两种结构\ \dash \ 后作方式的残差单元(Post-Norm)和前作方式的残差单元(Pre-Norm)。 \parinterval 为了探究为何深层的Transformer模型很难直接训练,首先对Transformer的模型结构进行简单的回顾(见{\chaptertwelve})。以Transformer的编码端为例,在多头自注意力网络和前馈神经网络中间,Transformer模型利用残差连接\upcite{DBLP:journals/corr/HeZRS15}和层标准化操作\upcite{Ba2016LayerN}来提高信息的传递效率。Transformer模型大致分为图\ref{fig:15-1}中两种结构\ \dash \ 后作方式的残差单元(Post-Norm)和前作方式的残差单元(Pre-Norm)。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -50,147 +59,387 @@ ...@@ -50,147 +59,387 @@
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval$x_l$$x_{l+1}$表示第$l$子层的输入和输出\footnote[1]{这里沿用Transformer中的定义,每一层(Layer)包含多个子层(Sub-layer)。比如,对于Transformer编码器,每一层包含一个自注意力子层和一个前馈神经网络子层。所有子层都需要进行层归一化和残差连接。}$y_l$表示中间的临时输出;$\textrm{LN}(\cdot)$表示层归一化操作\upcite{Ba2016LayerN},帮助减少子层输出分布的方差。从而让训练变得更稳定;{\red $\mathcal{F}(\cdot)$ (F这种斜体是有什么特殊含义吗)}表示子层所对应的函数,比如前馈神经网络、自注意力网络等。下面分别对Post-Norm和Pre-Norm进行简单的描述。 \parinterval$\mathbi{x}_l$$\mathbi{x}_{l+1}$表示第$l$个子层的输入和输出\footnote[1]{这里沿用Transformer中的定义,每一层(Layer)包含多个子层(Sub-layer)。比如,对于Transformer编码器,每一层包含一个自注意力子层和一个前馈神经网络子层。所有子层都需要进行层归一化和残差连接。}$\mathbi{y}_l$表示中间的临时输出;$\textrm{LN}(\cdot)$表示层归一化操作\upcite{Ba2016LayerN},帮助减少子层输出分布的方差。从而让训练变得更稳定;$F(\cdot)$表示子层所对应的函数,比如前馈神经网络、自注意力网络等。下面分别对Post-Norm和Pre-Norm进行简单的描述。
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\item Post-Norm:早期的Transformer遵循的是Post-Norm结构\upcite{vaswani2017attention}。也就是层正则化作用于每一子层的输入和输出的残差结果上,如图\ref{fig:15-1}(a)所示。可以表示如下: \item Post-Norm:早期的Transformer遵循的是Post-Norm结构\upcite{vaswani2017attention}。也就是层标准化作用于每一子层的输入和输出的残差结果上,如图\ref{fig:15-1}(a)所示。可以表示如下:
\begin{eqnarray} \begin{equation}
x_{l+1}=\textrm{LN}(x_l+\mathcal{F}(x_l;\theta_l)) \mathbi{x}_{l+1}=\textrm{LN}(\mathbi{x}_l+F(\mathbi{x}_l;{\bm \theta_l}))
\label{eq:15-1} \label{eq:15-1}
\end{eqnarray} \end{equation}
其中,$\theta_l$是子层$l$的参数。
\noindent 其中,$\bm \theta_l$是子层$l$的参数。
\vspace{0.5em} \vspace{0.5em}
\item Pre-Norm:通过调整层正则化的位置,将其放置于每一子层的输入之前,得到了Pre-Norm结构,如图\ref{eq:15-1}(b)所示。其思想与He等人的思想一致\upcite{DBLP:conf/eccv/HeZRS16},也被广泛应用于最新的Transformer开源系统中\upcite{Vaswani2018Tensor2TensorFN,Ottfairseq,KleinOpenNMT},公式如下: \item Pre-Norm:通过调整层标准化的位置,将其放置于每一子层的输入之前,得到了Pre-Norm结构,如图\ref{eq:15-1}(b)所示。其思想与He等人的思想一致\upcite{DBLP:conf/eccv/HeZRS16},也被广泛应用于最新的Transformer开源系统中\upcite{Vaswani2018Tensor2TensorFN,Ottfairseq,KleinOpenNMT},公式如下:
\begin{eqnarray} \begin{equation}
x_{l+1}=x_l+\mathcal{F}(\textrm{LN}(x_l);\theta_l) \mathbi{x}_{l+1}=\mathbi{x}_l+F(\textrm{LN}(\mathbi{x}_l);{\bm \theta_l})
\label{eq:15-2} \label{eq:15-2}
\end{eqnarray} \end{equation}
\vspace{0.5em}
\end{itemize} \end{itemize}
\parinterval 从上述公式可以看到Pre-Norm结构可以通过残差路径将底层网络的输出直接暴露给上层网络;另一方面从反向传播的角度看,使用Pre-Norm结构,顶层的梯度可以更容易地反馈到底层网络。这里以一个含有$L$个子层的结构为例。令$Loss$表示整个神经网络输出上的损失,$x_L$为顶层的输出。对于Post-Norm结构,根据链式法则,损失$Loss$相对于$x_l$的梯度可以表示为: \parinterval 从上述公式可以看到Pre-Norm结构可以通过残差路径将底层网络的输出直接暴露给上层网络;另一方面从反向传播的角度看,使用Pre-Norm结构,顶层的梯度可以更容易地反馈到底层网络。这里以一个含有$N$个子层的结构为例。令$Loss$表示整个神经网络输出上的损失,$\mathbi{x}_N$为顶层的输出。对于Post-Norm结构,根据链式法则,损失$Loss$相对于$\mathbi{x}_l$的梯度可以表示为:
\begin{eqnarray} \begin{equation}
\frac{\partial Loss}{\partial x_l}=\frac{\partial Loss}{\partial x_L} \times \prod_{k=l}^{L-1}\frac{\partial \textrm{LN}(y_k)}{\partial y_k} \times \prod_{k=l}^{L-1}(1+\frac{\partial \mathcal{F}(x_k;\theta_k)}{\partial x_k}) \frac{\partial Loss}{\partial \mathbi{x}_l}=\frac{\partial Loss}{\partial \mathbi{x}_N} \times \prod_{k=l}^{N-1}\frac{\partial \textrm{LN}(\mathbi{y}_k)}{\partial \mathbi{y}_k} \times \prod_{k=l}^{N-1}(1+\frac{\partial F(\mathbi{x}_k;{\bm \theta_k})}{\partial \mathbi{x}_k})
\label{eq:15-3} \label{eq:15-3}
\end{eqnarray} \end{equation}
其中$\prod_{k=l}^{L-1}\frac{\partial \textrm{LN}(y_k)}{\partial y_k}$表示在反向传播过程中经过层正则化得到的复合函数导数,$\prod_{k=l}^{L-1}(1+\frac{\partial \mathcal{F}(x_k;\theta_k)}{\partial x_k})$代表每个子层间残差连接的导数。
\parinterval 其中$\prod_{k=l}^{N-1}\frac{\partial \textrm{LN}(\mathbi{y}_k)}{\partial \mathbi{y}_k}$表示在反向传播过程中经过层标准化得到的复合函数导数,$\prod_{k=l}^{N-1}(1+\frac{\partial F(\mathbi{x}_k;{\bm \theta_k})}{\partial \mathbi{x}_k})$代表每个子层间残差连接的导数。
\parinterval 类似的,也能得到Pre-Norm结构的梯度计算结果,如下式所示: \parinterval 类似的,也能得到Pre-Norm结构的梯度计算结果,如下式所示:
\begin{eqnarray} \begin{equation}
\frac{\partial Loss}{\partial x_l}=\frac{\partial Loss}{\partial x_L} \times (1+\sum_{k=l}^{L-1}\frac{\partial \mathcal{F}(\textrm{LN}(x_k);\theta_k)}{\partial x_l}) \frac{\partial Loss}{\partial \mathbi{x}_l}=\frac{\partial Loss}{\partial \mathbi{x}_N} \times (1+\sum_{k=l}^{N-1}\frac{\partial F(\textrm{LN}(\mathbi{x}_k);{\bm \theta_k})}{\partial \mathbi{x}_l})
\label{eq:15-4} \label{eq:15-4}
\end{eqnarray} \end{equation}
\parinterval 对比公式\eqref{eq:15-3}和公式\eqref{eq:15-4}可以明显发现Pre-Norm结构直接把顶层的梯度$\frac{\partial Loss}{\partial x_L}$传递给下层,也就是$\frac{\partial Loss}{\partial x_l}$中直接含有$\frac{\partial Loss}{\partial x_L}$的部分。这个性质弱化了梯度计算对模型深度$L$的依赖;而如公式\eqref{eq:15-3}右侧所示,Post-Norm结构会导致一个与$L$相关的多项导数的积,伴随着$L$的增大更容易发生梯度消失和梯度爆炸问题。因此,Pre-Norm结构更适于堆叠多层神经网络的情况。比如,使用Pre-Norm结构可以很轻松的训练一个30层(60个子层)的Transformer编码器网络,并带来可观的BLEU提升。这个结果相当于标准Transformer编码器深度的6倍\upcite{Wang2019LearningDT}。相对的,用Pre-Norm结构训练深网络的时候,训练结果很不稳定,甚至有时候无法完成有效训练。这里把使用Pre-Norm的深层Transformer称为Transformer-Deep。 \parinterval 对比公式\eqref{eq:15-3}和公式\eqref{eq:15-4}可以明显发现Pre-Norm结构直接把顶层的梯度$\frac{\partial Loss}{\partial \mathbi{x}_N}$传递给下层,也就是$\frac{\partial Loss}{\partial \mathbi{x}_l}$中直接含有$\frac{\partial Loss}{\partial \mathbi{x}_N}$的部分。这个性质弱化了梯度计算对模型深度$N$的依赖;而如公式\eqref{eq:15-3}右侧所示,Post-Norm结构会导致一个与$N$相关的多项导数的积,伴随着$N$的增大更容易发生梯度消失和梯度爆炸问题\footnote[2]{类似地,在循环神经网络中当序列过长时,网络同样容易发生梯度消失和梯度爆炸问题。}。因此,Pre-Norm结构更适于堆叠多层神经网络的情况。比如,使用Pre-Norm结构可以很轻松地训练一个30层(60个子层)编码器的Transformer网络,并带来可观的BLEU提升。这个结果相当于标准Transformer编码器深度的6倍\upcite{WangLearning}。相对的,用Pre-Norm结构训练深层网络的时候,训练结果很不稳定,当编码器深度超过12层后很难完成有效训练\upcite{WangLearning},尤其是在低精度设备环境下损失函数出现发散情况。这里把使用Pre-Norm的深层Transformer称为Transformer-Deep。
\parinterval 另一个有趣的发现是,使用深层网络后,训练模型收敛的时间大大缩短。相比于Transformer-Big等宽网络,Transformer-Deep并不需要太大的隐藏层大小就可以取得相当甚至更优的翻译品质。也就是说,Transformer-Deep是一个更“窄”更“深”的网络。这种结构的参数量比Transformer-Big少,系统运行效率更高。表\ref{tab:15-1}对比了不同模型的参数量和训练/推断时间 \parinterval 另一个有趣的发现是,使用深层网络后,网络可以更有效地利用较大的学习率和batch size训练,大幅度缩短了模型达到收敛的时间。相比于Transformer-Big等宽网络,Transformer-Deep并不需要太大的隐藏层维度就可以取得相当甚至更优的翻译品质\upcite{WangLearning}。也就是说,Transformer-Deep是一个更“窄”更“深”的网络。这种结构的参数量比Transformer-Big少,系统运行效率更高
%---------------------------------------------- \parinterval 此外研究人员发现当编码器端使用深层网络之后,解码器端使用更浅的网络依然能够维持相当的翻译品质。这是由于解码器端的计算仍然会有对源语言端信息的加工和抽象,当编码器变深之后,解码器对源语言端的加工不那么重要了,因此可以减少解码网络的深度。这样做的一个直接好处是:可以通过减少解码器的深度加速翻译系统。对于一些延时敏感的场景,这种架构是极具潜力的\upcite{DBLP:journals/corr/abs-2006-10369}
\begin{table}[htp]
\centering
\caption{不同Transformer结构的训练/推断时间对比(WMT14英德任务)}
\begin{tabular}{l | r r r}
\rule{0pt}{15pt} 系统 & 参数量 & 训练时间 & 推断时间 \\
\hline
\rule{0pt}{15pt} Base & 63M & 4.6h & 19.4s \\
\rule{0pt}{15pt} Big & 210M & 36.1h & 29.3s \\
\rule{0pt}{15pt} DLCL-30 & 137M & 9.8h & 24.6s \\
\end{tabular}
\label{tab:15-1}
\end{table}
%----------------------------------------------
\parinterval 还有一个有趣的发现是,当编码器端使用深层网络之后,解码器端使用更浅的网络依然能够维持相当的翻译品质。这是由于解码器端的计算仍然会有对源语言端信息的加工和抽象,当编码器变深之后,解码器对源语言端的加工不那么重要了,因此可以减少解码网络的深度。这样做的一个直接好处是:可以通过减少解码器的深度加速翻译系统。对于一些延时敏感的场景,这种架构是极具潜力的。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\subsection{层聚合} \subsection{高效信息传递}
\parinterval 尽管使用Pre-Norm结构可以很容易地训练深层Transformer模型,但从信息传递的角度看,Transformer模型中第$l$层的输入仅仅依赖于前一层的输出。虽然残差连接可以跨层传递信息,但是对于很深的网络,整个模型的输入和输出之间仍需要很多次残差连接才能进行有效的传递。为了使上层的网络可以更加方便地访问下层网络的信息,一种方法是直接引入更多的跨层连接。最简单的一种方法是直接将所有层的输出都连接到最上层,达到聚合多层信息的目的\upcite{Bapna2018TrainingDN,Wang2018MultilayerRF,Dou2018ExploitingDR}
\parinterval 另一种更加有效的方式是在网络前向计算的过程中建立当前层与之前层表示之间的关系,例如动态线性聚合网络\upcite{WangLearning}{\small\bfnew{动态层聚合方法}}\upcite{Dou2019DynamicLA}\index{动态层聚合方法}(Dynamic Linear Combination of Layers,DLCL)\index{Dynamic Linear Combination of Layers}。两者共性在于,在每一层的输入中不仅考虑前一层的输出,而是将前面所有层的中间结果(包括词嵌入表示)进行聚合,本质上利用稠密的层间连接提高了网络中信息传递的效率(前向计算和反向梯度计算)。而前者利用线性的层融合手段来保证计算的时效性,主要应用于深层网络任务的训练,理论上等价于常微分方程中的高阶求解方法\upcite{WangLearning}。此外,为了进一步增强上层网络对底层表示的利用,研究人员从多尺度的维度对深层的编码器网络进行分块,并使用GRU网络来捕获不同块之间的联系,得到更高层次的表示。该方法可以看作是对上述动态线性聚合网络的延伸。接下来分别对上述几种改进方法进行展开讨论。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{1. 使用更多的跨层连接}
\parinterval 图15.2描述了引入了更多跨层连接的结构。在网络的前向计算过程中,假设编码端总层数为$N$,当完成编码端$N$层的逐层计算后,通过线性平均、加权平均等机制对网络的中间层表示进行融合,得到蕴含所有层信息的表示\mathbi{g},作为解码段编码-解码注意力机制的输入,与总共有$M$层的解码器共同处理解码信息。{转录时L换成N,15-4也是}
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.4]{./Chapter15/Figures/figure-layer-fusion-method.png}
\caption{层融合方法}
\label{fig:15-2}
\end{figure}
%-------------------------------------------
\parinterval 这里,令$\mathbi{h}_i$是第$i$层编码端的输出,$\mathbi{s}_j^k$是解码器解码第$j$个单词时第$k$层的输出。层融合机制可以大致划分为如下:
\parinterval 尽管使用Pre-Norm结构可以很容易地训练深层Transformer模型,但从信息传递的角度看,Transformer模型中第$n$层的输入仅仅依赖于前一层的输出。虽然残差连接可以将信息跨层传递,但是对于很深的网络,整个模型的输入和输出之间仍需要很多次残差连接才能进行有效的传递。为了使上层的网络可以更加方便地访问下层网络的信息,一种方法是直接引入更多跨层的连接。最简单的一种方法是直接将所有层的输出都连接到最上层,达到聚合多层信息的目的\upcite{Bapna2018TrainingDN,Wang2018MultilayerRF}。另一种更加有效的方式是使用{\small\bfnew{动态线性层聚合方法}}\index{动态线性层聚合方法}(Dynamic Linear Combination of Layers,DLCL)\index{Dynamic Linear Combination of Layers,DLCL}。在每一层的输入中不仅考虑前一层的输出,而是将前面所有层的中间结果(包括词嵌入)进行线性聚合,理论上等价于常微分方程中的高阶求解方法\upcite{Wang2019LearningDT}。以Pre-Norm结构为例,具体做法如下:
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\item 对于每一层的输出$x_{l+1}$,对其进行层正则化,得到每一层的信息的表示 \item 线性平均,即平均池化。通过对各层中间表示进行累加之后取平均值。
\begin{eqnarray} \begin{equation}
z_{l}=\textrm{LN}(x_{l+1}) \mathbi{g}=\frac{1}{N}\sum_{l=1}^{N}{\mathbi{h}_l}
\label{eq:15-5} \label{eq:15-5}
\end{eqnarray} \end{equation}
注意,$z_0$表示词嵌入层的输出,$z_l(l>0)$表示Transformer网络中最终的各层输出。
\vspace{0.5em} \vspace{0.5em}
\item 定义一个维度为$(L+1)\times(L+1)$的权值矩阵$\vectorn{W}$,矩阵中每一行表示之前各层对当前层计算的贡献度,其中$L$是编码端(或解码端)的层数。令$\vectorn{W}_{l,i}$代表权值矩阵$\vectorn{W}$$l$行第$i$列的权重,则层聚合的输出为$z_i$的线性加权和: \item 权重平均。在线性平均的基础上,赋予每一个中间层表示相应的权重。权重的值通常采用可学习的参数矩阵$\mathbi{W}$表示,通过反向传播来不断调整每一层的权重比例,通常会略优于线性平均方法。
\begin{eqnarray} \begin{equation}
g_l=\sum_{i=0}^{l}z_i\times \vectorn{W}_{l,i} \mathbi{g}=\sum_{l=1}^{N}{\mathbi{W}_l\mathbi{h}_l}
\label{eq:15-6} \label{eq:15-6}
\end{equation}
\vspace{0.5em}
\item 前馈神经网络。将之前中间层的表示进行级联,之后利用前馈神经网络得到融合的表示。
\begin{equation}
\mathbi{g}=\textrm{FNN}([\mathbi{h}_1,\mathbi{h}_2,\ldots,\mathbi{h}_N])
\label{eq:15-7}
\end{equation}
\noindent 其中,$[\cdot]$表示级联操作。这种方式对比权重平均具有更复杂的线性运算,同时引入非线性变化增加网络的表示能力。
\vspace{0.5em}
\item 基于多跳的自注意力机制,其结构图如图\ref{fig:15-3}所示。其做法与前馈神经网络类似,首先将不同层的表示拼接成2维的句子级矩阵表示示\footnote[3]{对比1维向量有更强的表示能力\upcite{DBLP:journals/corr/LinFSYXZB17}}。之后利用类似于前馈神经网络的思想将维度为$\mathbb{R}^{d\times N}$的矩阵映射到维度为$\mathbb{R}^{d\times n_{hop}}$的矩阵表示。
\begin{equation}
\mathbi{o}=\sigma ([\mathbi{h}_1,\mathbi{h}_2,\ldots,\mathbi{h}_N]^{T} \cdot \mathbi{W}_1)\mathbi{W}_2
\label{eq:15-8}
\end{equation}
\noindent 其中$\mathbi{W}_1 \in \mathbb{R}^{d\times d_a}$$\mathbi{W}_2 \in \mathbb{R}^{d_a\times n_{hop}}$。之后使用Softmax函数计算不同层在同一维度空间的归一化概率$\mathbi{u}_l$
\begin{equation}
\mathbi{u}_l=\frac{\textrm{exp}(\mathbi{o}_l)}{\sum_i^N{\textrm{exp}(\mathbi{o}_i)}}
\label{eq:15-9}
\end{equation}
\noindent 最后通过向量积操作得到维度为$\mathbb{R}^{d\times n_{hop}}$的稠密表示$\mathbi{v}$。通过单层的前馈神经网络得到最终的融合表示 :
\begin{eqnarray}
\mathbi{v}_n & = & [\mathbi{h}_1,\mathbi{h}_2,\ldots,\mathbi{h}_N]\cdot \mathbi{u}_l \\
\mathbi{g} & = & \textrm{FNN}([\mathbi{v}_1,\mathbi{v}_2,\ldots,\mathbi{v}_N])
\label{eq:15-11}
\end{eqnarray} \end{eqnarray}
$g_l$会作为输入的一部分送入第$l+1$层。其网络的结构如图\ref{fig:15-2}所示 \vspace{0.5em}
\end{itemize}
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.7]{./Chapter15/Figures/figure-layer-fusion-method-2d.png}
\caption{Post-Norm Transformer vs Pre-Norm Transformer}
\label{fig:15-3}
\end{figure}
%-------------------------------------------
\parinterval 上述工作更多应用于浅层的Transformer网络,这种仅在编码端顶部使用融合机制的方法并没有在深层Transformer上得到有效地验证。主要原因是融合机制仅作用于编码端或解码端的顶部,对网络中间层的计算并没有显著提升。因此当网络深度较深时,信息在前向计算和反向更新过程中的传播效率仍然有待提高,但这种“静态”的融合方式也为深层Transformer研究奠定了基础。例如研究人员提出了透明注意力网络\upcite{Bapna2018TrainingDN},即在权重平均的基础上,引入了$(N+1)\times (M+1)$的权重矩阵,其中$N$$M$分别代表编码端与解码端的层数。其核心思想是让解码端中每一层的编码-解码注意力网络接收到的编码端融合表示中对应不同编码层的权重是独立的,而不是共享相同的融合表示,如图\ref{fig:15-4}所示。此外二维的权重矩阵对比一维矩阵具有更强的学习能力,实验表明在英德数据集上获得了与宽网络(Transformer-Big)相当的翻译性能。
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.4]{./Chapter15/Figures/figure-transparent-attention-mechanism.png}
\caption{透明注意力机制}
\label{fig:15-4}
\end{figure}
%-------------------------------------------
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{2. 动态层融合}
\parinterval 那如何进一步提高信息的传递效率?对比层融合方法,本节介绍的动态层融合可以更充分利用之前层的信息,其网络连接更加稠密,表示能力更强\upcite{Bapna2018TrainingDN,WangLearning,Wei2020MultiscaleCD,DBLP:conf/acl/WuWXTGQLL19,li2020shallow,DBLP:journals/corr/abs-2007-06257}。以基于Pre-Norm结构的DLCL网络中编码器为例,具体做法如下:
\begin{itemize}
\vspace{0.5em}
\item 对于每一层的输出$\mathbi{x}_{l}$,对其进行层标准化,得到每一层的信息的表示
\begin{equation}
\mathbi{h}_l=\textrm{LN}(\mathbi{x}_{l})
\label{eq:15-12}
\end{equation}
注意,$\mathbi{h}_0$表示词嵌入层的输出,$\mathbi{h}_l(l>0)$表示Transformer网络中最终的各层输出。
\vspace{0.5em}
\item 定义一个维度为$(N+1)\times (M+1)$的权值矩阵$\mathbi{W}$,矩阵中每一行表示之前各层对当前层计算的贡献度,其中$L$是编码端(或解码端)的层数。令$\mathbi{W}_{l,i}$代表权值矩阵$\mathbi{W}$$l$行第$i$列的权重,则层聚合的输出为$\mathbi{h}_i$的线性加权和:
\begin{equation}
\mathbi{g}_l=\sum_{i=0}^{l}\mathbi{h}_i\times \mathbi{W}_{l,i}
\label{eq:15-13}
\end{equation}
$\mathbi{g}_l$会作为输入的一部分送入第$l+1$层。其网络的结构如图\ref{fig:15-2}所示
\vspace{0.5em}
\end{itemize} \end{itemize}
%--------------------------------------------- %---------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter15/Figures/figure-dynamic-linear-aggregation-network-structure} \input{./Chapter15/Figures/figure-dynamic-linear-aggregation-network-structure}
\caption{动态线性层聚合网络结构图} \caption{线性层聚合网络}
\label{fig:15-2} \label{fig:15-5}
\end{figure}
%-------------------------------------------
\parinterval 可以看到,权值矩阵$\mathbi{W}$是一个下三角矩阵。开始时,对矩阵参数的每行进行平均初始化,即初始化矩阵$\mathbi{W}_0$的每一行各个位置的值为$1/\lambda , \lambda \in (1,2,3 \cdots l+1)$。伴随着神经网络的训练,网络通过反向传播算法来不断更新$\mathbi{W}$中每一行不同位置权重的大小。
\parinterval 动态线性层聚合的一个好处是,系统可以自动学习不同层对当前层的贡献度。在实验中也发现,离当前层更近的部分贡献度(权重)会更大,如图\ref{fig:15-6}所示,在每一行中颜色越深代表对当前层的贡献度越大,这也是符合直觉的。
\parinterval 对比上述介绍的动态层线性聚合方法,研究人员利用更为复杂的胶囊网络\upcite{Dou2019DynamicLA},树状层次结构\upcite{Dou2018ExploitingDR}作为层间的融合方式,动态地计算每一层网络的输入。然而,研究人员发现进一步增加模型编码端的深度并不能取得更优的翻译性能。因此如何进一步突破神经网络深度的限制是值得关注的研究方向,类似的话题在图像处理领域也激起了广泛的讨论\upcite{DBLP:conf/nips/SrivastavaGS15,DBLP:conf/icml/BalduzziFLLMM17,DBLP:conf/icml/Allen-ZhuLS19,DBLP:conf/icml/DuLL0Z19}
%---------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.4]{./Chapter15/Figures/figure-weight-visualization-of-convergence-DLCL-network.png}
\caption{对收敛的DLCL网络进行权重的可视化\upcite{WangLearning}}
\label{fig:15-6}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 可以看到,权值矩阵$\vectorn{W}$是一个下三角矩阵。开始时,对矩阵参数的每行进行平均初始化,即初始化矩阵$\vectorn{W}_0$的每一行各个位置的值为$1/M,M \in (1,2,3 \cdots L+1)$。 伴随着神经网络的训练,网络通过反向传播算法来不断更新$\vectorn{W}$中每一行不同位置权重的大小。 %----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{3. 多尺度协同网络}
\parinterval 沿着动态线性层聚合思路(DLCL),研究者进一步提出了{\small\bfnew{多尺度协同框架}}\index{多尺度协同框架}(Multiscale Collaborative Framework)\index{Multiscale Collaborative Framework}进一步强化深层网络的表示能力该框架大致可以概括为两方面:
\parinterval 动态线性层聚合的一个好处是,系统可以自动学习不同层对当前层的贡献度。在实验中也发现,离当前层更近的部分贡献度(权重)会更大,这也是符合直觉的。 \begin{itemize}
\vspace{0.5em}
\item 采用组间协同机制。将连续的多个编码层或解码层组成块,保证编码端和解码端具有相同的块数\footnote[4]{例如,一个36层的深层网络包含6个编码块和6个解码块,其中每连续的6层编码层网络组成一个编码块,每一层解码层都是一个单独的解码块。}其核心思想是解码端能够利用对应的编码块输出作为注意力网络的Key和Value进行跨语言间映射,进而达到对编码端不同层次信息的利用。同时,在一定程度上缩短了信息传递的路径,让编码端底层网络的参数接收更丰富的梯度信息,进而达到更优的收敛状态。
\vspace{0.5em}
\item 上下文协同机制。单独使用组间协同机制来缩短信息传递的路径并不能带来显著地性能提升,尤其是当网络变得极深时,组间的堆叠无法有效地建模层间的长期依赖。为了改善这个问题,可以采用GRU网络来提取不同层之间的上下文信息,等价于在不同时间步根据对应编码块的输出来更新GRU的隐层状态。提取到的上下文信息,即{\red $g$(再确认一下上标)}也被作为输入分别送入编码端与解码端,利用注意力网络进行特征融合。之后采用门控机制的思想将得到的上下文表示与对应的编码/解码的自注意力输出融合。
\vspace{0.5em}
\end{itemize}
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\subsection{深层模型的训练加速} \subsection{面向深层模型的参数初始化策略}
\parinterval 网络的学习不仅仅依赖于精心设计的网络结构,合适的初始化策略同样十分重要。例如Transformer中参数矩阵采用了Xavier初始化方式根据其输入维度和输出维度来控制均匀分布的边界\upcite{pmlr-v9-glorot10a}。该初始化可以保证各层的激活函数的输出和状态梯度在传播过程中方差的一致性,即同时考虑正向传播和反向传播的输入输出的方差相同;同样针对不同的激活函数应该采取合适的初始化方式来更好的发挥复杂网络的优势。例如更适用于ReLu激活函数的Kaiming初始化方式\upcite{DBLP:conf/iccv/HeZRS15},其核心思想同样是保证方差一致性。
\parinterval 目前的Transformer模型初始化方式已经是精心设计过的,但该类初始化更适合于浅层网络,在深层Transformer网络训练时表现不佳\upcite{pmlr-v9-glorot10a}。近期,研究人员针对深层网络的参数初始化问题进行了广泛的探索。下面分别对比分析几个最近提出的初始化策略。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{1. 基于深度缩放的初始化策略}
\parinterval 为什么Transformer现有初始化策略无法满足训练深层网络?这是由于伴随着网络层数的加深,输入的特征要经过很多的线性及非线性变换,受网络中激活函数导数值域范围和连乘操作的影响,常常会带来梯度爆炸或梯度消失的问题。其根本理由是过深堆叠网络无法保证梯度在回传过程中的方差一致性,尽管在目前深层模型中所采用的很多标准化方式如层标准化、批次标准化等都是从方差一致性的维度来解决此问题,即通过将网络各层输出的取值范围控制在激活函数的梯度敏感区域,从而维持网络中梯度传递的稳定性。
\parinterval 首先说明浅层Transformer模型中是如何维持梯度的方差一致性。Transformer中在初始化线性变换矩阵$\mathbi{W}$的参数时采用了Xavier初始化方法保障网络在不断优化过程中方差的问题,其方式为从一个均匀分布中进行随机采样:
\begin{equation}
\mathbi{W} \in \mathbb{R}^{d_i\times d_o} \sim u(-\gamma,\gamma),\gamma=\sqrt{\frac{6}{d_i\times d_o}}
\label{eq:15-16}
\end{equation}
\noindent 其中$\mathbi{W}$为网络中的参数,$d_i$$d_o$分别为线性变换中输入和输出的纬度,通过这种方式可以维持在前向与反向过程中输入与输出方差的一致性\upcite{DBLP:conf/iccv/HeZRS15}。这是由于在矩阵运算的中,神经元输出$\mathbi{Z}=\sum_{i=1}^n{\mathbi{w}_i \mathbi{x}_i}$$n$是上一层神经元的数量。因此,根据概率统计里的两个随机变量乘积的方差展开式为:
\begin{equation}
\textrm{Var}(\mathbi{w}_i \mathbi{x}_i) = E[\mathbi{w}_i]^2 \textrm{Var}(\mathbi{x}_i) + E[\mathbi{x}_i]^2 \textrm{Var}(\mathbi{w}_i) + \textrm{Var}(\mathbi{w}_i)\textrm{Var}(\mathbi{x}_i)
\label{eq:15-17}
\end{equation}
\parinterval 在大多数情况下,基于各种标准化手段可以维持$E[\mathbi{w}_i]^2$$E[\mathbi{x}_i]^2$等于或者近似为0,因此输出的方差:
\begin{equation}
\textrm{Var}(\mathbi{Z}) = \sum_{i=1}^n{\textrm{Var}(\mathbi{x}_i) \textrm{Var}(\mathbi{w}_i)} = n\textrm{Var}(\mathbi{W})\textrm{Var}(\mathbi{X})
\label{eq:15-18}
\end{equation}
\parinterval 因此当$\textrm{Var}(\mathbi{W})=\frac{1}{n}$时,则可以保证输入和输出空间的分布差异不至于过大。通过计算得到网络正向传播时$\textrm{Var}(\mathbi{W})=\frac{1}{d_i}$,反向传播时$\textrm{Var}(\mathbi{W})=\frac{1}{d_o}$,通过对其取平均值,控制网络参数$\mathbi{W}$的方差为$\frac{2}{d_i+d_o}$,则可以维持在前向与反向过程中输入与输出方差的一致性。由于当参数服从边界为$[a,b]$的均匀分布,其方差为$\frac{{b-a}^2}{12}$,为了达到目标方差值域,在初始化时将边界设为$\sqrt{\frac{6}{d_i+d_o}}$
\parinterval 但是随着网络层数的加深,研究人员发现简单的通过伤初始化得到的参数状态对基于Post-Norm的 Transformer各层输出方差的约束逐渐减弱。当网络堆叠至较深时会发现,模型顶层输出的方差较大,同时反向传播的梯度范数顶层也要大于底层。因此,一个自然的想法是根据网络的深度对不同层的参数矩阵采取不同的初始化方式,进而强化对各层输出方差的约束:
\begin{equation}
\mathbi{W} \in \mathbb{R}^{d_i\times d_o} \sim u(-\gamma \frac{\alpha}{\sqrt{l}},\gamma \frac{\alpha}{\sqrt{l}})
\label{eq:15-19}
\end{equation}
\noindent 其中,$l$为对应的网络层的深度,$\alpha$为预先设定的超参数来控制缩放的比例,通过这种方式降低网络层输出方差,可以将缩减顶层网络输出分布与输入分布之间的差异,减少顶层网络参数的梯度范数。从而缓解由于网络层堆叠过深所带来的梯度消失问题,保证深层网络能够稳定的训练。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{2. 基于Lipschitz的初始化策略}
\parinterval 在前面已经介绍过,在Pre-Norm结构中每一个子层的输出$\mathbi{x}_{l+1}^{pre}=\mathbi{x}_l+\mathbi{y}_l$,其中$\mathbi{x}_l$为当前子层的输入, $\mathbi{y}_l$为经过自注意力层或前馈神经网络层计算后得到的子层输出。在Post-Norm结构中,在残差连接之后还要进行层标准化操作,具体的计算流程为:
\begin{itemize}
\vspace{0.5em}
\item 计算输入的均值:${\bm \mu}=\textrm{mean}(\mathbi{x}_l+\mathbi{y}_l)$
\vspace{0.5em}
\item 计算输入的方差:${\bm \sigma}=\textrm{std}(\mathbi{x}_l+\mathbi{y}_l)$
\vspace{0.5em}
\item 根据均值和方差对输入进行放缩,其中$\mathbi{w}$$\mathbi{b}$为可学习参数,用于进一步调整均值和方差到合适的位置,提高网络的表示能力:
\begin{equation}
\mathbi{x}_{l+1}^{post}=\frac{\mathbi{x}_l+\mathbi{y}_l-{\bm \mu}}{\bm \sigma} \cdot \mathbi{w}+\mathbi{b}
\label{eq:15-20}
\end{equation}
\noindent 将其展开后可得:
\begin{equation}
\mathbi{x}_{l+1}^{post}=\frac{\mathbi{w}}{\bm \sigma} \cdot \mathbi{x}_{l+1}^{pre}-\frac{\mathbi{w}}{\bm \sigma} \cdot {\bm \mu}+\mathbi{b}
\label{eq:15-21}
\end{equation}
\vspace{0.5em}
\end{itemize}
\parinterval 可以看到相比于Pre-Norm的计算方式,基于Post-Norm的Transformer中子层的输出为Pre-Norm形式的$\frac{\mathbi{w}}{\bm \sigma}$倍,当$\frac{\mathbi{w}}{\bm \sigma}<1.0$时,使残差层的输出较小,输入与输出分布之间差异过大,导致深层Transformer系统难以收敛。因此基于Lipschitz 的初始化策略通过维持条件$\frac{\mathbi{w}}{\bm \sigma}>1.0$,保证网络输入与输出范数一致,进而缓解梯度消失的问题\upcite{DBLP:conf/acl/XuLGXZ20}。一般情况下,$\mathbi{w}$可以被初始化为1,因此Lipschitz Initialization最终的约束条件则为:
\begin{equation}
0.0<{\bm \sigma}=\textrm{std}⁡(\mathbi{x}_l+\mathbi{y}_l) \leq 1.0
\label{eq:15-22}
\end{equation}
\parinterval 为了实现这个目标,可以限制$a \leq \mathbi{x}_l+\mathbi{y}_l \leq a + \Delta a$,在经过推导后可以发现,只要$\Delta a \leq 1.0$即可满足此条件。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{3. T-Fixup初始化策略}
\parinterval 另外一种初始化方法是是从网络的结构与优化器的计算方式入手,通过可视化训练过程中参数的范数发现Post-Norm网络在训练前期(Warmup阶段)难以很精确的估计参数的二阶动量,导致训练不稳定问题\upcite{huang2020improving}。其结论也证实了其他研究人员的发现\upcite{WangLearning},即层标准化是导致深层Transformer难以优化的主要矛盾。并强调了Post-Norm方式下Transformer的底层网络,尤其是编码段的词嵌入层严重面临梯度消失问题。导致矛盾的原因在于在不改变层标准化位置的条件下,由于Adam优化器利用滑动平均的方式来估计参数的二阶矩,其方差是无界的。这样在前期模型只能看到受限样本的前提下,其二阶矩很难进行有效的估计。因此反向更新参数时会引起参数的梯度方差过大问题。相较于用Pre-Norm代替Post-Norm结构来训练深层网络,也可以通过去除warmup策略并移除层标准化机制,并针对网络中不同的参数矩阵制定了相应的缩放机制来保证训练的稳定\upcite{huang2020improving}。具体的缩放策略如下:
\begin{itemize}
\vspace{0.5em}
\item 类似标准的Transformer初始化方式,使用Xavier初始化方式来初始化除了词嵌入以外的所有参数矩阵。词嵌入矩阵服从$\mathbb{N}(0,d^{-\frac{1}{2}})${\red (再确认N的形式,下面的也要确认)}的高斯分布,其中$d$代表词嵌入的维度。
\vspace{0.5em}
\item 对编码端中自注意力网络中$\mathbi{W}^V$$\mathbi{W}^o$矩阵以及前馈神经网络中所有参数矩阵进行缩放因子为$0.67\mathbb{N}^{-\frac{1}{4}}$的缩放,其中$\mathbi{W}^o$是注意力操作中的参数矩阵{\red 看下怎么说好(详见12章transformer部分)}
\vspace{0.5em}
\item 对解码端中注意力网络中的$\mathbi{W}^V$$\mathbi{W}^o$以及前馈神经网络中所有参数矩阵进行缩放因子为$(9\mathbb{N})^{-\frac{1}{4}}$的缩放
\vspace{0.5em}
\end{itemize}
\parinterval 这种初始化方法由于没有Warmup策略,学习率会直接从峰值根据参数的更新次数进行退火,大幅度增大了网络收敛的时间。其主要贡献是在不考虑训练代价的前提下,合理的初始化方法可以让浅层的Transformer网络达到更优的翻译性能。如何进一步解决该初始化方法下的模型收敛速度是比较关键的课题
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{4. ADMIN初始化策略}
\parinterval 相比于前人得出深层网络不能充分训练的痛点在于底层网络出现参数消失问题的结论,一些研究人员持不同的看法。他们认为Post-Norm网络在训练过程中过度的依赖残差支路,在训练初期很容易发生参数梯度方差过大的隐患\upcite{DBLP:conf/emnlp/LiuLGCH20}。同时分别从理论和经验性实验验证了底层网络的梯度消失是导致了训练的不稳定的重要因素,但并不是唯一因素。通过对基于Post-Norm的编码器和解码器与基于Pre-Norm的编码器与解码器进行两两组合,作者发现梯度消失的主要故障点在于基于Post-Norm的解码器。而且尽管通过调整网络结构解决梯度消失问题,网络的不稳定训练仍然没有很好地解决。进一步对基于Pre-Norm网络的输入与输出进行分析,研究人员发现其输入与输出之间方差的变换率为$O(\log N)${\red 跟他们确认一下有没有特殊用法,还有N是什么}。为了解决Post-Norm网络结构在训练初期过于依赖残差支路,作者提出了两阶段的初始化方法来间接控制其输入与输出之间的方差在$O(\log N)$内。其子层之间的残差连接如公式\eqref{eq:15-23}所示:
\begin{equation}
\mathbi{x}_{l+1}=\mathbi{x}_l \cdot {\bm \omega_{l+1}} + F_{l+1}(\mathbi{x}_l)
\label{eq:15-23}
\end{equation}
\parinterval 尽管训练这种窄而深的神经网络对比宽网络有更快的收敛速度,但伴随着训练数据的增加,以及模型进一步的加深,神经网络的训练代价成为不可忽视的问题。例如,在几千万甚至上亿的双语平行语料上训练一个48层的Transformer模型需要将近几周的时间能达到收敛\footnote[2]{训练时间的估算是在单台8卡Titan V GPU服务器上得到的}。因此,在保证模型精度不变的前提下如何高效地完成深层网络的训练也是至关重要的。在实践中能够发现,深层网络中相邻层之间具有一定的相似性。因此,一个想法是:能否通过不断复用浅层网络的参数来初始化更深层的网络,渐进式的训练深层网络,避免从头训练整个网络,进而达到加速深层网络训练的目的。 \noindent 其两阶段的初始化方法如下所示:
\begin{itemize}
\vspace{0.5em}
\item Profiling阶段:${\bm \omega_{l+1}} = 1$,只进行网络的前向计算,无需进行网络的梯度计算。在训练样本上计算$F_{l+1}(\mathbi{x}_l)$的方差
\vspace{0.5em}
\item Initialization阶段:通过Profiling阶段得到的$F_{l+1}(\mathbi{x}_l)$的方差来初始化$\bm \omega_{l+1}$
\begin{equation}
{\bm \omega_{l+1}} = \sqrt{\sum_{j<l}\textrm{Var}[F_{l+1}(\mathbi{x}_l)]}
\label{eq:15-24}
\end{equation}
\vspace{0.5em}
\end{itemize}
\parinterval 通过这种方式,研究人员成功训练了深层网络,同时该动态地参数初始化方法不受限于具体的模型结构,方法的稳定性更优。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\subsection{渐进式训练} \subsection{深层网络的训练加速}
\parinterval 尽管训练这种窄而深的神经网络对比宽网络有更快的收敛速度\upcite{WangLearning},但伴随着训练数据的增加,以及模型进一步的加深,神经网络的训练代价成为不可忽视的问题。例如,在几千万甚至上亿的双语平行语料上训练一个48层的Transformer模型需要将近几周的时间能达到收敛\footnote[5]{训练时间的估算是在单台8卡Titan V GPU服务器上得到的}。因此,在保证模型精度不变的前提下如何高效地完成深层网络的训练也是至关重要的。在实践中能够发现,深层网络中相邻层之间具有一定的相似性。因此,一个想法是:能否通过不断复用浅层网络的参数来初始化更深层的网络,渐进式的训练深层网络,避免从头训练整个网络,进而达到加速深层网络训练的目的。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{1. 渐进式训练}
\parinterval 所谓渐进式训练是指从浅层网络开始,在训练过程中逐渐增加训练的深度。一种比较简单的方法是将网络分为浅层部分和深层部分,之后分别进行训练,最终达到提高模型翻译性能的目的\upcite{DBLP:conf/acl/WuWXTGQLL19} \parinterval 所谓渐进式训练是指从浅层网络开始,在训练过程中逐渐增加训练的深度。一种比较简单的方法是将网络分为浅层部分和深层部分,之后分别进行训练,最终达到提高模型翻译性能的目的\upcite{DBLP:conf/acl/WuWXTGQLL19}
\parinterval 另一种方式是动态构建深层网络,并尽可能复用浅层网络的训练结果。假设开始的时候模型包含$h$层网络,然后训练这个模型至收敛。之后,直接拷贝这$h$层网络(包括参数),并堆叠出一个$2h$层的模型。之后继续训练,重复这个过程。进行$n$次之后就得到了$n\times h$层的模型。图\ref{fig:15-3}给出了在编码端使用渐进式训练的示意图。 \parinterval 另一种方式是动态构建深层网络,并尽可能复用浅层网络的训练结果。假设开始的时候模型包含$l$层网络,然后训练这个模型至收敛。之后,直接拷贝这$l$层网络(包括参数),并堆叠出一个$2l$层的模型。之后继续训练,重复这个过程。进行$n$次之后就得到了$n\times l$层的模型。图\ref{fig:15-9}给出了在编码端使用渐进式训练的示意图。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter15/Figures/figure-progressive-training} \input{./Chapter15/Figures/figure-progressive-training}
\caption{渐进式深层网络训练过程} \caption{渐进式深层网络训练过程}
\label{fig:15-3} \label{fig:15-9}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 渐进式训练的好处在于深层模型并不是从头开始训练。每一次堆叠,都相当于利用“浅”模型给“深”模型提供了一个很好的初始点,这样深层模型的训练会更加容易。 \parinterval 渐进式训练的好处在于深层模型并不是从头开始训练。每一次堆叠,都相当于利用“浅”模型给“深”模型提供了一个很好的初始点,这样深层模型的训练会更加容易。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUBSUB-SECTION
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\subsection{分组稠密连接} \subsubsection{2. 分组稠密连接}
\parinterval 很多研究者已经发现深层网络不同层之间的稠密连接能够很明显地提高信息传递的效率\upcite{Wang2019LearningDT,DBLP:conf/cvpr/HuangLMW17,Dou2018ExploitingDR,DBLP:conf/acl/WuWXTGQLL19}。与此同时,对之前层信息的不断复用有助于得到更好的表示,但随之而来的是网络计算代价过大的问题。由于动态线性层聚合方法(DLCL)在每一次聚合时都需要重新计算之前每一层表示对当前层网络输入的贡献度,因此伴随着编码端整体深度的不断增加,这部分的计算代价变得不可忽略。例如,一个基于动态层聚合的48层Transformer模型的训练时间比不使用动态层聚合慢近1.9倍。同时,缓存中间结果也增加了显存的使用量,尽管使用了FP16计算,每张12G显存的GPU上计算的词也不能超过2048个,这导致训练开销急剧增大。 \parinterval 很多研究者已经发现深层网络不同层之间的稠密连接能够很明显地提高信息传递的效率\upcite{WangLearning,DBLP:conf/cvpr/HuangLMW17,Dou2018ExploitingDR,DBLP:conf/acl/WuWXTGQLL19}。与此同时,对之前层信息的不断复用有助于得到更好的表示,但随之而来的是网络计算代价过大的问题。由于动态线性层聚合方法(DLCL)在每一次聚合时都需要重新计算之前每一层表示对当前层网络输入的贡献度,因此伴随着编码端整体深度的不断增加,这部分的计算代价变得不可忽略。例如,一个基于动态层聚合的48层Transformer模型的训练时间比不使用动态层聚合慢近1.9倍。同时,缓存中间结果也增加了显存的使用量,尽管使用了FP16计算,每张12G显存的GPU上计算的词也不能超过2048个,这导致训练开销急剧增大。
\parinterval 缓解这个问题的一种方法是使用更稀疏的层间连接方式。其核心思想与动态线性层聚合是类似的,不同点在于可以通过调整层之间连接的稠密程度来降低训练代价。比如,可以将每$p$层分为一组,之后动态线性层聚合只在不同组之间进行。这样,通过调节$p$值的大小可以控制网络中连接的稠密程度,作为一种训练代价与翻译性能之间的权衡。显然,标准的Transformer模型\upcite{vaswani2017attention}和DLCL模型\upcite{Wang2019LearningDT}都可以看作是该方法的一种特例。如图\ref{fig:15-4}所示:当$p=1$时,每一个单独的块被看作一个独立的组,这等价于基于动态层聚合的DLCL模型;当$p=\infty$时,这等价于正常的Transformer模型。值得注意的是,如果配合渐进式训练。在分组稠密连接中可以设置$p=h$ \parinterval 缓解这个问题的一种方法是使用更稀疏的层间连接方式。其核心思想与动态线性层聚合是类似的,不同点在于可以通过调整层之间连接的稠密程度来降低训练代价。比如,可以将每$p$层分为一组,之后动态线性层聚合只在不同组之间进行。这样,通过调节$p$值的大小可以控制网络中连接的稠密程度,作为一种训练代价与翻译性能之间的权衡。显然,标准的Transformer模型\upcite{vaswani2017attention}和DLCL模型\upcite{WangLearning}都可以看作是该方法的一种特例。如图\ref{fig:15-10}所示:当$p=1$时,每一个单独的块被看作一个独立的组,这等价于基于动态层聚合的DLCL模型;当$p=\infty$时,这等价于正常的Transformer模型。值得注意的是,如果配合渐进式训练。在分组稠密连接中可以设置$p=h$
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter15/Figures/figure-sparse-connections-between-different-groups} \input{./Chapter15/Figures/figure-sparse-connections-between-different-groups}
\caption{不同组之间的稀疏连接} \caption{不同组之间的稀疏连接}
\label{fig:15-4} \label{fig:15-10}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUBSUB-SECTION
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\subsection{学习率重置策略} \subsubsection{3. 学习率重置}
\parinterval 尽管渐进式训练策略与分组稠密连接结构可以加速深层网络的训练,但使用传统的学习率衰减策略会导致堆叠深层模型时的学习率较小,因此模型无法快速地达到收敛状态,同时也影响最终的模型性能。 \parinterval 尽管渐进式训练策略与分组稠密连接结构可以加速深层网络的训练,但使用传统的学习率衰减策略会导致堆叠深层模型时的学习率较小,因此模型无法快速地达到收敛状态,同时也影响最终的模型性能。
...@@ -201,7 +450,7 @@ $g_l$会作为输入的一部分送入第$l+1$层。其网络的结构如图\ref ...@@ -201,7 +450,7 @@ $g_l$会作为输入的一部分送入第$l+1$层。其网络的结构如图\ref
\centering \centering
\input{./Chapter15/Figures/figure-learning-rate} \input{./Chapter15/Figures/figure-learning-rate}
\caption{学习率重置vs从头训练的学习率曲线} \caption{学习率重置vs从头训练的学习率曲线}
\label{fig:15-5} \label{fig:15-11}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
...@@ -209,18 +458,19 @@ $g_l$会作为输入的一部分送入第$l+1$层。其网络的结构如图\ref ...@@ -209,18 +458,19 @@ $g_l$会作为输入的一部分送入第$l+1$层。其网络的结构如图\ref
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\item 在训练的初期,模型先经历一个学习率预热的过程: \item 在训练的初期,模型先经历一个学习率预热的过程:
\begin{eqnarray} \begin{equation}
lr=d_{model}^{-0.5}\cdot step\_num \cdot warmup\_steps^{-0.5} lr=d_{model}^{-0.5}\cdot step\_num \cdot warmup\_steps^{-0.5}
\label{eq:15-7} \label{eq:15-25}
\end{eqnarray} \end{equation}
这里,$step\_num$表示参数更新的次数,$warmup\_step$表示预热的更次次数,$d_{model}^{-0.5}$表示Transformer模型隐层大小,$lr$是学习率。 \noindent 这里,$step\_num$表示参数更新的次数,$warmup\_step$表示预热的更次次数,$d_{model}^{-0.5}$表示Transformer模型隐层大小,$lr$是学习率。
\vspace{0.5em} \vspace{0.5em}
\item 在之后的迭代训练过程中,每当进行新的迭代,学习率都会重置到峰值,之后进行相应的衰减: \item 在之后的迭代训练过程中,每当进行新的迭代,学习率都会重置到峰值,之后进行相应的衰减:
\begin{eqnarray} \begin{equation}
lr=d_{model}^{-0.5}\cdot step\_num^{-0.5} lr=d_{model}^{-0.5}\cdot step\_num^{-0.5}
\label{eq:15-8} \label{eq:15-26}
\end{eqnarray} \end{equation}
这里$step\_num$代表学习率重置后更新的步数。 \noindent 这里$step\_num$代表学习率重置后更新的步数。
\vspace{0.5em}
\end{itemize} \end{itemize}
\parinterval 综合使用渐进式训练、分组稠密连接、学习率重置策略可以在保证翻译品质不变的前提下,缩减近40\%的训练时间(40层编码器)。同时,加速比伴随着模型的加深与数据集的增大会进一步地扩大。 \parinterval 综合使用渐进式训练、分组稠密连接、学习率重置策略可以在保证翻译品质不变的前提下,缩减近40\%的训练时间(40层编码器)。同时,加速比伴随着模型的加深与数据集的增大会进一步地扩大。
...@@ -229,65 +479,342 @@ lr=d_{model}^{-0.5}\cdot step\_num^{-0.5} ...@@ -229,65 +479,342 @@ lr=d_{model}^{-0.5}\cdot step\_num^{-0.5}
% NEW SUB-SECTION % NEW SUB-SECTION
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\subsection{深层模型的鲁棒性训练} \subsection{深层网络的鲁棒性训练}
\parinterval 伴随着网络的加深,还会面临另外一个比较严峻的问题\ \dash \ 过拟合。由于参数量的增大,深层网络的输入与输出分布之间的差异也会越来越大,然而不同子层之间的{\small\bfnew{相互适应}}\index{相互适应}(Co-adaptation)\index{Co-adaptation}也会更加的明显,导致任意子层网络对其他子层的依赖过大。这对于训练阶段是有帮助的,因为不同子层可以协同工作从而更好地拟合训练数据。然而这种方式也降低了模型的泛化能力,即深层网络更容易陷入过拟合问题。 \parinterval 伴随着网络的加深,还会面临另外一个比较严峻的问题\ \dash \ 过拟合。由于参数量的增大,深层网络的输入与输出分布之间的差异也会越来越大,然而不同子层之间的{\small\bfnew{相互适应}}\index{相互适应}(Co-adaptation)\index{Co-adaptation}也会更加的明显,导致任意子层网络对其他子层的依赖过大。这对于训练阶段是有帮助的,因为不同子层可以协同工作从而更好地拟合训练数据。然而这种方式也降低了模型的泛化能力,即深层网络更容易陷入过拟合问题。
\parinterval 通常,可以使用Dropout手段用来缓解过拟合问题(见{\chapterthirteen})。不幸的是,尽管目前Transformer模型使用了多种Dropout手段(如Residual Dropout、Attention Dropout、 ReLU Dropout等),过拟合问题在深层网络中仍然存在。从图\ref{fig:15-6}中可以看到,深层网络对比浅层网络在训练集和校验集的困惑度上都有显著的优势,然而网络在训练一段时间后出现校验集困惑度上涨的现象,说明模型已经过拟合于训练数据。 \parinterval 通常,可以使用Dropout手段用来缓解过拟合问题(见{\chapterthirteen})。不幸的是,尽管目前Transformer模型使用了多种Dropout手段(如Residual Dropout、Attention Dropout、 ReLU Dropout等),过拟合问题在深层网络中仍然存在。从图\ref{fig:15-12}中可以看到,深层网络对比浅层网络在训练集和校验集的困惑度上都有显著的优势,然而网络在训练一段时间后出现校验集困惑度上涨的现象,说明模型已经过拟合于训练数据。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter15/Figures/figure-wmt16} \input{./Chapter15/Figures/figure-wmt16}
\caption{浅层网络(左)与深层网络(右)在WMT16英德的校验集与训练集的困惑度} \caption{浅层网络(左)与深层网络(右)在WMT16英德的校验集与训练集的困惑度}
\label{fig:15-6} \label{fig:15-12}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval{\chapterthirteen}提到的Layer Dropout方法可以有效地缓解这个问题。以编码端为例, Layer Dropout的过程可以被描述为:在训练过程中,对自注意力子层或前馈神经网络子层进行随机丢弃,以减少不同子层之间的相互适应。这里选择Pre-Norm结构作为基础架构,它可以被描述为: \parinterval{\chapterthirteen}提到的Layer Dropout方法可以有效地缓解这个问题。以编码端为例, Layer Dropout的过程可以被描述为:在训练过程中,对自注意力子层或前馈神经网络子层进行随机丢弃,以减少不同子层之间的相互适应。这里选择Pre-Norm结构作为基础架构,它可以被描述为:
\begin{eqnarray} \begin{equation}
x_{l+1}=\mathcal{F}(\textrm{LN}(x_l))+x_l x_{l+1}=F(\textrm{LN}(\mathbi{x}_l)) + \mathbi{x}_l
\label{eq:15-9} \label{eq:15-27}
\end{eqnarray} \end{equation}
其中$\textrm{LN}( \cdot )$表示层正则化函数, $\mathcal{F}( \cdot )$表示自注意力机制或者前馈神经网络,$x_l$表示第$l$个子层的输出。之后,使用一个掩码$M$(值为0或1)来控制每一子层是正常计算还是丢弃。于是,该子层的计算公式可以被重写为:
\begin{eqnarray} \noindent 其中$\textrm{LN}( \cdot )$表示层标准化函数, $F( \cdot )$表示自注意力机制或者前馈神经网络,$\mathbi{x}_l$表示第$l$个子层的输出。之后,使用一个掩码$\textrm{Mask}$(值为0或1)来控制每一子层是正常计算还是丢弃。于是,该子层的计算公式可以被重写为:
x_{l+1}=M \cdot \mathcal{F}(\textrm{LN}(x_l))+x_l \begin{equation}
\label{eq:15-10} \mathbi{x}_{l+1}=\textrm{Mask} \cdot F(\textrm{LN}(\mathbi{x}_l))+\mathbi{x}_l
\end{eqnarray} \label{eq:15-28}
$M=0$代表该子层被丢弃,而$M=1$代表正常进行当前子层的计算。图\ref{fig:15-7}展示了这个方法与标准Pre-Norm结构之间的区别。 \end{equation}
\noindent $\textrm{Mask}=0$代表该子层被丢弃,而$\textrm{Mask}=1$代表正常进行当前子层的计算。图\ref{fig:15-13}展示了这个方法与标准Pre-Norm结构之间的区别。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter15/Figures/figure-sublayer-skip} \input{./Chapter15/Figures/figure-sublayer-skip}
\caption{标准的Pre-Norm结构与基于随机跳跃子层的Pre-Norm结构} \caption{标准的Pre-Norm结构与基于随机跳跃子层的Pre-Norm结构}
\label{fig:15-7} \label{fig:15-13}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 除此之外,有研究者已经发现残差网络中底层的子网络通过对输入进行抽象得到的表示对最终的输出有很大的影响,上层网络通过对底层网络得到的表示不断修正来拟合训练目标\upcite{DBLP:journals/corr/GreffSS16}。该结论同样适用于Transformer模型,比如,在训练中,残差支路以及底层的梯度范数通常比较大,这也间接表明底层网络在整个优化的过程中需要更大的更新。考虑到这个因素,在设计每一个子层被丢弃的概率时可以采用自底向上线性增大的策略,保证底层的网络相比于顶层更容易保留下来。这里用$L$来代表编码端块的个数,$l$代表当前的子层的编号,那么$M$可以通过以下的方式得到: \parinterval 除此之外,有研究者已经发现残差网络中底层的子网络通过对输入进行抽象得到的表示对最终的输出有很大的影响,上层网络通过对底层网络得到的表示不断修正来拟合训练目标\upcite{DBLP:journals/corr/GreffSS16}。该结论同样适用于Transformer模型,比如,在训练中,残差支路以及底层的梯度范数通常比较大,这也间接表明底层网络在整个优化的过程中需要更大的更新。考虑到这个因素,在设计每一个子层被丢弃的概率时可以采用自底向上线性增大的策略,保证底层的网络相比于顶层更容易保留下来。
%----------------------------------------------------------------------------------------
% NEW SECTION
%----------------------------------------------------------------------------------------
\section{基于结构搜索的翻译模型优化}
%----------------------------------------------------------------------------------------
% 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-14}(a) 给出传统人工设计的Transformer模型编码器中若干层的结构,图\ref{fig:15-14}(b) 给出该结构经过进化算法优化后的编码器中相应的结构\upcite{DBLP:conf/icml/SoLL19}。可以看到,网络结构搜索系统得到的模型中,出现了与传统人工设计的Transformer结构不同的跨层连接,同时还搜索到了全新的多分支网络结构,而这种结构是人工不易设计出来的。
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.1]{./Chapter15/Figures/figure-encoder-structure-of-transformer-model-optimized-by-nas.jpg}
\caption{传统Transformer以及通过网络结构搜索方法优化后的Transformer模型编码器结构}
\label{fig:15-14}
\end{figure}
%-------------------------------------------
\parinterval 那么网络结构搜索究竟是一种什么样的技术呢?实际上,人类一直希望能够更加自动化地、更加快速地解决自己所遇到的问题。而机器学习也是为了达到这个目的所产生的技术。如图\ref{fig:15-15}所示,机器学习方法可以看做是一个黑盒模型,这个模型能够根据人类所提供输入自动给出所期望的输出,这里的输入和输出既可以是图像信息,也可以是自然语言领域中的文字。在传统机器学习方法中,研究者需要设计大量的特征来描述待解决的问题,即“特征工程”。在深度学习时代,神经网络模型可以进行特征的抽取和学习,但是随之而来的是需要人工设计神经网络结构,这项工作仍然十分繁重。因此一些科研人员开始思考,能否将模型结构设计的工作也交由机器自动完成?深度学习方法中模型参数能够通过梯度下降等方式进行自动优化,那么模型结构是否可以也看做是一种特殊的模型参数,使用搜索算法自动地根据不同任务的数据自动找到最适用于当前任务的模型结构?
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.6]{./Chapter15/Figures/figure-evolution-and-change-of-ml-methods.jpg}
\caption{机器学习方法的演化与变迁}
\label{fig:15-15}
\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 虽然目前网络结构搜索的技术尚且处于相对初级的阶段,不过在近些年该方向已经在很多任务中崭露头角。例如,在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
%----------------------------------------------------------------------------------------
\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}$的过程,如下所示:
\begin{equation}
\hat{a} = \arg\max_{a}\sum_{i=1}^{n}{\funp{P}(\mathbi{y}_{i}|\mathbi{x}_{i};a)}
\label{eq:15-29}
\end{equation}
\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{equation}
a = \funp{P}(\cdot|\mathbi{x};a)
\label{eq:15-30}
\end{equation}
\noindent 其中,$\funp{P}(\cdot|\mathbi{x};a)$表示在所有译文句子上的一个分布。图\ref{fig:15-16}展示了神经网络结构搜索方法的主要流程,主要包括三个部分:
\begin{itemize}
\vspace{0.5em}
\item 设计搜索空间:理论上来说网络结构搜索应在所有潜在的模型结构所组成的空间中进行搜索(图\ref{fig:15-16})。在这种情况下如果不对候选模型结构进行限制的话,搜索空间会十分巨大。因此,在实际的结构搜索过程中往往会针对特定任务设计一个搜索空间,这个搜索空间是全体结构空间的一个子集,之后的搜索过程将在这个子空间中进行。如图\ref{fig:15-16}例子中的搜索空间所示,该空间由循环神经网络构成,其中候选的模型包括人工设计的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}
\vspace{0.5em}
\item 进行性能评估:在搜索到模型结构之后需要对这种模型结构的性能进行验证,确定当前时刻找到的模型结构性能优劣。但是对于结构搜索任务来说,在搜索的过程中将产生大量中间模型结构,如果直接对所有可能的结构进行评价,其时间代价是难以接受的。因此在结构搜索任务中也有很多研究人员尝试如何快速获取模型性能(绝对性能或相对性能)\upcite{DBLP:conf/nips/LuoTQCL18,DBLP:journals/jmlr/LiJDRT17,DBLP:conf/eccv/LiuZNSHLFYHM18}
\vspace{0.5em}
\end{itemize}
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.22]{./Chapter15/Figures/figure-main-flow-of-neural-network-structure-search.png}
\caption{神经网络结构搜索的主要流程}
\label{fig:15-16}
\end{figure}
%-------------------------------------------
\parinterval 下面将对网络结构搜索任务中搜索空间、搜索策略以及性能评估几个方向进行简单介绍。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{1. 搜索空间}
\parinterval 对搜索空间建模是结构搜索任务中非常基础的一部分。如图\ref{fig:15-17}所示,结构空间中包含着所有潜在的模型结构,虽然可以假设这些模型结构都是等概率出现的,不过当众多模型结构面对同一个任务的时候,模型本身就具有了不同的性能表现。例如,卷积神经网络非常适合处理图像数据,而类似Transformer这类的模型结构在自然语言处理领域中可能更具优势。此外,由于不同网络结构之间往往存在局部结构上的复用,因此在结构空间中不同结构之间存在着距离上的远近,如图\ref{fig:15-17}中基于自注意力机制的模型结构往往聚在一起,而基于循环神经网络和基于卷积神经网络的各类模型之间的距离也相对较近。因此,在设计搜索空间的时候,很重要的一点在于,根据经验或者实验确定对当前任务而言更容易产出高性能模型结构的区域,将这个区域作为结构搜索任务中的搜索空间则更有可能找到最优结构。以自然语言处理任务为例,最初的网络结构搜索工作主要对由循环神经网络构成的搜索空间进行探索\upcite{DBLP:conf/iclr/ZophL17,DBLP:conf/icml/PhamGZLD18,DBLP:conf/iclr/LiuSY19},而近些年针对Transformer模型结构的研究工作也越来越多地引起研究人员的关注\upcite{DBLP:conf/icml/SoLL19,DBLP:journals/taslp/FanTXQLL20,DBLP:conf/ijcai/ChenLQWLDDHLZ20,DBLP:conf/acl/WangWLCZGH20}
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.6]{./Chapter15/Figures/figure-relationship-between-structures-in-structural-space.jpg}
\caption{结构空间内结构之间的关系}
\label{fig:15-17}
\end{figure}
%-------------------------------------------
\parinterval 在设计搜索空间的时候很重要的一个问题在于如何表示一个网络结构。在目前的结构搜索方法中,通常将模型结构分为整体框架和内部结构(元结构)两部分。整个模型结构由整体框架将若干内部结构的输出按照特定的方式组织起来,得到最终的模型输出。如图\ref{fig:15-18}所示,以循环神经网络模型结构为例,黄色部分即为内部结构,红色部分为整体框架,负责对循环单元进行组织。
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.3]{./Chapter15/Figures/figure-whole-structure-and-internal-structure-in-rnn.png}
\caption{循环神经网络模型中的整体结构和内部结构}
\label{fig:15-18}
\end{figure}
%-------------------------------------------
\parinterval 具体来说,内部结构负责的是如何计算出循环神经网络计算过程中$t$时刻的循环单元输出$\mathbi{h}_t$,如下所示:
\begin{equation}
\mathbi{h}_t = \pi(\hat{\mathbi{h}}_{t-1},\hat{\mathbi{x}_t})
\label{eq:15-31}
\end{equation}
\parinterval 其中函数$\pi(\cdot)$即为结构表示中的内部结构,而对于循环单元之间的组织方式(即整体框架)则决定了循环单元的输入信息,也就是上式中的循环单元表示$\hat{\mathbi{h}}_{t-1}$和输入表示$\hat{\mathbi{x}}_{t}$。理论上二者均能获得对应时刻之前所有可以获得的表示信息,因此可表示为:
\begin{eqnarray} \begin{eqnarray}
M = \left\{\begin{array}{ll} \hat{\mathbi{h}}_{t-1} &=& f(\mathbi{h}_{[0,t-1]};\mathbi{x}_{[1,t-1]}) \\
0&P \leqslant p_l\\ \hat{\mathbi{x}_t} &=& g(\mathbi{x}_{[1,t]};\mathbi{h}_{[0,t-1]})
1&P > p_l \label{eq:15-33}
\end{array}\right.
\label{eq:15-11}
\end{eqnarray} \end{eqnarray}
其中,$P$是服从伯努利分布的随机变量,$p_l$指每一个子层被丢弃的概率,具体计算方式如下:
\noindent 其中$\mathbi{h}_{[0,t-1]} = \{\mathbi{h}_0,\ldots,\mathbi{h}_{t-1}\}$$\mathbi{x}_{[1,t-1]} = \{\mathbi{x}_1,\ldots,\mathbi{x}_{t-1}\}$,函数$f(\cdot)$$g(\cdot)$即为循环神经网络模型中的整体框架。
\parinterval 可以看到,整体框架和内部结构共同组成了神经网络的模型结构,换句话说确定了在搜索过程中整体框架以及内部结构包括哪些模型也就确定了搜索空间。
\begin{itemize}
\vspace{0.5em}
\item 整体框架:如图\ref{fig:15-17}所示,不同任务下不同结构往往会表现出不同的建模能力,而类似的结构在结构空间中又相对集中,因此在搜索空间的设计中,整体框架部分一般根据不同任务特点选择已经得到验证的经验性结构,通过这种方式能够快速定位到更有潜力的搜索空间。如对于图像任务来说,一般会将卷积神经网络设计为候选搜索空间\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}。不过,对于搜索颗粒度的问题,目前还缺乏有效的方法针对不同任务进行自动优化。
\vspace{0.5em}
\end{itemize}
\parinterval 实际上,使用“整体+局部”的两层搜索空间表示模型的原因在于:问题过于复杂,无法有效的遍历原始的搜索空间。如果存在足够高效的搜索策略,搜索空间的表示也可能会发生变化,比如,直接对任意的网络结构使用统一的表示方式。理论上讲,这样的搜索空间可以涵盖更多的潜在模型结构。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{2. 搜索策略}
\parinterval 在定义好搜索空间之后,如何进行网络结构的搜索也同样重要。该过程被称为搜索策略的设计,其主要目的为根据已找到的模型结构计算出下一个最有潜力的模型结构,为保证模型有效性,在一些方法中也会引入外部知识(如经验性的模型结构或张量运算规则)对搜索过程中的结构进行剪枝。目前常见的搜索策略一般包括基于进化算法、强化学习、贝叶斯优化、梯度的方法的方式,不同的搜索策略一般也和搜索空间中结构建模方式相关。
\begin{itemize}
\vspace{0.5em}
\item 进化算法{\red 检查这些词是不是第一次提到}:最初主要通过进化算法对神经网络中的模型结构以及权重参数进行优化\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}。目前主流的方式主要是将模型结构看做是遗传算法中种群的个体,通过使用轮盘赌或锦标赛等抽取方式对种群中的结构进行取样作为亲本,之后通过亲本模型的突变产生新的模型结构,最终对这些新的模型结构进行适应度评估{\red (见XXX节)},根据模型结构在校验集上性能表现确定是否能够将其加入种群,整个过程如图\ref{fig:15-19}所示。对于进化算法中结构的突变主要指的是对模型中局部结构的改变,如增加跨层连接、替换局部操作等。
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.25]{./Chapter15/Figures/figure-structure-search-based-on-evolutionary-algorithm.png}
\caption{基于进化算法的结构搜索}
\label{fig:15-19}
\end{figure}
%-------------------------------------------
\vspace{0.5em}
\item 强化学习:除了使用进化算法对网络结构进行学习之外,近些年随着强化学习在各领域中的广泛应用,研究人员也逐渐开始将这种方法引入到神经网络的结构学习中来。例如,研究人员将网络结构的设计看做是序列生成任务,使用字符序列对网络结构进行表述,通过由强化学习指导训练出的循环神经网络对该模型结构序列(目标任务网络结构)进行预测,从而为目标任务生成提供高效的网络结构\upcite{DBLP:conf/iclr/ZophL17}。基于强化学习的结构搜索方法过程如图\ref{fig:15-20}所示,其中主体可以看做是一个模型结构的生成模型,用于产生当前状态下从主体角度上看最适用于当前任务的模型结构,强化学习中的动作在这里指的是由主体{\red (强化学习里经常用Agent,是这里的主体吗???Agent一般被翻译为智能体)}产生一个模型结构,而环境对应着模型将要应用在的任务,当环境得到了模型结构后,环境将输出当前任务下该模型的输出以及对输出结果的评价,二者分别对应强化学习中的状态和奖励,这两个信息将反馈给主体,让结构生成器对该状态下生成的模型结果有一个清晰的了解,从而对自身结构生成的模式进行调整,然后继续生成更优的模型结构。对于基于强化学习的结构搜索策略来说,不同研究工作的差异主要集中在如何表示生成网络的过程以及如何对结构生成器进行优化\upcite{DBLP:conf/iclr/ZophL17,DBLP:conf/cvpr/ZophVSL18,DBLP:conf/iclr/BakerGNR17,DBLP:conf/cvpr/ZhongYWSL18}
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.25]{./Chapter15/Figures/figure-structure-search-based-on-reinforcement-learning.png}
\caption{基于强化学习的结构搜索}
\label{fig:15-20}
\end{figure}
%-------------------------------------------
\vspace{0.5em}
\item 梯度方法:在基于进化算法和强化学习的结构搜索策略中,往往将模型结构看作是离散空间中的若干点,搜索策略通过诸如“进化”或“激励”等方式促进种群或者结构生成器产生更适用于对应任务的模型结构,这种方式相对而言并未直接对模型结构进行优化。不同于这些方法,有研究人员尝试在连续空间中对模型结构进行表示\upcite{DBLP:conf/iclr/LiuSY19},这种方式将模型结构建模为超网络中的权重,通过使用基于梯度的最优化方法对权重进行优化最终达到搜索结构的目的,如图\ref{fig:15-21}所示。这种方式相对进化算法以及强化学习方法而言更加直接,在搜索过程中的算力消耗以及时间消耗上也更有优势,因此也吸引了很多研究人员对基于梯度的结构搜索策略进行不断探索\upcite{DBLP:conf/cvpr/WuDZWSWTVJK19,DBLP:conf/iclr/XuX0CQ0X20,DBLP:conf/acl/LiHZXJXZLL20,DBLP:conf/emnlp/JiangHXZZ19}
\vspace{0.5em}
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.25]{./Chapter15/Figures/figure-structure-search-based-on-gradient-method.png}
\caption{基于梯度方法的结构搜索}
\label{fig:15-21}
\end{figure}
%-------------------------------------------
\end{itemize}
\parinterval 除了上述提到的基于进化算法、强化学习以及梯度的方法之外,结构搜索策略还有很多其他的方式,例如基于贝叶斯优化的方法、基于随机搜索的方法。贝叶斯优化的方法在搜索结构超参数的任务中表现优异,能够在给定模型结构基础上找到最适用于当前任务的超参数\upcite{DBLP:conf/icml/BergstraYC13,DBLP:conf/ijcai/DomhanSH15,DBLP:conf/icml/MendozaKFSH16,DBLP:journals/corr/abs-1807-06906},而随机搜索的方法也在一些结构搜索任务中引起众多研究人员的注意\upcite{DBLP:conf/uai/LiT19,li2020automated,DBLP:conf/cvpr/BenderLCCCKL20}
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{3. 性能评估}
\parinterval 在结构搜索的过程中会产生大量中间结构,因此如何快速获得这些结构的性能优劣也是网络结构搜索任务中的关键一环。通常有三类方法进行模型性能的快速评估。
\begin{itemize}
\vspace{0.5em}
\item 数据以及超参数的调整:一种常见的方法是从数据和超参数的角度简化模型训练难度。具体来说,可采取的策略包括使用更少量、更容易建模的数据作为训练集合\upcite{DBLP:conf/aistats/KleinFBHH17,DBLP:journals/corr/ChrabaszczLH17},如图像任务中使用低分辨率数据对模型进行训练及评估,在自然语言处理任务中也可以选择更容易建模的口语领域数据进行实验。在超参数的方面也可以通过减少模型训练轮数、减少模型的层数、减少每层中神经元数量等方式来简化模型参数,达到加速训练、评估的目的\upcite{DBLP:conf/cvpr/ZophVSL18,Real2019AgingEF,DBLP:journals/corr/abs-1807-06906}。上述两种方法虽然并不能准确地对模型绝对性能进行评价,但是其结果已经能够对搜索起到一定指示作用,并帮助结构搜索策略对结构生成的过程进行调优。
\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}
\vspace{0.5em}
\end{itemize}
%----------------------------------------------------------------------------------------
% NEW SUB-SECTION
%----------------------------------------------------------------------------------------
\subsection{机器翻译任务下的结构搜索}
\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
%----------------------------------------------------------------------------------------
\subsubsection{1. 模型性能改进}
\parinterval 结构搜索任务中一个非常重要的目标在于找到更加适用于当前任务的模型结构。目前来看,有两种思路:1)对模型中局部结构的搜索;2)对局部结构组合方式的优化。
\begin{itemize}
\vspace{0.5em}
\item 搜索模型中的局部结构:在机器翻译任务中,一种典型的局部模型结构搜索方法是面向激活函数的搜索\upcite{DBLP:conf/iclr/RamachandranZL18}。该方法将激活函数看作是简单函数的若干次复合使用,图\ref{fig:15-22}是激活函数结构的一个示例,其中核心单元由两个输入、两个一元函数(如绝对值、幂方运算等)和一个二元函数(如乘法、取最大值运算等)组成。
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.5]{./Chapter15/Figures/figure-activation-function-swish-structure-diagram.png}
\caption{激活函数结构图}
\label{fig:15-22}
\end{figure}
%-------------------------------------------
\noindent 还有方法将为深层神经网络找到更适合的激活函数作为搜索的目标\upcite{DBLP:conf/iclr/RamachandranZL18},通过基于强化学习的搜索策略对激活函数空间进行探索,找到了若干新的激活函数,之后通过对这些激活函数在包括图像分类、机器翻译等任务上进行实验,确定了Swish激活函数在深层神经网络上的有效性,函数公式如下式所示,函数曲线如图\ref{fig:15-23}所示。{\red 下面公式中x的形式}
\begin{eqnarray} \begin{eqnarray}
p_l=\frac{l}{2L}\cdot \varphi f(x) &=& x \cdot \delta(\beta x) \\
\label{eq:15-12} \delta(z) &=& {(1 + \exp{(-z)})}^{-1}
\label{eq:15-35}
\end{eqnarray} \end{eqnarray}
这里,$1 \leqslant l \leqslant 2L$ ,且$\varphi$是预先设定的超参数。
\parinterval 在Layer Dropout中,一个由$2L$个子层构成的残差网络,其顶层的输出相当于是$2^{2L}$个子网络的聚合结果。通过随机丢弃$n$个子层,则会屏蔽掉$2^n$个子网络的输出,将子网络的总体数量降低至$2^{2L-n}$。如图\ref{fig:15-8}所示的残差网络展开图,当有3个子层时,从输入到输出共存在8条路径,当删除子层sublayer2后,从输入到输出路径的路径则会减少到4条。 %----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.5]{./Chapter15/Figures/figure-swish-function-image.png}
\caption{Swish函数图像}
\label{fig:15-23}
\end{figure}
%-------------------------------------------
\noindent Swish函数相比传统人工设计的ReLU而言在多个机器翻译的测试集上具有更优的性能表现,同时不要求对原本模型结构进行更多修改,非常容易实现。
\vspace{0.5em}
\item 搜索模型中局部结构的组合:在基于Transformer模型的网络结构搜索任务中,对于局部结构的组合方式的学习也受到了很多关注,其中包括基于进化算法的方法以及基于梯度对现有Transformer模型结构进行改良的方式\upcite{DBLP:conf/icml/SoLL19,DBLP:journals/taslp/FanTXQLL20}。这类方法不同于前文所述的对局部结构的改良,更多地是希望利用现有经验性的局部结构进行组合,找到最佳的整体结构。在模型结构的表示方法上,这些方法会根据先验知识为搜索单元设定一个部分框架,如每当信息传递过来之后先进行层标准化,之后再对候选位置上的操作使用对应的搜索策略进行搜索。另外这类方法也会在Transformer结构中引入多分支的支持,一个搜索单元的输出可以被多个后续单元所使用,通过这种方式有效扩大了结构搜索过程中的搜索空间,能够在现有Transformer结构基础上找到更优的模型结构。对模型中结构组合方式的学习如图\ref{fig:15-24}所示。
%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.25]{./Chapter15/Figures/figure-learning-of-local-structure-combination.png}
\caption{局部结构组合方式的学习}
\label{fig:15-24}
\end{figure}
%-------------------------------------------
\vspace{0.5em}
\end{itemize}
\parinterval 此外对于模型结构中超参数的自动搜索同样能够有效提升模型的性能表现\upcite{DBLP:journals/corr/abs-2009-02070}。Transformer模型虽然已经在机器翻译任务中获得了非常优异的性能,不过如果希望稳定训练该模型还需要很多超参数上经验的累积,与此同时,不同翻译任务在使用Transformer模型的时候,也需要对超参数以及局部结构进行相应的调整(如层标准化的位置,注意力操作的过程中是否进行缩放,注意力操作的头数,激活函数等),因此面向超参数的搜索同样能够帮助研究人员快速找到最适用的模型结构。
%----------------------------------------------------------------------------------------
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{2. 模型效率优化}
\parinterval 网络结构搜索的方法除了能够应用于对机器翻译模型性能进行改进之外,也能够用来对模型执行效率进行优化。从实用的角度出发,一些研究人员尝试将设备的计算能力提供给结构搜索方法进行参考,希望能够找到适合于对应设备算力的模型结构。同时也有一些研究人员专注于对大规模的模型进行压缩,加速其在推断过程中的效率,这方面的工作不仅限于在机器翻译模型上,也有部分工作对基于注意力机制的预训练模型进行压缩。
\begin{itemize}
\vspace{0.5em}
\item 面向特定设备的模型结构优化:随着终端设备算力的日益增强,在小设备上直接进行机器翻译的需求也日益增大,简单地对Transformer模型的超参数进行削减能够让翻译模型在这些低算力的设备上运行,不过研究人员仍然希望得到更适用于当前设备的翻译模型。因此一些研究人员开始尝试使用结构搜索的方式对现有Transformer模型进行改良,在结构优化的过程中将设备上的算力条件作为一个约束,为不同硬件设备(如CPU、GPU等设备)发现更加有效的结构\upcite{DBLP:conf/acl/WangWLCZGH20}。例如可以将搜索空间中各种基于Transformer结构的变体建模在同一个超网络中,通过权重共享的方式进行训练。使用硬件算力约束训练得到的子模型,通过进化算法对子模型进行搜索,搜索到适用于目标硬件的模型结构,整个过程如图\ref{fig:15-25}所示。通过该方法搜索到的模型能够在保证机器翻译模型性能的前提下获得较大的效率提升。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter15/Figures/figure-expanded-residual-network} \input{./Chapter15/Figures/figure-model-structure-optimization-framework-for-specific-equipment.tex}
\caption{Layer Dropout中残差网络的展开图} \caption{面向特定设备的模型结构优化框架}
\label{fig:15-8} \label{fig:15-25}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\vspace{0.5em}
\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},然后将搜索到的模型结构应用到更多其他自然语言处理的任务中,这种方式有效提升了模型结构的可复用性,同时从大规模单语数据中获取到的信息可能比从特定任务下受限的数据集合中所得到的信息更加充分,能够更好地指导模型结构的设计。对于机器翻译任务而言,结构的预搜索同样是一个值得关注的研究方向。
...@@ -138,7 +138,7 @@ ...@@ -138,7 +138,7 @@
\node [anchor=south,inner sep=2pt,minimum height=1.5em,minimum width=3.0em] (c10) at (c11.north) {\scriptsize{源语言}}; \node [anchor=south,inner sep=2pt,minimum height=1.5em,minimum width=3.0em] (c10) at (c11.north) {\scriptsize{源语言}};
\node [anchor=south,inner sep=2pt,minimum height=1.5em,minimum width=3.0em] (c30) at (c31.north) {\small{$n$=3}}; \node [anchor=south,inner sep=2pt,minimum height=1.5em,minimum width=3.0em] (c30) at (c31.north) {\small{$n$=3}};
\node [anchor=south,inner sep=2pt,minimum height=1.5em,minimum width=3.0em] (c50) at (c51.north) {\small{$\mathbi{S}$}}; \node [anchor=south,inner sep=2pt,minimum height=1.5em,minimum width=3.0em] (c50) at (c51.north) {\small{$\seq{S}$}};
\node [anchor=south,inner sep=2pt] (c60) at (c61.north) {\scriptsize{进行排序}}; \node [anchor=south,inner sep=2pt] (c60) at (c61.north) {\scriptsize{进行排序}};
\node [anchor=south,inner sep=2pt] (c60-2) at (c60.north) {\scriptsize{由小到大}}; \node [anchor=south,inner sep=2pt] (c60-2) at (c60.north) {\scriptsize{由小到大}};
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
% NEW SECTION % NEW SECTION
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\section{数据的有效使用} \section{数据的有效使用}\label{effective-use-of-data}
\parinterval 数据稀缺是低资源机器翻译所面临的主要问题。因此,充分使用既有数据是一种解决问题的思路。比如,在双语训练不充分的时候,可以简单地对双语数据的部分单词用近义词进行替换,达到丰富双语数据的目的\upcite{DBLP:conf/acl/FadaeeBM17a,DBLP:conf/emnlp/WangPDN18},也可以考虑用转述等方式生成更多的双语训练数据\upcite{DBLP:conf/emnlp/MartonCR09,DBLP:conf/eacl/LapataSM17} \parinterval 数据稀缺是低资源机器翻译所面临的主要问题。因此,充分使用既有数据是一种解决问题的思路。比如,在双语训练不充分的时候,可以简单地对双语数据的部分单词用近义词进行替换,达到丰富双语数据的目的\upcite{DBLP:conf/acl/FadaeeBM17a,DBLP:conf/emnlp/WangPDN18},也可以考虑用转述等方式生成更多的双语训练数据\upcite{DBLP:conf/emnlp/MartonCR09,DBLP:conf/eacl/LapataSM17}
...@@ -97,7 +97,7 @@ ...@@ -97,7 +97,7 @@
\vspace{0.5em} \vspace{0.5em}
\end{itemize} \end{itemize}
\parinterval\ref{fig:16-4-xc}展示了三种加噪方法的示例。这里,$\funp{P}_{\rm{Drop}}$$\funp{P}_{\rm{Mask}}$均设置为0.1,表示每个词有$10\%$的概率被丢弃或掩码。打乱顺序的操作略微复杂,一种实现方法是,通过一个数字来表示每个词在句子中的位置,如“我”是第一个词,“你”是第三个词,然后,在每个位置生成一个$1$$n$的随机数,$n$一般设置为3,然后将每个词的位置数和对应的随机数相加,即图中的$\mathbi{S}${\color{blue} S为啥要加粗???})。 对$\mathbi{S}$ 按照从小到大排序,根据排序后每个位置的索引从原始句子中选择对应的词,从而得到最终打乱顺序后的结果。比如,在排序后,$S_2$的值小于$S_1$,其余词则保持递增顺序,则将原始句子中的第零个词和第一个词的顺序进行交换,其他词保持不变。 \parinterval\ref{fig:16-4-xc}展示了三种加噪方法的示例。这里,$\funp{P}_{\rm{Drop}}$$\funp{P}_{\rm{Mask}}$均设置为0.1,表示每个词有$10\%$的概率被丢弃或掩码。打乱顺序的操作略微复杂,一种实现方法是,通过一个数字来表示每个词在句子中的位置,如“我”是第一个词,“你”是第三个词,然后,在每个位置生成一个$1$$n$的随机数,$n$一般设置为3,然后将每个词的位置数和对应的随机数相加,即图中的$\seq{S}${\color{blue} S为啥要加粗???})。 对$\seq{S}$ 按照从小到大排序,根据排序后每个位置的索引从原始句子中选择对应的词,从而得到最终打乱顺序后的结果。比如,在排序后,$S_2$的值小于$S_1$,其余词则保持递增顺序,则将原始句子中的第零个词和第一个词的顺序进行交换,其他词保持不变。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -170,7 +170,7 @@ ...@@ -170,7 +170,7 @@
\parinterval 融合目标语言端的语言模型是一种最直接的使用单语数据的方法\upcite{2015OnGulcehre,DBLP:journals/csl/GulcehreFXCB17,DBLP:conf/wmt/StahlbergCS18}。实际上,神经机器翻译模型本身也具备了语言模型的作用,因为在解码器本质上也是一个语言模型,用于描述生成译文词串的规律。类似于语言模型,神经机器翻译模型可以自回归地生成翻译结果。对于一个双语句对$(\mathbi{x}, \mathbi{y})$,神经机器翻译模型根据源语言句子$\mathbi{x}$和前面生成的词来预测当前位置词的概率分布: \parinterval 融合目标语言端的语言模型是一种最直接的使用单语数据的方法\upcite{2015OnGulcehre,DBLP:journals/csl/GulcehreFXCB17,DBLP:conf/wmt/StahlbergCS18}。实际上,神经机器翻译模型本身也具备了语言模型的作用,因为在解码器本质上也是一个语言模型,用于描述生成译文词串的规律。类似于语言模型,神经机器翻译模型可以自回归地生成翻译结果。对于一个双语句对$(\mathbi{x}, \mathbi{y})$,神经机器翻译模型根据源语言句子$\mathbi{x}$和前面生成的词来预测当前位置词的概率分布:
\begin{eqnarray} \begin{eqnarray}
\log{P(\mathbi{y} | \mathbi{x}; \theta)} = \sum_{t}{\log{P(y_t | \mathbi{x}, {\mathbi{y}}_{<t}; \theta)}} \log{P(\mathbi{y} | \mathbi{x}; \theta)} & = & \sum_{t}{\log{P(y_t | \mathbi{x}, {\mathbi{y}}_{<t}; \theta)}}
\label{eq:16-1-xc} \label{eq:16-1-xc}
\end{eqnarray} \end{eqnarray}
...@@ -187,7 +187,7 @@ ...@@ -187,7 +187,7 @@
\parinterval 浅融合通过对神经机器翻译模型和语言模型的预测概率进行插值来得到最终的预测概率: \parinterval 浅融合通过对神经机器翻译模型和语言模型的预测概率进行插值来得到最终的预测概率:
\begin{eqnarray} \begin{eqnarray}
\log{\funp{P}(y_t | \mathbi{x}, \mathbi{y}_{<t})} = \log{\funp{P}(y_t | \mathbi{x}, \mathbi{y}_{<t}; \theta_{TM})} + \beta \log{\funp{P}(y_t | \mathbi{y}_{<t}; \theta_{LM})} \log{\funp{P}(y_t | \mathbi{x}, \mathbi{y}_{<t})}& = & \log{\funp{P}(y_t | \mathbi{x}, \mathbi{y}_{<t}; \theta_{TM})} + \beta \log{\funp{P}(y_t | \mathbi{y}_{<t}; \theta_{LM})}
\label{eq:16-2-xc} \label{eq:16-2-xc}
\end{eqnarray} \end{eqnarray}
...@@ -197,19 +197,19 @@ ...@@ -197,19 +197,19 @@
\parinterval 深融合的预测方式为: \parinterval 深融合的预测方式为:
\begin{eqnarray} \begin{eqnarray}
\log{\funp{P}(y_t | \mathbi{x}, \mathbi{y}_{<t})}= \log{\funp{P}(y_t | \mathbi{x}, \mathbi{y}_{<t}; s_{t})} \log{\funp{P}(y_t | \mathbi{x}, \mathbi{y}_{<t})}& = & \log{\funp{P}(y_t | \mathbi{x}, \mathbi{y}_{<t}; s_{t})}
\label{eq:16-3-xc} \label{eq:16-3-xc}
\end{eqnarray} \end{eqnarray}
\noindent 其中,$s_{t}$表示当前时刻$t$的隐藏层表示。 \noindent 其中,$s_{t}$表示当前时刻$t$的隐藏层表示。
\begin{eqnarray} \begin{eqnarray}
s_{t} = s_{t}^{TM} + g_{t} s_{t}^{LM} s_{t}& = & s_{t}^{TM} + g_{t} s_{t}^{LM}
\label{eq:16-4-xc} \label{eq:16-4-xc}
\end{eqnarray} \end{eqnarray}
\parinterval 这里,$s_{t}^{TM}$$s_{t}^{LM}$分别表示翻译模型和语言模型在时刻$t$的隐藏层表示,$g_{t}$用来控制语言模型隐藏层表示的权重,通过下面的计算得到: \parinterval 这里,$s_{t}^{TM}$$s_{t}^{LM}$分别表示翻译模型和语言模型在时刻$t$的隐藏层表示,$g_{t}$用来控制语言模型隐藏层表示的权重,通过下面的计算得到:
\begin{eqnarray} \begin{eqnarray}
g_{t} = \sigma (w^{T}s_{t}^{TM} + b) g_{t}& = & \sigma (w^{T}s_{t}^{TM} + b)
\label{eq:16-5-xc} \label{eq:16-5-xc}
\end{eqnarray} \end{eqnarray}
...@@ -314,7 +314,7 @@ g_{t} = \sigma (w^{T}s_{t}^{TM} + b) ...@@ -314,7 +314,7 @@ g_{t} = \sigma (w^{T}s_{t}^{TM} + b)
\parinterval 回顾神经机器翻译系统的建模过程,给定一个互译的句对$(\mathbi{x},\mathbi{y})$,一个从源语言句子$\mathbi{x}$到目标语言句子$\mathbi{y}$的翻译被表示为求条件概率$\funp{P}(\mathbi{y}|\mathbi{x})$的问题。类似地,一个从目标语言句子$\mathbi{y}$到源语言句子$\mathbi{x}$的翻译可以表示为$\funp{P}(\mathbi{x}|\mathbi{y})$。通常来说,神经机器翻译的训练一次只得到一个方向的模型,也就是$\funp{P}(\mathbi{y}|\mathbi{x})$或者$\funp{P}(\mathbi{x}|\mathbi{y})$。这意味着$\funp{P}(\mathbi{y}|\mathbi{x})$$\funp{P}(\mathbi{x}|\mathbi{y})$之间是互相独立的。$\funp{P}(\mathbi{y}|\mathbi{x})$$\funp{P}(\mathbi{x}|\mathbi{y})$是否真的没有关系呢?比如,$\mathbi{x}$$\mathbi{y}$是相同大小的向量,且$\mathbi{x}$$\mathbi{y}$的变换是一个线性变换,也就是与一个方阵$\mathbi{W}$做矩阵乘法: \parinterval 回顾神经机器翻译系统的建模过程,给定一个互译的句对$(\mathbi{x},\mathbi{y})$,一个从源语言句子$\mathbi{x}$到目标语言句子$\mathbi{y}$的翻译被表示为求条件概率$\funp{P}(\mathbi{y}|\mathbi{x})$的问题。类似地,一个从目标语言句子$\mathbi{y}$到源语言句子$\mathbi{x}$的翻译可以表示为$\funp{P}(\mathbi{x}|\mathbi{y})$。通常来说,神经机器翻译的训练一次只得到一个方向的模型,也就是$\funp{P}(\mathbi{y}|\mathbi{x})$或者$\funp{P}(\mathbi{x}|\mathbi{y})$。这意味着$\funp{P}(\mathbi{y}|\mathbi{x})$$\funp{P}(\mathbi{x}|\mathbi{y})$之间是互相独立的。$\funp{P}(\mathbi{y}|\mathbi{x})$$\funp{P}(\mathbi{x}|\mathbi{y})$是否真的没有关系呢?比如,$\mathbi{x}$$\mathbi{y}$是相同大小的向量,且$\mathbi{x}$$\mathbi{y}$的变换是一个线性变换,也就是与一个方阵$\mathbi{W}$做矩阵乘法:
\begin{eqnarray} \begin{eqnarray}
\mathbi{y} = \mathbi{x} \cdot \mathbi{W} \mathbi{y} & = & \mathbi{x} \cdot \mathbi{W}
\label{eq:16-6-xc} \label{eq:16-6-xc}
\end{eqnarray} \end{eqnarray}
...@@ -347,7 +347,7 @@ Joint training for neural machine translation models with monolingual data ...@@ -347,7 +347,7 @@ Joint training for neural machine translation models with monolingual data
\parinterval 公式\ref{eq:16-7-xc}很自然地把两个方向的翻译模型$\funp{P}(\mathbi{y}|\mathbi{x})$$\funp{P}(\mathbi{x}|\mathbi{y})$以及两个语言模型$\funp{P}(\mathbi{x})$$\funp{P}(\mathbi{y})$联系起来:$\funp{P}(\mathbi{x})\funp{P}(\mathbi{y}|\mathbi{x})$应该与$\funp{P}(\mathbi{y})\funp{P}(\mathbi{x}|\mathbi{y})$接近,因为它们都表达了同一个联合分布$\funp{P}(\mathbi{x},\mathbi{y})$。因此,在构建训练两个方向的翻译模型的目标函数时,除了它们单独训练时各自使用的极大似然估计目标函数,可以额外增加一个目标项来鼓励两个方向的翻译模型。这种方法也被看做是一种{\small\bfnew{有监督对偶学习}}\index{有监督对偶学习}(Supervised Dual Learning\index{Supervised Dual Learning}): \parinterval 公式\ref{eq:16-7-xc}很自然地把两个方向的翻译模型$\funp{P}(\mathbi{y}|\mathbi{x})$$\funp{P}(\mathbi{x}|\mathbi{y})$以及两个语言模型$\funp{P}(\mathbi{x})$$\funp{P}(\mathbi{y})$联系起来:$\funp{P}(\mathbi{x})\funp{P}(\mathbi{y}|\mathbi{x})$应该与$\funp{P}(\mathbi{y})\funp{P}(\mathbi{x}|\mathbi{y})$接近,因为它们都表达了同一个联合分布$\funp{P}(\mathbi{x},\mathbi{y})$。因此,在构建训练两个方向的翻译模型的目标函数时,除了它们单独训练时各自使用的极大似然估计目标函数,可以额外增加一个目标项来鼓励两个方向的翻译模型。这种方法也被看做是一种{\small\bfnew{有监督对偶学习}}\index{有监督对偶学习}(Supervised Dual Learning\index{Supervised Dual Learning}):
\begin{eqnarray} \begin{eqnarray}
\mathcal{L} = (\textrm{log P}(\mathbi{x}) + \textrm{log P}(\mathbi{y}|\mathbi{x}) - \textrm{log P}(\mathbi{y}) - \textrm{log P}(\mathbi{x}|\mathbi{y}))^{2} \mathcal{L} & = & (\textrm{log P}(\mathbi{x}) + \textrm{log P}(\mathbi{y}|\mathbi{x}) - \textrm{log P}(\mathbi{y}) - \textrm{log P}(\mathbi{x}|\mathbi{y}))^{2}
\label{eq:16-8-xc} \label{eq:16-8-xc}
\end{eqnarray} \end{eqnarray}
...@@ -391,7 +391,7 @@ Joint training for neural machine translation models with monolingual data ...@@ -391,7 +391,7 @@ Joint training for neural machine translation models with monolingual data
\parinterval 重新回顾公式\ref{eq:16-9-xc}对应的目标函数,无监督对偶学习跟回译(假设现在只在一个句对$(\mathbi{x},\mathbi{y})$上做回译)之间有着很深的内在联系:给定一个句子$\mathbi{x}$,无监督对偶学习和回译都首先用$\funp{P}(\mathbi{y}|\mathbi{x})$$\mathbi{x}$翻译成$\mathbi{y}$,然后无监督对偶学习最大化$\funp{P}(\mathbi{x}|\mathbi{y})\funp{P}(\mathbi{y}|\mathbi{x})$,而回译则是最大化$\funp{P}(\mathbi{x}|\mathbi{y})$。可以看到,当无监督对偶学习假设$\funp{P}(\mathbi{y}|\mathbi{x})$是一个完美的翻译模型的时候,它与回译是等价的。此外,在共享两个方向的模型参数$\theta$的情况下,可以看到无监督对偶学习的梯度为 \parinterval 重新回顾公式\ref{eq:16-9-xc}对应的目标函数,无监督对偶学习跟回译(假设现在只在一个句对$(\mathbi{x},\mathbi{y})$上做回译)之间有着很深的内在联系:给定一个句子$\mathbi{x}$,无监督对偶学习和回译都首先用$\funp{P}(\mathbi{y}|\mathbi{x})$$\mathbi{x}$翻译成$\mathbi{y}$,然后无监督对偶学习最大化$\funp{P}(\mathbi{x}|\mathbi{y})\funp{P}(\mathbi{y}|\mathbi{x})$,而回译则是最大化$\funp{P}(\mathbi{x}|\mathbi{y})$。可以看到,当无监督对偶学习假设$\funp{P}(\mathbi{y}|\mathbi{x})$是一个完美的翻译模型的时候,它与回译是等价的。此外,在共享两个方向的模型参数$\theta$的情况下,可以看到无监督对偶学习的梯度为
\begin{equation} \begin{equation}
\frac{\partial \funp{P}(\mathbi{x})}{\partial \theta} =\funp{P}(\mathbi{y}|\mathbi{x}) \frac{\partial \funp{P}(\mathbi{x}|\mathbi{y})}{\partial \theta}+\funp{P}(\mathbi{x}|\mathbi{y}) \frac{\partial \funp{P}(\mathbi{y}|\mathbi{x})}{\partial \theta} \frac{\partial \funp{P}(\mathbi{x})}{\partial \theta} = \funp{P}(\mathbi{y}|\mathbi{x}) \frac{\partial \funp{P}(\mathbi{x}|\mathbi{y})}{\partial \theta}+\funp{P}(\mathbi{x}|\mathbi{y}) \frac{\partial \funp{P}(\mathbi{y}|\mathbi{x})}{\partial \theta}
\end{equation} \end{equation}
\noindent 而回译的梯度为$\frac{\partial \funp{P}(\mathbi{x}|\mathbi{y})}{\partial \theta}$。从这个角度出发,无监督对偶学习与回译都在优化语言模型$\funp{P}(\mathbi{x})$这个目标函数,只不过回译使用对$\theta$有偏的梯度估计。 \noindent 而回译的梯度为$\frac{\partial \funp{P}(\mathbi{x}|\mathbi{y})}{\partial \theta}$。从这个角度出发,无监督对偶学习与回译都在优化语言模型$\funp{P}(\mathbi{x})$这个目标函数,只不过回译使用对$\theta$有偏的梯度估计。
...@@ -442,7 +442,7 @@ Joint training for neural machine translation models with monolingual data ...@@ -442,7 +442,7 @@ Joint training for neural machine translation models with monolingual data
\end{figure} \end{figure}
\begin{equation} \begin{equation}
\funp{P}(\mathbi{y}|\mathbi{x}) =\sum_{\mathbi{p}}{\funp{P}(\mathbi{p}|\mathbi{x})\funp{P}(\mathbi{y}|\mathbi{p})} \funp{P}(\mathbi{y}|\mathbi{x}) = \sum_{\mathbi{p}}{\funp{P}(\mathbi{p}|\mathbi{x})\funp{P}(\mathbi{y}|\mathbi{p})}
\label{eq:ll-1} \label{eq:ll-1}
\end{equation} \end{equation}
...@@ -551,9 +551,9 @@ Joint training for neural machine translation models with monolingual data ...@@ -551,9 +551,9 @@ Joint training for neural machine translation models with monolingual data
\begin{itemize} \begin{itemize}
\vspace{0.5em} \vspace{0.5em}
\item 父模型和子模型之间的语言空间不匹配问题:父模型使用的语言跟子模型使用的语言的数据很少甚至没有(零资源)的情况下,无法通过训练弥补父模型跟子模型之间的差异,因此微调的结果很差。一种解决方案是先预训练一个多语言的模型,然后固定这个预训练模型的部分参数后训练父模型,最后从父模型中微调子模型\upcite{ji2020cross}。这样做的好处在于先用预训练提取父模型的任务和子模型的任务之间通用的信息(保存在模型参数里),然后强制在训练父模型的时候保留这些信息(通过固定参数),这样最后微调子模型的时候就可以利用这些通用信息,减少了父模型和子模型之间的差异,使得微调的结果得到提升{\red{(加参考文献)}} \item 父模型和子模型之间的语言空间不匹配问题:父模型使用的语言跟子模型使用的语言的数据很少甚至没有(零资源)的情况下,无法通过训练弥补父模型跟子模型之间的差异,因此微调的结果很差。一种解决方案是先预训练一个多语言的模型,然后固定这个预训练模型的部分参数后训练父模型,最后从父模型中微调子模型\upcite{ji2020cross}。这样做的好处在于先用预训练提取父模型的任务和子模型的任务之间通用的信息(保存在模型参数里),然后强制在训练父模型的时候保留这些信息(通过固定参数),这样最后微调子模型的时候就可以利用这些通用信息,减少了父模型和子模型之间的差异,使得微调的结果得到提升\upcite{DBLP:conf/emnlp/LinPWQFZL20}
\vspace{0.5em} \vspace{0.5em}
\item 脱靶翻译问题:多语言单模型系统经常出现脱靶翻译问题,即把源语翻译成错误的目标语言,比如要求翻译成英语,结果却是汉语或者英语夹杂其他语言的字符。这是因为多语言单模型系统对所有语言都使用一样的参数,导致每个语言竞争系统固定的建模能力。研究人员提出在原来共享参数的基础上为每种语言添加额外的独立的参数,使得每种语言拥有足够的建模能力,以便于特定语言的翻译\upcite{DBLP:conf/acl/ZhangWTS20}{\red{(加参考文献)}} \item 脱靶翻译问题:多语言单模型系统经常出现脱靶翻译问题,即把源语翻译成错误的目标语言,比如要求翻译成英语,结果却是汉语或者英语夹杂其他语言的字符。这是因为多语言单模型系统对所有语言都使用一样的参数,导致每个语言竞争系统固定的建模能力。研究人员提出在原来共享参数的基础上为每种语言添加额外的独立的参数,使得每种语言拥有足够的建模能力,以便于特定语言的翻译\upcite{DBLP:conf/acl/ZhangWTS20,DBLP:journals/corr/abs-2010-11125}
\vspace{0.5em} \vspace{0.5em}
\end{itemize} \end{itemize}
...@@ -689,7 +689,7 @@ Joint training for neural machine translation models with monolingual data ...@@ -689,7 +689,7 @@ Joint training for neural machine translation models with monolingual data
\parinterval 尽管已经得到了短语的翻译,短语表的另外一个重要的组成部分,也就是短语对的得分(概率)无法直接由词典归纳方法直接给出,而这些得分在统计机器翻译模型中非常重要。在无监督词典归纳中,在推断词典的时候会为一对源语言单词和目标语言单词打分(词嵌入之间的相似度),然后根据打分来决定哪一个目标语言单词更有可能是当前源语言单词的翻译。在无监督短语归纳中,这样一个打分已经提供了对短语对质量的度量,因此经过适当的归一化处理后就可以得到短语对的得分: \parinterval 尽管已经得到了短语的翻译,短语表的另外一个重要的组成部分,也就是短语对的得分(概率)无法直接由词典归纳方法直接给出,而这些得分在统计机器翻译模型中非常重要。在无监督词典归纳中,在推断词典的时候会为一对源语言单词和目标语言单词打分(词嵌入之间的相似度),然后根据打分来决定哪一个目标语言单词更有可能是当前源语言单词的翻译。在无监督短语归纳中,这样一个打分已经提供了对短语对质量的度量,因此经过适当的归一化处理后就可以得到短语对的得分:
\begin{eqnarray} \begin{eqnarray}
P(t|s)=\frac{\mathrm{cos}(\mathbi{x},\mathbi{y})/\tau}{\sum_{\mathbi{y}^{'}}\mathrm{cos}(\mathbi{x},\mathbi{y}^{'})\tau} P(\mathbi{y}|\mathbi{x}) & = & \frac{\mathrm{cos}(\mathbi{x},\mathbi{y})/\tau}{\sum_{\mathbi{y}^{'}}\mathrm{cos}(\mathbi{x},\mathbi{y}^{'})\tau}
\label{eq:16-2} \label{eq:16-2}
\end{eqnarray} \end{eqnarray}
...@@ -809,7 +809,7 @@ P(t|s)=\frac{\mathrm{cos}(\mathbi{x},\mathbi{y})/\tau}{\sum_{\mathbi{y}^{'}}\mat ...@@ -809,7 +809,7 @@ P(t|s)=\frac{\mathrm{cos}(\mathbi{x},\mathbi{y})/\tau}{\sum_{\mathbi{y}^{'}}\mat
\vspace{0.5em} \vspace{0.5em}
\item {\small\bfnew{语言模型的使用}}。无监督神经机器翻译的一个重要部分就是来自语言模型的目标函数。因为翻译模型本质上是在完成文本生成任务,所以只有文本生成类型的语言模型建模方法才可以应用到无监督神经机器翻译里。比如,经典的给定前文预测下一词就是一个典型的自回归生成任务(见{\chaptertwo}),因此可以运用到无监督神经机器翻译里。但是,目前在预训练里流行的BERT等模型是掩码语言模型\upcite{devlin2019bert},就不能直接在无监督神经翻译里使用。 \item {\small\bfnew{语言模型的使用}}。无监督神经机器翻译的一个重要部分就是来自语言模型的目标函数。因为翻译模型本质上是在完成文本生成任务,所以只有文本生成类型的语言模型建模方法才可以应用到无监督神经机器翻译里。比如,经典的给定前文预测下一词就是一个典型的自回归生成任务(见{\chaptertwo}),因此可以运用到无监督神经机器翻译里。但是,目前在预训练里流行的BERT等模型是掩码语言模型\upcite{devlin2019bert},就不能直接在无监督神经翻译里使用。
\parinterval 另外一个在无监督神经机器翻译中比较常见的语言模型目标函数则是{\small\bfnew{降噪自编码器}}\index{降噪自编码器}(Denoising Autoencoder\index{降噪自编码器})。它也是文本生成类型的语言模型建模方法。对于一个句子$\mathbi{x}$,首先使用一个噪声函数$\mathbi{x}^{'}=\mathrm{noise}(\mathbi{x})$ 来对$x$注入噪声,产生一个质量较差的句子$\mathbi{x}^{'}$。然后,让模型学习如何从$\mathbi{x}^{'}$还原出$\mathbi{x}$。这样一个目标函数比预测下一词更贴近翻译任务的本质,因为它是一个序列到序列的映射,并且输入输出两个序列在语义上是等价的。我们之所以采用$\mathbi{x}^{'}$而不是$\mathbi{x}$自己来预测$\mathbi{x}^{'}$,是因为模型可以通过简单的复制输入作为输出来完成从$\mathbi{x}$预测$\mathbi{x}$的任务,并且在输入中注入噪声会让模型更加鲁棒,因为模型可以通过训练集数据学会如何利用句子中噪声以外的信息来处理其中噪声并得到正确的输出。通常来说,噪声函数$\mathrm{noise}$有三种形式,如表\ref{tab:16-1}所示。 \parinterval 另外一个在无监督神经机器翻译中比较常见的语言模型目标函数则是{\small\bfnew{降噪自编码器}}\index{降噪自编码器}(Denoising Autoencoder\index{降噪自编码器})。它也是文本生成类型的语言模型建模方法。对于一个句子$\mathbi{x}$,首先使用一个噪声函数$\mathbi{x}^{'}=\mathrm{noise}(\mathbi{x})$ 来对$\mathbi{x}$注入噪声,产生一个质量较差的句子$\mathbi{x}^{'}$。然后,让模型学习如何从$\mathbi{x}^{'}$还原出$\mathbi{x}$。这样一个目标函数比预测下一词更贴近翻译任务的本质,因为它是一个序列到序列的映射,并且输入输出两个序列在语义上是等价的。我们之所以采用$\mathbi{x}^{'}$而不是$\mathbi{x}$自己来预测$\mathbi{x}^{'}$,是因为模型可以通过简单的复制输入作为输出来完成从$\mathbi{x}$预测$\mathbi{x}$的任务,并且在输入中注入噪声会让模型更加鲁棒,因为模型可以通过训练集数据学会如何利用句子中噪声以外的信息来处理其中噪声并得到正确的输出。通常来说,噪声函数$\mathrm{noise}$有三种形式,如表\ref{tab:16-1}所示。
\begin{table}[h] \begin{table}[h]
\centering \centering
...@@ -829,17 +829,272 @@ P(t|s)=\frac{\mathrm{cos}(\mathbi{x},\mathbi{y})/\tau}{\sum_{\mathbi{y}^{'}}\mat ...@@ -829,17 +829,272 @@ P(t|s)=\frac{\mathrm{cos}(\mathbi{x},\mathbi{y})/\tau}{\sum_{\mathbi{y}^{'}}\mat
\parinterval 实际当中三种形式的噪声函数都会被使用到,其中在交换方法中越相近的词越容易被交换,并且保证被交换的词的对数有限,而删除和空白方法里词的删除和替换概率通常都非常低,如$0.1$等。 \parinterval 实际当中三种形式的噪声函数都会被使用到,其中在交换方法中越相近的词越容易被交换,并且保证被交换的词的对数有限,而删除和空白方法里词的删除和替换概率通常都非常低,如$0.1$等。
\vspace{0.5em} \vspace{0.5em}
\end{itemize} \end{itemize}
%----------------------------------------------------------------------------------------
% NEW SECTION
%----------------------------------------------------------------------------------------
\section{领域适应}
\parinterval 机器翻译常常面临训练时与应用时所处领域不一致的问题,比如,在一个新闻类数据上训练的系统应用在翻译医学文献上。不同领域的句子通常存在着很大的区别,比如,日常用语的结构较为简单,而化学领域论文的单词和句子结构较为复杂。此外,不同领域之间存在着较为严重的一词多义问题,即同一个词在不同领域中经常会有不同的含义,如图\ref{fig:16-1-wbh}所示。
\begin{figure}[h]
\centering
\includegraphics[scale=3]{Chapter16/Figures/figure-the-meaning-of-pitch-in-different-fields.jpg}
\caption{单词pitch(图里标红)在不同领域的不同词义实例}
\label{fig:16-1-wbh}
\end{figure}
\parinterval 在机器翻译任务中,某些领域的双语数据相对容易获取,如新闻等领域,所以机器翻译在这些领域上表现较佳。然而,即使在富资源语种上,化学、医学等专业领域的双语数据却十分有限。如果直接使用低资源领域的数据训练一个机器翻译模型,由于数据稀缺问题,会导致模型的性能较差\upcite{DBLP:conf/iccv/SunSSG17}。混合多个领域的数据进行训练,不同领域的数据量不平衡会导致数据较少的领域训练不充分,模型容易忽略低资源领域的知识,使得在低资源领域上的翻译结果差强人意\upcite{DBLP:conf/acl/DuhNST13}
\parinterval {\small\bfnew{领域适应}}(Domain Adaptation)方法是利用其他领域(Source Domain\index{Source Domain}, 又称{\small\bfnew{源领域}}\index{源领域})知识来改进特定领域(Target Domain\index{Target Domain}, 又称{\small\bfnew{目标领域}}\index{目标领域})翻译效果的方法,可以有效地减少模型对目标领域数据的依赖。领域适应主要从两个方向出发:
\begin{itemize}
\vspace{0.5em}
\item 基于数据的方法。利用源领域的双语数据或目标领域单语数据进行数据选择或数据增强,来提升模型训练的数据量。
\vspace{0.5em}
\item 基于模型的方法。针对领域适应开发特定的模型结构或训练策略、推断方法。
\vspace{0.5em}
\end{itemize}
\parinterval 在统计机器翻译时代,从数据或模型角度提升机器翻译模型在特定领域上的翻译性能就已经备受关注,这些技术和思想也为神经机器翻译中的领域适应技术提供了参考。
%----------------------------------------------------------------------------------------
% NEW SUB-SECTION
%----------------------------------------------------------------------------------------
\subsection{统计机器翻译中的领域适应}
\parinterval 在统计机器翻译中,领域适应可以分为基于混合模型的方法\upcite{DBLP:conf/wmt/FosterK07,DBLP:conf/iwslt/BisazzaRF11,niehues2012detailed,DBLP:conf/acl/SennrichSA13,joty2015using,imamura2016multi}、基于数据加权的方法\upcite{DBLP:conf/emnlp/MatsoukasRZ09,DBLP:conf/emnlp/FosterGK10,shah2012general,DBLP:conf/iwslt/MansourN12,DBLP:conf/cncl/ZhouCZ15}、基于数据选择的方法\upcite{DBLP:conf/lrec/EckVW04,DBLP:conf/coling/ZhaoEV04,DBLP:conf/acl/MooreL10,DBLP:conf/acl/DuhNST13,DBLP:conf/coling/HoangS14,joty2015using,chen2016bilingual}和基于伪数据的方法\upcite{DBLP:conf/iwslt/Ueffing06,DBLP:conf/coling/WuWZ08,DBLP:conf/iwslt/Schwenk08,DBLP:conf/wmt/BertoldiF09,DBLP:conf/wmt/LambertSSA11}
%----------------------------------------------------------------------------------------
% NEW SUB-SUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{1. 基于混合模型的方法}
\parinterval 不同领域的数据存在着共性,但是又有各自的风格,使用多领域数据训练出不同的模型,分情况处理问题可能会带来更好的效果,例如对疑问句和陈述句分别使用两个模型进行推断效果更好\upcite{DBLP:conf/eacl/Sennrich12}。混合模型是统计机器学习理论中的传统实现技术之一,通过训练与每个语料库分别对应的多个统计机器翻译子模型,如语言模型、翻译模型和重排序模型,然后将它们进行组合以实现最佳性能\upcite{DBLP:conf/wmt/FosterK07}。混合模型方法的步骤如下:
\begin{itemize}
\vspace{0.5em}
\item 将训练数据根据所在的领域分为几个不同的部分。
\vspace{0.5em}
\item 利用每一部分数据训练一个子模型。
\vspace{0.5em}
\item 根据测试数据的上下文信息适当为每个子模型调整权重。
\vspace{0.5em}
\item 对不同的领域使用调整出的最佳权重,加权整合多个子模型的输出。
\vspace{0.5em}
\end{itemize}
\parinterval 混合模型方法把统计机器翻译的每个模块分为多个模型同时解决问题,有权重地组合多个模型的结果。这个想法对后来出现的神经机器翻译中的模型融合、加权推断等方法有一定的启发(见{\chapterfourteen})。
%----------------------------------------------------------------------------------------
% NEW SUB-SUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{2. 基于数据加权的方法}
\parinterval 在真实场景中,由于每个领域的数据量有限,同时领域数量较多,针对每个领域单独训练一个机器翻译模型是不现实的。所以,通常的策略是训练一个机器翻译模型来支持多领域的翻译。虽然混合多个领域的数据可以有效增加训练数据规模,但正如前面所说,由于各个领域样本的数据量不平衡,在训练数据稀缺的领域上,模型表现往往差强人意。一种观点认为,数据量较少的领域数据具有更大的学习价值,可以提供较为珍贵的知识和信息,应该在训练过程中获得更大的权重。数据加权方法使用规则或统计方法对每个实例或领域进行评分,作为它们的权重,然后赋予每个样本或领域不同的权重来训练统计机器翻译模型。一般来说,数据量较少的领域数据权重更高,从而使这些更有价值的数据发挥出更大的作用\upcite{DBLP:conf/emnlp/MatsoukasRZ09,DBLP:conf/emnlp/FosterGK10}
\parinterval 上述思想本质上在解决{\small\bfnew{类别不均衡问题}}\upcite{DBLP:conf/emnlp/ZhuH07}\index{类别不均衡问题}(Class Imbalance Problem\index{Class Imbalance Problem})。另一种方法是通过数据重新采样对语料库进行加权\upcite{DBLP:conf/wmt/ShahBS10,rousseau2011lium}。语料库加权方法通过构建目标领域语言模型,比较各个语料库与目标领域的相似性,赋予相似的语料库更高的权重。
%----------------------------------------------------------------------------------------
% NEW SUB-SUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{3. 基于数据选择的方法}
\parinterval 源领域大规模的双语数据中通常会包含一些和目标领域相似的句子,基于数据选择的方法通过相似度函数选择出与目标领域相似的源领域数据,再把选择出的源领域数据与原始目标领域数据混合训练模型,增加目标领域的双语数据规模,从而提高模型在目标领域的性能。相似度可以通过语言模型\upcite{DBLP:conf/lrec/EckVW04,DBLP:conf/coling/ZhaoEV04,moore2010intelligent,DBLP:conf/acl/DuhNST13}、 多模型联合\upcite{DBLP:conf/coling/HoangS14,joty2015using}、卷积神经网络\upcite{chen2016bilingual}等方法进行计算。
%----------------------------------------------------------------------------------------
% NEW SUB-SUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{4. 基于伪数据的方法}
\parinterval 数据选择方法可以从源领域中选择出和目标领域相似的训练数据,但可用的数据量是较为有限的。因此,另外一种思路是对现有的双语数据进行修改或通过单语数据生成伪数据来增加数据量。常用方法包括通过信息检索\upcite{DBLP:conf/acl/UtiyamaI03}、平行词嵌入\upcite{DBLP:conf/acl/MarieF17}等方法生成一些伪平行句对或平行短语对\upcite{DBLP:conf/coling/WangZLUS16,chu2015integrated}来增加可使用的伪双语数据。统计机器翻译可以有效地利用平行短语对来提高模型性能。
\parinterval 其中,{\small\bfnew{自学习}}(Self-training)是一种具有代表性的生成伪数据的方法\upcite{DBLP:journals/tit/Scudder65a}。自学习通过源领域的双语训练数据训练一个基准翻译系统,然后对目标领域的单语数据进行翻译,再从翻译候选集合中选择高质量的译文和源语言句子组合成为双语句对,之后将其加入到训练数据中重新训练翻译系统,该过程将一直迭代到翻译性能稳定为止\upcite{DBLP:conf/iwslt/Ueffing06}。基于自学习的统计机器翻译可以从一个性能较好的源领域机器翻译模型出发,逐步引入目标领域的知识,可以显著提高目标领域的翻译性能。
\parinterval 随着神经机器翻译的不断发展,许多基于神经网络的领域适应方法也被提出\upcite{DBLP:conf/coling/ChuW18},其核心思想仍和统计机器翻译时期相似,也是从数据角度和模型角度两方面进行改进。不同之处在于,统计机器翻译模型是多个独立模型的组合,而神经机器翻译是一个整体的模型,因此统计机器翻译中基于模型的方法不能直接应用于神经机器翻译。
%----------------------------------------------------------------------------------------
% NEW SUB-SECTION
%----------------------------------------------------------------------------------------
\subsection{基于数据的神经机器翻译领域适应}
\parinterval 增加训练数据是解决低资源领域性能较差问题的一个主要思路。受统计机器翻译时代技术的启发,可以通过类似的思想来增加神经机器翻译的训练数据量。下面分别介绍基于多领域数据的方法、基于数据选择的方法和基于单语数据的方法。
%----------------------------------------------------------------------------------------
% NEW SUB-SUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{1. 基于多领域数据的方法}
\parinterval 一种简单的思路是利用其他领域的数据来辅助低资源领域上的模型训练,即基于多领域数据的领域适应\upcite{DBLP:conf/acl/ChuDK17,DBLP:journals/corr/abs-1708-08712,DBLP:conf/acl/WangTNYCP20,DBLP:conf/acl/JiangLWZ20}。实际上,多领域建模也可以看作是一种多语言建模问题(\ref{multilingual-translation-model}节)。通过借助其他相似领域的训练数据,可以缓解目标领域数据缺乏的问题。比如,想要训练网络小说领域的翻译系统,可以通过加入文学、字幕等领域的翻译数据来增加数据量。
\parinterval 但在神经机器翻译中,多领域数据不平衡问题也会导致数据量较少的领域训练不充分,带来较低的翻译品质。目前比较常用的多领域数据方法是在数据中加入标签来提高神经机器翻译模型对不同领域的区分能力\upcite{DBLP:conf/acl/ChuDK17},该方法主要通过两种策略来缓解领域不平衡问题:
\begin{itemize}
\vspace{0.5em}
\item 在不同领域的源语句子句首加上不同的标签来指定该句子对应的领域,让神经机器翻译模型在预测过程中可以生成更符合领域特性的句子。
\item 把数据量较小的领域数据复制数倍,来对各个领域的数据量进行平衡,使模型对各个领域给与平等的关注。
\vspace{0.5em}
\end{itemize}
\parinterval 这种方法的优点在于思路简单、易于实现,可以大大提高可用的数据量,但不同领域的数据不可避免地会产生一些干扰,在实际使用中可能会产生词汇预测错误的问题。
%----------------------------------------------------------------------------------------
% NEW SUB-SUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{2. 基于数据选择的方法}
\parinterval 既然多领域数据的方法会对模型产生一些干扰,那么能否从其他领域数据中选择与目标领域比较相近的数据来提升数据量呢?与统计机器翻译相似,可以通过使用困惑度\upcite{DBLP:conf/emnlp/AxelrodHG11}或JS散度\upcite{DBLP:conf/icdm/Remus12}等方法计算源领域数据与目标领域数据的相似度,从而选择较为相似的数据以增加目标领域的数据量,提升模型能力。
\parinterval 一种相似度衡量方法是根据句子的词嵌入来计算\upcite{DBLP:conf/acl/WangFUS17},即把其他领域的双语数据根据与目标领域句子的词嵌入相似度进行排序,设定一个阈值来选择与目标领域比较相似的句子,将其与目标领域的数据混合用于模型训练。除了直接混合两部分数据,还可以修改数据的训练方式,从而更有效地利用训练数据,具体方法可以参考\ref{modeling-methods-in neural-machine-translation}节的内容。
\parinterval 数据选择充分地利用了其他领域的双语数据,使低资源问题得到了一定程度的缓解,模型可以学到更多目标领域相关的语言学知识,是目前比较常用的一个方法。
%----------------------------------------------------------------------------------------
% NEW SUB-SUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{3. 基于单语数据的方法}
\parinterval 尽管目标领域的双语数据是十分有限的,但通常存在大量可用的单语数据。例如在网络小说翻译任务中,只有少量的双语数据可用,而网络上有丰富的单语小说数据可用。\ref{effective-use-of-data}节中提到了很多在低资源场景下利用单语数据的模型方法,比如进行数据增强或利用语言模型等。这些方法均可以直接应用在领域适应任务上,有效地利用领域内的单语数据可以显著提高机器翻译性能。
\parinterval 此外,如果目标领域的双语数据极度稀缺,甚至完全没有任何双语数据,这时可以使用\ref{unsupervised-dictionary-induction}节中提到的无监督词典归纳方法从目标领域中归纳出双语词典,然后将目标领域的目标端单语数据通过逐词翻译的方法生成伪数据\upcite{DBLP:conf/acl/HuXNC19},即对每个单词根据双语词典进行对应翻译,构建伪平行语料,用来训练目标领域的神经机器翻译模型。
%----------------------------------------------------------------------------------------
% NEW SUB-SECTION
%----------------------------------------------------------------------------------------
\subsection{基于模型的神经机器翻译领域适应}\label{modeling-methods-in neural-machine-translation}
\parinterval 一个神经机器翻译模型的实现分为三个组成部分:设计神经网络模型结构、制定训练策略训练模型、模型推断生成翻译结果。因此,领域适应也可以体现在这三个步骤中:
\begin{itemize}
\vspace{0.5em}
\item 基于模型结构的方法,设计一个更适用于领域适应问题的模型结构\upcite{2015OnGulcehre,2019Non,britz2017effective,DBLP:conf/ranlp/KobusCS17}
\vspace{0.5em}
\item 基于训练策略的方法,制定能够更好利用多领域数据的训练方法\upcite{DBLP:conf/emnlp/WangULCS17,DBLP:conf/emnlp/WeesBM17,DBLP:conf/acl/ChuDK17}
\vspace{0.5em}
\item 基于模型推断的方法,生成更符合目标适应领域的翻译结果\upcite{DBLP:conf/emnlp/DouWHN19,khayrallah2017neural,DBLP:journals/corr/FreitagA16,DBLP:conf/acl/SaundersSGB19}
\vspace{0.5em}
\end{itemize}
%----------------------------------------------------------------------------------------
% NEW SUB-SUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{1. 基于模型结构的方法}
\parinterval 统计机器翻译时代基于模型结构的方法集中在提升词对齐模型、语言模型等子模型的领域适应性,从而提升统计机器翻译模型在特定领域的表现。而神经机器翻译模型是一个端到端的框架,因此对模型的调整往往体现在整体结构上。
\parinterval 在使用多领域数据时,神经机器翻译的结构无法有效地利用多领域语料库的信息多样性,混合多个相差较大的领域数据进行训练会使单个领域的翻译性能下降\upcite{DBLP:conf/eacl/NegriTFBF17}。为了解决这一问题,一个比较典型的做法是在使用多领域数据训练时,如图\ref{fig:16-2-wbh}所示,在神经机器翻译模型的编码器中添加一个判别器,使用判别器预测输入句子的领域\upcite{DBLP:conf/wmt/BritzLP17},具体的做法为:在编码器的顶部添加一个判别器网络,这个判别器使用源语言句子$x$的编码器表示$x'$作为输入,预测句子所属的领域标签$d$。为了使预测领域标签d的正确概率$\funp{P(d|H)}$最大,模型在训练过程中最小化如下损失函数$\funp{L}_{\rm{disc}}$
\begin{figure}[h]
\centering
\includegraphics[scale=1]{Chapter16/Figures/figure-schematic-of-the-domain-discriminator.jpg}
\caption{领域判别器示意图}
\label{fig:16-2-wbh}
\end{figure}
\begin{eqnarray}
\funp{L}_{\rm{disc}}& = &-\log\funp{P}(d|H)
\label{eq:16-1-wbh}
\end{eqnarray}
\noindent 其中,$H$是编码器的隐藏状态。同时,原始的翻译模型损失为:
\begin{eqnarray}
\funp{L}_{\rm{gen}}& = & -\log\funp{P}(y|x)\label{eq:16-2-wbh}
\end{eqnarray}
\noindent 神经机器翻译模型同时优化对领域标签的预测和对翻译结果的预测,如下:
\begin{eqnarray}
\funp{L} & =& \funp{L}_{\rm{disc}}+\funp{L}_{\rm{gen}}\label{eq:16-3-wbh}
\end{eqnarray}
\parinterval 这种方法使模型具备了识别不同领域数据的能力,从而可以针对不同领域进行特定的建模,生成符合领域特征的翻译结果。此外,还可以利用词频-逆文档频率方法\upcite{DBLP:journals/ibmrd/Luhn58}预测输入句子的领域标签,在词嵌入层加上领域特定的嵌入表示。还有一些对模型结构进行更改的工作在于融合语言模型到神经机器翻译模型中\upcite{2015OnGulcehre,DBLP:conf/emnlp/DomhanH17}
%----------------------------------------------------------------------------------------
% NEW SUB-SUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{2. 基于训练策略的方法}
\parinterval 因为特定领域的训练数据通常十分稀缺,所以如何更充分地利用数据是一个重要问题。基于训练策略的领域适应方法是神经机器翻译中较为广泛使用的方法,具有易于实现、作用显著的优点\upcite{DBLP:conf/naacl/SimianerWD19}。基于训练策略的领域适应方法是指在模型的训练阶段改变获得训练目标的过程,通过加权或者微调等方法更加高效地利用数据。
\parinterval 受到统计机器翻译中数据加权方法的启发,一个简单的思路是给神经机器翻译的训练数据分配不同的训练权重,从而使和目标领域更相似数据发挥更大的作用,并减少不相似数据的干扰。一种常用的做法是通过目标领域内和领域外语言模型计算样本的权重\upcite{DBLP:conf/emnlp/WangULCS17}。领域内语言模型对句子的打分越高,表示该句子与目标领域越相似,反之,领域外语言模型对句子的打分越高,表示该句子可能与目标领域无关,会对训练过程造成一些干扰。
\parinterval 与句子级别进行加权方法相似,加权思想还可以应用在词级别,即对每个词进行权重评分,对目标领域中的词赋予更高的权重,以使模型倾向于生成更多目标领域的词\upcite{DBLP:journals/corr/abs-1906-03129}
\parinterval 数据选择方法会降低训练数据的数据量,而在数据量较少的时候模型表现可能较差,针对这个问题,一种方法是在不同的训练轮次动态地改变训练数据子集。动态数据选择使得每轮的训练数据均小于全部数据量,但是在每轮中的训练数据均不同,可能前一轮没有训练的数据在当前轮被包括进来,由此可以缓解训练数据减小的问题。一种做法是先将完整的数据送入模型,再根据相似度逐次减少每轮的数据量,最后得到在目标领域上效果最好的领域适应模型\upcite{DBLP:conf/emnlp/WeesBM17}。或者将最相似的句子最先送入模型,让模型可以最先学到跟目标领域最相关的知识,奠定良好的基础\upcite{DBLP:conf/naacl/ZhangSKMCD19}
\parinterval 还有一种方法是不从随机状态开始训练网络,而是使用翻译性能较好的源领域模型作为初始状态,因为源领域模型中包含着一些通用知识可以被目标领域借鉴。比如,想获得口语领域的机器翻译模型,使用新闻领域模型作为初始状态训练口语领域模型。同时,微调方法经常配合预训练使用。微调方法的具体过程如下:
\begin{itemize}
\vspace{0.5em}
\item 在资源丰富的源领域语料库上对系统进行训练直至收敛。
\vspace{0.5em}
\item 在资源贫乏的目标领域语料库上进行训练,对系统参数进行微调使其更适应目标领域。
\vspace{0.5em}
\end{itemize}
\parinterval 然而微调的方法会带来严重的灾难性遗忘问题,即在目标领域上过拟合,导致在源领域上的翻译性能大幅度下降。如果想要保证模型在目标领域上有较好翻译性能的同时在源领域的翻译性能也不下降,一个比较常用的方法是进行混合微调\upcite{DBLP:conf/acl/ChuDK17}。具体做法是先在源领域数据上训练一个神经机器翻译模型,然后将目标领域数据复制数倍和源领域数据量相等,之后将数据混合后对神经机器翻译模型进行微调。混合微调方法既降低了目标领域数据量小导致的过拟合问题,又带来了更好的微调性能。除了混合微调外,还有研究人员使用\ref{multilingual-translation-model}节的知识蒸馏方法缓解灾难性遗忘问题,即对源领域和目标领域进行多次循环知识蒸馏,迭代学习对方领域的知识,可以保证在源领域和目标领域上的翻译性能共同逐步上升\upcite{DBLP:conf/emnlp/ZengLSGLYL19}。过拟合导致的灾难性遗忘还可以使用{\red{13.2节的正则化}}方法来缓解\upcite{barone2017regularization}
%----------------------------------------------------------------------------------------
% NEW SUB-SUB-SECTION
%----------------------------------------------------------------------------------------
\subsubsection{3. 基于模型推断的方法}
\parinterval 推断是指将输入序列转换成的向量再次转化为输出序列的过程,是机器翻译模型生成翻译结果的最后一步。典型的工作是优化推断算法\upcite{khayrallah2017neural},即通过更适用于领域适应任务的推断算法去选择最佳的结果,大部分基于模型推断的方法的相关工作集中在把多个模型融合成一个模型以增强模型的推断能力,来获得更适应目标领域的序列。目前比较常用的方法是集成推断,即把多个领域的模型使用{\chapterfourteen}的模型集成方法融合为一个模型用于推断\upcite{DBLP:journals/corr/FreitagA16},具体过程如下:
\begin{itemize}
\vspace{0.5em}
\item 在目标领域和多个源领域数据上分别训练多个独立的机器翻译模型。
\vspace{0.5em}
\item 把多个模型集成为一个模型。
\vspace{0.5em}
\item 使用目标领域数据对集成模型进行微调。
\vspace{0.5em}
\item 使用微调后的模型进行推断。
\vspace{0.5em}
\end{itemize}
\parinterval 集成推断方法相较于直接使用大量数据训练成一个模型的主要优势在于速度快,多个领域的模型可以并行地独立训练,使训练时间大大缩短。集成推断也可以结合加权思想,对不同领域的句子,赋予每个模型不同的先验权重进行推断,来获得最佳的推断结果\upcite{DBLP:conf/acl/SaundersSGB19}。还有部分工作研究在推断过程中融入语言模型\upcite{2015OnGulcehre,DBLP:conf/emnlp/DomhanH17}或目标领域的罕见词\upcite{DBLP:conf/naacl/BapnaF19}
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SECTION % NEW SECTION
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\section{小结及深入阅读} \section{小结及扩展阅读}
低资源机器翻译是机器翻译大规模应用所面临的挑战之一,因此也备受关注。一方面,小样本学习和零样本学习技术的发展,使得研究者可以有更多的手段对问题求解;另一方面,从多语言之间的联系出发,也可以进一步挖掘语料背后的知识,并应用于低资源翻译任务。本章从多个方面介绍了低资源机器翻译方法,并结合多语言、零资源翻译等问题给出了不同场景下解决问题的思路。除此之外,还有几方面工作值得进一步关注:
(扩展阅读) (扩展阅读)
\parinterval 除此之外,还有很多工作对数据增强方法进行了深入的研究与探讨。探索源语言单语数据在神经机器翻译中的使用方法\upcite{DBLP:conf/emnlp/ZhangZ16};选择何种单语数据来生成伪数据带来的收益更大\upcite{DBLP:conf/emnlp/FadaeeM18,DBLP:conf/nlpcc/XuLXLLXZ19};通过特别标识对真实双语和回译生成的伪双语数据进行区分\upcite{DBLP:conf/wmt/CaswellCG19};在回译过程中对训练数据进行动态选择与加权\upcite{DBLP:journals/corr/abs200403672};利用目标端单语数据和相关的富资源语言进行数据增强\upcite{DBLP:conf/acl/XiaKAN19};通过在源语言或目标语言中随机选择某些词,将这些词替换为词表中随机的一个词,可以得到伪双语数据\upcite{DBLP:conf/emnlp/WangPDN18};随机选择句子中的某个词,将这个词的词嵌入替换为多个语义相似词的加权表示融合\upcite{DBLP:conf/acl/GaoZWXQCZL19};基于模型的不确定性来量化预测结果的置信度,从而提升回译方法的性能\upcite{DBLP:conf/emnlp/WangLWLS19};探索如何利用大规模单语数据\upcite{DBLP:conf/emnlp/WuWXQLL19};还有一些工作对数据增强进行了理论分析\upcite{DBLP:conf/emnlp/LiLHZZ19}{\color{red},发现XXXX?}。({\color{red} 这部分写得不错} \parinterval 也有工作对数据增强方法进行了深入的研究与探讨。探索源语言单语数据在神经机器翻译中的使用方法\upcite{DBLP:conf/emnlp/ZhangZ16};选择何种单语数据来生成伪数据带来的收益更大\upcite{DBLP:conf/emnlp/FadaeeM18,DBLP:conf/nlpcc/XuLXLLXZ19};通过特别标识对真实双语和回译生成的伪双语数据进行区分\upcite{DBLP:conf/wmt/CaswellCG19};在回译过程中对训练数据进行动态选择与加权\upcite{DBLP:journals/corr/abs200403672};利用目标端单语数据和相关的富资源语言进行数据增强\upcite{DBLP:conf/acl/XiaKAN19};通过在源语言或目标语言中随机选择某些词,将这些词替换为词表中随机的一个词,可以得到伪双语数据\upcite{DBLP:conf/emnlp/WangPDN18};随机选择句子中的某个词,将这个词的词嵌入替换为多个语义相似词的加权表示融合\upcite{DBLP:conf/acl/GaoZWXQCZL19};基于模型的不确定性来量化预测结果的置信度,从而提升回译方法的性能\upcite{DBLP:conf/emnlp/WangLWLS19};探索如何利用大规模单语数据\upcite{DBLP:conf/emnlp/WuWXQLL19};还有一些工作对数据增强进行了理论分析\upcite{DBLP:conf/emnlp/LiLHZZ19}{\color{red},发现XXXX?}。({\color{red} 这部分写得不错}{\color{blue}肖:不要一条一条罗列,可以做总结,提炼共性问题和方法!}
(多语言扩展阅读) (多语言扩展阅读)
......
...@@ -653,13 +653,13 @@ span\textrm{[0,4]}&=&\textrm{“猫} \quad \textrm{喜欢} \quad \textrm{吃} \q ...@@ -653,13 +653,13 @@ span\textrm{[0,4]}&=&\textrm{“猫} \quad \textrm{喜欢} \quad \textrm{吃} \q
\subsection{基于句法的翻译模型分类} \subsection{基于句法的翻译模型分类}
\parinterval 可以说基于句法的翻译模型贯穿了现代统计机器翻译的发展历程。从概念上讲,不管是层次短语模型,还是语言学句法模型都是基于句法的模型。基于句法的机器翻译模型种类繁多,这里先对相关概念进行简要介绍,以避免后续论述中产生歧义。表\ref{tab:4-2}给出了基于句法的机器翻译中涉及的一些概念。 \parinterval 可以说基于句法的翻译模型贯穿了现代统计机器翻译的发展历程。从概念上讲,不管是层次短语模型,还是语言学句法模型都是基于句法的模型。基于句法的机器翻译模型种类繁多,这里先对相关概念进行简要介绍,以避免后续论述中产生歧义。表\ref{tab:8-2}给出了基于句法的机器翻译中涉及的一些概念。
%---------------------------------------------- %----------------------------------------------
\begin{table}[htp]{ \begin{table}[htp]{
\begin{center} \begin{center}
\caption{基于句法的机器翻译中常用概念} \caption{基于句法的机器翻译中常用概念}
\label{tab:4-2} \label{tab:8-2}
{ {
\begin{tabular}{p{6.5em} | l} \begin{tabular}{p{6.5em} | l}
术语 & 说明 \\ 术语 & 说明 \\
......
...@@ -158,7 +158,7 @@ ...@@ -158,7 +158,7 @@
\subsubsection{2. 深度学习的效果} \subsubsection{2. 深度学习的效果}
\parinterval 相比于传统的基于特征工程的方法,基于深度学习的模型更加方便、通用,在系统性能上也普遍更优。这里以语言建模任务为例。语言建模的目的是开发一个模型来描述词串出现的可能性(见{\chaptertwo})。这个任务已经有着很长时间的历史。表\ref{tab:9-1}给出了不同方法在常用的PTB数据集上的困惑度结果 \footnote{困惑度越低明语言建模的效果越好。} 。传统的$ n$-gram语言模型由于面临维度灾难和数据稀疏问题,最终语言模型的性能并不是很好。而在深度学习模型中,通过引入循环神经网络等结构,所得到的语言模型可以更好地描述序列生成的问题。而最新的基于Transformer架构的语言模型将PPL从最初的178.0 下降到了惊人的35.7。可见深度学习为这个任务带来的进步是巨大的。 \parinterval 相比于传统的基于特征工程的方法,基于深度学习的模型更加方便、通用,在系统性能上也普遍更优。这里以语言建模任务为例。语言建模的目的是开发一个模型来描述词串出现的可能性(见{\chaptertwo})。这个任务已经有着很长时间的历史。表\ref{tab:9-1}给出了不同方法在常用的PTB数据集上的困惑度结果 \footnote{困惑度越低明语言建模的效果越好。} 。传统的$ n$-gram语言模型由于面临维度灾难和数据稀疏问题,最终语言模型的性能并不是很好。而在深度学习模型中,通过引入循环神经网络等结构,所得到的语言模型可以更好地描述序列生成的问题。而最新的基于Transformer架构的语言模型将PPL从最初的178.0 下降到了惊人的35.7。可见深度学习为这个任务带来的进步是巨大的。
%---------------------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------------------
\begin{table}[htp] \begin{table}[htp]
...@@ -400,7 +400,7 @@ ...@@ -400,7 +400,7 @@
\subsubsection{5. 线性映射} \subsubsection{5. 线性映射}
\parinterval {\small\sffamily\bfseries{线性映射}}\index{线性映射}( Linear Mapping)\index{Linear Mapping}{\small\sffamily\bfseries{线性变换}}\index{线性变换}(Linear Transformation)\index{Linear Transformation}一个向量空间V到另一个向量空间W的映射函数$ f:v\rightarrow w$,且该映射函数保持加法运算和数量乘法运算,即对于空间V中任何两个向量$ {\mathbi{u}} $$ {\mathbi{v}} $以及任何标量$ c $,始终符合公式\eqref{eq:9-9}和公式\eqref{eq:9-10} \parinterval {\small\sffamily\bfseries{线性映射}}\index{线性映射}( Linear Mapping)\index{Linear Mapping}{\small\sffamily\bfseries{线性变换}}\index{线性变换}(Linear Transformation)\index{Linear Transformation}是一个向量空间V到另一个向量空间W的映射函数$ f:v\rightarrow w$,且该映射函数保持加法运算和数量乘法运算,即对于空间V中任何两个向量$ {\mathbi{u}} $$ {\mathbi{v}} $以及任何标量$ c $,始终符合公式\eqref{eq:9-9}和公式\eqref{eq:9-10}
\begin{eqnarray} \begin{eqnarray}
f({\mathbi{u}}+{\mathbi{v}})&=&f({\mathbi{u}})+f({\mathbi{v}})\label{eq:9-9}\\ f({\mathbi{u}}+{\mathbi{v}})&=&f({\mathbi{u}})+f({\mathbi{v}})\label{eq:9-9}\\
f(c{\mathbi{v}})&=&cf({\mathbi{v}}) f(c{\mathbi{v}})&=&cf({\mathbi{v}})
...@@ -578,7 +578,7 @@ x_1\cdot w_1+x_2\cdot w_2+x_3\cdot w_3 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -578,7 +578,7 @@ x_1\cdot w_1+x_2\cdot w_2+x_3\cdot w_3 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter9/Figures/figure-perceptron-to-predict-2} \input{./Chapter9/Figures/figure-perceptron-to-predict-2}
\caption{预测是否去剧场的感知机(改变权重} \caption{预测是否去剧场的感知机(权重不同}
\label{fig:9-7} \label{fig:9-7}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
...@@ -740,7 +740,7 @@ x_1\cdot w_1+x_2\cdot w_2+x_3\cdot w_3 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -740,7 +740,7 @@ x_1\cdot w_1+x_2\cdot w_2+x_3\cdot w_3 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
%------------------------------------------- %-------------------------------------------
\vspace{-0.5em} \vspace{-0.5em}
\parinterval 那激活函数又是什么?神经元在接收到经过线性变换的结果后,通过激活函数的处理,得到最终的输出$ \mathbi y $。激活函数的目的是解决实际问题中的非线性变换,线性变换只能拟合直线,而激活函数的加入,使神经网络具有了拟合曲线的能力。 特别是在实际问题中,很多现象都无法用简单的线性关系描述,这时可以使用非线性激活函数来描述更加复杂的问题。常见的非线性激活函数有Sigmoid、ReLU、Tanh等。图\ref{fig:9-15}中列举了几种激活函数的形式。 \parinterval 那激活函数又是什么?一个神经元在接收到经过线性变换的结果后,通过激活函数的处理,得到最终的输出$ y $。激活函数的目的是解决实际问题中的非线性变换,线性变换只能拟合直线,而激活函数的加入,使神经网络具有了拟合曲线的能力。 特别是在实际问题中,很多现象都无法用简单的线性关系描述,这时可以使用非线性激活函数来描述更加复杂的问题。常见的非线性激活函数有Sigmoid、ReLU、Tanh等。图\ref{fig:9-15}中列举了几种激活函数的形式。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -764,12 +764,12 @@ x_1\cdot w_1+x_2\cdot w_2+x_3\cdot w_3 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe ...@@ -764,12 +764,12 @@ x_1\cdot w_1+x_2\cdot w_2+x_3\cdot w_3 & = & 0\cdot 1+0\cdot 1+1\cdot 1 \nonumbe
\begin{figure}[htp] \begin{figure}[htp]
\centering \centering
\input{./Chapter9/Figures/figure-four-layers-of-neural-network} \input{./Chapter9/Figures/figure-four-layers-of-neural-network}
\caption{具有四层神经元的(三层)神经网络} \caption{三层神经网络}
\label{fig:9-17} \label{fig:9-17}
\end{figure} \end{figure}
%------------------------------------------- %-------------------------------------------
\parinterval 在多层神经网络中,通常包括输入层、输出层和至少一个隐藏层。图\ref{fig:9-17}展示了一个由四层神经网络构成的模型,包括输入层、输出层和两个隐藏层。\\ \parinterval 在多层神经网络中,通常包括输入层、输出层和至少一个隐藏层。图\ref{fig:9-17}展示了一个三层神经网络,包括输入层\footnote{由于输入层不存在神经元,因此在计算神经网络层数时不将其包括在内。}、输出层和两个隐藏层。\\
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
...@@ -1040,23 +1040,23 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases} ...@@ -1040,23 +1040,23 @@ f(x)=\begin{cases} 0 & x\le 0 \\x & x>0\end{cases}
\begin{tabular}{l | l} \begin{tabular}{l | l}
\rule{0pt}{15pt} 函数 & 描述 \\ \rule{0pt}{15pt} 函数 & 描述 \\
\hline \hline
\rule{0pt}{15pt} \texttt{a.Reshape(o,s)} &$ {\mathbi{a}} $变换成阶为o、形状为s的张量 \\ \rule{0pt}{15pt} \texttt{a.Reshape(o,s)} &张量$ {\mathbi{a}} $变换成阶为o、形状为s的张量 \\
\rule{0pt}{15pt} \texttt{a.Get(pos)} & 取张量中位置为pos的元素 \\ \rule{0pt}{15pt} \texttt{a.Get(pos)} & 取张量$ {\mathbi{a}} $中位置为pos的元素 \\
\rule{0pt}{15pt} \texttt{a.Set(v,pos)} & 把张量中位置为pos的元素值设为v \\ \rule{0pt}{15pt} \texttt{a.Set(v,pos)} & 把张量$ {\mathbi{a}} $中位置为pos的元素值设为v \\
\rule{0pt}{15pt} \texttt{a.Dump(file)} & 把张量存到file中,file为文件句柄 \\ \rule{0pt}{15pt} \texttt{a.Dump(file)} & 把张量$ {\mathbi{a}} $存到file中,file为文件句柄 \\
\rule{0pt}{15pt} \texttt{a.Read(file)} & 从file中读取张量,file为文件句柄 \\ \rule{0pt}{15pt} \texttt{a.Read(file)} & 从file中读取张量$ {\mathbi{a}} $,file为文件句柄 \\
\rule{0pt}{15pt} \texttt{Power(a,p)} & 计算指数$ a^p $ \\ \rule{0pt}{15pt} \texttt{Power(a,p)} & 计算指数$ a^p $ \\
\rule{0pt}{15pt} \texttt{Linear(a,s,b)} & 计算${\mathbi{a}}\ast s+b $,s和b都是一个实数 \\ \rule{0pt}{15pt} \texttt{Linear(a,s,b)} & 计算${\mathbi{a}}\ast s+b $,s和b都是一个实数 \\
\rule{0pt}{15pt} \texttt{CopyValue(a)} & 构建$ {\mathbi{a}} $的一个拷贝 \\ \rule{0pt}{15pt} \texttt{CopyValue(a)} & 构建张量$ {\mathbi{a}} $的一个拷贝 \\
\rule{0pt}{15pt} \texttt{ReduceMax(a,d)} &$ {\mathbi{a}} $沿着方向d进行规约,得到最大值 \\ \rule{0pt}{15pt} \texttt{ReduceMax(a,d)} &张量$ {\mathbi{a}} $沿着方向d进行规约,得到最大值 \\
\rule{0pt}{15pt} \texttt{ReduceSum(a,d)} &$ {\mathbi{a}} $沿着方向d进行规约,得到和 \\ \rule{0pt}{15pt} \texttt{ReduceSum(a,d)} &张量$ {\mathbi{a}} $沿着方向d进行规约,得到和 \\
\rule{0pt}{15pt} \texttt{Concatenate(a,b,d)} & 把两个张量$ {\mathbi{a}} $$ {\mathbi{b}} $沿d方向级联 \\ \rule{0pt}{15pt} \texttt{Concatenate(a,b,d)} & 把两个张量$ {\mathbi{a}} $$ {\mathbi{b}} $沿d方向级联 \\
\rule{0pt}{15pt} \texttt{Merge(a,d)} & 对张量$ {\mathbi{a}} $沿d方向合并 \\ \rule{0pt}{15pt} \texttt{Merge(a,d)} & 对张量$ {\mathbi{a}} $沿d方向合并 \\
\rule{0pt}{15pt} \texttt{Split(a,d,n)} & 对张量$ {\mathbi{a}} $沿d方向分裂成n份 \\ \rule{0pt}{15pt} \texttt{Split(a,d,n)} & 对张量$ {\mathbi{a}} $沿d方向分裂成n份 \\
\rule{0pt}{15pt} \texttt{Sigmoid(a)} &${\mathbi{a}}$进行Sigmoid变换 \\ \rule{0pt}{15pt} \texttt{Sigmoid(a)} &张量${\mathbi{a}}$进行Sigmoid变换 \\
\rule{0pt}{15pt} \texttt{Softmax(a)} &$ {\mathbi{a}} $进行Softmax变换,沿最后一个方向 \\ \rule{0pt}{15pt} \texttt{Softmax(a)} &张量$ {\mathbi{a}} $进行Softmax变换,沿最后一个方向 \\
\rule{0pt}{15pt} \texttt{HardTanh(a)} &$ {\mathbi{a}} $进行hard Tanh变换(双曲正切的近似) \\ \rule{0pt}{15pt} \texttt{HardTanh(a)} &张量$ {\mathbi{a}} $进行HardTanh变换(双曲正切的近似) \\
\rule{0pt}{15pt} \texttt{Rectify(a)} &$ {\mathbi{a}} $进行ReLU变换 \\ \rule{0pt}{15pt} \texttt{Rectify(a)} &张量$ {\mathbi{a}} $进行ReLU变换 \\
\end{tabular} \end{tabular}
\end{table} \end{table}
%-------------------------------------------------------------------- %--------------------------------------------------------------------
...@@ -1179,7 +1179,7 @@ y&=&{\textrm{Sigmoid}}({\textrm{Tanh}}({\mathbi{x}}\cdot {\mathbi{W}}^{[1]}+{\ma ...@@ -1179,7 +1179,7 @@ y&=&{\textrm{Sigmoid}}({\textrm{Tanh}}({\mathbi{x}}\cdot {\mathbi{W}}^{[1]}+{\ma
\label{eq:9-28} \label{eq:9-28}
\end{eqnarray} \end{eqnarray}
\noindent 其中,$ \widehat{\bm \theta} $表示在训练数据上使损失的平均值达到最小的参数,$n$为训练数据总量。$ \frac{1}{n}\sum_{i=1}^{n}{L({\mathbi{x}}_i,\widetilde{\mathbi{y}}_i;{\bm \theta})} $也被称作{\small\sffamily\bfseries{代价函数}}\index{代价函数}(Cost Function)\index{Cost Function},它是损失函数均值期望的估计,记为$ J({\bm \theta}) $ \noindent 其中,$ \widehat{\bm \theta} $表示在训练数据上使损失的平均值达到最小的参数,$n$为训练数据总量。$ \frac{1}{n}\sum \limits_{i=1}^{n}{L({\mathbi{x}}_i,\widetilde{\mathbi{y}}_i;{\bm \theta})} $也被称作{\small\sffamily\bfseries{代价函数}}\index{代价函数}(Cost Function)\index{Cost Function},它是损失函数均值期望的估计,记为$ J({\bm \theta}) $
\parinterval 参数优化的核心问题是:找到使代价函数$ J({\bm\theta}) $达到最小的$ \bm \theta $。然而$ J({\bm\theta}) $可能会包含大量的参数,比如,基于神经网络的机器翻译模型的参数量可能会超过一亿个。这时不可能用手动方法进行调参。为了实现高效的参数优化,比较常用的手段是使用{\small\bfnew{梯度下降方法}}\index{梯度下降方法}(The Gradient Descent Method)\index{The Gradient Descent Method} \parinterval 参数优化的核心问题是:找到使代价函数$ J({\bm\theta}) $达到最小的$ \bm \theta $。然而$ J({\bm\theta}) $可能会包含大量的参数,比如,基于神经网络的机器翻译模型的参数量可能会超过一亿个。这时不可能用手动方法进行调参。为了实现高效的参数优化,比较常用的手段是使用{\small\bfnew{梯度下降方法}}\index{梯度下降方法}(The Gradient Descent Method)\index{The Gradient Descent Method}
...@@ -1389,10 +1389,10 @@ $+2x^2+x+1)$ & \ \ $(x^4+2x^3+2x^2+x+1)$ & $+6x+1$ \\ ...@@ -1389,10 +1389,10 @@ $+2x^2+x+1)$ & \ \ $(x^4+2x^3+2x^2+x+1)$ & $+6x+1$ \\
\subsubsection{3. 基于梯度的方法的变种和改进}\label{sec:9.4.2.3} \subsubsection{3. 基于梯度的方法的变种和改进}\label{sec:9.4.2.3}
\parinterval 参数优化通常基于梯度下降算法,即在每个更新步骤$ t $,沿梯度反方向更新参数: \parinterval 参数优化通常基于梯度下降算法,即在每个更新步骤$ t $,沿梯度反方向更新参数,如公式\eqref{eq:9-200}所示
\begin{eqnarray} \begin{eqnarray}
{\bm \theta}_{t+1}&=&{\bm \theta}_{t}-\alpha \cdot \frac{\partial J({\bm \theta}_t)}{\partial {\bm \theta}_t} {\bm \theta}_{t+1}&=&{\bm \theta}_{t}-\alpha \cdot \frac{\partial J({\bm \theta}_t)}{\partial {\bm \theta}_t}
\label{} \label{eq:9-200}
\end{eqnarray} \end{eqnarray}
\noindent 其中,$ \alpha $是一个超参数,表示更新步幅的大小,称作学习率。当然,这是一种最基本的梯度下降方法。如果函数的形状非均向,比如呈延伸状,搜索最优点的路径就会非常低效,因为这时梯度的方向并没有指向最小值的方向,并且随着参数的更新,梯度方向往往呈锯齿状,这将是一条相当低效的路径;此外这种梯度下降算法并不是总能到达最优点,而是在其附近徘徊;还有一个最令人苦恼的问题\ \dash \ 设置学习率,如果学习率设置的比较小,会导致训练收敛速度慢,如果学习率设置的比较大,会导致训练过程中因为优化幅度过大而频频跳过最优点。我们希望网络在优化的时候损失函数有一个很好的收敛速度同时又不至于摆动幅度太大。 \noindent 其中,$ \alpha $是一个超参数,表示更新步幅的大小,称作学习率。当然,这是一种最基本的梯度下降方法。如果函数的形状非均向,比如呈延伸状,搜索最优点的路径就会非常低效,因为这时梯度的方向并没有指向最小值的方向,并且随着参数的更新,梯度方向往往呈锯齿状,这将是一条相当低效的路径;此外这种梯度下降算法并不是总能到达最优点,而是在其附近徘徊;还有一个最令人苦恼的问题\ \dash \ 设置学习率,如果学习率设置的比较小,会导致训练收敛速度慢,如果学习率设置的比较大,会导致训练过程中因为优化幅度过大而频频跳过最优点。我们希望网络在优化的时候损失函数有一个很好的收敛速度同时又不至于摆动幅度太大。
...@@ -1547,7 +1547,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f ...@@ -1547,7 +1547,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f
\parinterval 网络训练过程中,如果参数的初始值过大,而且每层网络的梯度都大于1,反向传播过程中,各层梯度的偏导数都会比较大,会导致梯度指数级地增长直至超出浮点数表示的范围,这就产生了梯度爆炸现象。如果发生这种情况,模型中离输入近的部分比离输入远的部分参数更新得更快,使网络变得非常不稳定。在极端情况下,模型的参数值变得非常大,甚至于溢出。针对梯度爆炸的问题,常用的解决办法为{\small\sffamily\bfseries{梯度裁剪}}\index{梯度裁剪}(Gradient Clipping)\index{Gradient Clipping} \parinterval 网络训练过程中,如果参数的初始值过大,而且每层网络的梯度都大于1,反向传播过程中,各层梯度的偏导数都会比较大,会导致梯度指数级地增长直至超出浮点数表示的范围,这就产生了梯度爆炸现象。如果发生这种情况,模型中离输入近的部分比离输入远的部分参数更新得更快,使网络变得非常不稳定。在极端情况下,模型的参数值变得非常大,甚至于溢出。针对梯度爆炸的问题,常用的解决办法为{\small\sffamily\bfseries{梯度裁剪}}\index{梯度裁剪}(Gradient Clipping)\index{Gradient Clipping}
\parinterval 梯度裁剪的思想是设置一个梯度剪切阈值。在更新梯度的时候,如果梯度超过这个阈值,就将其强制限制在这个范围之内。假设梯度为${\mathbi{g}}$,梯度剪切阈值为$\sigma $,梯度裁剪的公式为 \parinterval 梯度裁剪的思想是设置一个梯度剪切阈值。在更新梯度的时候,如果梯度超过这个阈值,就将其强制限制在这个范围之内。假设梯度为${\mathbi{g}}$,梯度剪切阈值为$\sigma $,梯度裁剪过程如公式\eqref{eq:9-43}所示
\begin{eqnarray} \begin{eqnarray}
{\mathbi{g}}&=&{\textrm{min}}(\frac{\sigma}{\Vert {\mathbi{g}}\Vert},1){\mathbi{g}} {\mathbi{g}}&=&{\textrm{min}}(\frac{\sigma}{\Vert {\mathbi{g}}\Vert},1){\mathbi{g}}
\label{eq:9-43} \label{eq:9-43}
...@@ -1607,7 +1607,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f ...@@ -1607,7 +1607,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f
\parinterval {\small\sffamily\bfseries{正则化}}\index{正则化}(Regularization)\index{Regularization}是常见的缓解过拟合问题的手段,通过在损失函数中加上用来刻画模型复杂程度的正则项来惩罚过度复杂的模型,从而避免神经网络过度学习造成过拟合。引入正则化处理之后目标函数变为$ J({\bm \theta})+\lambda R({\bm \theta}) $,其中$ J({\bm \theta}) $是原来的代价函数,$ R({\bm \theta}) $即为正则项,$ \lambda $用来调节正则项对结果影响的程度。 \parinterval {\small\sffamily\bfseries{正则化}}\index{正则化}(Regularization)\index{Regularization}是常见的缓解过拟合问题的手段,通过在损失函数中加上用来刻画模型复杂程度的正则项来惩罚过度复杂的模型,从而避免神经网络过度学习造成过拟合。引入正则化处理之后目标函数变为$ J({\bm \theta})+\lambda R({\bm \theta}) $,其中$ J({\bm \theta}) $是原来的代价函数,$ R({\bm \theta}) $即为正则项,$ \lambda $用来调节正则项对结果影响的程度。
\parinterval 过拟合的模型通常会表现为部分非零参数过多或者参数的值过大。这种参数产生的原因在于模型需要复杂的参数才能匹配样本中的个别现象甚至噪声。基于此,常见的正则化方法有L1正则化和L2正则化,其命名方式是由$ R({\bm \theta}) $的计算形式来决定的。在L1正则化中,$ R({\bm \theta}) $即为参数$ {\bm \theta} $$ l_1 $范数,即$ R({\bm \theta}) ={\Vert {\bm \theta}\Vert}_1=\sum_{i=1}^{n}{\vert \theta_i\vert} $;在L2正则化中,$ R(\bm \theta) $即为参数${\bm \theta} $$ l_2 $范数的平方,即$ R(\bm \theta) =({\Vert {\bm \theta}\Vert}_2)^2=\sum_{i=1}^{n}{\theta_i^2} $。L1正则化中的正则项衡量了模型权数中的绝对值大小,倾向于生成值为0的参数,从而让参数变得更加稀疏;而L2正则化由于平方的加入,当参数中的某一项小到一定程度,比如0.001的时候,参数的平方结果已经可以忽略不计了,因此L2正则化会倾向生成很小的参数,在这种情况下,即便训练数据中含有少量随机噪音,模型也不太容易通过增加个别参数的值来对噪声进行过度拟合,即提高了模型的抗扰动能力。 \parinterval 过拟合的模型通常会表现为部分非零参数过多或者参数的值过大。这种参数产生的原因在于模型需要复杂的参数才能匹配样本中的个别现象甚至噪声。基于此,常见的正则化方法有L1正则化和L2正则化,其命名方式是由$ R({\bm \theta}) $的计算形式来决定的。在L1正则化中,$ R({\bm \theta}) $即为参数$ {\bm \theta} $$ l_1 $范数,即$ R({\bm \theta}) ={\Vert {\bm \theta}\Vert}_1=\sum\limits_{i=1}^{n}{\vert \theta_i\vert} $;在L2正则化中,$ R(\bm \theta) $即为参数${\bm \theta} $$ l_2 $范数的平方,即$ R(\bm \theta) =({\Vert {\bm \theta}\Vert}_2)^2=\sum\limits_{i=1}^{n}{\theta_i^2} $。L1正则化中的正则项衡量了模型权数中的绝对值大小,倾向于生成值为0的参数,从而让参数变得更加稀疏;而L2正则化由于平方的加入,当参数中的某一项小到一定程度,比如0.001的时候,参数的平方结果已经可以忽略不计了,因此L2正则化会倾向生成很小的参数,在这种情况下,即便训练数据中含有少量随机噪音,模型也不太容易通过增加个别参数的值来对噪声进行过度拟合,即提高了模型的抗扰动能力。
\parinterval 此外,在{\chaptertwelve}即将介绍的Dropout和标签平滑方法也可以被看作是一种正则化操作。它们都可以提高模型在未见数据上的泛化能力。 \parinterval 此外,在{\chaptertwelve}即将介绍的Dropout和标签平滑方法也可以被看作是一种正则化操作。它们都可以提高模型在未见数据上的泛化能力。
...@@ -1946,7 +1946,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f ...@@ -1946,7 +1946,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f
\label{eq:9-120} \label{eq:9-120}
\end{eqnarray} \end{eqnarray}
\noindent 这里,exp($\cdot$)表示指数函数。Softmax函数是一个典型的标准化函数,它可以将输入的向量的每一维都转化为0-1之间的数,同时保证所有维的和等于1。Softmax的另一个优点是,它本身(对于输出的每一维)都是可微的(如图\ref{fig:softmax}所示),因此可以直接使用基于梯度的方法进行优化。实际上,Softmax经常被用于分类任务。也可以把机器翻译中目标语单词的生成看作一个分类问题,它的类别数是|$V$|。 \noindent 这里,exp($\cdot$)表示指数函数。Softmax函数是一个典型的归一化函数,它可以将输入的向量的每一维都转化为0-1之间的数,同时保证所有维的和等于1。Softmax的另一个优点是,它本身(对于输出的每一维)都是可微的(如图\ref{fig:softmax}所示),因此可以直接使用基于梯度的方法进行优化。实际上,Softmax经常被用于分类任务。也可以把机器翻译中目标语单词的生成看作一个分类问题,它的类别数是|$V$|。
%---------------------------------------------- %----------------------------------------------
\begin{figure}[htp] \begin{figure}[htp]
...@@ -1965,7 +1965,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f ...@@ -1965,7 +1965,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f
\parinterval 值得注意的是,在FNNLM中,单词已经不再是一个孤立的符号串,而是被表示为一个实数向量。这样,两个单词之间可以通过向量计算某种相似度或距离。这导致相似的单词会具有相似的分布,进而缓解$n$-gram语言模型的问题\ \dash \ 明明意思很相近的两个词但是概率估计的结果差异性却很大。 \parinterval 值得注意的是,在FNNLM中,单词已经不再是一个孤立的符号串,而是被表示为一个实数向量。这样,两个单词之间可以通过向量计算某种相似度或距离。这导致相似的单词会具有相似的分布,进而缓解$n$-gram语言模型的问题\ \dash \ 明明意思很相近的两个词但是概率估计的结果差异性却很大。
\parinterval 在FNNLM中,所有的参数、输入、输出都是连续变量,因此FNNLM也是典型的一个连续空间模型。通过使用交叉熵等损失函数,FNNLM很容易进行优化。比如,可以使用梯度下降方法对FNNLM的模型参数进行训练。 \parinterval 在FNNLM中,所有的参数、输入、输出都是连续变量,因此FNNLM也是一个典型的连续空间模型。通过使用交叉熵等损失函数,可以很容易地对FNNLM进行优化。比如,可以使用梯度下降方法对FNNLM的模型参数进行训练。
\parinterval 虽然FNNLM形式简单,却为处理自然语言提供了一个全新的视角。首先,该模型重新定义了“词是什么”\ \dash \ 它并非词典的一项,而是可以用一个连续实数向量进行表示的可计算的“量”。此外,由于$n$-gram不再是离散的符号序列,模型不需要记录$n$-gram,所以很好的缓解了上面所提到的数据稀疏问题,模型体积也大大减小。 \parinterval 虽然FNNLM形式简单,却为处理自然语言提供了一个全新的视角。首先,该模型重新定义了“词是什么”\ \dash \ 它并非词典的一项,而是可以用一个连续实数向量进行表示的可计算的“量”。此外,由于$n$-gram不再是离散的符号序列,模型不需要记录$n$-gram,所以很好的缓解了上面所提到的数据稀疏问题,模型体积也大大减小。
...@@ -2024,7 +2024,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f ...@@ -2024,7 +2024,7 @@ z_t&=&\gamma z_{t-1}+(1-\gamma) \frac{\partial J}{\partial {\theta}_t} \cdot \f
\parinterval 针对这个问题,一种解决方法是使用卷积神经网络\upcite{Pham2016ConvolutionalNN}。卷积神经网络的特点是可以对一定窗口大小内的连续单词进行统一建模,这样非常易于捕捉窗口内单词之间的依赖,同时对它们进行整体的表示。进一步,卷积操作可以被多次叠加使用,通过更多层的卷积神经网络可以捕捉更大范围的依赖关系。关于卷积神经网络及其在机器翻译中的应用,{\chaptereleven}会有详细论述。 \parinterval 针对这个问题,一种解决方法是使用卷积神经网络\upcite{Pham2016ConvolutionalNN}。卷积神经网络的特点是可以对一定窗口大小内的连续单词进行统一建模,这样非常易于捕捉窗口内单词之间的依赖,同时对它们进行整体的表示。进一步,卷积操作可以被多次叠加使用,通过更多层的卷积神经网络可以捕捉更大范围的依赖关系。关于卷积神经网络及其在机器翻译中的应用,{\chaptereleven}会有详细论述。
\parinterval 此外,研究者也提出了另一种新的结构$\ \dash \ ${\small\bfnew{自注意力机制}}\index{自注意力机制}(Self-attention Mechanism)\index{Self-attention Mechanism}。自注意力是一种特殊的神经网络结构,它可以对序列上任意两个词的相互作用直接进行建模,这样也就避免了循环神经网络中随着距离变长信息传递步骤增多的缺陷。在自然语言处理领域,自注意力机制被成功地应用在机器翻译任务上,形成了著名的Transformer模型\upcite{vaswani2017attention}{\chaptertwelve}会系统地介绍自注意力机制和Transformer模型。 \parinterval 此外,研究者也提出了另一种新的结构$\ \dash \ ${\small\bfnew{自注意力机制}}\index{自注意力机制}(Self-attention Mechanism)\index{Self-attention Mechanism}。自注意力是一种特殊的神经网络结构,它可以对序列上任意两个词的相互作用直接进行建模,这样也就避免了循环神经网络中随着距离变长信息传递步骤增多的缺陷。在自然语言处理领域,自注意力机制被成功地应用在机器翻译任务上,著名的Transformer模型\upcite{vaswani2017attention}就是基于该原理工作的{\chaptertwelve}会系统地介绍自注意力机制和Transformer模型。
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
% NEW SUB-SECTION % NEW SUB-SECTION
......
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
\node [partnode,anchor=south,orange,minimum height=11.5em,minimum width=18.1em,fill=white] (part2) at ([yshift=3em]part1.north west) {}; \node [partnode,anchor=south,orange,minimum height=11.5em,minimum width=18.1em,fill=white] (part2) at ([yshift=3em]part1.north west) {};
\node [anchor=north] (part2label) at ([yshift=-0.3em]part2.north) {\sffamily\bfseries{统计机器翻译}}; \node [anchor=north] (part2label) at ([yshift=-0.3em]part2.north) {\sffamily\bfseries{统计机器翻译}};
\node [anchor=north west,draw=orange,thick,fill=white,rounded corners] (part2title) at ([xshift=-0.3em,yshift=0.3em]part2.north west) {{\color{orange} {\sffamily\bfseries 第二部分}}}; \node [anchor=north west,draw=orange,thick,fill=white,rounded corners] (part2title) at ([xshift=-0.3em,yshift=0.3em]part2.north west) {{\color{orange} {\sffamily\bfseries 第二部分}}};
\node [secnode,anchor=south,fill=orange!20,minimum width=17em,align=left] (sec04) at ([yshift=0.5em]part2.south) {四章\hspace{1em} 基于词的机器翻译建模 \hspace{2.0em}}; \node [secnode,anchor=south,fill=orange!20,minimum width=17em,align=left] (sec04) at ([yshift=0.5em]part2.south) {五章\hspace{1em} 基于词的机器翻译建模 \hspace{2.35em}};
\node [secnode,anchor=south,fill=orange!20,minimum width=17em,align=center] (sec05) at ([yshift=0.8em]sec04.north) {第五章\hspace{1em} 基于扭曲度和繁衍率的模型}; \node [secnode,anchor=south,fill=orange!20,minimum width=17em,align=center] (sec05) at ([yshift=0.8em]sec04.north) {\hspace{1.4em}第六章\hspace{1em} 基于扭曲度和繁衍率的翻译模型};
\node [secnode,anchor=south,fill=orange!20,minimum width=17em,align=center] (sec06) at ([yshift=0.8em]sec05.north) {六章\hspace{1em} 基于短语的模型 \hspace{4.7em}}; \node [secnode,anchor=south,fill=orange!20,minimum width=17em,align=center] (sec06) at ([yshift=0.8em]sec05.north) {七章\hspace{1em} 基于短语的模型 \hspace{5.35em}};
\node [secnode,anchor=south,fill=orange!20,minimum width=17em,align=center] (sec07) at ([yshift=0.8em]sec06.north) {七章\hspace{1em} 基于句法的模型 \hspace{4.7em}}; \node [secnode,anchor=south,fill=orange!20,minimum width=17em,align=center] (sec07) at ([yshift=0.8em]sec06.north) {八章\hspace{1em} 基于句法的模型 \hspace{5.35em}};
\draw [->,very thick] ([yshift=-0.7em]sec05.south) -- ([yshift=-0.1em]sec05.south); \draw [->,very thick] ([yshift=-0.7em]sec05.south) -- ([yshift=-0.1em]sec05.south);
\draw [->,very thick] ([yshift=-0.7em]sec06.south) -- ([yshift=-0.1em]sec06.south); \draw [->,very thick] ([yshift=-0.7em]sec06.south) -- ([yshift=-0.1em]sec06.south);
\draw [->,very thick] ([yshift=-0.7em]sec07.south) -- ([yshift=-0.1em]sec07.south); \draw [->,very thick] ([yshift=-0.7em]sec07.south) -- ([yshift=-0.1em]sec07.south);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -527,7 +527,7 @@ innerbottommargin=5pt]{cBox} ...@@ -527,7 +527,7 @@ innerbottommargin=5pt]{cBox}
%---------------------------------------------------------------------------------------- %----------------------------------------------------------------------------------------
\usepackage{hyperref} \usepackage{hyperref}
\hypersetup{hidelinks,backref=true,pagebackref=true,hyperindex=true,colorlinks=false,breaklinks=true,urlcolor=ocre,bookmarks=true,bookmarksopen=true} \hypersetup{hidelinks,colorlinks=false,breaklinks=true,urlcolor=ocre,bookmarksopen=true}
%backref反向引用 %backref反向引用
%pagebackref反向引用页码 %pagebackref反向引用页码
%hyperindex索引链接 %hyperindex索引链接
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论