Commit 4aeb846b by xiaotong

updates of section 7

parent e8c5a116
......@@ -775,11 +775,13 @@ y_{j}^{ls}=(1-\alpha) \cdot \tilde{y}_j + \alpha \cdot q
\parinterval 下面就列举一些常用的神经机器翻译加速方法。这些方法通常是应用在解码器端,因为相比编码器,神经机器翻译的解码器是推断过程中最耗时的部分。
%%%%%%%%%%%%%%%%%%
\noindent {\small\bfnew{输出层的词汇选择}}
\vspace{0.5em}
\noindent {\small\bfnew{a) 输出层的词汇选择}}
\vspace{0.5em}
\parinterval 神经机器翻译需要对输入和输出的单词进行分布式表示,比如,每一个单词都用一个512维向量进行表示。但是,由于真实的词表通常很大,因此计算并保存这些单词向量表示就会消耗较多的计算和存储资源。特别是对于基于Softmax的输出层,使用大词表往往会占用较多的系统运算时间。虽然可以通过BPE和限制词汇表规模的方法降低输出层计算的负担,但是为了获得可接受的翻译品质,词汇表也不能过小(比如小于10000),输出层仍然十分耗时。
\parinterval 对于这个问题,可以通过改变输出层的网络结构进行缓解\cite{luong2016acl_hybrid}。一种比较简单的方法是对可能输出的单词进行筛选,简称词汇选择。我们可以利用类似于统计机器翻译的翻译表,获得每个源语言单词最可能的译文。在翻译过程中,利用注意力机制找到每个目标语位置对应的源语言位置,之后获得这些源语言单词最可能的翻译候选。之后,Softmax只需要在这个有限的翻译候选单词集合上计算,大大降低了输出层的计算量。尤其是对于CPU上的系统,这个方法往往会带来明显的速度提升,同时保证翻译品质。图\ref{fig:7-20}给出了词汇选择方法的示意图。
\parinterval 对于这个问题,可以通过改变输出层的网络结构进行缓解\cite{luong2016acl_hybrid}。一种比较简单的方法是对可能输出的单词进行筛选,简称词汇选择。这里,可以利用类似于统计机器翻译的翻译表,获得每个源语言单词最可能的译文。在翻译过程中,利用注意力机制找到每个目标语位置对应的源语言位置,之后获得这些源语言单词最可能的翻译候选。之后,Softmax只需要在这个有限的翻译候选单词集合上计算,大大降低了输出层的计算量。尤其是对于CPU上的系统,这个方法往往会带来明显的速度提升,同时保证翻译品质。图\ref{fig:7-20}给出了词汇选择方法的示意图。
%----------------------------------------------
% 图7.
......@@ -792,56 +794,62 @@ y_{j}^{ls}=(1-\alpha) \cdot \tilde{y}_j + \alpha \cdot q
%----------------------------------------------
%%%%%%%%%%%%%%%%%%
\noindent {\small\bfnew{消除冗余计算}}
\vspace{0.5em}
\noindent {\small\bfnew{b) 消除冗余计算}}
\vspace{0.5em}
\parinterval 消除不必要的计算是加速机器翻译的常用技术。比如,在统计机器翻译时代,假设重组就是一种典型的避免冗余计算的手段(第四章)。对于神经机器翻译中的Transformer模型,一种简单有效的方法是对解码端的注意力结果进行缓存。在生成每个目标语译文时,Transformer模型会对当前位置之前所有位置进行自注意力操作,但是这些计算里只有和当前位置相关的计算是``新''的,前面位置之间的注意力结果已经在之前的解码步骤里计算过,因此可以对其进行缓存。
\parinterval 此外,由于Transformer模型较为复杂,还存在很多冗余。比如,Transformer的每一层会包含自注意力机制、层正则化、残差连接、前馈神经网络等多种不同的结构。同时,不同结构之间还会包含一些线性变换。多层Transformer(通常为6层)模型会更加复杂。但是,这些层可能在做相似的事情,甚至有些计算根本就是重复的。图\ref{fig:7-21}中展示了解码端自注意力和编码-解码注意力中不同层的注意力权重的相似性,其中相似性利用Jensen-Shannon散度进行度量。可以看到,自注意力中,2-5层之间的注意力权重的分布非常相似。编码-解码注意力也有类似的现象,临近的层之间有非常相似的注意力权重。这个现象说明:在多层神经网络中有些计算是冗余的,因此很自然的想法是消除这些冗余使得机器翻译变得更``轻''。
\parinterval 此外,由于Transformer模型较为复杂,还存在很多冗余。比如,Transformer的每一层会包含自注意力机制、层正则化、残差连接、前馈神经网络等多种不同的结构。同时,不同结构之间还会包含一些线性变换。多层Transformer(通常为6层)模型会更加复杂。但是,这些层可能在做相似的事情,甚至有些计算根本就是重复的。图\ref{fig:7-21}中展示了解码端自注意力和编码-解码注意力中不同层的注意力权重的相似性,这里的相似性利用Jensen-Shannon散度进行度量({\red 参考文献!}。可以看到,自注意力中,2-5层之间的注意力权重的分布非常相似。编码-解码注意力也有类似的现象,临近的层之间有非常相似的注意力权重。这个现象说明:在多层神经网络中有些计算是冗余的,因此很自然的想法是消除这些冗余使得机器翻译变得更``轻''。
%----------------------------------------------
% 图7.
\begin{figure}[htp]
\centering
\input{./Chapter7/Figures/figure-weight-similarity}
\caption{自注意力和编码-解码注意力中注意力权重的相似性(深色表示相似)}
\caption{自注意力和编码-解码注意力中不同层之间注意力权重的相似性(深色表示相似)}
\label{fig:7-21}
\end{figure}
%----------------------------------------------
\parinterval 一种方法是将不同层的注意力权重进行共享,这样上层的注意力权重可以复用下层的注意力权重。在编码-解码注意力中,由于注意力机制中输入的Value都是一样的 \footnote{在Transformer解码端,编码-解码注意力输入的Value是编码端的输出,因此是相同的(详见第六章Transformer模型介绍的内容)。},我们甚至可以直接复用前一层注意力计算的结果。图\ref{fig:7-22}给出了不同方法的对比,其中$S$表示注意力权重,$A$表示注意机制的输出。可以看到,使用共享的思想,可以大大减少冗余的计算。当然,这种方法也可能会带来翻译精度的损失。在WMT的多个任务上发现,使用层共享的方法可以带来20\%以上的提速,同时BLEU的浮动在0.2个点左右\cite{Xiao2019SharingAW}
\parinterval 一种方法是将不同层的注意力权重进行共享,这样上层的注意力权重可以复用下层的注意力权重。在编码-解码注意力中,由于注意力机制中输入的Value都是一样的 \footnote{在Transformer解码端,编码-解码注意力输入的Value是编码端的输出,因此是相同的(详见第六章关于Transformer模型的内容)。},我们甚至可以直接复用前一层注意力计算的结果。图\ref{fig:7-22}给出了不同方法的对比,其中$S$表示注意力权重,$A$表示注意机制的输出。可以看到,使用共享的思想,可以大大减少冗余的计算。当然,这种方法也可能会带来翻译精度的损失。在WMT的多个任务上发现,使用层共享的方法可以带来20\%以上的提速,同时BLEU的浮动在0.2个点左右\cite{Xiao2019SharingAW}
%----------------------------------------------
% 图7.
\begin{figure}[htp]
\centering
\input{./Chapter7/Figures/figure-comparison-of-different-attention-method}
\caption{标准的多层自注意力、共享自注意力、共享编码-解码注意力方法的对比}
\caption{标准的多层自注意力、共享自注意力、共享编码-解码注意力方法的对比\cite{Xiao2019SharingAW}}
\label{fig:7-22}
\end{figure}
%----------------------------------------------
\parinterval 另一种方法是对不同层的参数进行共享。这种方法虽然不能带来直接的提速,但是可以大大减小模型的体积。比如,可以重复使用同一层的参数完成多层的计算。极端一些的情况下,六层网络可以只是用一层网络的参数\cite{DBLP:conf/aaai/DabreF19}。不过,在深层模型中(层数>20),浅层部分的差异往往较大,而深层(远离输出)之间的相似度会更高。这时可以考虑对深层的部分进行更多的共享。
\parinterval 另一种方法是对不同层的参数进行共享。这种方法虽然不能带来直接的提速,但是可以大大减小模型的体积。比如,可以重复使用同一层的参数完成多层的计算。极端一些的情况下,六层网络可以只是用一层网络的参数\cite{DBLP:conf/aaai/DabreF19}。不过,在深层模型中(层数$>20$),浅层部分的差异往往较大,而深层(远离输出)之间的相似度会更高。这时可以考虑对深层的部分进行更多的共享。
%%%%%%%%%%%%%%%%%%
\noindent {\small\bfnew{轻量解码端及小模型}}
\vspace{0.5em}
\noindent {\small\bfnew{c) 轻量解码端及小模型}}
\vspace{0.5em}
\parinterval 在推断时,神经机器翻译的解码端是最耗时的,因为每个目标语位置需要单独输出单词的分布,同时在搜索过程中每一个翻译假设都要被扩展成多个翻译假设,进一步增加了计算量。因此,另一种加速系统的思路是使用更加轻量的解码器神经网络。
\parinterval 比较简单的做法是直接把解码端的网络变得更``浅''、更``窄''。所谓浅网络是指使用更少的层构建神经网络,比如,使用3层,甚至1层网络的Transformer解码器。所谓窄网络是指将网络中某些层中神经元的数量减少。不过,直接训练这样的小模型会带来翻译品质的下降。这时会考虑使用知识精炼(见\ref{subsection-7.5.3}节)或深层解码器(见\ref{subsection-7.3.1}节)配合基于小模型的解码网络一起使用。
\parinterval 比较简单的做法是把解码端的网络变得更``浅''、更``窄''。所谓浅网络是指使用更少的层构建神经网络,比如,使用3层,甚至1层网络的Transformer解码器。所谓窄网络是指将网络中某些层中神经元的数量减少。不过,直接训练这样的小模型会带来翻译品质的下降。这时会考虑使用知识精炼(见\ref{subsection-7.5.3}节)或深层编码器(见\ref{subsection-7.3.1}节)配合基于小模型的解码神经网络一起使用。
\parinterval 另一种思路是化简Transformer的解码端神经网络。比如,可以使用平均注意力机制代替原始的Transformer自注意力机制\cite{DBLP:journals/corr/abs-1805-00631},也可以使用运算更轻的卷积操作代替注意力模块\cite{Wu2019PayLA}。前面提到的基于共享注意力机制的模型也是一种典型的轻量模型\cite{Xiao2019SharingAW}
\parinterval 此外,使用异构神经网络也是一种平衡精度和速度的有效方法。在很多研究中发现,基于Transformer的编码端对翻译品质的影响更大,但是解码端的作用会小一些。因此,一种容易想到的想法就是用更快速的解码端结构,比如,用基于循环神经网络的解码端替换基于Transformer的解码端\cite{Chen2018TheBO}。这样,既能发挥Transformer在编码上的优势,同时也能利用循环神经网络在解码端速度上的优势。使用类似的思想,也可以用卷积网络等结构进行解码端网络的设计。
\parinterval 此外,使用异构神经网络也是一种平衡精度和速度的有效方法。在很多研究中发现,基于Transformer的编码器对翻译品质的影响更大,但是解码端的作用会小一些。因此,一种想法是用更快速的解码端结构,比如,用基于循环神经网络的解码端替换基于Transformer的解码端\cite{Chen2018TheBO}。这样,既能发挥Transformer在编码上的优势,同时也能利用循环神经网络在解码端速度上的优势。使用类似的思想,也可以用卷积网络等结构进行解码端网络的设计。
%%%%%%%%%%%%%%%%%%
\noindent {\small\bfnew{批量推断}}
\vspace{0.5em}
\noindent {\small\bfnew{d) 批量推断}}
\vspace{0.5em}
\parinterval 深度学习时代下,使用GPU(图形处理单元)已经是成为的绝大多数神经网络模型研究的基本要求。特别是对于像机器翻译这样的复杂任务, GPU的并行运算能力会带来明显的速度提升。为了充分利用GPU的并行能力,一种方法是同时对多个句子进行翻译,即{\small\bfnew{批量推断}}\index{批量推断}(Batch Inference)\index{Batch Inference}
\parinterval 深度学习时代下,使用GPU(图形处理单元)已经是成为的绝大多数神经网络模型研究的基本要求。特别是对于像机器翻译这样的复杂任务, GPU的并行运算能力会带来明显的速度提升。为了充分利用GPU的并行能力,可以同时对多个句子进行翻译,即{\small\bfnew{批量推断}}\index{批量推断}(Batch Inference)\index{Batch Inference}
\parinterval 在第六章已经介绍了神经机器翻译中{\small\bfnew{批量处理}}\index{批量处理}(Batching)\index{Batching}的基本概念。其实现并不困难,不过有两方面问题需要注意:
\begin{itemize}
\item 批次生成策略。对于源语言文本预先给定的情况,通常是按句子长度组织每个批次,即:把长度相似的句法放到一个批次里。这样做的好处是可以尽可能保证一个批次中的内容是``满''的,否则如果句长差异过大会造成批次中有很多位置用占位符填充,产生无用计算。对于实时翻译的情况,批次的组织较为复杂。由于有翻译延时的限制,可能无法等到有足够多的句子就要进行翻译。常见的做法是,设置一个等待的时间,在同一个时间段中的句子可以放到一个批次中(或者几个批次中)。对于高并发的情况,也可以考虑使用不同的Bucket保存不同长度范围的句子,之后将同一个Bucket中的句子进行批量推断。
\item 批次生成策略。对于源语言文本预先给定的情况,通常是按句子长度组织每个批次,即:把长度相似的句法放到一个批次里。这样做的好处是可以尽可能保证一个批次中的内容是``满''的,否则如果句长差异过大会造成批次中有很多位置用占位符填充,产生无用计算。对于实时翻译的情况,批次的组织较为复杂。由于有翻译延时的限制,可能无法等到有足够多的句子就要进行翻译。常见的做法是,设置一个等待的时间,在同一个时间段中的句子可以放到一个批次中(或者几个批次中)。对于高并发的情况,也可以考虑使用不同的Bucket保存不同长度范围的句子,之后将同一个Bucket中的句子进行批量推断。
\item 批次大小的选择。一个批次中的句子数量越多,GPU设备的利用率越高,系统吞吐越大。但是,一个批次中所有句子翻译结束后才能拿到翻译结果,因此批次中有些句子即使已经翻译结束也要等待其它没有完成的句子。也就是说,从单个句子来看,批次越大翻译的延时越长,这也导致在翻译实时性要求较高的场景中,不能使用过大的批次。而且,大批次对GPU显存的消耗更大。因此合理选择批次大小也需要根据具体任务进行调整。为了说明这些问题,图\ref{fig:7-23}展示了不同批次大小下的吞吐、延时和显存消耗。
\end{itemize}
......@@ -857,15 +865,20 @@ y_{j}^{ls}=(1-\alpha) \cdot \tilde{y}_j + \alpha \cdot q
%----------------------------------------------
%%%%%%%%%%%%%%%%%%
\noindent {\small\bfnew{低精度运算}}
\vspace{0.5em}
\noindent {\small\bfnew{e) 低精度运算}}
\vspace{0.5em}
\parinterval 降低运算强度也是计算密集型任务的加速手段之一。标准的神经机器翻译系统大多基于单精度浮点运算。从计算机的硬件发展看,单精度浮点运算还是很``重''的。当计算不需要单精度或者能容忍一些精度损失的时候,可以考虑降低运算精度来达到加速的目的。比如:
\parinterval 降低运算强度也是计算密集型任务的加速手段之一。标准的神经机器翻译系统大多基于单精度浮点运算。从计算机的硬件发展看,单精度浮点运算还是很``重''的。当计算能容忍一些精度损失的时候,可以考虑降低运算精度来达到加速的目的。比如:
\begin{itemize}
\item 半精度运算。半精度运算是随着近几年GPU技术发展而逐渐流行的一种运算方式。简单来说,半精度的表示要比单精度需要更少的存储单元,所表示的浮点数范围也有相应的变小。不过,实践中已经证明神经机器翻译中的许多运算用半精度计算就可以满足对精度的要求。因此,直接使用半精度运算可以大大加速系统的训练和推断进程,同时对翻译品质的影响很小。不过,需要注意的是,在分布式训练的时候,由于参数服务器需要对多个计算节点上的梯度进行累加,因此保存参数的部分仍然会使用单精度浮点以保证多次累加之后不会造成精度的损失。
\vspace{0.3em}
\item 半精度运算。半精度运算是随着近几年GPU技术发展而逐渐流行的一种运算方式。简单来说,半精度的表示要比单精度需要更少的存储单元,所表示的浮点数范围也相应的变小。不过,实践中已经证明神经机器翻译中的许多运算用半精度计算就可以满足对精度的要求。因此,直接使用半精度运算可以大大加速系统的训练和推断进程,同时对翻译品质的影响很小。不过,需要注意的是,在分布式训练的时候,由于参数服务器需要对多个计算节点上的梯度进行累加,因此保存参数的部分仍然会使用单精度浮点以保证多次累加之后不会造成精度的损失。
\item 整型运算。整数运算是一种比浮点运算``轻''很多的运算。无论是芯片占用面积、能耗还是处理单次运算的时钟周期数,整数运算相比浮点运算都有着明显的优势。因此,使用整数运算也是很有潜力的加速手段。不过,整数的表示和浮点数有着很大的不同。一个基本的问题是,整数是不连续的,因此无法准确的刻画浮点数中很小的小数。对于这个问题,一种解决方法是利用``量化+反量化+缩放''的策略让整数运算近似浮点运算的效果 \cite{DBLP:journals/corr/abs-1906-00532}\cite{DBLP:journals/corr/abs-1712-05877}\cite{DBLP:journals/corr/abs-1910-10485})。所谓``量化''和``反量化''就是把一个浮点数离散化为一个整数,以及这个过程的逆过程。由于浮点数可能超出整数的范围,因此会引入一个缩放因子。在量化前将浮点数缩放到整数可以表示的范围,反量化前再缩放回原始浮点数的表示范围。这种方法在理论上可以带来很好的加速效果。不过由于量化和反量化的操作本身也有时间消耗,而且在不同处理器上的表现差异较大。因此不同的实现方式带来的加速效果并不相同,需要通过实验测算。
\vspace{0.3em}
\item 整型运算。整数运算是一种比浮点运算``轻''很多的运算。无论是芯片占用面积、能耗还是处理单次运算的时钟周期数,整数运算相比浮点运算都有着明显的优势。因此,使用整数运算也是很有潜力的加速手段。不过,整数的表示和浮点数有着很大的不同。一个基本的问题是,整数是不连续的,因此无法准确的刻画浮点数中很小的小数。对于这个问题,一种解决方法是利用``量化+反量化+缩放''的策略让整数运算近似浮点运算的效果 \cite{DBLP:journals/corr/abs-1906-00532}\cite{DBLP:journals/corr/abs-1712-05877}\cite{DBLP:journals/corr/abs-1910-10485})。所谓``量化''就是把一个浮点数离散化为一个整数,``反量化''是这个过程的逆过程。由于浮点数可能超出整数的范围,因此会引入一个缩放因子。在量化前将浮点数缩放到整数可以表示的范围,反量化前再缩放回原始浮点数的表示范围。这种方法在理论上可以带来很好的加速效果。不过由于量化和反量化的操作本身也有时间消耗,而且在不同处理器上的表现差异较大。因此不同的实现方式带来的加速效果并不相同,需要通过实验测算。
\vspace{0.3em}
\item 低精度整形运算。使用更低精度的整形运算是进一步加速的手段之一。比如使用16位整数、8位整数,甚至4位整数在理论上都会带来速度的提升(表\ref{tab:Comparison-of-occupied-area-and-computing-speed})。不过,并不是所有处理器都支持低精度整数的运算。开发这样的系统,一般需要硬件和特殊低精度整数计算库的支持。而且相关计算大多是在CPU上实现,应用会受到一定的限制。
%----------------------------------------------
......@@ -876,27 +889,31 @@ y_{j}^{ls}=(1-\alpha) \cdot \tilde{y}_j + \alpha \cdot q
\label{tab:Comparison-of-occupied-area-and-computing-speed}
\begin{tabular}{ l | l l l l l}
\rule{0pt}{13pt} 指标 & FP32 &INT32 &INT16 &INT8 &INT4 \\ \hline
\rule{0pt}{13pt} 速度 & 1 & 3$\sim$4 & $\approx$4 & 4$\sim$6 & $\approx$8
\rule{0pt}{13pt} 速度 & 1$\times$ & 3$\sim$4$\times$ & $\approx$4$\times$ & 4$\sim$6$\times$ & $\approx$8$\times$
\end{tabular}
\end{table}
\footnotetext{表中比较了几种通用数据类型的乘法运算速度,不同硬件和架构上不同类型的数据的计算速度略有不同。总体来看整型数据类型和浮点型数据相比具有显著的计算速度优势,INT4相比于FP32数据类型的计算最高能达到8倍的速度提升。}
%--------------------------------------
\vspace{0.3em}
\end{itemize}
\parinterval 实际上,低精度表示的另一个好处是可以减少模型存储的体积。比如,如果要把机器翻译模型作为软件的一部分打包存储,这时可以考虑用低精度的方式保存模型参数,使用时再恢复成原始精度的参数。值得注意的是,参数的离散化表示(比如整形表示)的一个极端例子是二值网络(Binarized neural networks)\cite{Hubara2016BinarizedNN},即只用-1和1表示网络的每个参数。二值化可以被看作是一种极端的量化手段。不过,这类方法还没有在机器翻译中得到大规模验证。
\parinterval 实际上,低精度表示的另一个好处是可以减少模型存储的体积。比如,如果要把机器翻译模型作为软件的一部分打包存储,这时可以考虑用低精度的方式保存模型参数,使用时再恢复成原始精度的参数。值得注意的是,参数的离散化表示(比如整形表示)的一个极端例子是{\small\bfnew{二值网络}}\index{二值网络}(Binarized Neural Networks)\index{Binarized Neural Networks}\cite{Hubara2016BinarizedNN},即只用$-1$$+1$表示网络的每个参数。二值化可以被看作是一种极端的量化手段。不过,这类方法还没有在机器翻译中得到大规模验证。
%%%%%%%%%%%%%%%%%%
\noindent {\small\bfnew{非自回归翻译}}
\vspace{0.5em}
\noindent {\small\bfnew{f) 非自回归翻译}}
\vspace{0.5em}
\parinterval 神经机器翻译的推断是一种自回归翻译(Autoregressive Translation)过程。所谓自回归是一种描述时间序列生成的方式。对于序列$\{ x_1,...,x_m \}$,自回归模型假设$i$时刻状态$x_i$的生成依赖于之前的状态$\{ x_1,...,x_{i-1} \}$,而且$x_i$$\{ x_1,...,x_{i-1} \}$构成线性关系。神经机器翻译借用了这个概念,但是并不要求线性模型。对于输入的源语言序列$\mathbf{x}=\{ x_1,...,x_m \}$,用自回归翻译模型生成译文序列$\mathbf{y}=\{ y_1,...,y_n \}$的概率可以被定义为:
\parinterval 神经机器翻译的推断是一种{\small\bfnew{自回归翻译}}\index{自回归翻译}(Autoregressive Translation)\index{Autoregressive Translation}过程。所谓自回归是一种描述时间序列生成的方式。对于序列$\{ x_1,...,x_m \}$,自回归模型假设$i$时刻状态$x_i$的生成依赖于之前的状态$\{ x_1,...,x_{i-1} \}$,而且$x_i$$\{ x_1,...,x_{i-1} \}$构成线性关系。神经机器翻译借用了这个概念,但是并不要求线性模型。对于输入的源语言序列$\mathbf{x}=\{ x_1,...,x_m \}$,用自回归翻译模型生成译文序列$\mathbf{y}=\{ y_1,...,y_n \}$的概率可以被定义为:
\begin{eqnarray}
\textrm{P}(\mathbf{y}|\mathbf{x}) = \prod_{j=1}^{n} \textrm{P}(y_j|y_1,...,y_{j-1},\mathbf{x})
\textrm{P}(\mathbf{y}|\mathbf{x}) = \prod_{j=1}^{n} \textrm{P}(y_j|\mathbf{y}_{<j},\mathbf{x})
\label{eqC7.6}
\end{eqnarray}
\noindent 即译文单词$y_j$依赖前面已经生成的单词$\{y_1,...,y_{j-1}\}$和源语言句子$\mathbf{x}$。显然,这个模型中,每一个目标语位置$j$都需要等待前面$j-1$个位置输出的结果。因此,自回归翻译会阻碍不同译文单词生成的并行化。特别是在GPU上,翻译的自回归性会大大降低计算的并行度,导致推断过程的效率不高。
\noindent 即译文单词$y_j$依赖前面已经生成的单词$\mathbf{y}_{<j}=\{y_1,...,y_{j-1}\}$和源语言句子$\mathbf{x}$。显然,这个模型中,每一个目标语位置$j$都需要等待前面$j-1$个位置输出的结果。因此,自回归翻译会阻碍不同译文单词生成的并行化。特别是在GPU上,翻译的自回归性会大大降低计算的并行度,导致推断过程的效率不高。
\parinterval 对于这个问题,研究者也考虑移除翻译的自归回性(Non-autoregressive Neural Machine Translation)\cite{Gu2017NonAutoregressiveNM},进行{\small\bfnew{非自回归翻译}}\index{非自回归翻译}(Regressive Translation)\index{Regressive Translation}。非自回归翻译可以用如下公式描述:
\parinterval 对于这个问题,研究者也考虑移除翻译的自归回性\cite{Gu2017NonAutoregressiveNM},进行{\small\bfnew{非自回归翻译}}\index{非自回归翻译}(Regressive Translation)\index{Regressive Translation}。非自回归翻译可以用如下公式描述:
\begin{eqnarray}
\textrm{P}(\mathbf{y}|\mathbf{x}) = \prod_{j=1}^{n} \textrm{P}(y_j| \mathbf{x})
\label{eqC7.7}
......@@ -904,44 +921,52 @@ y_{j}^{ls}=(1-\alpha) \cdot \tilde{y}_j + \alpha \cdot q
\noindent 其中,位置$j$上的输出$y_j$只依赖于输入句子$\mathbf{x}$,与其它位置上的输出无关。于是,所有位置上$y_j$都可以并行生成,大大提高了GPU等并行运算设备的利用率。这种方式一般可以带来几倍的速度提升。
\parinterval 不过非自回归翻译也面临一些挑战。最主要的问题在于,系统无法靠生成eos等结束符来判断翻译是否结束,也就是,非自回归翻译不知道译文的长度。对于这个问题,可以考虑借用统计机器翻译中{\small\bfnew{ 繁衍率}}\index{繁衍率}(Fertility)\index{Fertility}的概念(见第三章)。对于每个源语言单词预测所对应的目标语单词的个数,即繁衍率。这样,目标语句子的长度可以由这个源语言的繁衍率序列决定。繁衍率模型也可以被看作是一种基于隐含变量的非自回归模型。也可以考虑使用其它的先验知识设计隐含变量,比如,用句法结构指导非自回归翻译\cite{Gu2017NonAutoregressiveNM}。不过,非自回归模型的翻译品质与自回归模型还有一些距离,特别是在保证翻译速度的情况下,非自回归翻译会带来一定的性能损失。如何融合自回归和非自回归翻译各自的优点也是值得探索的方向。
\parinterval 不过非自回归翻译也面临一些挑战。最主要的问题在于,系统无法靠生成$<$eos$>$等结束符来判断翻译是否结束,也就是,非自回归翻译不知道译文的长度。对于这个问题,可以考虑借用统计机器翻译中{\small\bfnew{ 繁衍率}}\index{繁衍率}(Fertility)\index{Fertility}的概念(见第三章)。对于每个源语言单词预测所对应的目标语单词的个数,即繁衍率。这样,目标语句子的长度可以由这个源语言的繁衍率序列决定。
\parinterval 繁衍率模型也可以被看作是一种基于隐含变量的非自回归模型。也可以考虑使用其它的先验知识设计隐含变量,比如,用句法结构指导非自回归翻译\cite{Gu2017NonAutoregressiveNM}。不过,非自回归模型的翻译品质与自回归模型还有一些距离,特别是在保证翻译速度的情况下,非自回归翻译会带来一定的性能损失。如何融合自回归和非自回归翻译各自的优点也是值得探索的方向。
%%%%%%%%%%%%%%%%%%
\noindent {\small\bfnew{其它方法}}
\vspace{0.5em}
\noindent {\small\bfnew{g) 其它方法}}
\vspace{0.5em}
\parinterval 还有很多方法可以用于神经机器翻译的推断加速。比如:
\begin{itemize}
\item 更多的剪枝。可以使用更小的束宽度进行搜索,或者直接使用贪婪的方法进行搜索,即搜索的每个步骤中只保留最好的一个结果。这种方法基本上不用对代码进行修改,比较适合对系统的快速验证和调试。
\vspace{0.3em}
\item 更多的剪枝。可以使用更小的束宽度进行搜索,或者直接使用贪婪的方法进行搜索,即搜索的每个步骤中只保留最好的一个结果。这种方法基本上不用修改代码,比较适合对系统的快速验证和调试。
\vspace{0.3em}
\item 新的搜索终止条件。影响推断时间的一个因素是搜索的终止条件。为了保证搜索到高质量的译文,推断系统往往会多``看''一部分样本,比如,会在一个目标语长度范围内生成译文,但是这个范围都是凭经验设置,甚至无法保证最佳译文的长度会落在这个范围内。理想的情况下,当最佳结果出现的时候就可以停止搜索。因此,可以考虑设计更加合理的搜索终止条件减少不必要的计算\cite{DBLP:journals/corr/abs-1809-00069}。比如,可以考虑当前最优翻译假设的得分和其它翻译假设得分的差距,如果差距过大就可以提前终止。
\vspace{0.3em}
\end{itemize}
\parinterval 实际上,推断速度是机器翻译能否应用的重要因素之一。虽然,在一些研究性课题中,人们可能并不太在乎系统翻译有多``快''。但是,很多场景中速度是必须要考虑的问题:
\parinterval 实际上,推断速度是机器翻译能否应用的重要因素之一。虽然,在一些研究性课题中,人们可能并不太在乎系统翻译有多``快''。但是,很多场景中速度是必须要考虑的问题,例如
\begin{itemize}
\vspace{0.3em}
\item 需要大量自生成数据的情况。比如,需要利用机器翻译生成大量的伪数据的情况。在无指导神经机器翻译训练中,数据的生成也非常频繁。
\item 交互式翻译。机器翻译的一个应用场景就是交互式机器翻译\footnote{人机交互式机器翻译研究与实现: \url{https://www.infoq.cn/article/r9w2KPvGdFeTsh5Si7wD}},即机器翻译会根据用户的行为实时进行调整,这时机器翻译的延时会影响用户体验。
\vspace{0.3em}
\item 交互式翻译。机器翻译的一个应用场景就是交互式机器翻译{\red 参考文献!2-3篇,Guoping Huang},即机器翻译会根据用户的行为实时进行调整,这时机器翻译的延时会影响用户体验。
\vspace{0.3em}
\item 互联网机器翻译服务和产品。在大并发时如何保证翻译的低延时也是开发这类应用中必须要考虑的。
\vspace{0.3em}
\item 机器同声传译。同声传译是机器翻译的一个重要的应用场景。由于同传对实时性的要求,机器翻译的速度是影响整个系统的关键要素。此外,为了保证更好的用户体验,往往需要在讲话者没说完前就开始翻译,也就是根据一句话的前缀进行翻译,当得到后面的内容后再对翻译进行调整。这些都对机器翻译提出了新的要求\cite{DBLP:journals/corr/abs-1810-08398}
\vspace{0.3em}
\item 小设备上的机器翻译。在手机或者专用翻译设备上的机器翻译对速度也有很高的要求,同时需要考虑设备存储的限制。尤其是,CPU上的推断加速是这类场景中需要关注的。
\vspace{0.3em}
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{译文长度控制}
\parinterval 机器翻译的一个特点是译文长度需要额外的机制进行控制。这是因为机器翻译在建模时仅考虑了将训练样本(即标准答案)上的损失最小化,但是推断的时候会看到从未见过的现象,而且这些未见样本占据了样本空间的绝大多数。这时,模型会产生{\small\bfnew{ 偏置}}\index{偏置}(Bias)\index{Bias},也就是模型仅仅能够对见过的样本进行准确建模,而对于未见样本的建模并不准确。所导致的一个现象是:直接使用训练好的模型会翻译出长度短的离谱的译文。这是一个典型的{\small\bfnew{ 退化}}\index{退化}(Degenerate)\index{Degenerate}问题,即:在推断时,模型倾向于使用更少的步骤生成结果。我们使用单词概率的乘积表示整个句子的翻译概率。于是,模型天然就倾向生成短译文,因为短译文会使用更少的概率因式相乘。在使用极大似然估计进行模型训练时,这个问题会更加严重,因为模型只关心每个目标语位置的正确预测,对于译文长度没有考虑。此外,在机器翻译中译文长度如此重要的另一个原因在于:以BLEU为代表的评价指标对译文长度是非常敏感的,如果译文长度偏离参考答案过多,BLEU的结果会非常低。
\parinterval 机器翻译的一个特点是译文长度需要额外的机制进行控制。这是因为机器翻译在建模时仅考虑了将训练样本(即标准答案)上的损失最小化,但是推断的时候会看到从未见过的现象,而且这些未见样本占据了样本空间的绝大多数。这时,模型会产生{\small\bfnew{ 偏置}}\index{偏置}(Bias)\index{Bias},也就是模型仅仅能够对见过的样本进行准确建模,而对于未见样本的建模并不准确。所导致的一个现象是:直接使用训练好的模型会翻译出长度短的离谱的译文。这是一个典型的{\small\bfnew{ 退化}}\index{退化}(Degenerate)\index{Degenerate}问题,即:在推断时,模型倾向于使用更少的步骤生成结果。神经机器翻译模型使用单词概率的乘积表示整个句子的翻译概率,它天然就倾向生成短译文,因为短译文会使用更少的概率因式相乘。在使用极大似然估计进行模型训练时,这个问题会更加严重,因为模型只关心每个目标语位置的正确预测,对于译文长度没有考虑。此外,在机器翻译中译文长度如此重要的另一个原因在于:以BLEU为代表的评价指标对译文长度是非常敏感的,如果译文长度偏离参考答案过多,BLEU的结果会非常低。
\parinterval 译文长度不合理的问题也出现在统计机器翻译模型中,当时的策略是在推断过程中引入译文长度控制机制。神经机器翻译也借用了类似的想法,有几种简单的方法。
\parinterval 译文长度不合理的问题也出现在统计机器翻译模型中,当时的策略是在推断过程中引入译文长度控制机制。神经机器翻译也借用了类似的思想,有几种简单的方法。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection{长度惩罚因子}
\parinterval 最常用的方法是直接对翻译概率进行正规化,也就是用译文长度来归一化翻译概率。令源语言句子为$\mathbf{x}=\{ x_1, x_2,...,x_m \}$,译文为$\mathbf{y}=\{ y_1,y_2,...,y_n\}$,于是翻译模型得分$\textrm{score}(\mathbf{x},\mathbf{y})$可以被定义为:
\parinterval 最常用的方法是直接对翻译概率进行正规化,也就是用译文长度来归一化翻译概率。令源语言句子为$\mathbf{x}=\{ x_1, ...,x_m \}$,译文为$\mathbf{y}=\{ y_1,...,y_n\}$,于是翻译模型得分$\textrm{score}(\mathbf{x},\mathbf{y})$可以被定义为:
\begin{eqnarray}
\textrm{score}(\mathbf{x},\mathbf{y}) = \textrm{log}(\textrm{P}(\mathbf{y} | \mathbf{x}))
\label{eqC7.8}
......@@ -975,16 +1000,16 @@ y_{j}^{ls}=(1-\alpha) \cdot \tilde{y}_j + \alpha \cdot q
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection{译文长度范围约束}
\parinterval 神经机器翻译系统进行推断时,可以依靠生成结束符eos来判断一个句子是否翻译完毕。不过,经常会出现生成了很长的译文仍然没有eos出现。另一种极端的情况是,刚刚生成了几个词,eos就出现了。这两种情况对应了译文过长或者过短的情况。为了让译文的长度落在合理的范围,神经机器翻译的推断也会有一个译文长度约束。令$[a,b]$表示一个长度范围,可以定义:
\parinterval 神经机器翻译系统进行推断时,可以依靠生成结束符$<$eos$>$来判断一个句子是否翻译完毕。不过,经常会出现生成了很长的译文仍然没有$<$eos$>$出现。另一种极端的情况是,刚刚生成了几个词,$<$eos$>$就出现了。这两种情况对应了译文过长或者过短的情况。为了让译文的长度落在合理的范围,神经机器翻译的推断也会有一个译文长度约束。令$[a,b]$表示一个长度范围,可以定义:
\begin{eqnarray}
a &=& \omega_{\textrm{low}}\cdot |\mathbf{x}| \\
b &=& \omega_{\textrm{high}}\cdot |\mathbf{x}|
\label{eqC7.11}
\end{eqnarray}
\noindent 其中,$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$是两个数,用来表示译文长度的下限和上限。比如,很多系统中有$\omega_{\textrm{low}}=\frac{1}{2}$$\omega_{\textrm{high}}=2$,表示译文至少有源语言句子一半长,最多有源语言句子两倍长。
\noindent 其中,$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$是两个数,用来表示译文长度的下限和上限。比如,很多系统中有$\omega_{\textrm{low}}=\frac{1}{2}$$\omega_{\textrm{high}}=2$,表示译文至少有源语言句子一半长,最多有源语言句子两倍长。
\parinterval 值得注意的是,$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$的设置对推断效率影响很大。$\omega_{\textrm{high}}$可以被看作是一个推断的终止条件,最理想的情况是$\omega_{\textrm{high}} \cdot |\mathbf{x}|$恰巧就等于最佳译文的长度,这时我们不会浪费任何计算。反过来的一种情况,$\omega_{\textrm{high}} \cdot |\mathbf{x}|$远大于最佳译文的长度,这时很多计算都是无用的。实际上,译文长度预测是机器翻译的核心问题,而且十分困难。包括非自回归翻译在内的很多方法都依赖对目标语译文长度的建模见\ref{subsection-7.4.1.3}节)。为了找到长度预测准确率和召回率之间的平衡,一般需要大量的实验最终确定$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$。当然,利用统计模型预测$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$也是非常值得探索的方向,比如基于产出率的模型。
\parinterval 值得注意的是,$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$的设置对推断效率影响很大。$\omega_{\textrm{high}}$可以被看作是一个推断的终止条件,最理想的情况是$\omega_{\textrm{high}} \cdot |\mathbf{x}|$恰巧就等于最佳译文的长度,这时没有任何计算的浪费。反过来的一种情况,$\omega_{\textrm{high}} \cdot |\mathbf{x}|$远大于最佳译文的长度,这时很多计算都是无用的。实际上,译文长度预测是机器翻译的核心问题,而且十分困难。包括非自回归翻译在内的很多方法都依赖对目标语译文长度的建模(见\ref{subsection-7.4.1.3}节)。为了找到长度预测的准确率和召回率之间的平衡,一般需要大量的实验最终确定$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$。当然,利用统计模型预测$\omega_{\textrm{low}}$$\omega_{\textrm{high}}$也是非常值得探索的方向,比如基于产出率的模型。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......@@ -993,12 +1018,14 @@ b &=& \omega_{\textrm{high}}\cdot |\mathbf{x}|
\parinterval 上面提到的译文长度过长或过短的问题,本质上对应着{\small\bfnew{过翻译}}\index{过翻译}(Over Translation)\index{Over Translation}{\small\bfnew{ 欠翻译}}\index{欠翻译}(Under Translation)\index{Under Translation}的问题。具体来说,过翻译的一种表现是重复翻译,比如,神经机器翻译系统的输出中有时候会莫名其妙的将同一个片段重复生成多次;欠翻译的主要表现就是删词,也就是源语言句子中的一些内容根本就没在译文中得到体现。这两个问题都会带来用户体验的下降。过翻译和欠翻译问题出现的原因在于:
\begin{itemize}
\vspace{0.3em}
\item 机器翻译自动评价指标对过翻译和欠翻译并不敏感。众所周知,在机器翻译系统开发和调试过程中,使用较多的是BLEU等自动评价指标。但是,过翻译和欠翻译在BLEU这样的指标中是没有明确体现的\footnote{BLEU中也有准确率和长度惩罚因子,但是并没有考虑源语言句子和译文之间的对应关系,因此无法捕捉过翻译和欠翻译。}。一个典型的例子是实词漏翻。在人翻译一个句子的时候,如果漏掉一个实词会带来很差甚至不正确的翻译结果,但是在BLEU等指标中可能只是影响几个$n$-gram的匹配。特别是,极大似然训练会使模型对过翻译和欠翻译``更加''不敏感,因为目标函数对这两个问题没有显性的考虑。
\vspace{0.3em}
\item 神经机器翻译没有对过翻译和欠翻译建模。在统计机器翻译中,由于有覆盖度模型会保证所有单词都可以被翻译,且只被翻译一次,因此过翻译和欠翻译等问题很少出现。这也对应了翻译{\small\bfnew{ 充分性}}\index{充分性}(Adequacy)\index{Adequacy}的问题,也就是机器翻译结果能否准确、完整的表达源文的意思。而在神经机器翻译中这个问题没有明确的模型与之对应。
\vspace{0.3em}
\end{itemize}
\parinterval 对于第一个问题,可以通过引入人工评价和基于代价的评价方式进行缓解。机器翻译研究者更多的是关注第二个问题,即机器翻译覆盖度问题\cite{TuModeling}。其核心思想是对每个源语言单词被翻译的``程度''进行建模,一般来说希望每个单词被翻译的``程度''接近1。这个模型可以从训练数据中自动学习,不过这样会增加系统的复杂性。一种更加常用的方法是在推断的过程中引入一个度量覆盖度的模型。比如,现在常用的是GNMT覆盖度模型\cite{Wu2016GooglesNM},其中翻译模型得分被定义为:
\parinterval 对于第一个问题,可以通过引入人工评价和基于代价的评价方式进行缓解。机器翻译研究者更多的是关注第二个问题,即机器翻译覆盖度问题\cite{TuModeling}。其核心思想是对每个源语言单词被翻译的``程度''进行建模,一般来说希望每个单词被翻译的``程度''接近1。这个模型可以从训练数据中自动学习,不过这样会增加系统的复杂性。一种更加常用的方法是在推断的过程中引入一个度量覆盖度的模型。比如,使用GNMT覆盖度模型\cite{Wu2016GooglesNM},其中翻译模型得分被定义为:
\begin{eqnarray}
\textrm{score}(\mathbf{x},\mathbf{y}) &=& \frac{\textrm{logP}(\mathbf{y} | \mathbf{x})}{\textrm{lp}(\mathbf{y})} + \textrm{cp}(\mathbf{x},\mathbf{y}) \\
\textrm{cp}(\mathbf{x},\mathbf{y}) &=& \beta \cdot \sum_{i=1}^{|\mathbf{x}|} \textrm{log}(\textrm{min} (\sum_{j}^{|\mathbf{y}|} a_{ij} , 1))
......@@ -1013,7 +1040,7 @@ b &=& \omega_{\textrm{high}}\cdot |\mathbf{x}|
\label{eqC7.14}
\end{eqnarray}
\noindent 公式\ref{eqC7.14}将公式\ref{eqC7.13}中的向下截断方式换为了向上截断。这样,模型可以对过翻译(或重复翻译)有更好的建模能力。不过,这个模型需要在开发集上调试$\beta$,也带来了一定的额外工作量。
\noindent 公式\ref{eqC7.14}将公式\ref{eqC7.13}中的向下截断方式换为了向上截断。这样,模型可以对过翻译(或重复翻译)有更好的建模能力。不过,这个模型需要在开发集上细致的调整$\beta$,也带来了一定的额外工作量。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{多模型集成}
......@@ -1029,8 +1056,10 @@ b &=& \omega_{\textrm{high}}\cdot |\mathbf{x}|
\parinterval {\small\bfnew{假设选择}}\index{假设选择}(Hypothesis Selection)\index{Hypothesis Selection}是最简单的系统融合方法\cite{DBLP:conf/emnlp/DuanLXZ09}。其思想是:给定一个翻译假设集合, 综合多个模型对每一个翻译假设进行打分,之后选择得分最高的假设作为结果输出。其中包含两方面问题:
\begin{itemize}
\item 翻译假设生成。构建翻译假设集合是假设选择的第一步,也是最重要的一步。理想的情况下,我们希望这个集合尽可能包含更多高质量的翻译假设,这样后面有更大的几率选出更好的结果。不过,由于单个模型的性能是有上限的,因此无法期望这些翻译假设的品质超越单个模型的上限。研究人员更加关心的是翻译假设的{\small\bfnew{多样性}}\index{多样性}(Diversity)\index{Diversity},因为已经证明多样的翻译假设非常有助于提升系统融合的性能\cite{DBLP:journals/corr/LiMJ16}\cite{xiao2013bagging})。为了生成多样的翻译假设,通常有两种思路:1)使用不同的模型生成翻译假设;2)使用同一个模型的不同参数和设置生成翻译假设。图\ref{fig:7-24}展示了二者的区别。
\vspace{0.3em}
\item 假设生成。构建翻译假设集合是假设选择的第一步,也是最重要的一步。理想的情况下,我们希望这个集合尽可能包含更多高质量的翻译假设,这样后面有更大的几率选出更好的结果。不过,由于单个模型的性能是有上限的,因此无法期望这些翻译假设的品质超越单个模型的上限。研究人员更加关心的是翻译假设的{\small\bfnew{多样性}}\index{多样性}(Diversity)\index{Diversity},因为已经证明多样的翻译假设非常有助于提升系统融合的性能\cite{DBLP:journals/corr/LiMJ16}\cite{xiao2013bagging})。为了生成多样的翻译假设,通常有两种思路:1)使用不同的模型生成翻译假设;2)使用同一个模型的不同参数和设置生成翻译假设。图\ref{fig:7-24}展示了二者的区别。
\vspace{0.5em}
%----------------------------------------------
% 图7.
\begin{figure}[htp]
......@@ -1043,7 +1072,10 @@ b &=& \omega_{\textrm{high}}\cdot |\mathbf{x}|
比如,可以使用基于RNN的模型和Transformer模型生成不同的翻译假设,之后都放入集合中;也可以只用Transformer模型,但是用不同的模型参数构建多个系统,之后分别生成翻译假设。在神经机器翻译中,经常采用的是第二种方式,因为系统开发的成本更低。比如,很多研究工作都是基于一个基础模型,用不同的初始参数、不同层数、不同解码方式生成多个模型进行翻译假设生成。
\item 选择模型。所谓假设选择实际上就是要用一个更强的模型在候选中进行选择。这个``强''模型一般是由更多、更复杂的子模型组合而成。常用的方式是直接使用翻译假设生成时的模型构建``强''模型。比如,我们使用了两个模型生成了翻译假设集合,之后对所有翻译假设都分别用这两个模型进行打分。最后,综合两个模型的打分(如线性组合)得到翻译假设的最终得分,并进行选择。当然,也可以使用更强大的统计模型对多个子模型进行组合(如使用多层神经网络)。
\vspace{0.3em}
\item 选择模型。所谓假设选择实际上就是要用一个更强的模型在候选中进行选择。这个``强''模型一般是由更多、更复杂的子模型组合而成。常用的方法是直接使用翻译假设生成时的模型构建``强''模型。比如,我们使用了两个模型生成了翻译假设集合,之后对所有翻译假设都分别用这两个模型进行打分。最后,综合两个模型的打分(如线性插值)得到翻译假设的最终得分,并进行选择。当然,也可以使用更强大的统计模型对多个子模型进行组合(如使用多层神经网络)。
\vspace{0.3em}
\end{itemize}
\parinterval 假设选择也可以被看作是一种简单的投票模型。对所有的候选用多个模型投票,选出最好的结果输出。包括{\small\bfnew{重排序}}\index{重排序}(Re-ranking)\index{Re-ranking}在内的很多方法也是假设选择的一种特例。比如,在重排序中,可以把生成$n$-best列表的过程看作是翻译假设生成过程,而重排序的过程可以被看作是融合多个子模型进行最终结果选择的过程。
......@@ -1059,7 +1091,7 @@ b &=& \omega_{\textrm{high}}\cdot |\mathbf{x}|
\noindent 其中$\gamma_{k}$表示第$k$个系统的权重,且满足$\sum_{k=1}^{K} \gamma_{k} = 1$。公式\ref{eqC7.15}是一种线性模型。权重$\{ \gamma_{k}\}$可以在开发集上自动调整,比如,使用最小错误率训练得到最优的权重(见第四章)。不过在实践中发现,如果这$K$个模型都是由一个基础模型衍生出来的,权重$\{ \gamma_{k}\}$对最终结果的影响并不大。因此,有时候也简单的将权重设置为$\gamma_{k} = \frac{1}{K}$
\parinterval 公式\ref{eqC7.15}是一种典型的线性插值模型,这类模型在语言建模等任务中已经得到成功应用。从统计学习的角度,对多个模型的插值可以有效的降低经验错误率。不过,多模型集成依赖一个假设:这些模型之间需要有一定的互补性。这种互补性有时也体现在多个模型预测的上限上,称为Oracle。比如,可以把这K个模型输出中BLEU最高的结果作为Oracle,也可以选择每个预测结果中使BLEU达到最高的译文单词,这样构成的句子作为Oracle。当然,并不是说Oracle提高,模型集成的结果一定会变好。因为Oracle是最理想情况下的结果,而实际预测的结果与Oracle往往有很大差异。如何使用Oracle进行模型优化也是很多研究者在探索的问题。
\parinterval 公式\ref{eqC7.15}是一种典型的线性插值模型,这类模型在语言建模等任务中已经得到成功应用。从统计学习的角度,对多个模型的插值可以有效的降低经验错误率。不过,多模型集成依赖一个假设:这些模型之间需要有一定的互补性。这种互补性有时也体现在多个模型预测的上限上,称为Oracle。比如,可以把这$K$个模型输出中BLEU最高的结果作为Oracle,也可以选择每个预测结果中使BLEU达到最高的译文单词,这样构成的句子作为Oracle。当然,并不是说Oracle提高,模型集成的结果一定会变好。因为Oracle是最理想情况下的结果,而实际预测的结果与Oracle往往有很大差异。如何使用Oracle进行模型优化也是很多研究者在探索的问题。
%----------------------------------------------
% 图7.
......@@ -1074,17 +1106,19 @@ b &=& \omega_{\textrm{high}}\cdot |\mathbf{x}|
\parinterval 此外,如何构建集成用的模型也是非常重要的,甚至说这部分工作会成为模型集成方法中最困难的部分。绝大多数时候,模型生成并没有固定的方法。系统研发者大多也是``八仙过海、各显神通''。一些常用的方法有:
\begin{itemize}
\vspace{0.3em}
\item 改变模型宽度和深度,即用不同层数或者不同隐藏层大小得到多个模型;
\vspace{0.3em}
\item 不同的参数初始化,即用不同的参数初始化随机种子训练多个模型;
\vspace{0.3em}
\item 不同模型(局部)架构的调整,比如,使用不同的位置编码模型\cite{Shaw2018SelfAttentionWR}、多层融合模型\cite{WangLearning}等。
\vspace{0.3em}
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection{译文重组}
\parinterval 假设直接从已经生成的译文中进行选择,因此无法产生``新''的译文,也就是它的输出只能是某个单模型的输出。另一反面,预测融合需要同时使用多个模型进行推断,对计算和内存消耗较大。而且这两种方法有一个共性问题:搜索都是基于一个个字符串,相比指数级的译文空间,所看到的结果还是非常小的一部分。对于这个问题,一种方法是利用更加紧凑的数据结构对指数级的译文串进行表示。比如,可以使用格(lattice)对多个译文串进行表示\cite{DBLP:conf/emnlp/TrombleKOM08}。图\ref{fig:7-26}展示了基于$n$-best词串和基于lattice的表示方法的区别。可以看到,lattice中从起始状态到结束状态的每一条路径都表示一个译文,不同译文的不同部分可以通过lattice中的节点得到共享。理论上,lattice可以把指数级数量的词串用线性复杂度的结构表示出来。
\parinterval 假设直接从已经生成的译文中进行选择,因此无法产生``新''的译文,也就是它的输出只能是某个单模型的输出。另一方面,预测融合需要同时使用多个模型进行推断,对计算和内存消耗较大。而且这两种方法有一个共性问题:搜索都是基于一个个字符串,相比指数级的译文空间,所看到的结果还是非常小的一部分。对于这个问题,一种方法是利用更加紧凑的数据结构对指数级的译文串进行表示。比如,可以使用格(lattice)对多个译文串进行表示\cite{DBLP:conf/emnlp/TrombleKOM08}。图\ref{fig:7-26}展示了基于$n$-best词串和基于lattice的表示方法的区别。可以看到,lattice中从起始状态到结束状态的每一条路径都表示一个译文,不同译文的不同部分可以通过lattice中的节点得到共享\footnote{本例中的lattice也是一个{\scriptsize\bfnew{混淆网络}}\index{混淆网络}(Confusion Network)\index{Confusion Network}}。理论上,lattice可以把指数级数量的词串用线性复杂度的结构表示出来。
%----------------------------------------------
% 图7.
......@@ -1096,9 +1130,9 @@ b &=& \omega_{\textrm{high}}\cdot |\mathbf{x}|
\end{figure}
%----------------------------------------------
\parinterval 有了lattice这样的结构,多模型融合又有了新的思路。首先,可以将多个模型的译文融合为lattice。注意,这个lattice会包含这些模型无法生成的完整译文句子。之后,用一个更强的模型(也可以是融合后的模型)在lattice上搜索最优的结果。这个过程有可能找到一些``新''的译文,即结果可能是从多个模型的结果中重组而来的。lattice上的搜索模型可以基于多模型的融合,也可以使用一个简单的模型,这里需要考虑的是将神经机器翻译模型适应到lattice上进行推断\cite{DBLP:conf/aaai/SuTXJSL17}。其过程基本与原始的模型推断没有区别,只是需要把模型预测的结果附着到lattice中的每条边上,再进行推断。
\parinterval 有了lattice这样的结构,多模型融合又有了新的思路。首先,可以将多个模型的译文融合为lattice。注意,这个lattice会包含这些模型无法生成的完整译文句子。之后,用一个更强的模型在lattice上搜索最优的结果。这个过程有可能找到一些``新''的译文,即结果可能是从多个模型的结果中重组而来的。lattice上的搜索模型可以基于多模型的融合,也可以使用一个简单的模型,这里需要考虑的是将神经机器翻译模型适应到lattice上进行推断\cite{DBLP:conf/aaai/SuTXJSL17}。其过程基本与原始的模型推断没有区别,只是需要把模型预测的结果附着到lattice中的每条边上,再进行推断。
\parinterval\ref{fig:7-27}对比了不同模型集成方法的区别。从系统开发的角度看,假设选择和模型预测融合的复杂度较低,适合快速原型,而且性能稳定。译文重组需要更多的模块,系统调试的复杂度较高,但是由于看到了更大的搜索空间,因此系统性能提升的潜力较大\footnote{一般来说lattice上的oracle要比n-best译文上的oracle要高。}
\parinterval\ref{fig:7-27}对比了不同模型集成方法的区别。从系统开发的角度看,假设选择和模型预测融合的复杂度较低,适合快速原型,而且性能稳定。译文重组需要更多的模块,系统调试的复杂度较高,但是由于看到了更大的搜索空间,因此系统性能提升的潜力较大\footnote{一般来说lattice上的oracle要比$n$-best译文上的oracle的质量高。}
%----------------------------------------------
% 图7.
......@@ -1497,6 +1531,7 @@ p_l=\frac{l}{2L}\cdot \varphi
%--7.5.3 知识精炼---------------------
\subsection{知识精炼}
\label{subsection-7.5.3}
\parinterval 理想的机器翻译系统应该是品质好、速度块、存储占用少。不过现实的机器翻译系统往往需要用运行速度和存储空间来换取翻译品质,比如,\ref{subsection-7.3.2}节提到的增大模型容量的方法就是通过增加模型参数量来达到更好的函数拟合效果,但是这也导致系统变得更加笨拙。在很多场景下,这样的模型甚至无法使用。比如,Transformer-Big等``大''模型通常在专用GPU服务器上运行,在手机等受限环境下仍很难应用。
......@@ -1692,7 +1727,7 @@ L_{\textrm{seq}} = - \textrm{logP}_{\textrm{s}}(\hat{\textbf{y}} | \textbf{x})
\vspace{0.5em}
\item 结构搜索。除了由研究人员手工设计神经网络结构之外,近些年{\small\bfnew{网络结构搜索技术}}\index{网络结构搜索技术}(Neural Architecture Search;NAS)\index{Neural Architecture Search;NAS}也逐渐在包括机器翻译在内的自然语言处理任务中得到广泛关注\cite{DBLP:journals/jmlr/ElskenMH19}。不同于前文提到的基于循环神经网络、Transformer结构的机器翻译模型,网络结构搜索旨在通过自动的方式根据提供的训练数据自动学习到最适合于当前任务的神经网络模型结构,这种方式能够有效将研究人员从模型结构设计者的位置上“解救”出来,让计算机能够像学网络参数一样学习神经网络模型的结构。目前而言,网络结构搜索的方法已经在自然语言处理的各项任务中崭露头角,在语言模型、命名实体识别等任务中获得优异的成绩\cite{DBLP:conf/iclr/ZophL17,DBLP:conf/emnlp/JiangHXZZ19,liyinqiaoESS},但对于机器翻译任务而言,由于其任务的复杂性,网络结构的搜索空间往往比较大,很难直接对其空间进行搜索,因此研究人员更倾向于对基于现有经验设计的模型结构进行改良。谷歌大脑团队在The Evolved Transformer文章中提出使用进化算法,在Transformer结构基础上对模型结构进行演化,得到更加高效且建模能力更强的机器翻译模型。微软团队也在Neural Architecture Optimization\cite{Luo2018Neural}论文中提出NAO的方法,通过将神经网络结构映射到连续空间上进行优化来获得优于初始结构的模型,NAO方法在WMT19机器翻译评测任务中也进行了使用,在英语-芬兰语以及芬兰语-英语的任务上均取得了优异的成绩。
\vspace{0.5em}
\item 与统计机器翻译的结合。尽管神经机器翻译在自动评价和人工评价上都取得比统计机器翻译优异的结果,神经机器翻译仍然面临一些统计机器翻译没有的问题\cite{DBLP:conf/aclnmt/KoehnK17},如神经机器翻译系统会产生漏译的现象,也就是源语句子的一些短语甚至从句没有被翻译,而统计机器翻译因为是把源语里所有短语都翻译出来后进行拼装,因此不会产生这种译文对原文的忠实度低的问题。一个解决的思路就是把统计机器翻译系统和神经机器翻译系统进行结合。目前的方法主要分为两种,一种是模型的改进,比如在神经机器翻译里建模统计机器翻译的概念或者使用统计机器翻译系统的模块,如词对齐,覆盖度等等\cite{DBLP:conf/aaai/HeHWW16},或者是把神经机器翻译系统结合到统计机器翻译系统中,如作为一个特征\cite{DBLP:journals/corr/GulcehreFXCBLBS15};第二种是系统融合,在不改变模型的情况下,把来自神经机器翻译系统的输出和统计机器翻译系统的输出进行融合,得到更好的结果,如使用重排序\cite{DBLP:conf/ijcnlp/KhayrallahKDPK17,DBLP:conf/acl/StahlbergHWB16,DBLP:conf/aclwat/NeubigMN15,DBLP:conf/naacl/GrundkiewiczJ18},后处理\cite{niehues-etal-2016-pre},或者把统计机器翻译系统的输出作为神经机器翻译系统解码的约束条件等等\cite{DBLP:conf/eacl/GispertBHS17}使用新方法来更好地结合不同系统的优点,甚至建立统一的框架来融合两种系统会是非常有趣的方向。
\item 与统计机器翻译的结合。尽管神经机器翻译在自动评价和人工评价上都取得比统计机器翻译优异的结果,神经机器翻译仍然面临一些统计机器翻译没有的问题\cite{DBLP:conf/aclnmt/KoehnK17},如神经机器翻译系统会产生漏译的现象,也就是源语句子的一些短语甚至从句没有被翻译,而统计机器翻译因为是把源语里所有短语都翻译出来后进行拼装,因此不会产生这种译文对原文的忠实度低的问题。一个解决的思路就是把统计机器翻译系统和神经机器翻译系统进行结合。目前的方法主要分为两种,一种是模型的改进,比如在神经机器翻译里建模统计机器翻译的概念或者使用统计机器翻译系统的模块,如词对齐,覆盖度等等\cite{DBLP:conf/aaai/HeHWW16},或者是把神经机器翻译系统结合到统计机器翻译系统中,如作为一个特征\cite{DBLP:journals/corr/GulcehreFXCBLBS15};第二种是系统融合,在不改变模型的情况下,把来自神经机器翻译系统的输出和统计机器翻译系统的输出进行融合,得到更好的结果,如使用重排序\cite{DBLP:conf/ijcnlp/KhayrallahKDPK17,DBLP:conf/acl/StahlbergHWB16,DBLP:conf/aclwat/NeubigMN15,DBLP:conf/naacl/GrundkiewiczJ18},后处理\cite{niehues-etal-2016-pre},或者把统计机器翻译系统的输出作为神经机器翻译系统解码的约束条件等等\cite{DBLP:conf/eacl/GispertBHS17}除此之外,也可以把神经机器翻译与翻译记忆相融合({\red 参考文献!引用Guoping Huang的论文2篇}),在机器翻译应用中也是非常有趣的方向。
......
......@@ -18,7 +18,7 @@
\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=1pt,draw,fill=blue!15] (model) at ([xshift=4em]box0.east){{Model}};
\node[rectangle,inner sep=0.5em,rounded corners=1pt,draw,fill=blue!15] (model) at ([xshift=4em]box0.east){{模型}};
% big batch
\node [anchor=west,snode] (sbi1) at ([xshift=3em,yshift=6em]model.east) {\tiny{}};
......@@ -63,25 +63,25 @@
\draw [->,very thick] (box2.east) -- (box3.west);
%%%%%
\node [] (t10) at ([yshift=1.5em]box1.north) {t1};
\node [] (t11) at ([yshift=1.5em]box2.north) {t1};
\node [] (t2) at ([yshift=1.5em]box3.north) {t2};
\node [] (t10) at ([yshift=1.5em]box1.north) {$t_1$};
\node [] (t11) at ([yshift=1.5em]box2.north) {$t_1$};
\node [] (t2) at ([yshift=1.5em]box3.north) {$t_2$};
\draw [very thick,decorate,decoration={brace}] ([xshift=0em,yshift=0.3em]box1.north west) to node [midway,name=final] {} ([xshift=0em,yshift=0.3em]box1.north east);
\draw [very thick,decorate,decoration={brace}] ([xshift=0em,yshift=0.3em]box2.north west) to node [midway,name=final] {} ([xshift=0em,yshift=0.3em]box2.north east);
\draw [very thick,decorate,decoration={brace}] ([xshift=0em,yshift=0.3em]box3.north west) to node [midway,name=final] {} ([xshift=0em,yshift=0.3em]box3.north east);
\node [] (m1) at ([xshift=1.5em]box1.east) {m1};
\node [] (m2) at ([xshift=1.5em]box3.east) {m2};
\node [] (m1) at ([xshift=1.5em]box1.east) {$m_1$};
\node [] (m2) at ([xshift=1.5em]box3.east) {$m_2$};
\draw [very thick,decorate,decoration={brace}] ([xshift=3pt]box1.north east) to node [midway,name=final] {} ([xshift=3pt]box1.south east);
\draw [very thick,decorate,decoration={brace}] ([xshift=3pt]box3.north east) to node [midway,name=final] {} ([xshift=3pt]box3.south east);
\node [rectangle,inner sep=0.5em,rounded corners=2pt,draw,fill=red!5,font=\scriptsize] at ([yshift=-2em,xshift=10em]sbi1.east) {
\begin{tabular}{l}
m: 显存 \\
t: 时间 \\
$\textrm{m}_1>\textrm{m}_2$ \\
$\textrm{t}_1>\textrm{t}_2$
$m$: 显存 \\
$t$: 时间 \\
$m_1>m_2$ \\
$t_1>t_2$
\end{tabular}
};
......
......@@ -65,7 +65,7 @@
\draw [->] (out3) |- (plabel9.east);
\end{scope}
\node [anchor=north,font=\scriptsize] () at ([yshift=-0.2em]STANDARD.south) {(a) Standard};
\node [anchor=north,font=\scriptsize] () at (SELECTION.south) {(b) Word selection};
\node [anchor=north,font=\scriptsize] () at ([yshift=-0.2em]STANDARD.south) {(a) 标准方法};
\node [anchor=north,font=\scriptsize] () at ([xshift=-3em]SELECTION.south) {(b) 词汇选择};
\end{tikzpicture}
\ No newline at end of file
......@@ -22,9 +22,9 @@
\draw [->] (w5.north) -- ([yshift=1.3em]w5.north);
\draw [->] (w6.north) -- ([yshift=1.4em]w6.north);
\draw [->] (w7.south) -- ([yshift=-1.4em]w7.south);
\draw [->] (w8.south) -- ([yshift=-1.4em]w8.south);
\draw [->] (w9.south) -- ([yshift=-1.4em]w9.south);
\draw [<-] (w7.south) -- ([yshift=-1.4em]w7.south);
\draw [<-] (w8.south) -- ([yshift=-1.4em]w8.south);
\draw [<-] (w9.south) -- ([yshift=-1.4em]w9.south);
\node [model] (encoder1) at ([xshift=8em]encoder0.east) {Encoder};
......
\begin{tikzpicture}
\node [anchor=north west] (part1) at (0,0) {\small{$\begin{bmatrix} Have \; 0.5 \\ Has \ \ \; 0.1 \\ . \\ . \\ . \\ . \\ . \end{bmatrix}$}};
\node [anchor=north](p1) at ([yshift=-0.3em]part1.south) {$P1$};
\node [anchor=west](part2) at ([xshift=0.5em]part1.east){\small{$\begin{bmatrix} Have \; 0.2 \\ Has \ \ \; 0.3 \\ . \\ . \\ . \\ . \\ . \end{bmatrix}$}};
\node [anchor=north](p2) at ([yshift=-0.3em]part2.south) {$P2$};
\node [anchor=west](part3) at ([xshift=0.5em]part2.east){\small{$\begin{bmatrix} Have \; 0.4 \\ Has \ \ \; 0.3 \\ . \\ . \\ . \\ . \\ . \end{bmatrix}$}};
\node [anchor=north](p3) at ([yshift=-0.3em]part3.south) {$P3$};
\node [anchor=north west] (part1) at (0,0) {\small{$\begin{bmatrix} \textrm{Have} \; 0.5 \\ \textrm{Has} \ \ \; 0.1 \\ . \\ . \\ . \\ . \\ . \end{bmatrix}$}};
\node [anchor=north](p1) at ([yshift=-0.3em]part1.south) {$P_1$};
\node [anchor=west](part2) at ([xshift=0.5em]part1.east){\small{$\begin{bmatrix} \textrm{Have} \; 0.2 \\ \textrm{Has} \ \ \; 0.3 \\ . \\ . \\ . \\ . \\ . \end{bmatrix}$}};
\node [anchor=north](p2) at ([yshift=-0.3em]part2.south) {$P_2$};
\node [anchor=west](part3) at ([xshift=0.5em]part2.east){\small{$\begin{bmatrix} \textrm{Have} \; 0.4 \\ \textrm{Has} \ \ \; 0.3 \\ . \\ . \\ . \\ . \\ . \end{bmatrix}$}};
\node [anchor=north](p3) at ([yshift=-0.3em]part3.south) {$P_3$};
\node [anchor=west](part4) at ([xshift=0.5em]part3.east){\huge{$\Rightarrow$}};
\node [anchor=west](part5) at ([xshift=0.5em]part4.east){\small{$\begin{bmatrix} Have \; 0.37 \\ Has \ \ \; 0.23 \\ . \\ . \\ . \\ . \\ . \end{bmatrix}$}};
\node [anchor=west](part5) at ([xshift=0.5em]part4.east){\small{$\begin{bmatrix} \textrm{Have} \; 0.37 \\ \textrm{Has} \ \ \; 0.23 \\ . \\ . \\ . \\ . \\ . \end{bmatrix}$}};
\node [anchor=north](p5) at (part5.south) {$P=\sum_{i=1}^{3}{\frac{1}{3}P_{i}}$};
\end{tikzpicture}
......
......@@ -71,32 +71,38 @@
\indexentry{Re-ranking|hyperpage}{34}
\indexentry{双向推断|hyperpage}{34}
\indexentry{Bidirectional Inference|hyperpage}{34}
\indexentry{批量推断|hyperpage}{37}
\indexentry{Batch Inference|hyperpage}{37}
\indexentry{批量处理|hyperpage}{37}
\indexentry{Batching|hyperpage}{37}
\indexentry{批量推断|hyperpage}{38}
\indexentry{Batch Inference|hyperpage}{38}
\indexentry{批量处理|hyperpage}{38}
\indexentry{Batching|hyperpage}{38}
\indexentry{二值网络|hyperpage}{39}
\indexentry{Binarized Neural Networks|hyperpage}{39}
\indexentry{自回归翻译|hyperpage}{40}
\indexentry{Autoregressive Translation|hyperpage}{40}
\indexentry{非自回归翻译|hyperpage}{40}
\indexentry{Regressive Translation|hyperpage}{40}
\indexentry{繁衍率|hyperpage}{40}
\indexentry{Fertility|hyperpage}{40}
\indexentry{偏置|hyperpage}{41}
\indexentry{Bias|hyperpage}{41}
\indexentry{退化|hyperpage}{41}
\indexentry{Degenerate|hyperpage}{41}
\indexentry{退化|hyperpage}{42}
\indexentry{Degenerate|hyperpage}{42}
\indexentry{过翻译|hyperpage}{43}
\indexentry{Over Translation|hyperpage}{43}
\indexentry{欠翻译|hyperpage}{43}
\indexentry{Under Translation|hyperpage}{43}
\indexentry{充分性|hyperpage}{43}
\indexentry{Adequacy|hyperpage}{43}
\indexentry{充分性|hyperpage}{44}
\indexentry{Adequacy|hyperpage}{44}
\indexentry{系统融合|hyperpage}{44}
\indexentry{System Combination|hyperpage}{44}
\indexentry{假设选择|hyperpage}{44}
\indexentry{Hypothesis Selection|hyperpage}{44}
\indexentry{假设选择|hyperpage}{45}
\indexentry{Hypothesis Selection|hyperpage}{45}
\indexentry{多样性|hyperpage}{45}
\indexentry{Diversity|hyperpage}{45}
\indexentry{重排序|hyperpage}{45}
\indexentry{Re-ranking|hyperpage}{45}
\indexentry{重排序|hyperpage}{46}
\indexentry{Re-ranking|hyperpage}{46}
\indexentry{混淆网络|hyperpage}{47}
\indexentry{Confusion Network|hyperpage}{47}
\indexentry{动态线性层聚合方法|hyperpage}{51}
\indexentry{Dynamic Linear Combination of Layers,DLCL|hyperpage}{51}
\indexentry{相互适应|hyperpage}{55}
......@@ -109,20 +115,20 @@
\indexentry{Iterative Back Translation|hyperpage}{58}
\indexentry{前向翻译|hyperpage}{58}
\indexentry{Forward Translation|hyperpage}{58}
\indexentry{预训练|hyperpage}{58}
\indexentry{Pre-training|hyperpage}{58}
\indexentry{微调|hyperpage}{58}
\indexentry{Fine-tuning|hyperpage}{58}
\indexentry{多任务学习|hyperpage}{60}
\indexentry{Multitask Learning|hyperpage}{60}
\indexentry{模型压缩|hyperpage}{61}
\indexentry{预训练|hyperpage}{59}
\indexentry{Pre-training|hyperpage}{59}
\indexentry{微调|hyperpage}{59}
\indexentry{Fine-tuning|hyperpage}{59}
\indexentry{多任务学习|hyperpage}{61}
\indexentry{Multitask Learning|hyperpage}{61}
\indexentry{模型压缩|hyperpage}{62}
\indexentry{Model Compression|hyperpage}{62}
\indexentry{学习难度|hyperpage}{62}
\indexentry{Learning Difficulty|hyperpage}{62}
\indexentry{教师模型|hyperpage}{62}
\indexentry{Teacher Model|hyperpage}{62}
\indexentry{学生模型|hyperpage}{62}
\indexentry{Student Model|hyperpage}{62}
\indexentry{教师模型|hyperpage}{63}
\indexentry{Teacher Model|hyperpage}{63}
\indexentry{学生模型|hyperpage}{63}
\indexentry{Student Model|hyperpage}{63}
\indexentry{基于单词的知识精炼|hyperpage}{63}
\indexentry{Word-level Knowledge Distillation|hyperpage}{63}
\indexentry{基于序列的知识精炼|hyperpage}{63}
......@@ -135,5 +141,5 @@
\indexentry{Circle Consistency|hyperpage}{67}
\indexentry{翻译中回译|hyperpage}{68}
\indexentry{On-the-fly Back-translation|hyperpage}{68}
\indexentry{网络结构搜索技术|hyperpage}{70}
\indexentry{Neural Architecture Search;NAS|hyperpage}{70}
\indexentry{网络结构搜索技术|hyperpage}{71}
\indexentry{Neural Architecture Search;NAS|hyperpage}{71}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论