序列模型能够应用在许多领域,例如:
这些序列模型基本都属于监督式学习,输入 x 和输出 y 不一定都是序列模型。如果都是序列模型的话,模型长度不一定完全一致。
Harry Potter and Hermione Granger invented a new spell.
对于输入 x,表示为:
[ x < 1 > x < 2 > x < 3 > x < 4 > x < 5 > x < 6 > x < 7 > x < 8 > x < 9 > ] [x^{<1>}\ \ x^{<2>}\ \ x^{<3>}\ \ x^{<4>}\ \ x^{<5>}\ \ x^{<6>}\ \ x^{<7>}\ \ x^{<8>}\ \ x^{<9>}] [x<1> x<2> x<3> x<4> x<5> x<6> x<7> x<8> x<9>]
x < t > x^{
该句话包含 9 个单词,输出 y 即为 1 x 9 向量,每位表征对应单词是否为人名的一部分,1 表示是,0 表示否。很明显,该句话中 “Harry”,“Potter”,“Hermione”,“Granger” 均是人名成分,所以,对应的输出 y 可表示为:
y = [ 1 1 0 1 1 0 0 0 0 ] y=[1\ \ 1\ \ 0\ \ 1\ \ 1\ \ 0\ \ 0\ \ 0\ \ 0] y=[1 1 0 1 1 0 0 0 0]
y < t > y^{
x < t > x^{
如果出现词汇表之外的单词,可以使用 UNK 或其他字符串来表示。
对于多样本,以上序列模型对应的命名规则可表示为: X ( i ) < t > X^{(i)
对于序列模型,如果使用标准的神经网络,其模型结构如下:
使用标准的神经网络模型存在两个问题:
标准的神经网络不适合解决序列模型问题,而循环神经网络(RNN)是专门用来解决序列模型问题的。RNN 模型结构如下:
序列模型从左到右,依次传递,此例中, T x = T y T_x=T_y Tx=Ty。 x < t > x^{
RNN 模型包含三类权重系数,分别是 W a x , W a a , W y a W_{ax}, W_{aa}, W_{ya} Wax,Waa,Wya。且不同元素之间同一位置共享同一权重系数。
RNN 的正向传播(Forward Propagation)过程为:
a < t > = g ( W a a ⋅ a < t − 1 > + W a x ⋅ x < t > + b a ) a^{
y ^ < t > = g ( W y a ⋅ a < t > + b y ) \hat y^{
其中,g(⋅) 表示激活函数,不同的问题需要使用不同的激活函数。
为了简化表达式,可以对 a < t > a^{
W a a ⋅ a < t − 1 > + W a x ⋅ x < t > = [ W a a W a x ] [ a < t − 1 > x < t > ] → W a [ a < t − 1 > , x < t > ] W_{aa}\cdot a^{
则正向传播可表示为:
a < t > = g ( W a [ a < t − 1 > , x < t > ] + b a ) a^{
y ^ < t > = g ( W y ⋅ a < t > + b y ) \hat y^{
值得一提的是,以上所述的 RNN 为单向 RNN,即按照从左到右顺序,单向进行, y ^ < t > \hat y^{
He said, “Teddy Roosevelt was a great President.”
He said, “Teddy bears are on sale!”
因此,有另外一种 RNN 结构是双向 RNN,简称为 BRNN。 y ^ < t > \hat y^{
针对上面识别人名的例子,经过 RNN 正向传播,单个元素的 Loss function 为:
L < t > ( y ^ < t > , y < t > ) = − y < t > l o g y ^ < t > − ( 1 − y < t > ) l o g ( 1 − y ^ < t > ) L^{
该样本所有元素的 Loss function 为:
L ( y ^ , y ) = ∑ t = 1 T y L < t > ( y ^ < t > , y < t > ) L(\hat y,y)=\sum_{t=1}^{T_y}L^{
然后,反向传播(Backpropagation)过程就是从右到左分别计算 L ( y ^ , y ) L(\hat y,y) L(y^,y) 对参数 W a W_{a} Wa, W y W_{y} Wy, b a b_{a} ba, b y b_{y} by 的偏导数。思路与做法与标准的神经网络是一样的。一般可以通过成熟的深度学习框架自动求导,例如 PyTorch、Tensorflow 等。这种从右到左的求导过程被称为 Backpropagation through time。
以上介绍的例子中, T x = T y T_x=T_y Tx=Ty。但是在很多 RNN 模型中,Tx 是不等于 Ty 的。例如第 1 节介绍的许多模型都是Tx≠Ty。根据 Tx 与 Ty 的关系,RNN 模型包含以下几个类型:
不同类型相应的示例结构如下:
语言模型:语言模型就是用来计算一个句子的概率的模型,也就是判断一句话是否是人话的概率?
语言模型是自然语言处理(NLP)中最基本和最重要的任务之一。使用 RNN 能够很好地建立需要的不同语言风格的语言模型。
什么是语言模型呢?举个例子,在语音识别中,某句语音有两种翻译:
The apple and pair salad.
The apple and pear salad.
很明显,第二句话更有可能是正确的翻译。语言模型实际上会计算出这两句话各自的出现概率。比如第一句话概率为 1 0 − 13 10^{−13} 10−13,第二句话概率为 1 0 − 10 10^{−10} 10−10。也就是说,利用语言模型得到各自语句的概率,选择概率最大的语句作为正确的翻译。概率计算的表达式为:
P ( y < 1 > , y < 2 > , ⋯ , y < T y > ) P(y^{<1>},y^{<2>},\cdots,y^{
如何使用 RNN 构建语言模型?首先,我们需要一个足够大的训练集,训练集由大量的单词语句语料库(corpus)构成。然后,对 corpus 的每句话进行切分词(tokenize)。做法就跟第 2 节介绍的一样,建立 vocabulary,对每个单词进行 one-hot 编码。
准备好训练集并对语料库进行切分词等处理之后,接下来构建相应的 RNN 模型。
语言模型的 RNN 结构如上图所示, x < 1 > x^{<1>} x<1> 和 a < 0 > a^{<0>} a<0> 均为零向量。Softmax 输出层 y ^ < 1 > \hat y^{<1>} y^<1> 表示出现该语句第一个单词的概率,softmax 输出层表 y ^ < 2 > \hat y^{<2>} y^<2> 示在第一个单词基础上出现第二个单词的概率,即条件概率,以此类推,最后是出现 < E O S > < EOS > <EOS> 的条件概率。
单个元素的 softmax loss function 为:
L < t > ( y ^ < t > , y < t > ) = − ∑ i y i < t > l o g y ^ i < t > L^{
该样本所有元素的 Loss function 为:
L ( y ^ , y ) = ∑ t L < t > ( y ^ < t > , y < t > ) L(\hat y,y)=\sum_tL^{
对语料库的每条语句进行 RNN 模型训练,最终得到的模型可以根据给出语句的前几个单词预测其余部分,将语句补充完整。例如给出 “Cats average 15”,RNN 模型可能预测完整的语句是 “Cats average 15 hours of sleep a day.”。
最后补充一点,整个语句出现的概率等于语句中所有元素出现的条件概率乘积。例如某个语句包含 y < 1 > , y < 2 > , y < 3 > y^{<1>},y^{<2>},y^{<3>} y<1>,y<2>,y<3> 则整个语句出现的概率为:
P ( y < 1 > , y < 2 > , y < 3 > ) = P ( y < 1 > ) ⋅ P ( y < 2 > ∣ y < 1 > ) ⋅ P ( y < 3 > ∣ y < 1 > , y < 2 > ) P(y^{<1>},y^{<2>},y^{<3>})=P(y^{<1>})\cdot P(y^{<2>}|y^{<1>})\cdot P(y^{<3>}|y^{<1>},y^{<2>}) P(y<1>,y<2>,y<3>)=P(y<1>)⋅P(y<2>∣y<1>)⋅P(y<3>∣y<1>,y<2>)
利用训练好的 RNN 语言模型,可以进行新的序列采样,从而随机产生新的语句。与上一节介绍的一样,相应的 RNN 模型如下所示:
首先,从第一个元素输出 y ^ < 1 > \hat y^{<1>} y^<1> 的 softmax 分布中随机选取一个 word 作为新语句的首单词。然后,作 y < 1 > y^{<1>} y<1> 为 x < 2 > x^{<2>} x<2> ,得到 y ^ < 2 > \hat y^{<2>} y^<2> 的 softmax 分布。从中选取概率最大的 word 作为 y < 2 > y^{<2>} y<2> ,继续将 y < 2 > y^{<2>} y<2> 作为 x < 3 > x^{<3>} x<3> ,以此类推。直到产生 < E O S > < EOS > <EOS> 结束符,则标志语句生成完毕。当然,也可以设定语句长度上限,达到长度上限即停止生成新的单词。最终,根据随机选择的首单词,RNN 模型会生成一条新的语句。
以上介绍的是 word level RNN,即每次生成单个 word,语句由多个 words 构成。另外一种情况是 character level RNN,即词汇表由单个英文字母或字符组成,如下所示:
V o c a b u l a y = [ a , b , c , ⋯ , z , . , ; , , 0 , 1 , ⋯ , 9 , A , B , ⋯ , Z ] Vocabulay=[a,b,c,\cdots,z,.,;,\ ,0,1,\cdots,9,A,B,\cdots,Z] Vocabulay=[a,b,c,⋯,z,.,;, ,0,1,⋯,9,A,B,⋯,Z]
Character level RNN 与 word level RNN 不同的是, y ^ < t > \hat y^{
语句中可能存在跨度很大的依赖关系,即某个 word 可能与它距离较远的某个 word 具有强依赖关系。例如下面这两条语句:
The cat, which already ate fish, was full.
The cats, which already ate fish, were full.
第一句话中,was 受 cat 影响;第二句话中,were 受 cats 影响。它们之间都跨越了很多单词。而一般的 RNN 模型每个元素受其周围附近的影响较大,难以建立跨度较大的依赖性(long-term dependicies)。上面两句话的这种依赖关系,由于跨度很大,普通的 RNN 网络容易出现梯度消失,捕捉不到它们之间的依赖,造成语法错误。
另一方面,RNN 也可能出现梯度爆炸的问题,即 gradient 过大。常用的解决办法是设定一个阈值,一旦梯度最大值达到这个阈值,就对整个梯度向量进行尺度缩小。这种做法被称为 gradient clipping。
GRU 的基本思想是通过加入门,扑捉非常长范围的依赖
RNN 的隐藏层单元结构如下图所示:
a < t > = t a n h ( W a [ a < t − 1 > , x < t > ] + b a ) a^{
为了解决梯度消失问题,对上述单元进行修改,添加了记忆单元,构建 GRU,如下图所示:
相应的表达式为:
c ~ < t > = t a n h ( W c [ c < t − 1 > , x < t > ] + b c ) \tilde c^{
Γ u = σ ( W u [ c < t − 1 > , x < t > ] + b u ) \Gamma_u=\sigma(W_u[c^{
c < t > = Γ ∗ c ~ < t > + ( 1 − Γ u ) ∗ c < t − 1 > c^{
其中, c < t − 1 > = a < t − 1 > c^{
上面介绍的是简化的 GRU 模型,完整的 GRU 添加了另外一个 gate,即 Γ r \Gamma_r Γr,表达式如下:
c ~ < t > = t a n h ( W c [ Γ r ∗ c < t − 1 > , x < t > ] + b c ) \tilde c^{
Γ u = σ ( W u [ c < t − 1 > , x < t > ] + b u ) \Gamma_u=\sigma(W_u[c^{
Γ r = σ ( W r [ c < t − 1 > , x < t > ] + b r ) \Gamma_r=\sigma(W_r[c^{
c < t > = Γ ∗ c ~ < t > + ( 1 − Γ u ) ∗ c < t − 1 > c^{
a < t > = c < t > a^{
注意,以上表达式中的∗∗表示元素相乘,而非矩阵相乘。
LSTM 是另一种更强大的解决梯度消失问题的方法。它对应的 RNN 隐藏层单元结构如下图所示:
GRU 和 LSTM 公式对比图
c ~ < t > = t a n h ( W c [ a < t − 1 > , x < t > ] + b c ) \tilde c^{
Γ u = σ ( W u [ a < t − 1 > , x < t > ] + b u ) ( U p d a t e G a t e ) \Gamma_u=\sigma(W_u[a^{
Γ f = σ ( W f [ a < t − 1 > , x < t > ] + b f ) ( F o r g e t G a t e ) \Gamma_f=\sigma(W_f[a^{
Γ o = σ ( W o [ a < t − 1 > , x < t > ] + b o ) ( O u t p u t G a t e ) \Gamma_o=\sigma(W_o[a^{
c < t > = Γ u ∗ c ~ < t > + Γ f ∗ c < t − 1 > c^{
a < t > = Γ o ∗ c < t > a^{
LSTM 包含三个 gates: Γ u \Gamma_u Γu, Γ f \Gamma_f Γf, Γ o \Gamma_o Γo,分别对应 update gate,forget gate 和 output gate。
BRNN 对应位置的输出同时接受前面和后面的激活函数值,通过前向和反向过程获取句子整体信息。
He said, “Teddy bears are on sale!”
He said, “Teddy Roosevelt was a great President!”
我们在第 3 节中简单提过 Bidirectional RNN,它的结构如下图所示:
BRNN 对应的输出 y < t > y^{
y ^ < t > = g ( W y [ a → < t > , a ← < t > ] + b y ) \hat y^{
BRNN 能够同时对序列进行双向处理,性能大大提高。但是计算量较大,且在处理实时语音时,需要等到完整的一句话结束时才能进行分析。
Deep RNNs 由多层 RNN 组成,其结构如下图所示:
与 DNN 一样,用上标 [l] 表示层数。Deep RNNs 中 a [ l ] < t > a^{[l]
a [ l ] < t > = g ( W a [ l ] [ a [ l ] < t − 1 > , a [ l − 1 ] < t > ] + b a [ l ] ) a^{[l]
当前节点接收同一层的前一个和同一时间的下面一个作为输入。
我们知道 DNN 层数可达 100 多,而 Deep RNNs 一般没有那么多层,3 层 RNNs 已经较复杂了。
另外一种 Deep RNNs 结构是每个输出层上还有一些垂直单元,如下图所示:
one-hot 编码相关性差,数据稀疏——>特征表示可以表征很多特征,得到单词之间的相关性
上节课我们介绍过表征单词的方式是首先建立一个较大的词汇表(例如 10000),然后使用 one-hot 的方式对每个单词进行编码。例如单词 Man,Woman,King,Queen,Apple,Orange 分别出现在词汇表的第 5391,9853,4914,7157,456,6257 的位置
这中 one-hot 表征单词的方法最大的缺点就是每个单词都是独立的、正交的,无法知道不同单词之间的相似程度。例如 Apple 和 Orange 都是水果,词性相近,但是单从 one-hot 编码上来看,内积为零,无法知道二者的相似性。在 NLP 中,我们更希望能掌握不同单词之间的相似程度。
因此,我们可以使用**特征表征(Featurized representation)**的方法对每个单词进行编码。也就是使用一个特征向量表征单词,特征向量的每个元素都是对该单词某一特征的量化描述,量化范围可以是 [-1,1] 之间。特征表征的例子如下图所示:
特征向量的长度依情况而定,特征元素越多则对单词表征得越全面。这里的特征向量长度设定为 300。使用特征表征之后,词汇表中的每个单词都可以使用对应的 300 x 1 的向量来表示,该向量的每个元素表示该单词对应的某个特征值。
这种特征表征的优点是根据特征向量能清晰知道不同单词之间的相似程度,例如 Apple 和 Orange 之间的相似度较高,很可能属于同一类别。这种单词 “类别” 化的方式,大大提高了有限词汇量的泛化能力。这种特征化单词的操作被称为 Word Embeddings,即单词嵌入。
值得一提的是,这里特征向量的每个特征元素含义是具体的,对应到实际特征,例如性别、年龄等。而在实际应用中,特征向量很多特征元素并不一定对应到有物理意义的特征,是比较抽象的。但是,这并不影响对每个单词的有效表征,同样能比较不同单词之间的相似性。
每个单词都由高维特征向量表征,为了可视化不同单词之间的相似性,可以使用降维操作,例如 t-SNE 算法,将 300D 降到 2D 平面上。如下图所示:
从上图可以看出相似的单词分布距离较近,从而也证明了 Word Embeddings 能有效表征单词的关键特征。
Word Embedding 对于小样本数据具有很好的效果,使用预训练模型得到词的向量表示时就包含很多特征信息,这样即使样本数量不多也能捕获词之间的相关性和相似度。迁移学习可以很好地应用到这里。但是对于语言模型和机器翻译作用不大,因为两者有大量数据可以通过深度学习模型训练。
之前我们介绍过 Named entity 识别的例子,每个单词采用的是 one-hot 编码。如下图所示,因为 “orange farmer” 是份职业,很明显 “Sally Johnson” 是一个人名。
如果采用 featurized representation 对每个单词进行编码,再构建该 RNN 模型。对于一个新的句子:
Robert Lin is an apple farmer
由于这两个句子中,“apple” 与 “orange” 特征向量很接近,很容易能判断出 “Robert Lin” 也是一个人名。这就是 featurized representation 的优点之一。
可以看出,featurized representation 的优点是可以减少训练样本的数目,前提是对海量单词建立特征向量表述(word embedding)。这样,即使训练样本不够多,测试时遇到陌生单词,例如 “durian cultivator”,根据之前海量词汇特征向量就判断出 “durian” 也是一种水果,与 “apple” 类似,而 “cultivator” 与 “farmer” 也很相似。从而得到与 “durian cultivator” 对应的应该也是一个人名。这种做法将单词用不同的特征来表示,即使是训练样本中没有的单词,也可以根据 word embedding 的结果得到与其词性相近的单词,从而得到与该单词相近的结果,有效减少了训练样本的数量。
featurized representation 的特性使得很多 NLP 任务能方便地进行迁移学习。方法是:
建议仅当训练样本足够大的时候,再进行上述第三步。
word embeddings 与人脸特征编码有很多相似性。人脸图片经过 Siamese 网络,得到其特征向量 f(x),这点跟 word embedding 是类似的。二者不同的是 Siamese 网络输入的人脸图片可以是数据库之外的;而 word embedding 一般都是已建立的词汇库中的单词,非词汇库单词统一用 < U N K >
Word embeddings 可以帮助我们找到不同单词之间的相似类别关系。如下图所示:
上例中,特征维度是 4 维的,分别是 [Gender, Royal, Age, Food]。常识地,“Man” 与 “Woman” 的关系类比于 “King” 与 “Queen” 的关系。而利用 Word embeddings 可以找到这样的对应类比关系。
我们将 “Man” 的 embedding vector 与 “Woman” 的 embedding vector 相减:
e m a n − e w o m a n = [ − 1 0.01 0.03 0.09 ] − [ 1 0.02 0.02 0.01 ] ≈ [ − 2 0 0 0 ] e_{man}-e_{woman}=\left[ \begin{matrix} -1 \\ 0.01 \\ 0.03 \\ 0.09 \end{matrix} \right]-\left[ \begin{matrix} 1 \\ 0.02 \\ 0.02 \\ 0.01 \end{matrix} \right]\approx\left[ \begin{matrix} -2 \\ 0 \\ 0 \\ 0 \end{matrix} \right] eman−ewoman=⎣⎢⎢⎡−10.010.030.09⎦⎥⎥⎤−⎣⎢⎢⎡10.020.020.01⎦⎥⎥⎤≈⎣⎢⎢⎡−2000⎦⎥⎥⎤
类似地,我们将 “King” 的 embedding vector 与 “Queen” 的 embedding vector 相减:
e k i n g − e q u e e n = [ − 0.95 0.93 0.70 0.02 ] − [ 0.97 0.95 0.69 0.01 ] ≈ [ − 2 0 0 0 ] e_{king}-e_{queen}=\left[ \begin{matrix} -0.95 \\ 0.93 \\ 0.70 \\ 0.02 \end{matrix} \right]-\left[ \begin{matrix} 0.97 \\ 0.95 \\ 0.69 \\ 0.01 \end{matrix} \right]\approx\left[ \begin{matrix} -2 \\ 0 \\ 0 \\ 0 \end{matrix} \right] eking−equeen=⎣⎢⎢⎡−0.950.930.700.02⎦⎥⎥⎤−⎣⎢⎢⎡0.970.950.690.01⎦⎥⎥⎤≈⎣⎢⎢⎡−2000⎦⎥⎥⎤
相减结果表明,“Man” 与 “Woman” 的主要区别是性别,“King” 与 “Queen” 也是一样。
一般地,A 类比于 B 相当于 C 类比于 “?”,这类问题可以使用 embedding vector 进行运算。
如上图所示,根据等式 e m a n − e w o m a n ≈ e k i n g − e ? e_{man}-e_{woman}\approx e_{king}-e_? eman−ewoman≈eking−e? 得:
e ? = e k i n g − e m a n + e w o m a n e_?=e_{king}-e_{man}+e_{woman} e?=eking−eman+ewoman
利用相似函数计算可能性最大的 e ? e_{?} e?
关于相似函数,比较常用的是余弦相似度(cosine similarity)。其表达式为:
S i m ( u , v ) = u T v ∣ ∣ u ∣ ∣ ⋅ ∣ ∣ v ∣ ∣ Sim(u,v)=\frac{u^Tv}{||u||\cdot ||v||} Sim(u,v)=∣∣u∣∣⋅∣∣v∣∣uTv
还可以计算 Euclidian distance 来比较相似性,即 ∣ ∣ u − v ∣ ∣ 2 ||u−v||^{2} ∣∣u−v∣∣2。距离越大,相似性越小。
词嵌入的一个显著成果就是,可学习的类比关系的一般性。举个例子,它能学会 man 对于 woman 相当于 boy 对于 girl,因为 man 和 woman 之间和 king 和 queen 之间,还有 boy 和 girl 之间的向量差在 gender( 性别)这一维都是一样的。它还能学习 Canada( 加拿大)的首都是 Ottawa( 渥太华),而渥太华对于加拿大相当于 Nairobi( 内罗毕)对于 Kenya( 肯尼亚),这些都是国家中首都城市名字。它还能学习 big 对于 bigger 相当于 tall 对于 taller,还能学习 Yen( 円)对于 Janpan( 日本),円是日本的货币单位,相当于 Ruble( 卢比)对于 Russia( 俄罗斯)。这些东西都能够学习,只要你在大型的文本语料库上实现一个词嵌入学习算法,只要从足够大的语料库中进行学习,它就能自主地发现这些模式。
假设某个词汇库包含了 10000 个单词,每个单词包含的特征维度为 300,那么表征所有单词的 embedding matrix 维度为 300 x 10000,用 E 来表示。某单词 w 的 one-hot 向量表示为 O w O_{w} Ow,维度为 10000 x 1,则该单词的 embedding vector 表达式为:
e w = E ⋅ O w e_w=E\cdot O_w ew=E⋅Ow
因此,只要知道了 embedding matrix E,就能计算出所有单词的 embedding vector ewew。后面我们将重点介绍如何求出 E。
值得一提的是,上述这种矩阵乘积运算 E ⋅ O w E⋅O_{w} E⋅Ow 效率并不高,矩阵维度很大,且 O w O_{w} Ow 大部分元素为零。通常做法是直接从 E 中选取第 w 列作为 e w e_{w} ew 即可。
通过上下文预测某个位置的词,输入为 context,目标为 target
embedding matrix E 可以通过构建自然语言模型,运用梯度下降算法得到。举个简单的例子,输入样本是下面这句话:
I want a glass of orange (juice).
通过这句话的前 6 个单词,预测最后的单词 “juice”。E 未知待求,每个单词可用 embedding vector e w e_{w} ew 表示。构建的神经网络模型结构如下图所示:
神经网络输入层包含 6 个 embedding vactors,每个 embedding vector 维度是 300,则输入层总共有 1800 个输入。Softmax 层有 10000 个概率输出,与词汇表包含的单词数目一致。正确的输出 label 是 “juice”。其中 E , W [ 1 ] , b [ 1 ] , W [ 2 ] , b [ 2 ] E,W^{[1]},b^{[1]},W^{[2]},b^{[2]} E,W[1],b[1],W[2],b[2] 为待求值。对足够的训练例句样本,运用梯度下降算法,迭代优化,最终求出 embedding matrix E。
这种算法的效果还不错,能够保证具有相似属性单词的 embedding vector 相近。
为了让神经网络输入层数目固定,可以选择只取预测单词的前 4 个单词作为输入,例如该句中只选择 “a glass of orange” 四个单词作为输入。当然,这里的 4 是超参数,可调。
一般地,我们把输入叫做 context,输出叫做 target。对应到上面这句话里:
关于 context 的选择有多种方法:
事实证明,不同的 context 选择方法都能计算出较准确的 embedding matrix E。
上一小节我们介绍了 context 和 target 的选择方法,比较流行的是采用 Skip-Gram 模型。以下面这句话为例:
I want a glass of orange juice to go along with my cereal.
Skip-Gram 模型的做法是:首先随机选择一个单词作为 context,例如 “orange”;然后使用一个宽度为 5 或 10(自定义)的滑动窗,在 context 附近选择一个单词作为 target,可以是 “juice”、“glass”、“my” 等等。最终得到了多个 context—target 对作为监督式学习样本。
训练的过程是构建自然语言模型,经过 softmax 单元的输出为:
y ^ = e θ t T ⋅ e c ∑ j = 1 10000 e θ j T ⋅ e c \hat y=\frac{e^{\theta_t^T\cdot e_c}}{\sum_{j=1}^{10000}e^{\theta_j^T\cdot e_c}} y^=∑j=110000eθjT⋅eceθtT⋅ec
其中, θ t \theta_t θt 为 target 对应的参数, e c e_{c} ec 为 context 的 embedding vector,且 e c = E ⋅ O c e_c=E\cdot O_c ec=E⋅Oc。
相应的 loss function 为:
L ( y ^ , y ) = − ∑ i = 1 10000 y i l o g y ^ i L(\hat y,y)=-\sum_{i=1}^{10000}y_ilog\ \hat y_i L(y^,y)=−i=1∑10000yilog y^i
这是常用的 softmax 损失函数,y 就是只有一个 1 其他都是 0 的 one-hot 向量,如果目标词是 juice,那么第 4834 个元素就是 1,其余是 0。类似的 y ^ \hat y y^ 是一个从 softmax 单元输出的 10,000 维的向量,这个向量是所有可能目标词的概率。
然后,运用梯度下降算法,迭代优化,最终得到 embedding matrix E。如果优化这个关于所有这些参数的损失函数,你就会得到一个较好的嵌入向量集,这个就叫做 Skip-Gram 模型。它把一个像 orange 这样的词作为输入,并预测这个词从左数或从右数的某个词,预测上下文词的前面一些或者后面一些是什么词。
实际上使用这个算法会遇到一些问题,首要的问题就是计算速度。主要因为 softmax 输出单元为 10000 个, y ^ \hat y y^ 计算公式中包含了大量的求和运算。
这里有一些解决方案,如分级(hierarchical)的 softmax 分类器和 负采样( Negative Sampling)。
解决的办法之一是使用 hierarchical softmax classifier,即树形分类器。其结构如下图所示:
这种树形分类器是一种二分类。与之前的 softmax 分类器不同,它在每个数节点上对目标单词进行区间判断,最终定位到目标单词。这好比是猜数字游戏,数字范围 0~100。我们可以先猜 50,如果分类器给出目标数字比 50 大,则继续猜 75,以此类推,每次从数据区间中部开始。这种树形分类器最多需要 log N 步就能找到目标单词,N 为单词总数。
实际应用中,对树形分类器做了一些改进。改进后的树形分类器是非对称的,通常选择把比较常用的单词放在树的顶层,而把不常用的单词放在树的底层。这样更能提高搜索速度。(哈夫曼树)
最后提一点,关于 context 的采样,需要注意的是如果使用均匀采样,那么一些常用的介词、冠词,例如 the, of, a, and, to 等出现的概率更大一些。但是,这些单词的 embedding vectors 通常不是我们最关心的,我们更关心例如 orange, apple, juice 等这些名词等。所以,实际应用中,一般不选择随机均匀采样的方式来选择 context,而是使用其它算法来处理这类问题。
CBOW 是从原始语句推测目标字词;而 Skip-Gram 正好相反,是从目标字词推测出原始语句。CBOW 对小型数据库比较合适,而 Skip-Gram 在大型语料中表现更好。 上面为 CBOW,下面为 Skip-Gram
而刚才讲的 Skip-Gram 模型,关键问题在于 softmax 这个步骤的计算成本非常昂贵,因为它需要在分母里对词汇表中所有词求和。通常情况下,Skip-Gram 模型用到更多点。在下个视频中,我会展示给你一个算法,它修改了训练目标使其可以运行得更有效,因此它可以让你应用在一个更大的训练集上面,也可以学到更好的词嵌入。
Negative sampling 是另外一种有效的求解 embedding matrix EE 的方法。它的做法是判断选取的 context word 和 target word 是否构成一组正确的 context-target 对,一般包含一个正样本和 k 个负样本。例如,“orange” 为 context word,“juice” 为 target word,很明显 “orange juice” 是一组 context-target 对,为正样本,相应的 target label 为 1。若 “orange” 为 context word 不变,target word 随机选择 “king”、“book”、“the” 或者 “of” 等。这些都不是正确的 context-target 对,为负样本,相应的 target label 为 0。
一般地,固定某个 context word 对应的负样本个数 k 一般遵循:
Negative sampling 的数学模型为:
P ( y = 1 ∣ c , t ) = σ ( θ t T ⋅ e c ) P(y=1|c,t)=\sigma(\theta^T_t\cdot e_c) P(y=1∣c,t)=σ(θtT⋅ec)
其中,σ 表示 sigmoid 激活函数。
很明显,negative sampling 某个固定的正样本对应 k 个负样本,即模型总共包含了 k+1 个 binary classification。对比之前介绍的 10000 个输出单元的 softmax 分类,negative sampling 转化为 k+1 个二分类问题,计算量要小很多,大大提高了模型运算速度。
最后提一点,关于如何选择负样本对应的 target 单词,可以使用随机选择的方法。但有资料提出一个更实用、效果更好的方法,就是根据该词出现的频率进行选择,相应的概率公式为:
P ( w i ) = f ( w i ) 3 4 ∑ j 10000 f ( w j ) 3 4 P(w_i)=\frac{f(w_i)^{\frac34}}{\sum_j^{10000}f(w_j)^{\frac34}} P(wi)=∑j10000f(wj)43f(wi)43
其中, f ( w i ) f(w_{i}) f(wi) 表示单词 w i w_{i} wi 在单词表中出现的概率。
GloVe 算法引入了一个新的参数:
其中,i 表示 context,j 表示 target。一般地,如果不限定 context 一定在 target 的前面,则有对称关系 X i j = X j i X_{ij}=X_{ji} Xij=Xji;如果有限定先后,则 X i j ≠ X j i X_{ij}\neq X_{ji} Xij=Xji。接下来的讨论中,我们默认存在对称关系 X i j = X j i X_{ij}=X_{ji} Xij=Xji。
GloVe 模型的 loss function 为:
L = ∑ i = 1 10000 ∑ j = 1 10000 ( θ i T e j − l o g X i j ) 2 L=\sum_{i=1}^{10000}\sum_{j=1}^{10000}(\theta_i^Te_j-log X_{ij})^2 L=i=1∑10000j=1∑10000(θiTej−logXij)2
从上式可以看出,若两个词的 embedding vector 越相近,同时出现的次数越多,则对应的 loss 越小。
为了防止出现 “log 0”,即两个单词不会同时出现,无相关性的情况,对 loss function 引入一个权重因子 f ( X i j ) f(X_{ij}) f(Xij):
L = ∑ i = 1 10000 ∑ j = 1 10000 f ( X i j ) ( θ i T e j − l o g X i j ) 2 L=\sum_{i=1}^{10000}\sum_{j=1}^{10000}f(X_{ij})(\theta_i^Te_j-log X_{ij})^2 L=i=1∑10000j=1∑10000f(Xij)(θiTej−logXij)2
当 X i j = 0 X_{ij}=0 Xij=0 时,权重因子 f ( X i j ) = 0 f(X_{ij})=0 f(Xij)=0。这种做法直接忽略了无任何相关性的 context 和 target,只考虑 X i j > 0 X_{ij}>0 Xij>0 的情况。
出现频率较大的单词相应的权重因子 f ( X i j ) f(X_{ij}) f(Xij) 较大,出现频率较小的单词相应的权重因子 f ( X i j ) f(X_{ij}) f(Xij) 较小一些。具体的权重因子 f ( X i j ) f(X_{ij}) f(Xij) 选取方法可查阅相关论文资料。
一般地,引入偏移量,则 loss function 表达式为:
L = ∑ i = 1 10000 ∑ j = 1 10000 f ( X i j ) ( θ i T e j + b i + b j ′ − l o g X i j ) 2 L=\sum_{i=1}^{10000}\sum_{j=1}^{10000}f(X_{ij})(\theta_i^Te_j+b_i+b_j'-log X_{ij})^2 L=i=1∑10000j=1∑10000f(Xij)(θiTej+bi+bj′−logXij)2
值得注意的是,参数 θ i \theta_i θi和 e j e_{j} ej是对称的。使用优化算法得到所有参数之后,最终的 e w e_{w} ew 可表示为:
e w = e w + θ w 2 e_w=\frac{e_w+\theta_w}{2} ew=2ew+θw
最后提一点的是,无论使用 Skip-Gram 模型还是 GloVe 模型等等,计算得到的 embedding matrix EE 的每一个特征值不一定对应有实际物理意义的特征值,如 gender,age 等。
情感分类一般是根据一句话来判断其喜爱程度,例如 1~5 星分布。如下图所示:
情感分类问题的一个主要挑战是缺少足够多的训练样本。而 Word embedding 恰恰可以帮助解决训练样本不足的问题。
首先介绍使用 word embedding 解决情感分类问题的一个简单模型算法。
如上图所示,这句话的 4 个单词分别用 embedding vector 表示。 e 8928 , e 2468 , e 4694 , e 3180 e_{8928},e_{2468},e_{4694},e_{3180} e8928,e2468,e4694,e3180 计算均值,这样得到的平均向量的维度仍是 300。最后经过 softmax 输出 1~5 星。这种模型结构简单,计算量不大,不论句子长度多长,都使用平均的方式得到 300D 的 embedding vector。该模型实际表现较好。
但是,这种简单模型的缺点是使用平均方法,没有考虑句子中单词出现的次序,忽略其位置信息。而有时候,不同单词出现的次序直接决定了句意,即情感分类的结果。例如下面这句话:
Completely lacking in good taste, good service, and good ambience.
虽然这句话中包含了 3 个 “good”,但是其前面出现了 “lacking”,很明显这句话句意是 negative 的。如果使用上面介绍的平均算法,则很可能会错误识别为 positive 的,因为忽略了单词出现的次序。
为了解决这一问题,情感分类的另一种模型是 RNN。
该 RNN 模型是典型的 many-to-one 模型,考虑单词出现的次序,能够有效识别句子表达的真实情感。
值得一提的是使用 word embedding,能够有效提高模型的泛化能力,即使训练样本不多,也能保证模型有不错的性能。
Word embeddings 中存在一些性别、宗教、种族等偏见或者歧视。例如下面这两句话:
Man: Woman —— King: Queen
Man: Computer programmer —— Woman: Homemaker
Father: Doctor —— Mother: Nurse
很明显,第二句话和第三句话存在性别偏见,因为 Woman 和 Mother 也可以是 Computer programmer 和 Doctor。
以性别偏见为例,我们来探讨下如何消除 word embeddings 中偏见。
首先,确定偏见 bias 的方向。方法是对所有性别对立的单词求差值,再平均。上图展示了 bias direction 和 non-bias direction。
b i a s d i r e c t i o n = 1 N ( ( e h e − e s h e ) + ( e m a l e − e f e m a l e ) + ⋯ ) bias\ direction=\frac1N ((e_{he}-e_{she})+(e_{male}-e_{female})+\cdots) bias direction=N1((ehe−eshe)+(emale−efemale)+⋯)
然后,单词中立化(Neutralize)。将需要消除性别偏见的单词投影到 non-bias direction 上去,消除 bias 维度,例如 babysitter,doctor 等。
最后,均衡对(Equalize pairs)。让性别对立单词与上面的中立词距离相等,具有同样的相似度。例如让 grandmother 和 grandfather 与 babysitter 的距离同一化。
值得注意的是,掌握哪些单词需要中立化非常重要。一般来说,大部分英文单词,例如职业、身份等都需要中立化,消除 embedding vector 中性别这一维度的影响。
Sequence to sequence(序列)模型在机器翻译和语音识别方面都有着广泛的应用。下面,我们来看一个机器翻译的简单例子:
针对该机器翻译问题,可以使用 “编码网络(encoder network)”+“解码网络(decoder network)” 两个 RNN 模型组合的形式来解决。encoder network 将输入语句编码为一个特征向量,传递给 decoder network,完成翻译。具体模型结构如下图所示:
其中,encoder vector 代表了输入语句的编码特征。encoder network 和 decoder network 都是 RNN 模型,可使用 GRU 或 LSTM 单元。这种 “编码网络(encoder network)”+“解码网络(decoder network)” 的模型,在实际的机器翻译应用中有着不错的效果。
这种模型也可以应用到图像捕捉领域。图像捕捉,即捕捉图像中主体动作和行为,描述图像内容。例如下面这个例子,根据图像,捕捉图像内容。
首先,可以将图片输入到 CNN,例如使用预训练好的 AlexNet,删去最后的 softmax 层,保留至最后的全连接层。则该全连接层就构成了一个图片的特征向量(编码向量),表征了图片特征信息。
然后,将 encoder vector 输入至 RNN,即 decoder network 中,进行解码翻译。
Sequence to sequence machine translation 模型与我们第一节课介绍的 language 模型有一些相似,但也存在不同之处。二者模型结构如下所示:
**Language model 是自动生成一条完整语句,语句是随机的。**而 **machine translation model 是根据输入语句,进行翻译,生成另外一条完整语句。**上图中,绿色部分表示 encoder network,紫色部分表示 decoder network。decoder network 与 language model 是相似的,encoder network 可以看成是 language model 的 a < 0 > a^{<0>} a<0>,是模型的一个条件。也就是说,在输入语句的条件下,生成正确的翻译语句。因此,machine translation 可以看成是有条件的语言模型(conditional language model)。这就是二者之间的区别与联系。
所以,machine translation 的目标就是根据输入语句,作为条件,找到最佳翻译语句,使其概率最大:
m a x P ( y < 1 > , y < 2 > , ⋯ , y < T y > ∣ x < 1 > , x < 2 > , ⋯ , x < T x > ) max\ P(y^{<1>},y^{<2>},\cdots,y^{
例如,本节笔记开始介绍的例子,列举几个模型可能得到的翻译:
显然,第一条翻译 “Jane is visiting Africa in September.” 最为准确。那我们的优化目标就是要让这条翻译对应的 P ( y < 1 > , ⋯ , y < T y > ∣ x ) P(y^{<1>},\cdots,y^{
实现优化目标的方法之一是使用贪婪搜索(greedy search)。Greedy search 根据条件,每次只寻找一个最佳单词作为翻译输出,力求把每个单词都翻译准确。例如,首先根据输入语句,找到第一个翻译的单词 “Jane”,然后再找第二个单词 “is”,再继续找第三个单词 “visiting”,以此类推。这也是其 “贪婪” 名称的由来。
概率更高并不代表翻译更准确;所有单词组合的运算成本太高
Greedy search 存在一些缺点。首先,因为 greedy search 每次只搜索一个单词,没有考虑该单词前后关系,概率选择上有可能会出错。例如,上面翻译语句中,第三个单词 “going” 比 “visiting” 更常见,模型很可能会错误地选择了 “going”,而错失最佳翻译语句。其次,greedy search 大大增加了运算成本,降低运算速度。
因此,greedy search 并不是最佳的方法。下一小节,我们将介绍 Beam Search,使用近似最优的查找方式,最大化输出概率,寻找最佳的翻译语句。
- 每次找出 B 个概率最大的单词,且每轮更新
- 本轮概率由前面的概率拆解乘积计算
Greedy search 每次是找出预测概率最大的单词,而 beam search 则是每次找出预测概率最大的 B 个单词。其中,参数 B 表示取概率最大的单词个数,可调。本例中,令 B=3。
按照 beam search 的搜索原理,首先,先从词汇表中找出翻译的第一个单词概率最大的 B 个预测单词。例如上面的例子中,预测得到的第一个单词为:in,jane,september。
概率表示为: P ( y ^ < 1 > ∣ x ) P(\hat y^{<1>} | x) P(y^<1>∣x)
然后,再分别以 in,jane,september 为条件,计算每个词汇表单词作为预测第二个单词的概率。从中选择概率最大的 3 个作为第二个单词的预测值,得到:in september,jane is,jane visits。
概率表示为: P ( y ^ < 2 > ∣ x , y ^ < 1 > ) P(\hat y^{<2>}|x,\hat y^{<1>}) P(y^<2>∣x,y^<1>)
此时,得到的前两个单词的 3 种情况的概率为:
P ( y ^ < 1 > , y ^ < 2 > ∣ x ) = P ( y ^ < 1 > ∣ x ) ⋅ P ( y ^ < 2 > ∣ x , y ^ < 1 > ) P(\hat y^{<1>},\hat y^{<2>}|x)=P(\hat y^{<1>} | x)\cdot P(\hat y^{<2>}|x,\hat y^{<1>}) P(y^<1>,y^<2>∣x)=P(y^<1>∣x)⋅P(y^<2>∣x,y^<1>)
接着,再预测第三个单词。方法一样,分别以 in september,jane is,jane visits 为条件,计算每个词汇表单词作为预测第三个单词的概率。从中选择概率最大的 3 个作为第三个单词的预测值,得到:in september jane,jane is visiting,jane visits africa。
概率表示为: P ( y ^ < 3 > ∣ x , y ^ < 1 > , y ^ < 2 > ) P(\hat y^{<3>}|x,\hat y^{<1>},\hat y^{<2>}) P(y^<3>∣x,y^<1>,y^<2>)
此时,得到的前三个单词的 3 种情况的概率为:
P ( y ^ < 1 > , y ^ < 2 > , y ^ < 3 > ∣ x ) = P ( y ^ < 1 > ∣ x ) ⋅ P ( y ^ < 2 > ∣ x , y ^ < 1 > ) ⋅ P ( y ^ < 3 > ∣ x , y ^ < 1 > , y ^ < 2 > ) P(\hat y^{<1>},\hat y^{<2>},\hat y^{<3>}|x)=P(\hat y^{<1>} | x)\cdot P(\hat y^{<2>}|x,\hat y^{<1>})\cdot P(\hat y^{<3>}|x,\hat y^{<1>},\hat y^{<2>}) P(y^<1>,y^<2>,y^<3>∣x)=P(y^<1>∣x)⋅P(y^<2>∣x,y^<1>)⋅P(y^<3>∣x,y^<1>,y^<2>)
以此类推,每次都取概率最大的三种预测。最后,选择概率最大的那一组作为最终的翻译语句。
Jane is visiting Africa in September.
值得注意的是,如果参数 B=1,则就等同于 greedy search。实际应用中,可以根据不同的需要设置 B 为不同的值。一般 B 越大,机器翻译越准确,但同时也会增加计算复杂度。
- 多个概率乘积造成数值下溢——>取对数运算
- 目标函数倾向短句——>归一化处理
- 加入归一化因子(试探性但是效果好)
- beam search 相比 BFS、DFS,速度更快,但是不能保证最优
Beam search 中,最终机器翻译的概率是乘积的形式:
a r g m a x ∏ t = 1 T y P ( y ^ < t > ∣ x , y ^ < 1 > , ⋯ , y ^ < t − 1 > ) arg\ max\prod_{t=1}^{T_y} P(\hat y^{
多个概率相乘可能会使乘积结果很小,远小于 1,造成数值下溢。为了解决这个问题,可以对上述乘积形式进行取对数 log 运算,即:
a r g m a x ∑ t = 1 T y P ( y ^ < t > ∣ x , y ^ < 1 > , ⋯ , y ^ < t − 1 > ) arg\ max\sum_{t=1}^{T_y} P(\hat y^{
因为取对数运算,将乘积转化为求和形式,避免了数值下溢,使得数据更加稳定有效。
这种概率表达式还存在一个问题,就是机器翻译的单词越多,乘积形式或求和形式得到的概率就越小,这样会造成模型倾向于选择单词数更少的翻译语句,使机器翻译受单词数目的影响,这显然是不太合适的。因此,一种改进方式是进行长度归一化,消除语句长度影响。
a r g m a x 1 T y ∑ t = 1 T y P ( y ^ < t > ∣ x , y ^ < 1 > , ⋯ , y ^ < t − 1 > ) arg\ max\ \frac{1}{T_y}\sum_{t=1}^{T_y} P(\hat y^{
实际应用中,通常会引入归一化因子 α:
a r g m a x 1 T y α ∑ t = 1 T y P ( y ^ < t > ∣ x , y ^ < 1 > , ⋯ , y ^ < t − 1 > ) arg\ max\ \frac{1}{T_y^{\alpha}}\sum_{t=1}^{T_y} P(\hat y^{
若 α=1,则完全进行长度归一化;若 α=0,则不进行长度归一化。一般令 α=0.7,效果不错。
值得一提的是,与 BFS (Breadth First Search) 、DFS (Depth First Search) 算法不同,beam search 运算速度更快,但是并不保证一定能找到正确的翻译语句。
误差分析应该从整体到局部,找到合适的评判标准来区别是哪个部分出现了问题,再深入部分去优化改进。
Beam search 是一种近似搜索算法。实际应用中,如果机器翻译效果不好,需要通过错误分析,判断是 RNN 模型问题还是 beam search 算法问题。
一般来说,增加训练样本、增大 beam search 参数 B 都能提高准确率。但是,这种做法并不能得到我们期待的性能,且并不实际。
首先,为待翻译语句建立人工翻译,记为 y ∗ y^{∗} y∗。在 RNN 模型上使用 beam search 算法,得到机器翻译,记为 y ^ \hat y y^。显然,人工翻译 y ∗ y^{∗} y∗ 最为准确。
Jane visite l’Afrique en septembre.
Human: Jane visits Africa in September. y ∗ y^{∗} y∗
Algorithm: Jane visited Africa last September. y ^ \hat y y^
这样,整个模型包含两部分:RNN 和 beam search 算法。
然后,将输入语句输入到 RNN 模型中,分别计算输出是 y ∗ y^{∗} y∗ 的概率 P ( y ∗ ∣ x ) P(y^*|x) P(y∗∣x) 和 y ^ \hat y y^ 的概率 P ( y ^ ∣ x ) P(\hat y|x) P(y^∣x)。
接下来就是比较 P ( y ∗ ∣ x ) P(y^*|x) P(y∗∣x)和 P ( y ^ ∣ x ) P(\hat y|x) P(y^∣x)的大小。
如果 beam search 算法表现不佳,可以调试参数 B;若 RNN 模型不好,则可以增加网络层数,使用正则化,增加训练样本数目等方法来优化。
单一实数评估指标(a single real number evaluation metric)对于问题的解决至关重要,它指出了解决问题的核心在哪里。
评价标准包括两部分, precision 和 BP,对应到 Precision 和 Recall,Precision 倾向于保守选择,却会使得 Recall 值变小,通过引入 BP 惩罚短句优化翻译结果
使用 bleu score,对机器翻译进行打分。
首先,对原语句建立人工翻译参考,一般有多个人工翻译(利用验证集火测试集)。例如下面这个例子:
French: Le chat est sur le tapis.
Reference 1: The cat is on the mat.
Reference 2: There is a cat on the mat.
上述两个人工翻译都是正确的,作为参考。相应的机器翻译如下所示:
French: Le chat est sur le tapis.
Reference 1: The cat is on the mat.
Reference 2: There is a cat on the mat.
MT output: the the the the the the the.
如上所示,机器翻译为 “the the the the the the the.”,效果很差。Bleu Score 的宗旨是机器翻译越接近参考的人工翻译,其得分越高,方法原理就是看机器翻译的各个单词是否出现在参考翻译中。
最简单的准确度评价方法是看机器翻译的每个单词是否出现在参考翻译中。显然,上述机器翻译的每个单词都出现在参考翻译里,准确率为 7 7 = 1 \frac77=1 77=1,其中,分母为机器翻译单词数目,分子为相应单词是否出现在参考翻译中。但是,这种方法很不科学,并不可取。
另外一种评价方法是看机器翻译单词出现在参考翻译单个语句中的次数,取最大次数。上述例子对应的准确率为2727,其中,分母为机器翻译单词数目,分子为相应单词出现在参考翻译中的次数(分子为 2 是因为 “the” 在参考 1 中出现了两次)。这种评价方法较为准确。
上述两种方法都是对单个单词进行评价。按照 beam search 的思想,另外一种更科学的打分方法是 bleu score on bigrams,即同时对两个连续单词进行打分。仍然是上面那个翻译例子:
French: Le chat est sur le tapis.
Reference 1: The cat is on the mat.
Reference 2: There is a cat on the mat.
MT output: The cat the cat on the mat.
对 MIT output 进行分解,得到的 bigrams 及其出现在 MIT output 中的次数 count 为:
the cat: 2
cat the: 1
cat on: 1
on the: 1
the mat: 1
然后,统计上述 bigrams 出现在参考翻译单个语句中的次数(取最大次数) c o u n t c l i p count_{clip} countclip 为:
the cat: 1
cat the: 0
cat on: 1
on the: 1
the mat: 1
相应的 bigrams precision 为: c o u n t c l i p c o u n t = 1 + 0 + 1 + 1 + 1 2 + 1 + 1 + 1 + 1 = 4 6 = 2 3 \frac{count_{clip}}{count}=\frac{1+0+1+1+1}{2+1+1+1+1}=\frac46=\frac23 countcountclip=2+1+1+1+11+0+1+1+1=64=32
如果是 n 个连续单词,相应的 n-grams precision 为:
通常,对上式进行指数处理,并引入参数因子 brevity penalty,记为 BP。顾名思义,BP 是为了 “惩罚” 机器翻译语句过短而造成的得分 “虚高” 的情况。
p = B P ⋅ e x p ( 1 n ∑ i = 1 n p i ) p=BP\cdot exp(\frac1n\sum_{i=1}^np_i) p=BP⋅exp(n1i=1∑npi)
其中,BP 值由机器翻译长度和参考翻译长度共同决定。
对需要翻译的句子,让神经网络只注意一部分输入(类似于滑动窗口),此外窗口内单词分配权重,表示单词对当前翻译结果的影响程度,一部分一部分地翻译,避免长句翻译效果不佳的问题。
如果原语句很长,要对整个语句输入 RNN 的编码网络和解码网络进行翻译,则效果不佳。相应的 bleu score 会随着单词数目增加而逐渐降低。
对待长语句,正确的翻译方法是将长语句分段,每次只对长语句的一部分进行翻译。人工翻译也是采用这样的方法,高效准确。也就是说,每次翻译只注重一部分区域,这种方法使得 bleu score 不太受语句长度的影响。
根据这种 “局部聚焦” 的思想,建立相应的注意力模型(attention model)。
如上图所示,attention model 仍由类似的编码网络(下)和解码网络(上)构成。其中, S < t > S^{
当前单元的输入由(1)前一个状态的输出 S < t − 1 > S^{
} S<t−1> 和(2)原始输入加权 C 组成(2)原始输入加权 C:
- C 由权重×单词求和得到
- 注意力权重 α < t , t ′ > \alpha^{
} α<t,t′> 之和为 1——softmax 思想引入 e < t , t ′ > e^{} e<t,t′>- e < t , t ′ > e^{
} e<t,t′> 由神经网络输入(1)前一个状态的输出(2)当前单词训练得到
Attention model 中选择双向 RNN,可以使用 GRU 单元或者 LSTM。由于是双向 RNN,每个 a < t ′ > a^{
a < t ′ > = ( a → < t ′ > , a ← < t ′ > ) a^{
RNN 编码生成特征,注意力权重用 α 表示,C 是各个 RNN 神经元经过注意力权重得到的参数值。例如, α < 1 , t ′ > \alpha^{<1,t'>} α<1,t′> 表示机器翻译的第一个单词 “jane” 对应的第 t’个 RNN 神经元, C < 1 > C^{<1>} C<1> 表示机器翻译第一个单词 “jane” 对应的解码网络输入参数。满足:
∑ t ′ α < 1 , t ′ > = 1 \sum_{t'}\alpha^{<1,t'>}=1 t′∑α<1,t′>=1
C < 1 > = ∑ t ′ α < 1 , t ′ > ⋅ a < t ′ > C^{<1>}=\sum_{t'}\alpha^{<1,t'>}\cdot a^{
也就是说, α < t , t ′ > \alpha^{
为了让 α < t , t ′ > \alpha^{
α < t , t ′ > = e < t , t ′ > ∑ t ′ T x e < t , t ′ > \alpha^{
这样,只要求出 e < t , t ′ > e^{
如何求出 e < t , t ′ > e^{
然后,利用梯度下降算法迭代优化,计算得到 e < t , t ′ > e^{
Attention model 的一个缺点是其计算量较大,若输入句子长度为 T x T_x Tx,输出句子长度为 T y T_y Ty,则计算时间约为 T x ∗ T y T_x*T_y Tx∗Ty。但是,其性能提升很多,计算量大一些也是可以接受的。
有趣的是,Attention model 在图像捕捉方面也有应用。
Attention model 能有效处理很多机器翻译问题,例如下面的时间格式归一化:
下图将注意力权重可视化:
上图中,颜色越白表示注意力权重越大,颜色越深表示权重越小。可见,输出语句单词与其输入语句单词对应位置的注意力权重较大,即对角线附近。
深度学习中,语音识别的输入是声音,量化成时间序列。更一般地,可以把信号转化为频域信号,即声谱图(spectrogram),再进入 RNN 模型进行语音识别。
之前,语言学家们会将语音中每个单词分解成多个音素(phoneme),构建更精准的传统识别算法。但在 end-to-end 深度神经网络模型中,一般不需要这么做也能得到很好的识别效果。通常训练样本很大,需要上千上万个小时的语音素材。
语音识别的注意力模型(attention model)如下图所示:
一般来说,语音识别的输入时间序列都比较长,例如是 10s 语音信号,采样率为 100Hz,则语音长度为 1000。而翻译的语句通常很短,例如 “the quick brown fox”,包含 19 个字符。这时候,Tx 与 Ty 差别很大。为了让 T x = T y T_x=T_y Tx=Ty,可以把输出相应字符重复并加入空白(blank),形如:
其中,下划线"_"表示空白,”⊔“表示两个单词之间的空字符。这种写法的一个基本准则是没有被空白符”_“分割的重复字符将被折叠到一起,即表示一个字符。
这样,加入了重复字符和空白符、空字符,可以让输出长度也达到 1000,即 T x = T y T_x=T_y Tx=Ty。这种模型被称为 CTC(Connectionist temporal classification)。
触发字检测(Trigger Word Detection)在很多产品中都有应用,操作方法就是说出触发字通过语音来启动相应的设备。例如 Amazon Echo 的触发字是”Alexa“,百度 DuerOS 的触发字是” 小度你好 “,Apple Siri 的触发字是”Hey Siri“,Google Home 的触发字是”Okay Google“。
触发字检测系统可以使用 RNN 模型来建立。如下图所示,输入语音中包含一些触发字,其余都是非触发字。RNN 检测到触发字后输出 1,非触发字输出 0。这样训练的 RNN 模型就能实现触发字检测。
但是这种模型有一个缺点,就是通常训练样本语音中的触发字较非触发字数目少得多,即正负样本分布不均。一种解决办法是在出现一个触发字时,将其附近的 RNN 都输出 1。这样就简单粗暴地增加了正样本。
总结一下我们对序列模型的学习。我们学了 RNN,包括 GRU 和 LSTM,然后在上一周我们学了词嵌入(word embeddings),以及它们如何学习词汇的表达(how they learn representations of words)。在这周还学了注意力模型(the attention model)以及如何使用它来处理音频数据(audio data)。
参考链接
b 站视频
中文笔记
红色石头笔记