% !Mode:: "TeX:UTF-8"
% !TEX encoding = UTF-8 Unicode

%----------------------------------------------------------------------------------------
% 机器翻译：统计建模与深度学习方法
% Machine Translation: Statistical Modeling and Deep Learning Methods
%
% Copyright 2020
% 肖桐(xiaotong@mail.neu.edu.cn) 朱靖波 (zhujingbo@mail.neu.edu.cn)
%----------------------------------------------------------------------------------------

%----------------------------------------------------------------------------------------
%    CONFIGURATIONS
%----------------------------------------------------------------------------------------
\part{机器翻译前沿}
\renewcommand\figurename{图}%将figure改为图
\renewcommand\tablename{表}%将figure改为图
\chapterimage{fig-NEU-4.jpg} % Chapter heading image

%----------------------------------------------------------------------------------------
%	CHAPTER 13
%----------------------------------------------------------------------------------------

\chapter{神经机器翻译模型推断}

\parinterval 神经机器翻译的一个关键步骤是对神经网络进行训练。也就是，在双语平行数据上优化训练目标函数，使模型参数自动调整到一个“最佳”状态，从而可以对新的句子进行翻译。通常，训练过程对模型性能的好坏起到关键性作用。因此，对模型训练方法的研究也机器翻译领域的重要研究方向，其中的很多发现也对其它自然语言处理任务有很好的借鉴意义。

\parinterval 神经机器翻译模型训练面临着一些挑战，例如：

\begin{itemize}
\vspace{0.5em}
\item 如何对大容量模型进行有效的训练？例如，避免过拟合问题，并让模型更加健壮，同时有效地处理更大的词汇表；
\vspace{0.5em}
\item 如何设计更好的模型训练策略？例如，在训练中更好地利用机器翻译评价指标，同时选择对翻译更有价值的样本进行参数更新；
\vspace{0.5em}
\item 如何让模型学习到的“知识”在模型之间迁移？例如，把一个“强”模型的能力迁移到一个“弱”模型上，而这种能力可能是无法通过直接训练“弱”模型得到的。
\vspace{0.5em}
\end{itemize}

\parinterval 本章将就这些问题展开讨论，内容会覆盖开放词表、正则化、对抗样本训练、最小风险训练、知识蒸馏等多个主题。需要注意的是，神经机器翻译模型训练涉及的内容十分广泛。很多情况下，模型训练问题会和建模问题强相关。因此，本章的内容主要集中在相对独立的模型训练问题上。在后续章节中，仍然会有模型训练方面的介绍，其主要针对机器翻译的特定主题，如极深神经网络训练、无指导训练等。

%----------------------------------------------------------------------------------------
%    NEW SECTION
%----------------------------------------------------------------------------------------

\sectionnewpage
\section{开放词表}

\parinterval 人类表达语言的方式是十分多样的，这也体现在单词的构成上，甚至我们都无法想象数据中存在的不同单词的数量。即便使用分词策略，在WMT、CCMT等评测数据上，英文词表大小都会在100万以上。当然，这里面也包括很多的数字和字母的混合，还有一些组合词。不过，如果不加限制，机器翻译所面对的词表将会很“大”。这也会导致系统速度变慢，模型变大。更严重的问题是，测试数据中的一些单词根本就没有在训练数据中出现过，这时会出现OOV翻译问题，即系统无法对未见单词进行翻译。在神经机器翻译中，通常会考虑使用更小的翻译单元来缓解以上问题。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{大词表和OOV问题}

\parinterval 首先来具体看一看神经机器翻译的大词表问题。神经机器翻译模型训练和解码都依赖于源语言和目标语言的词表。在建模中，词表中的每一个单词都会被转换为分布式（向量）表示，即词嵌入。这些向量会作为模型的输入（见{\chapterten}）。如果每个单词都对应一个向量，那么单词的各种变形（时态、语态等）都会导致词表和相应的向量数量的增加。图\ref{fig:13-1}展示了一些英语单词的时态语态变化。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-word-change}
\caption{单词时态、语态、单复数的变化}
\label{fig:13-1}
\end{figure}
%----------------------------------------------

\parinterval 如果要覆盖更多的翻译现象，词表会不断膨胀，并带来下述两个问题：

\begin{itemize}
\vspace{0.5em}
\item 数据稀疏。很多不常见的低频词包含在词表中，而这些低频词的分布式表示很难得到充分学习；
\vspace{0.5em}
\item 词向量矩阵的增大。这会增加计算和存储的负担。
\vspace{0.5em}
\end{itemize}

\parinterval 理想情况下，机器翻译应该是一个{\small\bfnew{开放词表}}\index{开放词表}（Open-Vocabulary）\index{Open-Vocabulary}的翻译任务。也就是，无论测试数据中包含什么样的词，机器翻译系统都应该能够正常翻译。但是，现实的情况是即使不断扩充词表，也不可能覆盖所有可能的单词，即OOV问题，或被称作集外词问题。这个问题在使用受限词表时会更加严重，因为低频词和未见过的词都会被看作OOV单词。这时会将这些单词用<UNK>代替。通常，数据中<UNK>的数量会直接影响翻译性能，过多的<UNK>会造成欠翻译、结构混乱等问题。因此神经机器翻译需要额外的机制解决大词表和OOV问题。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{子词}

\parinterval 一种解决开放词表翻译问题的方法是改造输出层结构\upcite{garcia-martinez2016factored,DBLP:conf/acl/JeanCMB15}，比如，替换原始的Softmax层，用更加高效的神经网络结构进行超大规模词表上的预测。不过，由于模型结构和训练方法的调整使得系统开发与调试的工作量增加，因此使用这类方法时往往需要对系统进行修改，并且这类方法仍然无法解决OOV问题，因此在实用系统中并不常用。

\parinterval 另一种思路是不改变机器翻译系统，而是从数据处理的角度来缓解OOV问题。既然使用单词会带来数据稀疏问题，那么自然会想到使用更小的单元。比如，把字符作为最小的翻译单元 \footnote{中文里的字符可以被看作是汉字。} \ \dash \ 也就是基于字符的翻译模型\upcite{DBLP:journals/tacl/LeeCH17}。以英文为例，只需要构造一个包含26个英文字母、数字和一些特殊符号的字符表，便可以表示所有的单词。

\parinterval 但是字符级翻译也面临着新的问题\ \dash\ 使用字符增加了系统捕捉不同语言单元之间搭配的难度。假设平均一个单词由5个字符组成，系统所处理的序列长度便增大5倍。这使得具有独立意义的不同语言单元需要跨越更远的距离才能产生联系。此外，基于字符的方法也破坏了单词中天然存在的构词规律，或者说破坏了单词内字符的局部依赖。比如，英文单词“telephone”中的“tele”和“phone”都是有具体意义的词缀，但是如果把它们打散为字符就失去了这些含义。

\parinterval 那么有没有一种方式能够兼顾基于单词和基于字符方法的优点呢？常用的手段包括两种，一种是采用字词融合的方式构建词表，将未知单词转换为字符的序列并通过特殊的标记将其与普通的单词区分开来\upcite{luong2016acl_hybrid}。而另一种方式是将单词切分为{\small\bfnew{子词}}\index{子词}（Sub-word）\index{Sub-word}，它是介于单词和字符中间的一种语言单元表示形式。比如，将英文单词“doing”切分为“do”+“ing”。对于形态学丰富的语言来说，子词体现了一种具有独立意义的构词基本单元。比如，如图\ref{fig:13-2}，子词“do”，和“new”在可以用于组成其他不同形态的单词。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-word-root}
\caption{不同单词共享相同的子词（前缀）}
\label{fig:13-2}
\end{figure}
%----------------------------------------------

\parinterval 在极端一些的情况下，子词仍然可以包含所有的字母和数字。这样，理论上，所有的单词都可以用子词进行组装。当然，理想的状况是：在子词词表不太大的情况下，使用尽可能少的子词单元拼装出每个单词。在神经机器翻译中，基于子词的切分是很常用的数据处理方法，称为子词切分。主要包括三个步骤：

\begin{itemize}
\vspace{0.5em}
\item 对原始数据进行分词操作；
\vspace{0.5em}
\item 构建符号合并表；
\vspace{0.5em}
\item 通过合并表，将按字符切分的单词合并为字词组合。
\vspace{0.5em}
\end{itemize}

\parinterval 这里面的核心是如何构建符号合并表，下面对一些典型方法进行介绍。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{双字节编码（BPE）}

\parinterval {\small\bfnew{字节对编码}}\index{字节对编码}或{\small\bfnew{双字节编码}}\index{双字节编码}（Byte Pair Encoding\index{Byte Pair Encoding}，BPE）是一种常用的子词词表构建方法\upcite{DBLP:conf/acl/SennrichHB16a}。BPE方法最早用于数据压缩，该方法将数据中常见的连续字符串替换为一个不存在的字符，之后通过构建一个替换关系的对应表，对压缩后的数据进行还原。机器翻译借用了这种思想，把子词切分看作是学习对自然语言句子进行压缩编码表示的问题\upcite{Gage1994ANA}。其目的是，保证编码后的结果（即子词切分）占用的字节尽可能少。这样，子词单元会尽可能被不同单词复用，同时又不会因为使用过小的单元造成子词切分序列过长。使用BPE算法构建符号合并表可以分为如下几个步骤：

\begin{itemize}
\vspace{0.5em}
\item 对每个句子进行分词；
\vspace{0.5em}
\item 将分词后的每个单词进行进一步切分，划分为字符序列。同时，在每个单词结尾添加结束符<e>用于标记单词的边界。之后，统计该单词在数据中出现的次数。例如单词low在数据中出现了5次，可以将其记为`l o w <e>:'5。
\vspace{0.5em}
\item 对得到的字符集合进行统计，统计每个单词中2-gram符号出现的频次 \footnote{发生合并前，一个字符便是一个符号}。之后，选择最高频的2-gram符号，将其合并为新的符号，即新的子词。例如“A”和“B”连续出现的频次最高，则以“AB”替换所有单词内连续出现的“A”和“B”并将其加入子词词表。这样，“AB”会被作为一个整体，在之后的过程中可以与其他符号进一步合并。需要注意的是替换和合并不会跨越单词的边界，即只对单个单词进行替换和合并。
\vspace{0.5em}
\item 不断重复上一步骤，直到子词词表大小达到预定的大小或者下一个最高频的2-gram字符的频次为1。子词词表大小是BPE的唯一的参数，它用来控制上述子词合并的规模。
\vspace{0.5em}

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-bpe}
\caption{BPE算法运行实例}
\label{fig:7-9}
\end{figure}
%----------------------------------------------
\end{itemize}

\parinterval 图\ref{fig:7-9}给出了BPE算法执行的实例。其中预先设定的合并表的大小为10

\parinterval 在得到了符号合并表后，便需要对用字符表示的单词进行合并，得到以子词形式表示的文本。首先，将单词切分为以字符表示的符号序列，并在尾部加上终结符。然后按照符号合并表的顺序依次遍历，如果存在相同的2-gram符号组合，则对其进行合并，直至遍历结束。图1.4给出了一个使用字符合并表对单词进行子词切分的实例。红色单元为每次合并后得到的新符号，直至无法合并，或遍历结束，得到最终的合并结果。其中每一个单元为一个子词，如图\ref{fig:7-10} 。{\red{图有问题}}

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-unk-of-bpe}
\caption{BPE中的子词切分过程}
\label{fig:7-10}
\end{figure}
%----------------------------------------------

\parinterval 由于模型的输出也是子词序列，因此需要对最终得到的翻译结果进行子词还原，即将子词形式表达的单元重新组合为原本的单词。这一步操作也十分简单，只需要不断的将每个子词向后合并，直至遇到表示单词边界的结束符<e>，便得到了一个完整的单词。

\parinterval 使用BPE方法的策略有很多。不仅可以单独对源语言和目标语言进行子词的切分，也可以联合源语言和目标语言，共同进行子词切分，被称作Joint-BPE\upcite{DBLP:conf/acl/SennrichHB16a}。单语BPE比较简单直接，而Joint-BPE则可以增加两种语言子词切分的一致性。对于相似语系中的语言，如英语和德语，常使用Joint-BPE的方法联合构建词表。而对于中英这些差异比较大的语种，则需要独立的进行子词切分。使用子词表示句子的方法可以有效的平衡词汇量，增大对未见单词的覆盖度。像英译德、汉译英任务，使用16k或者32k的子词词表大小便能取得很好的效果。

\parinterval BPE还有很多变种方法。在进行子词切分时，BPE从最长的子词开始进行切分。这个启发性规则可以保证切分结果的唯一性，实际上，在对一个单词用同一个子词词表切分时，可能存在多种切分方式，如hello，我们可以分割为“hell”和“o”，也可以分割为“h”和“ello”。这种切分的多样性可以用来提高神经机器翻译系统的健壮性\upcite{DBLP:conf/acl/Kudo18}。{\red 而在T5等预训练模型中\upcite{DBLP:journals/jmlr/RaffelSRLNMZLL20}，则使用了基于字符级别的BPE。此外，尽管BPE被命名为字节对编码，实际上一般处理的是Unicode编码，而不是字节。在预训练模型GPT2中，也探索了字节级别的BPE，在机器翻译、问答等任务中取得了很好的效果\upcite{radford2019language}}。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{其他方法}

\parinterval 与基于统计的BPE算法不同，基于Word Piece的子词切分方法则是利用语言模型进行子词词表的构造\upcite{DBLP:conf/icassp/SchusterN12}。本质上，基于语言模型的方法和基于BPE的方法的思路是一样的，即通过合并字符和子词不断生成新的子词。它们的区别仅在于合并子词的方式不同。{\red 基于BPE的方法选择出现频次最高的连续字符2-gram合并为新的子词}，而基于语言模型的方法则是根据语言模型输出的概率选择要合并哪些子词。具体来说，基于Word Piece的方法首先将句子切割为字符表示的形式\upcite{DBLP:conf/icassp/SchusterN12}，并利用该数据训练一个1-gram语言模型，记为$\textrm{log}\funp{P}(\cdot)$。假设两个相邻的子词单元$a$和$b$被合并为新的子词$c$，则整个句子的语言模型得分的变化为$\triangle=\textrm{log}\funp{P}(c)-\textrm{log}\funp{P}(a)-\textrm{log}\funp{P}(b)$。这样，可以不断的选择使$\triangle$最大的两个子词单元进行合并，直到达到预设的词表大小或者句子概率的增量低于某个阈值。

\parinterval 目前比较主流的子词切分方法都是作用于分词后的序列，对一些没有明显词边界且资源稀缺的语种并不友好。相比之下，SentencePiece可以作用于未经过分词处理的输入序列\upcite{kudo2018sentencepiece}，同时囊括了双字节编码和语言模型的子词切分方法，更加灵活易用。

\parinterval 通过上述子词切分方法，可以缓解OOV的问题，允许模型利用到一些词法上的信息。然而主流的BPE子词切分方法中，每个单词都对应一种唯一的子词切分方式，因此输入的数据经过子词切分后的序列表示也是唯一的。在给定词表的情况下，每句话仍然存在多种切分方式。而经过现有BPE处理后的序列，模型只能接收到单一的表示，可能会阻止模型更好地学习词的组成，不能充分利用单词中的形态学特征。此外，针对切分错误的输入数据表现不够鲁棒，常常会导致整句话的翻译效果极差。为此，研究人员提出一些正则化方法\upcite{DBLP:conf/acl/Kudo18,provilkov2020bpe}。

\begin{itemize}
\vspace{0.5em}
\item 子词正则化方法\upcite{DBLP:conf/acl/Kudo18}。其思想是在训练过程中扰乱确定的子词边界，根据1-gram Language Model{\red （ULM）}采样出多种子词切分候选。通过最大化整个句子的概率为目标构建词表。在实现上，与上述基于Word Piece的方法略有不同，这里不做详细介绍。
\vspace{0.5em}
\item BPE-Dropout\upcite{provilkov2020bpe}。在训练时，通过在合并过程中按照一定概率$p${\red（这个p能不能改成P）}（介于0与1之间）随机丢弃一些可行的合并操作，从而产生不同的子词切分结果，进而增强模型健壮性。而在推断阶段，将p设置为0，等同于标准的BPE。总的来说，上述方法相当于在子词的粒度上对输入的序列进行扰动，进而达到鲁棒性训练的目的。在之后的小节中同样会针对鲁棒性训练进行详细介绍。
\vspace{0.5em}
\item DPE\upcite{he2020dynamic}。引入了混合字符-子词的切分方式，将句子的子词分割方式看作一种潜变量，该结构能够利用{\small\bfnew{动态规划}}\index{动态规划}（Dynamic Programming）\index{Dynamic Programming}的思想精确地将潜在的子字片段边缘化。解码端的输入是基于字符表示的目标语序列，推断时将每个时间步的输出映射到预先设定好的子词词表之上，得到当前最可能得子词结果。若当前子词长度为$m$，则接下来的$m$个时间步的输入为该子词，并在$m$个时间步后得到下一个切分的子词。
\vspace{0.5em}
\end{itemize}

%----------------------------------------------------------------------------------------
%    NEW SECTION
%----------------------------------------------------------------------------------------

\sectionnewpage
\section{正则化}\label{subsection-13.2}

\parinterval {\small\bfnew{正则化}}\index{正则化}（Regularization）\index{Regularization}是机器学习中的经典技术，通常用于缓解{\small\bfnew{过拟合问题}}\index{过拟合问题}（The Overfitting Problem）\index{Overfitting Problem}。正则化的概念源自线性代数和代数几何。在实践中，它更多的是指对{\small\bfnew{反问题}}\index{反问题}（The Inverse Problem）\index{Inverse Problem}的一种求解方式。假设输入$x$和输出$y$之间存在一种映射$f$
\begin{eqnarray}
y &=& f(x)
\label{eq:13-1}
\end{eqnarray}

\noindent 反问题是指：当观测到$y$时，能否求出$x$。反问题对应了很多实际问题，比如，可以把$y$看作经过美化的图片，$x$看作原始的图片，反问题就对应了图片还原。机器翻译的训练也是一种反问题，因为可以把$y$看作是正确的译文，$x$看作是输入句子或者模型参数\footnote{在训练中，如果把源语言句子看作是不变的量，这时$f$的输入只有模型参数。}。

\parinterval 理想的情况下，我们希望反问题的解是{\small\bfnew{适定的}}\index{适定的}（Well-posed）\index{Well-posed}。所谓适定解，需要满足三个条件：解是存在的、解是唯一的、解是稳定的（即$y$微小的变化会导致$x$微小的变化，也被称作解连续）。所有不存在唯一稳定解的问题都被称作{\small\bfnew{不适定问题}}\index{不适定问题}（Ill-posed Problem）\index{Ill-posed Problem}。对于机器学习问题，解的存在性比较容易理解。解的唯一性大多由问题决定。比如，如果把描述问题的函数$f(\cdot)$看作一个$n\times n$矩阵$\mathbf{A}$，$x$和$y$都看作是$n$维向量。那么$x$不唯一的原因在于$\mathbf{A}$不满秩（非奇异矩阵）。不过，存在性和唯一性并不会对机器学习方法造成太大困扰，因为在实践中往往会找到近似的解。

\parinterval 但是，解的稳定性却给神经机器翻译带来了很大的挑战。因为神经机器翻译模型非常复杂，里面存在大量的矩阵乘法和非线性变化。这导致$f(\cdot)$往往是不稳定的，也就是说，神经机器翻译中输出$y$ 的微小变化会导致输入$x$的巨大变化。比如，在系统研发中经常会发现，即使训练样本发生很小的变化，模型训练得到的参数都会有非常明显的区别。不仅如此，神经机器翻译模型参数解的稳定性还存在两方面问题：

\begin{itemize}
\vspace{0.5em}
\item 观测数据不充分。由于语言现象的多样性，训练样本只能覆盖非常有限的翻译现象。从样本的表示空间上看，对于没有观测样本的区域，根本无法知道真实解的样子，更不用说稳定性训练了。
\vspace{0.5em}
\item 数据中存在噪声。噪声问题是稳定性训练最大的挑战之一。因为，即使是很小的噪声，也可能会导致解的巨大变化。
\vspace{0.5em}
\end{itemize}

\parinterval 以上问题体现出来的现象就是过拟合。因为训练数据有限同时存在噪声，因此模型参数会过分拟合噪声数据。而且，这样的模型参数又与真实（理想）的模型参数相差很远。正则化正是针对这个问题。有时候，正则化也被称作{\small\bfnew{降噪}}\index{降噪}（Denoising）\index{Denoising}，虽然它的出发点并不只是去除噪声的影响。图\ref{fig:13-11}对比了不同函数对二维空间中一些数据点的拟合情况。在过拟合现象中，函数可以完美的拟合所有的数据点，即使有些数据点是噪声。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-underfitting-vs-overfitting}
\caption{欠拟合 vs 过拟合}
\label{fig:13-11}
\end{figure}
%----------------------------------------------

\parinterval 正则化的一种实现是在训练目标中引入一个正则项。在神经机器翻译中，引入正则项的训练目标为：
\begin{eqnarray}
\widehat{\mathbf{w}} &=& \argmax_{\mathbf{w}}L(\mathbf{w}) + \lambda R(\mathbf{w})
\label{eq:13-2}
\end{eqnarray}

\noindent 其中，$L(\mathbf{w})$是损失函数，$R(\mathbf{w})$是正则项，$\lambda$是正则项的系数，用于控制正则化对训练影响的程度。$R(\mathbf{w})$通常也可以被看作是一种先验，因为在数据不充分且存在噪声的情况下，可以根据一些先验知识让模型偏向正确的方向一些，而不是一味地根据受噪声影响的不准确的$L(\mathbf{w})$进行优化。相应的，引入正则化后的模型可以获得更好的{\small\bfnew{泛化}}\index{泛化}（Generalization）\index{Generalization}能力，即模型在新的未见数据上表现会更好。

\parinterval 实践中已经证明，正则化方法有助于像神经机器翻译这样复杂的模型获得稳定的模型参数。甚至有些情况下，如果不引入正则化，训练得到的翻译模型根本无法使用。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{L1/L2正则化}

\parinterval L1/L2正则化是常用的正则化方法。它们分别对应正则项是L1和L2范数的情况。具体来说，L1正则化是指
\begin{eqnarray}
R(\mathbf{w}) & = & \big| |\mathbf{w}| {\big|}_1 \\
			     & =  &\sum_{w_i}|w_i| \nonumber
\label{eq:13-3}
\end{eqnarray}

\parinterval L2正则化是指
\begin{eqnarray}
R(\mathbf{w}) & = & (\big| |\mathbf{w}| {\big|}_2)^2 \\
			     & =  &\sum_{w_i}{w_i}^2 \nonumber
\label{eq:13-4}
\end{eqnarray}

\parinterval 从几何的角度看，L1和L2正则项都是有物理意义的。二者都可以被看作是空间上的一个区域，比如，在二维平面上，L1范数表示一个以0点为中心的矩形，L2范数表示一个以0点为中心的圆。因此，优化问题可以被看作是在两个区域（$L(\mathbf{w})$和$R(\mathbf{w})$）叠加在一起所形成的区域上进行优化。由于L1和L2正则项都是在0点（坐标原点）附近形成的区域，因此优化的过程可以确保参数不会偏离0点太多。也就是说，L1和L2正则项引入了一个先验：模型的解不应该离0点太远。而L1和L2正则项实际上是在度量这个距离。

\parinterval 那为什么要用L1和L2正则项惩罚离0点远的解呢？这还要从模型复杂度谈起。实际上，对于神经机器翻译这样的模型来说，模型的容量是足够的。所谓容量可以被简单的理解为独立参数的个数 \footnote{关于模型容量，在\ref{section-13.2}节会有进一步讨论。}。也就是说，理论上存在一种模型可以完美的描述问题。但是，从目标函数拟合的角度来看，如果一个模型可以拟合很复杂的目标函数，那模型所表示的函数形态也会很复杂。这往往体现在模型中参数的值“偏大”。比如，用一个多项式函数拟合一些空间中的点，如果希望拟合得很好，各个项的系数往往是非零的。而且为了对每个点进行拟合，通常需要多项式中的某些项具有较大的系数，以获得函数在局部有较大的斜率。显然，这样的模型是很复杂的。而模型的复杂度可以用函数中的参数（比如多项式中各项的系数）的“值”进行度量，体现出来就是模型参数的范数。

\parinterval 因此，L1和L2正则项的目的是防止模型为了匹配少数（噪声）样本而导致模型的参数过大。反过来说，L1和L2正则项会鼓励那些参数值在0点附近的情况。从实践的角度看，这种方法可以很好的对统计模型的训练进行校正，得到泛化能力更强的模型。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{标签平滑}

\parinterval 神经机器翻译在每个目标语位置$j$会输出一个分布$y_j$，这个分布描述了每个目标语言单词出现的可能性。在训练时，每个目标语言位置上的答案是一个单词，也就对应了One-hot分布$\tilde{y}_j$，它仅仅在正确答案那一维为1，其它维均为0。模型训练可以被看作是一个调整模型参数让$y_j$逼近$\tilde{y}_j$的过程。但是，$\tilde{y}_j$的每一个维度是一个非0即1的目标，这样也就无法考虑类别之间的相关性。具体来说，除非模型在答案那一维输出1，否则都会得到惩罚。即使模型把一部分概率分配给与答案相近的单词（比如同义词），这个相近的单词仍被视为完全错误的预测。

\parinterval {\small\bfnew{标签平滑}}\index{标签平滑}（Label Smoothing）\index{Label Smoothing}的思想很简单\upcite{Szegedy_2016_CVPR}：答案所对应的单词不应该“独享”所有的概率，其它单词应该有机会作为答案。这个观点与第二章中语言模型的平滑非常类似。在复杂模型的参数估计中，往往需要给未见或者低频事件分配一些概率，以保证模型具有更好的泛化能力。具体实现时，标签平滑使用了一个额外的分布$q$，它是在词汇表$V$ 上的一个均匀分布，即$q(k)=\frac{1}{|V|}$，其中$q(k)$表示分布的第$k$维。然后，答案分布被重新定义为$\tilde{y}_j$和$q$的线性插值：
\begin{eqnarray}
y_{j}^{ls} &=& (1-\alpha) \cdot \tilde{y}_j + \alpha \cdot q
\label{eq:13-5}
\end{eqnarray}

\noindent 这里$\alpha$表示一个系数，用于控制分布$q$的重要性。$y_{j}^{ls}$会被作为最终的答案分布用于模型的训练。

\parinterval 标签平滑实际上定义了一种“软”标签，使得所有标签都可以分到一些概率。一方面可以缓解数据中噪声的影响，另一方面目标分布会更合理（显然，真实的分布不应该是One-hot分布）。图\ref{fig:13-12}展示了标签平滑前后的损失函数计算结果的对比。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-label-smoothing}
\caption{不使用标签平滑 vs 使用标签平滑}
\label{fig:13-12}
\end{figure}
%----------------------------------------------

\parinterval 标签平滑也可以被看作是对损失函数的一种调整，并引入了额外的先验知识（即与$q$相关的部分）。只不过这种先验知识并不是通过线性插值的方式与原始损失函数进行融合（公式\ref{eq:13-2}）。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{Dropout}

\parinterval 神经机器翻译模型是一种典型的多层神经网络模型。每一层网络都包含若干神经元，负责接收前一层所有神经元的输出，并进行诸如乘法、加法等变换，并有选择的使用非线性的激活函数，最终得到当前层每个神经元的输出。从模型最终预测的角度看，每个神经元都在参与最终的预测。理想的情况下，我们希望每个神经元都能相互独立的做出“贡献”。这样的模型会更加健壮，因为即使一部分神经元不能正常工作，其它神经元仍然可以独立做出合理的预测。但是，随着每一层神经元数量的增加以及网络结构的复杂化，研究者发现神经元之间会出现{\small\bfnew{相互适应}}\index{相互适应}（Co-Adaptation）\index{Co-Adaptation}的现象。所谓相互适应是指，一个神经元对输出的贡献与同一层其它神经元的行为是相关的，也就是说这个神经元已经适应到它周围的“环境”中。

\parinterval 相互适应的好处在于神经网络可以处理更加复杂的问题，因为联合使用两个神经元要比单独使用每个神经元的表示能力强。这也类似于传统机器学习任务中往往会设计一些高阶特征，比如自然语言序列标注中对bi-gram和tri-gram的使用。不过另一方面，相互适应会导致模型变得更加“脆弱”。因为相互适应的神经元可以更好的描述训练数据中的现象，但是在测试数据上，由于很多现象是未见的，细微的扰动会导致神经元无法适应。具体体现出来就是过拟合问题。

\parinterval Dropout是解决这个问题的一种常用方法\upcite{DBLP:journals/corr/abs-1207-0580}。方法很简单，在训练时随机让一部分神经元停止工作，这样每次参数更新中每个神经元周围的环境都在变化，它就不会过分适应到环境中。图\ref{fig:13-13}中给出了某一次参数训练中使用Dropout之前和之后的状态对比。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-network-with-dropout}
\caption{使用Dropout之前（左）和之后（右）神经网络状态的对比，其中虚线圆圈表示不工作的神经元，实线圆圈表示工作的神经元。}
\label{fig:13-13}
\end{figure}
%----------------------------------------------

\parinterval 具体实现时，可以设置一个参数$p\in (0,1)$。在每次参数更新所使用的前向和反向计算中，每个神经元都以概率$p$停止工作。相当于每层神经网络会有以$p$为比例的神经元被“屏蔽”掉。每一次参数更新中会随机屏蔽不同的神经元。图\ref{fig:13-14}给出了Dropout方法和传统方法计算方式的对比。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-computation-of-dropout}
\caption{使用Dropout之前（左）和之后（右）一层神经网络的计算}
\label{fig:13-14}
\end{figure}
%----------------------------------------------

\parinterval 对于新的样本，可以使用Dropout训练之后的模型对其进行推断，但是每个神经元的输出要乘以$1-p$，以保证每层神经元输出的期望和训练时是一样的。另一种常用的做法是，在训练时对每个神经元的输出乘以$\frac{1}{1-p}$，然后在推断时神经网络可以不经过任何调整就直接使用。

\parinterval Dropout方法的另一种解释是，训练中屏蔽掉一些神经元相当于从原始的神经网络中抽取出了一个子网络。这样，每次训练都在一个随机生成的子网络上进行，而不同子网络之间的参数是共享的。在推断时，则把所有的子网络集成到一起。这种思想也有一些{\small\bfnew{集成学习}}\index{集成学习}（Ensemble Learning）\index{Ensemble Learning}的味道。只不过Dropout中子模型（或子网络）是在指数级空间中采样出来的。由于Dropout可以很好的缓解复杂神经模型的过拟合问题，因此也成为了大多数神经机器翻译系统的标配。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{Layer Dropout}

\parinterval 随时网络层数的增多，相互适应也会出现在不同层之间。特别是在引入残差网络之后，不同层的输出可以进行线性组合，因此不同层之间的相互影响会更加直接。对于这个问题，也可以使用Dropout的思想对不同层进行屏蔽。比如，可以使用一个开关来控制一个层能否发挥作用，这个开关以概率$p$被随机关闭，即该层有为$p$的可能性不工作。图\ref{fig:13-15}展示了Transformer多层网络引入Layer Dropout 前后的情况。可以看到，使用Layer Dropout后，开关M会被随机打开或者关闭，以达到屏蔽某一层计算的目的。由于使用了残差网络，关闭每一层相当于“跳过”这一层网络，因此Layer Dropout并不会影响神经网络中数据流的传递。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-norm}
\caption{标准Transformer网络(a)  vs 引入Layer Dropout后的Transformer网络(b)}
\label{fig:13-15}
\end{figure}
%----------------------------------------------

\parinterval Layer Dropout可以被理解为在一个深网络（即原始网络）中随机采样出一个由若干层网络构成的“浅”网络。不同“浅”网络所对应的同一层的模型参数是共享的。这也达到了对指数级子网络高效训练的目的。需要注意的是，在推断阶段，每层的输出需要乘以$1-p$，确保训练时每层输出的期望和解码是一致的。Layer Dropout可以非常有效的缓解深层网路中的过拟合问题。在\ref{subsection-13.2}节还会看到Layer Dropout可以成功地帮助我们训练Deep Transformer模型。

%----------------------------------------------------------------------------------------
%    NEW SECTION
%----------------------------------------------------------------------------------------

\sectionnewpage
\section{增大模型容量}\label{section-13.2}

\parinterval 神经机器翻译是一种典型的多层神经网络。一方面，可以通过设计合适的网络连接方式和激活函数来捕捉复杂的翻译现象；另一方面，越来越多的可用数据让模型能够得到更有效的训练。在训练数据较为充分的情况下，设计更加“复杂”的模型成为了提升系统性能的有效手段。比如，Transformer模型有两个常用配置Transformer-Base和Transformer-Big。其中，Transformer-Big比Transformer-Base使用了更多的神经元，相应的翻译品质更优\upcite{NIPS2017_7181}。

\parinterval 那么是否还有类似的方法可以改善系统性能呢？答案显然是肯定的。这里，把这类方法统称为基于大容量模型的方法。在传统机器学习的观点中，神经网络的性能不仅依赖于架构设计，同样与容量密切相关。那么什么是模型的{\small\bfnew{容量}}\index{容量}（Capacity）\index{Capacity}？简单理解，容量是指神经网络的参数量，即神经元之间连接权重的个数。另一种定义是把容量看作神经网络所能表示的假设空间大小\upcite{DBLP:journals/nature/LeCunBH15}，也就是神经网络能表示的不同函数所构成的空间。

\parinterval 而学习一个神经网络就是要找到一个“最优”的函数，它可以准确地拟合数据。当假设空间变大时，训练系统有机会找到更好的函数，但是同时也需要依赖更多的训练样本才能完成最优函数的搜索。相反，当假设空间变小时，训练系统会更容易完成函数搜索，但是很多优质的函数可能都没有被包含在假设空间里。这也体现了一种简单的辩证思想：如果训练（搜索）的代价高，会有更大的机会找到更好的解；另一方面，如果想少花力气进行训练（搜索），那就设计一个小一些的假设空间，在小一些规模的样本集上进行训练，当然搜索到的解可能不是最好的。

\parinterval 在很多机器翻译任务中，训练数据是相对充分的。这时增加模型容量是提升性能的一种很好的选择。常见的方法有三种：

\begin{itemize}
\vspace{0.5em}
\item 增加隐藏层维度：即增加网络宽度，加强每一层网络的线性拟合能力。
\vspace{0.5em}
\item 增加网络的整体层数：即增加网络深度，利用更多的线性和非线性变换来获得更复杂的特征抽取能力。
\vspace{0.5em}
\item 增大输入层和输出层的维度：即增强模型对词表中每个词的表示能力。
\end{itemize}

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{宽网络}

\parinterval 宽网络通常指隐藏层维度更大的网络，目前在图像处理领域和自然语言处理领域被广泛地使用。第五章已经验证了包含足够多神经元的多层前馈神经网络可以无限逼近任意复杂的连续函数\upcite{Hornic1989Multilayer}，这也在一定程度上说明了神经网络建模中神经元数目的重要性。

\parinterval 增大隐藏层神经元的数目是网络变宽的基本方式之一。例如，图像处理领域中提出的{\small\bfnew{宽残差网络}}\index{宽残差网络}（Wide Residual Network）\index{Wide Residual Network}使用更大的卷积核来提高每次卷积计算的精度\upcite{DBLP:conf/bmvc/ZagoruykoK16}；神经机器翻译中，Transformer-Big模型广受研究人员的认可\upcite{NIPS2017_7181}，它同样是一个典型的宽网络。对比基线模型Transformer-Base，Transformer-Big通过扩大隐藏层维度与滤波器（Filter）维度，取得了显著的翻译性能提升。表\ref{tab:13-2}是相应的参数设置。

%----------------------------------------------
\begin{table}[htp]
\centering
\caption{基线网络与宽网络的参数设置}
\begin{tabular}{ l | l l}
 & Transformer-Base &Transformer-Big \\ \hline
 \rule{0pt}{13pt} 词向量维度 & 512 &1024 \\
 \rule{0pt}{13pt} 注意力头数 &8 &16 \\
 \rule{0pt}{13pt} 隐藏层维度 &512 &1024 \\
 \rule{0pt}{13pt}  FFN子层映射维度 &2048 &4096
\end{tabular}
\label{tab:13-2}
\end{table}
%--------------------------------------

\parinterval 值得注意的是， Transformer模型中的前馈神经网络子层将隐藏层表示映射到更高维度的空间（通过一个Filter），之后经过激活函数Relu后再映射回原来的维度大小。这个操作对翻译模型的性能有明显的正向作用。从表\ref{tab:13-2}中可以看出，Filter的维度是普通隐藏层维度的四倍。通过增大Filter大小可以有效地扩展网络的宽度，比如，有些情况下可以将Filter增大到8192甚至更大。

\parinterval 但伴随着模型变宽，网络的整体参数量会显著增长\footnote{在一个全连接神经网络中，参数的数量与各层宽度呈平方关系。}。同时，宽网络需要更长的训练时间才能达到稳定的收敛状态。此外，训练宽网络时通常需要对一些超参数进行相应的调整，例如Dropout的大小，学习率的峰值等。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{深网络}

\parinterval 虽然，理论上宽网络有能力拟合任意的函数，但是获得这种能力的代价是非常高的。在实践中，往往需要增加相当的宽度，以极大的训练代价才能换来少量的性能提升。当神经网络达到一定宽度后这种现象更为严重。“无限”增加宽度显然是不现实的。

\parinterval 因此，另一种思路是使用更深的网络以增加模型的容量。深网络是指包含更多层的神经网络。相比宽网络的参数量随着宽度呈平方增长，深网络的参数量随着深度呈线性增长。这带给深网络一个优点：在同样参数量下可以通过更多的非线性变换来对问题进行描述。这也赋予了深网络对复杂问题建模的能力。比如，在图像识别领域，很多先进的系统都是基于很深的神经网络，甚至在一些任务上最好的的结果需要1000 层以上的神经网络。

\parinterval 宽网络和深网络是增加模型表示能力的两个维度。宽网络相当于增强了模型线性变换的能力，将模型的输入在更高维度的空间上进行抽象；深网络通过引入更多的层构建了多个表示空间，通过逐层的变换，在多个表示空间上对输入进行多次抽象。二者在有些情况下甚至可以相互转换。

\parinterval 除了数学上的解释，深度神经网络也可以给分析、理解现实世界的问题提供有效的手段。很多时候，可以把一个多层神经网络看作是对一个复杂问题的拆解，每层（或每几层）是在处理一个子问题。例如，在人脸识别任务中，一个3层的神经网络中第一层主要提取低层次的简单特征，即边缘特征；第二层将简单的特征组合成更为复杂的特征，如器官特征；第三层针对第二层的输出进行进一步的抽象得到人脸的面部特征。这样，深网络通过不同层的逐层特征抽象可以在人脸识别数据集上超越人类的精度\upcite{DBLP:journals/corr/HeZRS15}。

\parinterval 类似的现象也出现在基于语言模型的预训练任务中。比如，研究人员通过使用{\small\bfnew{探测任务}}\index{探测任务}（Probing Task）\index{Probing Task}来分析12层的BERT模型中的不同层所表示的含义\upcite{ethayarajh-2019-contextual,DBLP:conf/acl/JawaharSS19}：

\begin{itemize}
\vspace{0.5em}
\item 浅层网络表示：网络的底层部分更擅长处理词串的{\small\bfnew{表面信息}}\index{表面信息}（Surface Information）\index{Surface Information}，例如词性选择、词义消歧等。
\vspace{0.5em}
\item 中间层的表示：中间层部分更关注于{\small\bfnew{语法信息}}\index{语法信息}（Syntactic Information）\index{Syntactic Information}
\vspace{0.5em}
\item 顶层网络的表示：上层部分更擅长处理{\small\bfnew{语义信息}}\index{语义信息}（Semantic Information）\index{Semantic Information}
\vspace{0.5em}
\end{itemize}

\parinterval 目前在神经机器翻译领域，研究人员发现编码端的表示能力对翻译性能有较大的影响，因此加深编码网络是一种有效的改进系统的手段（如图\ref{fig:13-16} ）。而且，增加编码端的深度对模型推断的速度并没有较大影响，因为整个序列可以通过GPU进行并行计算。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-increase-the-encoder}
\caption{增大神经机器翻译的编码端来增大模型的容量}
\label{fig:13-16}
\end{figure}
%----------------------------------------------

\parinterval 不过，深网络容易发生梯度消失和梯度爆炸问题。因此在使用深网络时，训练策略的选择是至关重要的。实际上，标准的Transformer模型已经是不太“浅”的神经网络，因此里面使用了残差连接来缓解梯度消失等问题。此外，为了避免过拟合，深层网络的训练也要与Dropout等正则化策略相配合，并且需要设计恰当的参数初始化方法和学习率调整策略。关于构建深层神经机器翻译的方法，本章\ref{subsection-7.5.1}节还会有进一步讨论。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{增大输入层和输出层表示能力}

\parinterval 如前所述，神经机器翻译的原始输入是单词序列，包括源语言端和目标语言端。模型中的输入层将这种离散的单词表示转换成实数向量的表示，也就是常说的{\small\bfnew{词嵌入}}\index{词嵌入}（Embedding）\index{Embedding}。从实现的角度来看，输入层其实就是从一个词嵌入矩阵中提取对应的词向量表示，这个矩阵两个维度大小分别对应着词表大小和词嵌入的维度。词嵌入的维度也代表着模型对单词刻画的能力。因此适当增加词嵌入的维度也是一种增加模型容量的手段。通常，词嵌入和隐藏层的维度是一致的，这种设计也是为了便于系统实现。

\parinterval 当然，并不是说词嵌入的维度一定越大就越好。本质上，词嵌入是要在一个多维空间上有效的区分含有不同语义的单词。如果词表较大，更大的词嵌入维度会更有意义，因为需要更多的“特征”描述更多的语义。当词表较小时，增大词嵌入维度可能不会带来增益，相反会增加系统计算的负担。另一种策略是，动态选择词嵌入维度，比如，对于高频词使用较大的词嵌入维度，而对于低频词则使用较小的词嵌入维度\upcite{DBLP:conf/iclr/BaevskiA19}。这种方法可以用同样的参数量处理更大的词表。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{大模型的分布式计算}

\parinterval 伴随着模型容量的增大，复杂模型可能无法在单GPU上完成训练。比如，即使是不太复杂的Transformer-Base模型在很多任务上也需要在8张GPU进行训练。如何利用多个设备进行大模型的并行训练是一个很现实的问题。比较简单的策略是使用{\small\bfnew{数据并行}}\index{数据并行}（Data Parallelism）\index{Data Parallelism}，即把一个批次分到多个GPU上进行训练，之后对多个GPU上的梯度进行汇总，并更新参数。不过，当模型规模增大到一定程度时，单GPU可能仍然无法处理。这个问题在GPU显存较小的时候会非常突出。这时需要考虑{\small\bfnew{模型并行}}\index{模型并行}（Model Parallelism）\index{Model Parallelism}。模型并行是指将模型分割成不同的部分，在不同的GPU上运行其中的一部分。例如，在训练深层LSTM模型时可以将不同层放置在不同GPU上，这种方式一定程度上能够加速模型的训练。对于更大的模型，如参数量为10亿的BERT-Large模型\upcite{DBLP:conf/naacl/DevlinCLT19}，同样可以使用这种策略。不过，模型并行中不同设备传输的延时会大大降低模型运行的效率，因此很多时候要考虑训练效率和模型性能之间的平衡。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{大批量训练}

\parinterval 在第六章已经介绍了神经机器翻译模型需要使用梯度下降方法进行训练。其中，一项非常重要的技术就是{\small\bfnew{小批量训练}}\index{小批量训练}（Mini-batch Training）\index{Mini-batch Training}，即每次使用多个样本来获取梯度并对模型参数进行更新。这里将每次参数更新使用的多个样本集合称为批次，将样本的数量称作批次的大小。在机器翻译中，通常用批次中的源语言/目标语言单词数或者句子数来表示批次大小。理论上，过小的批次会带来训练的不稳定，而且参数更新次数会大大增加。因此，很多研究者尝试增加批次大小来提高训练的稳定性。在Transformer模型中，使用更大的批次已经被验证是有效的。这种方法也被称作大批量训练。不过，这里所谓“ 大”批量是一个相对的概念。下面就一起看一看如何使用合适的批次大小来训练神经机器翻译模型。

%----------------------------------------------------------------------------------------
%    NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------

\subsubsection{为什么需要大批量训练}

\parinterval 在模型训练的过程中，训练批次的大小对模型的收敛状态有很大影响，合理选择批次的大小往往会取得事半功倍的效果。较大的批次可以保证模型每次更新时梯度是在较多的样本上计算，其梯度结果更准确，有效地缓解训练中出现的性能震荡的问题。此外，较大的批次可以让模型在更新次数更少的情况下遍历整个数据集。同时大矩阵运算在GPU上的并行度更高，提高了设备的利用率。

\parinterval 然而，批次也不是越大越好，要根据训练数据集的规模与模型的容量做出合理的选择。此外，GPU显存的大小也对批次大小有约束，因为过大的批次可能无法放入GPU显存中。另一方面，在一些场景例中，如增量式训练、领域迁移，往往需要对模型进行微调。这时，常用的做法是使用小批次并固定较小的学习率，防止现有的模型参数发生较大的偏离。

\parinterval 大多数情况下，批次的大小是指单独一块GPU上的数据量，然而考虑到利用数据并行进行分布式训练时，批次大小等于所有GPU 中批次大小的和。下面以Transformer模型为例。通常Transformer-Base模型使用4096词/GPU的批次在8张GPU上进行训练，此时真实批次大小为$4096\times 8=32768$词。伴随着模型容量的进一步增加，例如Transformer-Big模型，由于训练过程中网络的中间表示要消耗大量的GPU显存，可能会考虑减小批次的大小并使用累计梯度的方式来保证稳定的训练。累计梯度是一种大批量训练的常用手段，即按照一定频率缓存多个相邻批次的梯度后再进行参数的更新。比如，为了获取大批次，可以考虑将累计的更新频率设置为2或4。图\ref{fig:13-17}给出了累计梯度的参数更新方法，可以看到使用累积梯度的方式可以减少设备的空闲时间。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-batch-generation-method}
\caption{生成批次的方式}
\label{fig:13-17}
\end{figure}
%----------------------------------------------

\parinterval 此外，前人工作表明，使用大批量训练复杂网络结构时要配合略大一些的学习率，加快模型在梯度方向上的更新速度，进而达到更优的翻译性能\upcite{DBLP:conf/wmt/OttEGA18}。例如，深层网络也需要对学习率进行适当的调整才能发挥较好的性能。表\ref{tab:13-3}展示了30层网络在不同批次大小和学习率峰值的条件下的BLEU值（WMT14 En-De）\footnote{学习率峰值是指Transformer模型训练的预热阶段，学习率所到达的最高值。}。可以发现，在固定学习率峰值的条件下增大批次大小并不能带来性能上的增益，必须同时调整学习率的峰值。也有研究团队验证了Transformer-Big模型在128张GPU上进行分布式训练时，适当的增大学习率会带来明显的BLEU提升\upcite{DBLP:conf/wmt/OttEGA18}。\\ \\ \\

%----------------------------------------------
\begin{table}[htp]
\centering
\caption{深层Transformer不同批次大学和学习率峰值设置下的BLEU值}
\begin{tabular}{ l | l  l }
\rule{0pt}{13pt} batch & lr & BLEU \\ \hline
\rule{0pt}{13pt} 4096 & 0.01 & 29.15 \\
\rule{0pt}{13pt} 8192 & 0.01 & 29.06 \\
\rule{0pt}{13pt} 8192 & 0.02 & 29.49
\end{tabular}
\label{tab:13-3}
\end{table}
%--------------------------------------

%----------------------------------------------------------------------------------------
%    NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------

\subsubsection{如何构建批次}

\parinterval 由于不同句子之间的长度有明显的差异，这时批次所占用的显存/内存大小由其中最长句子的长度决定。通常使用{\small\bfnew{填充}}（Padding）的方式对一个批次中句长不足的部分用空白填充（见第六章）。但由于生成批次的方式不同，最终批次内的Padding数量各不相同，因此合理选择生成批次的方式也是至关重要的。通常有几种方法：

\begin{itemize}
\vspace{0.5em}
\item 随机生成：最简单的方式是从整个数据集中随机生成批次。这种方式可以有效地保证样本间的随机性，但随机生成的批次中不同句子之间的长度会有较大区别，因此Padding数量较多会导致显卡的利用率较低。
\vspace{0.5em}
\item 按句长排序：为了减少显卡利用率低的问题，可以根据源语言或者目标语言的句子长度进行排序，让相邻句长的样本更为相近（图\ref{fig:13-18} ）。这样在同一个批次中不会因为句长差异过大造成设备利用率的降低。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-randomly-generation-vs-generate-by-sentence-length}
\caption{批次生成 - 随机生成 vs 按句长生成}
\label{fig:13-18}
\end{figure}
%----------------------------------------------

\vspace{0.5em}
\item 按词数构建批次：对比按照句长生成批次，按词数生成批次可以防止某些批次中句子整体长度特别长或者特别短的情况，保证不同批次之间整体的词数处于大致相同的范围，这样所得到的梯度也是可比较的。通常的做法是根据源语言词数、目标语言词数，或者源语言词数与目标语言词数的最大值等指标生成批次。

\vspace{0.5em}
\item 按课程学习的方式：考虑样本的“难度”也是生成批次的一种策略。比如，可以使用{\small\bfnew{课程学习}}\index{课程学习}（Curriculum Learning）\index{Curriculum Learning} 的思想\upcite{DBLP:conf/icml/BengioLCW09}，让系统先学习“简单”的样本，之后逐渐增加样本的难度，达到循序渐进的学习。具体来说，可以利用句子长度、词频等指标计算每个批次的“难度”，记为$d$。 之后，选择满足$d \leq c$的样本构建一个批次。这里，$c$表示难度的阈值，它可以随着训练的执行不断增大。
\vspace{0.5em}
\end{itemize}

%----------------------------------------------------------------------------------------
%    NEW SECTION
%----------------------------------------------------------------------------------------

\sectionnewpage
\section{对抗样本训练}

\parinterval 同其它基于神经网络的方法一样，提高{\small\bfnew{鲁棒性}}\index{鲁棒性}（Robustness）\index{Robustness}也是神经机器翻译研发中需要关注的。比如，大容量模型可以很好的拟合训练数据，但是当测试样本与训练样本差异较大时，会导致很糟糕的翻译结果\upcite{JMLR:v15:srivastava14a,DBLP:conf/amta/MullerRS20}。另一方面，实践中也发现，有些情况下即使输入中有微小的扰动，神经网络模型的输出也会产生巨大变化。或者说，神经网络模型在输入样本上容易受到{\small\bfnew{攻击}}\index{攻击}（Attack）\index{Attack}\upcite{DBLP:conf/sp/Carlini017,DBLP:conf/cvpr/Moosavi-Dezfooli16,DBLP:conf/acl/ChengJM19}。图\ref{fig:13-19}展示了一个神经机器翻译系统的结果，可以看到，输入中把单词“他”换成“她”会造成完全不同的译文。这时神经机器翻译系统就存在鲁棒性问题。

%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.5]{./Chapter13/Figures/figure-example-of-neural-machine-translation.png}
\caption{神经机器翻译实例}
\label{fig:13-19}
\end{figure}
%----------------------------------------------

\parinterval 决定神经网络模型鲁棒性的因素主要包括训练数据、网络结构、正则化方法等。仅仅从网络结构设计和训练算法优化的角度来改善鲁棒性一般是较为困难的，因为如果输入数据是“干净”的，模型就会学习在这样的数据上进行预测。无论模型的能力是强还是弱，当推断时输入数据出现扰动的时候，模型可能无法适应，因为它从未见过这种新的数据。因此，一种简单直接的方法是从训练样本出发，让模型在学习的过程中能对样本中的扰动进行处理，进而在推断时具有更强的鲁棒性。具体来说，可以在训练过程中构造有噪声的样本，即基于{\small\bfnew{对抗样本}}\index{对抗样本}（Adversarial Examples）\index{Adversarial Examples}进行{\small\bfnew{对抗训练}}\index{对抗训练}（Adversarial Training）\index{Adversarial Training}。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{对抗样本及对抗攻击}

\parinterval 在图像识别领域，研究人员就发现，对于输入图像的细小扰动，如像素变化等，会使模型以高置信度给出错误的预测\upcite{DBLP:conf/cvpr/NguyenYC15,DBLP:journals/corr/SzegedyZSBEGF13,DBLP:journals/corr/GoodfellowSS14}，但是这种扰动并不会影响人类的判断。也就是说，样本中的微小变化“欺骗”了图像识别系统，但是“欺骗”不了人类。这种现象背后的原因有很多，例如，一种可能的原因是：系统并没有理解图像，而是在拟合数据，因此拟合能力越强，反而对数据中的微小变化更加敏感。从统计学习的角度看，既然新的数据中可能会有扰动，那更好的学习方式就是在训练中显性地把这种扰动建模出来，让模型对输入的细微变化更加鲁棒。

\parinterval 这种对原样本上增加一些难以察觉的扰动从而使模型的到错误判断的样本，被称为对抗样本。对于输入$\mathbi{x}$和输出$\mathbi{y}$，对抗样本形式上可以被描述为：{\red s.t.的形式再确认一下}
\begin{eqnarray}
\funp{C}(\mathbi{x}) &=& \mathbi{y} 
\label{eq:13-6}\\
\funp{C}(\mathbi{x}) &\neq& \mathbi{y} 
\label{eq:13-7}\\
\textrm{s.t.} \quad \funp{R}(\mathbi{x},\mathbi{x}') &<& \varepsilon
\label{eq:13-8}
\end{eqnarray}

\noindent 其中，$(\mathbi{x},\mathbi{y})$为原样本，$(\mathbi{x}',\mathbi{y})$为输入中含有扰动的对抗样本，函数$\funp{C}(\cdot)$为模型。公式\eqref{eq:13-8}中$\funp{R}(\mathbi{x},\mathbi{x}')$表示扰动后的输入$\mathbi{x}'$和原输入$\mathbi{x}$之间的距离，$\varepsilon$表示扰动的受限范围当模型对包含噪声的数据容易给出较差的结果时，往往意味着模型的抗干扰能力差，因此可以利用对抗样本检测现有模型的鲁棒性\upcite{DBLP:conf/emnlp/JiaL17}。同时，采用类似数据增强的方式将对抗样本混合至训练数据中，能够帮助模型学习到更普适的特征使模型的到稳定的输出，这种方式也被称为对抗训练\upcite{DBLP:journals/corr/GoodfellowSS14,DBLP:conf/emnlp/BekoulisDDD18,DBLP:conf/naacl/YasunagaKR18}。

\parinterval 通过对抗样本训练提升模型鲁棒性的首要问题是如何生成对抗样本。通过当前模型$\funp{C}$，和样本$(\mathbi{x},\mathbi{y})$，生成对抗样本的过程，被称为{\small\bfnew{对抗攻击}}\index{对抗攻击}（Adversarial Attack）\index{Adversarial Attack}。对抗攻击可以被分为两种，分别是黑盒攻击和白盒攻击。在白盒攻击中，攻击算法可以访问模型的完整信息，包括模型结构、网络参数、损失函数、激活函数、输入和输出数据等。而黑盒攻击不需要知道神经网络的详细信息，仅仅通过访问模型的输入和输出达到攻击目的，因此 通常依赖启发式方法来生成对抗样本。由于神经网络本身便是一个黑盒模型，研究人员对模型内部的参数干预度有限，因此黑盒攻击在许多实际应用中更加实用。

\parinterval 在神经机器翻译中，输入中细小的扰动经常会使模型变得脆弱\upcite{DBLP:conf/iclr/BelinkovB18}。但是图像和文本之间存在着一定的差异，图像中的对抗攻击方法难以直接应用于自然语言处理领域，这是由于以像素值等表示的图像数据是连续的\upcite{DBLP:conf/naacl/MichelLNP19}{\red （如何理解连续？）}，而文本中的一个个单词本身离散的。因此简单替换这些离散的单词，可能会生成语法错误或者语义错误的句子。这时的扰动过大，模型很容易判别，因此无法涵盖原始问题。即使对词嵌入等连续表示部分进行扰动，也会产生无法与词嵌入空间中的任何词匹配的问题\upcite{Gong2018AdversarialTW}。针对这些问题，下面着重介绍神经机器翻译任务中有效的生成和利用对抗样本的方法。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{基于黑盒攻击的方法}

\parinterval 一个好的对抗样本应该具有一些性质，如：对文本做最少的修改，并最大程度地保留原文的语义。这些可以通过对文本加噪声的方式来来实现，分为自然噪声和人工噪声\upcite{DBLP:conf/iclr/BelinkovB18}。自然噪声一般是指人为的在语料库中收集自然出现的错误，如输入错误，拼写错误等，构建可用的词汇替换表，在文本中加入噪声。人为噪声则可以通过多种方式来处理文本。如可以通过在干净的数据中通过固定的规则或是使用噪声生成器以一定的概率引入不同类型的噪声，如：拼写、表情符号、语法错误等\upcite{DBLP:conf/naacl/VaibhavSSN19,DBLP:conf/naacl/AnastasopoulosL19,DBLP:conf/acl/SinghGR18}；此外，也可以在文本中加入精心设计，或毫无意义的单词序列，以此来分散模型的注意，通过不同的算法来确定插入的位置和内容，这种方式常用于阅读理解任务中\upcite{DBLP:conf/emnlp/JiaL17}。

\parinterval 除了单纯的在文本中引入各种扰动外，还可以通过文本编辑的方式构建对抗样本，在不改变语义的情况下尽可能的修改文本\upcite{DBLP:journals/corr/SamantaM17,DBLP:conf/ijcai/0002LSBLS18}，从而生成对抗样本。文本的编辑方式主要包括交换，插入，替换和删除操作。图\ref{fig:13-20}给出了一些通过上述方式生成的对抗样本。

%----------------------------------------------
\begin{figure}[htp]
\centering
\includegraphics[scale=0.5]{./Chapter13/Figures/figure-true-case-of-adversarial-examples.jpg}
\caption{对抗样本实例{\red（需要让读者真实的感受一下）}}
\label{fig:13-20}
\end{figure}
%----------------------------------------------

\parinterval 形式上可以利用FGSM\upcite{DBLP:journals/corr/GoodfellowSS14}等算法验证文本中每一个单词对语义的贡献度，同时为每一个单词构建其候选池，包括单词的近义词，拼写错误词，同音词等。对于贡献度较低的词如语气词，副词等，可以通过插入，删除操作进行扰动。对于文本序列中其他的单词可以进行在候选池中选择相应的单词进行替换。对于交换操作可以基于词级别交换序列中的单词，也可以是基于字符级的交换单词中的字符\upcite{DBLP:conf/coling/EbrahimiLD18}。重复的进行不同的编辑操作，直至误导模型做出错误的判断。

\parinterval 基于语义的方法除了通过不同的算法进行修改输入生成对抗样本外，也可以通过神经网络模型增加扰动，例如在机器翻译中常用的回译技术也是生成对抗样本的一种有效方式，通过反向模型将目标语言翻译成源语言，并再次应用于神经机器翻译系统的训练。除了翻译模型，语言模型也可以用于生成对抗样本。前面也已经介绍过语言模型可以用于检测句子流畅度，根据上文预测当前位置可能出现的单词，因此可以通过语言模型根据上文预测出当前位置最可能出现的多个单词，与序列中的原本的单词进行替换。在机器翻译任务中，可以通过与神经机器翻译系统联合训练，共享词向量矩阵的方式得到语言模型。{\red （引用）}

\parinterval 此外，生成{\small\bfnew{对抗网络}}\index{对抗网络}（Generative Adversarial Networks\index{Generative Adversarial Networks}, GANs）也可以被用来生成对抗样本\upcite{DBLP:conf/iclr/ZhaoDS18}。与回译方法类似，GAN的方法将原始的输入映射为潜在分布$\funp{P}$，并在其中搜索出服从相同分布的文本构成对抗样本。一些研究正也对这种方法进行了优化\upcite{DBLP:conf/iclr/ZhaoDS18}，在稠密的向量空间$z$中进行搜索，也就是说在定义$\funp{P}$的基础稠密向量空间中找到对抗性表示$\mathbi{z}'$，然后利用生成模型将其映射回$\mathbi{x}'$，使最终生成的对抗样本在语义上接近原始输入。{\red（既然GAN不是主流，可以考虑把这部分放到拓展阅读中）}

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{基于白盒攻击的方法}

\parinterval 除了在离散的词汇级别的增加扰动，还可以在模型内部增加扰动。这里简单介绍一下利用白盒攻击方法增加模型鲁棒性的方法：

\begin{itemize}
\vspace{0.5em}
\item 与利用词向量的余弦相似度选择近义词对当前词进行替换类似，可以对于每一个词都在其词嵌入表示的基础上累加了一个从正太分布，之后将其作为模型的最终输入。同时，可以在训练目标中增加额外的训练目标，比如，迫使模型在接收到被扰动的输入后，编码端生成与正常输入类似的表示，解码端输出正确的翻译结果\upcite{DBLP:conf/acl/LiuTMCZ18}。
\vspace{0.5em}
\item 除了引入标准的噪声外，还可以根据模型所存在的具体问题， 构建不同的扰动。例如，针对输入中包含同音字错误导致模型输出误差较大的问题，可以将单词的发音转换为一个包含$n$个发音单元，如音素，音节等的发音序列，并训练相应的嵌入矩阵将每一个发音单元转换为对应的向量表示。对发音序列中的发音单元的嵌入表示进行平均后，得到当前单词的发音表示。最后将词嵌入与单词的发音表示，加权求和后的结果作为模型的输入\upcite{DBLP:conf/acl/LiuMHXH19}。通过这种方式可以提高模型对同音异形词的鲁棒性，得到更准确的翻译结果。此外除了在词嵌入层增加扰动，同样有研究人员证明了，在端到端模型的中的编码端输出中引入额外的噪声，能起到与在层输入中增加扰动生成对抗样本进行对抗训练类似的效果，增强了模型训练的鲁棒性\upcite{DBLP:conf/acl/LiLWJXZLL20}。
\vspace{0.5em}
\item 此外还有一类基于梯度的方法来生成对抗样本进行对抗性训练。例如，可以通过最大化替换词与原始单词词向量之间的差值和候选词的梯度向量之间的相似度来生成对抗样本\upcite{DBLP:conf/acl/ChengJM19}，具体的计算方式如下：{\red 下面的是sin还是sim，而且文字中是正弦把？下面三角是不是delta}
\begin{eqnarray}
{\mathbi{x}'}_i &=& \arg\max_{\mathbi{x}\in \nu_{\mathbi{x}}}\textrm{sim}(\funp{e}(\mathbi{x})-\funp{e}(\mathbi{x}_i),\mathbi{g}_{\mathbi{x}_i}) 
\label{eq:13-9} \\
\mathbi{g}_{\mathbi{x}_i} &=&  \Delta_{\funp{e}(\mathbi{x}_i)} - \log \funp{P}(\mathbi{y}|\mathbi{x};\theta)
\label{eq:13-10}
\end{eqnarray}

\noindent 其中，$\mathbi{x}_i$为输入中第$i$个词，$\mathbi{g}_{\mathbi{x}_i}$为对应的梯度向量，$\funp{e}(\cdot)$用于获取词向量，$\textrm{sim}(\cdot,\cdot)$用于评估两个向量之间的余弦距离{\red（很多符号没有解释，$∇_(e(x_i))$是什么？等等）}。$\nu_{\mathbi{x}}$为源语的词表，但是由于对词表中所有单词进行枚举，计算成本较大，因此利用语言模型选择最可能的$n$个词作为候选，进而缩减匹配范围，通过此方式对采样出的源语词进行替换。同时为了保护模型不受解码器预测误差的影响，对模型目标端的输入同样做了调整，方法与源语端类似，不同的地方在于将公式\eqref{eq:13-10}中的损失替换为$- \log \funp{P}(\mathbi{y}|\mathbi{x}')$，利用语言模型选择候选和采样的方式也做出了相应的调整。在进行对抗性训练时，在原有的训练损失上增加了三个额外的损失，最终的训练目标为：
\begin{eqnarray}
Loss(\theta_{\textrm{mt}},\theta_{\textrm{lm}}^{\mathbi{x}},\theta_{\textrm{lm}}^{\mathbi{y}}) &=& Loss_{\textrm{clean}}(\theta_{\textrm{mt}}) + Loss_{\textrm{lm}}(\theta_{\textrm{lm}}^{\mathbi{x}}) + \nonumber \\
& & Loss_{\textrm{robust}}(\theta_{\textrm{mt}}) + Loss_{\textrm{lm}}(\theta_{\textrm{lm}}^{\mathbi{y}})
\label{eq:13-11}
\end{eqnarray}

\noindent 其中分别$Loss_{\textrm{clean}}(\theta_{\textrm{mt}})$为正常情况下的损失，$Loss_{\textrm{lm}}(\theta_{\textrm{lm}}^{\mathbi{x}})$和$Loss_{\textrm{lm}}(\theta_{\textrm{lm}}^{\mathbi{y}})$生成对抗样本所用到的源语言与目标语言语言模型的损失，$Loss_{\textrm{robust}}(\theta_{\textrm{mt}})$是以对源语言和目标端做出修改后得到的对抗样本作为输入，原始的目标语作为答案计算得到的损失，其具体形式如下：
\begin{eqnarray}
Loss_{\textrm{robust}}(\theta_{\textrm{mt}}) &=&  \frac{1}{\textrm{S}}\sum_{(\mathbi{x},\mathbi{y}\in \textrm{S})}-\log \funp{P}(\mathbi{y}|\mathbi{x}',\mathbi{z}';\theta_{\textrm{mt}})
\label{eq:13-11}
\end{eqnarray}

\noindent 这里$\textrm{S}$代表整体的语料库。通过上述方式达到对抗训练的目的。
\vspace{0.5em}
\end{itemize}

\parinterval 不论是黑盒方法还是白盒方法，本质上都是通过增加噪声使得模型训练更加健壮。类似的思想在很多机器学习方法都有体现，比如，最大熵模型中使用高斯噪声就是常用的增加模型健壮性的手段之一\upcite{chen1999gaussian}{\red 这篇文章再找一下}。而在深度学习时代下，对抗训练将问题定义为：有意识地构造系统容易出错的样本，进而更加有效的增加系统抗干扰的能力。

%----------------------------------------------------------------------------------------
%    NEW SECTION
%----------------------------------------------------------------------------------------

\sectionnewpage
\section{高级模型训练技术}

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{极大似然估计的问题}

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{非teacher-forcing方法}

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{增强学习方法}

%----------------------------------------------------------------------------------------
%    NEW SECTION
%----------------------------------------------------------------------------------------

\sectionnewpage
\section{知识精炼}\label{subsection-7.5.3}

\parinterval 理想的机器翻译系统应该是品质好、速度块、存储占用少。不过现实的机器翻译系统往往需要用运行速度和存储空间来换取翻译品质，比如，\ref{subsection-7.3.2}节提到的增大模型容量的方法就是通过增加模型参数量来达到更好的函数拟合效果，但是这也导致系统变得更加笨拙。在很多场景下，这样的模型甚至无法使用。比如，Transformer-Big等“大”模型通常在专用GPU服务器上运行，在手机等受限环境下仍很难应用。

\parinterval 另一方面，直接训练“小”模型的效果往往并不理想，其翻译品质与“大”模型相比仍有比较明显的差距。比如，在Transformer中，使用一个48层的编码器要比传统的6层编码器在BLEU上高出1-2个点，而且两者翻译结果的人工评价的区别也十分明显。

\parinterval 面对小模型难以训练的问题，一种有趣的想法是把“大”模型的知识传递给“小”模型，让“小”模型可以更好的进行学习。这类似于，教小孩子学习数学，是请一个权威数学家（数据中的标准答案），还是请一个小学数学教师（“大”模型）。这就是知识精炼的基本思想。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{什么是知识精炼}

\parinterval 通常，知识精炼可以被看作是一种知识迁移的手段\upcite{Hinton2015Distilling}。如果把“大”模型的知识迁移到“小”模型，这种方法的直接结果就是{\small\bfnew{模型压缩}}\index{模型压缩}（Model Compression）\index{Model Compression}。当然，理论上也可以把“小”模型的知识迁移到“大”模型，比如，将迁移后得到的“大”模型作为初始状态，之后继续训练该模型，以期望取得加速收敛的效果。不过，在实践中更多是使用“大”模型到“小”模型的迁移，这也是本节讨论的重点。

\parinterval 知识精炼基于两个假设：

\begin{itemize}
\vspace{0.5em}
\item “知识”在模型间是可迁移的。也就是说，一个模型中蕴含的规律可以被另一个模型使用。最典型的例子就是预训练模型（见\ref{subsection-7.2.6}）。使用单语数据学习到的表示模型，在双语的翻译任务中仍然可以发挥很好的作用。也就是，把单语语言模型学习到的知识迁移到双语翻译中对句子表示的任务中；
\vspace{0.5em}
\item 模型所蕴含的“知识”比原始数据中的“知识”更容易被学习到。比如，机器翻译中大量使用的回译（伪数据）方法，就把模型的输出作为数据让系统进行学习。
\vspace{0.5em}
\end{itemize}

\parinterval 这里所说的第二个假设对应了机器学习中的一大类问题\ \dash \ {\small\bfnew{学习难度}}\index{学习难度}（Learning Difficulty）\index{Learning Difficulty}。所谓难度是指：在给定一个模型的情况下，需要花费多少代价对目标任务进行学习。如果目标任务很简单，同时模型与任务很匹配，那学习难度就会降低。如果目标任务很复杂，同时模型与其匹配程度很低，那学习难度就会很大。在自然语言处理任务中，这个问题的一种表现是：在很好的数据中学习的模型的翻译质量可能仍然很差。即使训练数据是完美的，但是模型仍然无法做到完美的学习。这可能是因为建模的不合理，导致模型无法描述目标任务中复杂的规律。也就是纵然数据很好，但是模型学不到其中的“知识”。在机器翻译中这个问题体现的尤为明显。比如，在机器翻译系统$n$-best结果中挑选最好的译文（成为Oracle）作为训练样本让系统重新学习，系统仍然达不到Oracle的水平。

\parinterval 知识精炼本身也体现了一种“自学习”的思想。即利用模型（自己）的预测来教模型（自己）。这样既保证了知识可以向更轻量的模型迁移，同时也避免了模型从原始数据中学习难度大的问题。虽然“大”模型的预测中也会有错误，但是这种预测是更符合建模的假设的，因此“小”模型反倒更容易从不完美的信息中学习\footnote[15]{很多时候，“大”模型和“小”模型都是基于同一种架构，因此二者对问题的假设和模型结构都是相似的。}到更多的知识。类似于，刚开始学习围棋的人从职业九段身上可能什么也学不到，但是向一个业余初段的选手学习可能更容易入门。另外，也有研究表明：在机器翻译中，相比于“小”模型，“大”模型更容易进行优化，也更容易找到更好的模型收敛状态。因此在需要一个性能优越，存储较小的模型时，也会考虑将大模型压缩得到更轻量模型的手段\upcite{DBLP:journals/corr/abs-2002-11794}。

\parinterval 通常把“大”模型看作的传授知识的“教师”，被称作{\small\bfnew{教师模型}}\index{教师模型}（Teacher Model）\index{Teacher Model}；把“小”模型看作是接收知识的“学生”，被称作{\small\bfnew{学生模型}}\index{学生模型}（Student Model）\index{Student Model}。比如，可以把Transformer-Big看作是教师模型，把Transformer-Base看作是学生模型。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{知识精炼的基本方法}

\parinterval 知识精炼的基本思路是让学生模型所表示的函数尽可能去拟合教师模型所表示的函数\upcite{Hinton2015Distilling}。通常有两种实现方式\upcite{DBLP:conf/emnlp/KimR16}：

\begin{itemize}
\vspace{0.5em}
\item {\small\bfnew{基于单词的知识精炼}}\index{基于单词的知识精炼}（Word-level Knowledge Distillation）\index{Word-level Knowledge Distillation}。该方法的目标是使得学生模型的预测（分布）尽可能逼近教师模型的预测（分布）。令$\mathbf{x}=\{x_1,\ldots,x_m\}$和$\mathbf{y}=\{y_1,\ldots,y_n\}$分别表示输入和输出（数据中的答案）序列，$V$表示目标语言词表，$n$表示译文序列的长度，则基于单词的知识精炼的损失函数被定义为：
\begin{eqnarray}
L_{\textrm{word}} = - \sum_{j=1}^n \sum_{y_j \in V} \textrm{P}_{\textrm{t}} (y_{\textrm{j}}|\mathbf{x})\textrm{logP}_{\textrm{s}}(y_j|\mathbf{x})
\label{eq:13-28}
\end{eqnarray}

这里， $\textrm{P}_{\textrm{s}}(y_j|\mathbf{x})$和$\textrm{P}_{\textrm{t}} (y_i|\mathbf{x})$分别表示学生模型和教师模型在$j$位置的输出的概率。公式\ref{eq:13-28}实际上在最小化教师模型和学生模型输出分布之间的交叉熵。
\vspace{0.5em}
\item {\small\bfnew{基于序列的知识精炼}}\index{基于序列的知识精炼}（Sequence-level Knowledge Distillation）\index{Sequence-level Knowledge Distillation}。除了单词一级的拟合，基于序列的知识精炼希望在序列整体上进行拟合。其损失函数被定义为：
\begin{eqnarray}
L_{\textrm{seq}} = - \sum_{\textrm{y}}\textrm{P}_{\textrm{t}} (\mathbf{y}|\mathbf{x})\textrm{logP}_{\textrm{s}}(\mathbf{y}|\mathbf{x})
\label{eq:13-29}
\end{eqnarray}

公式\ref{eq:13-29}要求遍历所有可能的译文序列，并进行求和，当词表大小为$V$，序列长度为$L$时，则可能的序列的数量有$V$的$L$次幂，这么多的译文将消耗大量的计算资源。因此，会考虑用教师模型的真实输出序列$\hat{\mathbf{y}}$来代替整个空间，即假设$\textrm{P}_{\textrm{t}}(\hat{\mathbf{y}}|\mathbf{x})=1$。于是，目标函数变为：
\begin{eqnarray}
L_{\textrm{seq}} = - \textrm{logP}_{\textrm{s}}(\hat{\mathbf{y}} | \mathbf{x})
\label{eq:13-30}
\end{eqnarray}

这样的损失函数带来最直接的好处是，知识精炼的流程会非常简单。因为只需要利用教师模型将训练数据（源语言）翻译一遍，之后把它的输出替换为训练数据的目标语言部分。之后，利用得到的新的双语数据训练学生模型即可，图\ref{fig:13-41}展示了简化后词级和序列级的不同，其中词级知识精炼的解码端输入为真实双语数据的目标语言，并以teacher模型输出的概率分布作为学习目标，而序列级则直接将teacher推断后得到的结果作为解码端的输入，并将解码结果的One-hot向量作为学习目标。
\vspace{0.5em}
\end{itemize}

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-difference-between-word-level-and-sequence-level-in-knowledge-distillation}
\caption{词级和序列级知识精炼的差异}
\label{fig:13-41}
\end{figure}
%-------------------------------------------

\parinterval 本质上，基于单词的知识精炼和传统的语言模型等问题的建模方式是一致的。在传统方法中，训练数据中的答案会被看作是一个One-hot分布，之后让模型去尽可能拟合这种分布。而这里，答案不再是一个One-hot分布，而是由教师模型生成的真实分布，但是损失函数的形式是一模一样的。在具体实现时，一个容易出现的问题是在词级别的知识精炼中，teacher模型的Softmax可能会生成非常尖锐的分布。这时需要考虑对分布进行平滑，提高模型的泛化能力\footnote[16]{比如，可以在Softmax函数中加入一个参数$\alpha$，如$\textrm{Softmax}(s_i)=\frac{exp(s_i/\alpha)}{\sum_j exp(s_i/\alpha)}$。这样可以通过$\alpha$控制分布的平滑程度。
}。

\parinterval 除了在模型最后输出的分布上进行知识精炼，同样可以使用教师模型对学生模型的{\small\bfnew{中间层输出}}\index{中间层输出}（Hint-based Knowledge Transfer）\index{Hint-based Knowledge Transfer}和{\small\bfnew{注意力分布}}\index{注意力分布}（Attention To Attention Transfer）\index{Attention To Attention Transfer}进行约束。而对翻译常用的Transformer架构，也有研究者使用更精细的精炼方式对模型各个位置的知识重新设计了知识迁移的方法\upcite{DBLP:journals/corr/abs-1909-10351}。

%----------------------------------------------------------------------------------------
%    NEW SUB-SECTION
%----------------------------------------------------------------------------------------

\subsection{机器翻译中的知识精炼}

\parinterval 在神经机器翻译中，通常使用公式\ref{eq:13-30}的方法进行知识精炼，即通过教师模型构造伪数据，之后让学生模型从伪数据中学习。这样做的好处在于，系统研发人员不需要对系统进行任何修改，整个过程只需要调用教师模型和学生模型标准的训练和推断模块即可。

\parinterval 另一个问题是如何构造教师模型和学生模型。以Transformer为例，通常有两种思路：

\begin{itemize}
\vspace{0.5em}
\item 固定教师模型，通过减少模型容量的方式设计学生模型。比如，可以使用容量较大的模型作为教师模型（如：Transformer-Big或Transformer-Deep），然后通过将神经网络变“窄”、变“浅”的方式得到学生模型。我们可以用Transformer-Big做教师模型，然后把Transformer-Big的解码器变为一层网络，作为学生模型。
\vspace{0.5em}
\item 固定学生模型，通过模型集成的方式设计教师模型。可以组合多个模型生成更高质量的译文（见\ref{subsection-7.4.3}节）。比如，融合多个Transformer-Big模型（不同参数初始化方式），之后学习一个Transformer-Base模型。
\vspace{0.5em}
\end{itemize}

\parinterval 此外还可以采用迭代的知识精炼的方式。首先，通过模型集成得到较强的教师模型，再将知识迁移到不同的学生模型上，随后继续使用这些学生模型集成新的教师模型。不断的重复上述过程可以逐步提升集成模型的性能，如图\ref{fig:13-42}所示。值得注意的是，随着迭代次数的增加，集成所带来的收益也会随着子模型之间差异性的减小而减少。

%----------------------------------------------
\begin{figure}[htp]
\centering
\input{./Chapter13/Figures/figure-ensemble-knowledge-distillation}
\caption{迭代式知识精炼}
\label{fig:13-42}
\end{figure}
%-------------------------------------------

\parinterval 如果倾向于使用更少的存储，更快的推理速度，则可以使用更小的学生模型。值得注意的是，对于Transformer模型来说，减少解码端的层数会给推理速度带来巨大的提升。特别是对于基于深层编码器的Transformer-Deep，适当减少解码端层数往往不会带来翻译品质的下降。可以根据不同任务的需求，选择适当大小的学生模型，来平衡存储、推断速度和模型品质之间的关系。

%----------------------------------------------------------------------------------------
%    NEW SECTION
%----------------------------------------------------------------------------------------

\sectionnewpage
\section{可解释性}

%----------------------------------------------------------------------------------------
%    NEW SECTION
%----------------------------------------------------------------------------------------

\sectionnewpage
\section{小结及深入阅读}

\parinterval 对抗样本除了用于提高模型的鲁棒性之外，还有很多其他的应用场景。其中最主要的便是用于评估模型。通过构建由对抗样本构造的数据集，可以验证模型对于不同类型噪声鲁棒性\upcite{DBLP:conf/emnlp/MichelN18}。正是由于对抗样本在检测和提高模型鲁棒性具有明显的效果，因此很多的研究人员在针对不同的任务提出了很多有效的方法。但是在生成对抗样本时常常要注意或考虑很多问题，比如扰动是否足够细微，在人类难以察觉的同时做到欺骗模型的目的，对抗样本在不同的模型结构或数据集上是否具有足够的泛化能力。生成的方法是否足够高效等等。 


