Sequence Models 笔记

1 Recurrent Neural Networks(循环神经网络)

1.1 序列数据

输入或输出其中一个或两个是序列构成。例如语音识别,自然语言处理,音乐生成,感觉分类,dna序列,机器翻译,视频状态识别,名称识别。

1.2 Notation(符号)

\(x ^ { ( i ) < t > }\)表示第\(i\)个训练样本输入的第\(t\)个元素

\(T ^ { ( i ) < t > } _ x\)表示第\(i\)个训练样本输入的长度为\(t\)

\(y ^ { ( i ) < t > }\)表示第\(i\)个训练样本输出的第\(t\)个元素

\(T ^ { ( i ) < t > } _ y\)表示第\(i\)个训练样本输出的长度为\(t\)

使用one-hot方式表示单词。有一个单词编号的词组,使用一个只有一个1的向量表示每个单词。

1.3 Recurrent Neural Network Model(循环神经网络)

1.3.1 为什么不用标准的神经网络

  1. 输入输出可能不同长度
  2. 标准神经网络不会将不同文本位置学到的特征进行共享
  3. 会有大量的参数需要训练(自己总结的,吴恩达没有列出来,但是讲了)

1.3.2 循环神经网络的前向传播

循环神经网络的网络图一般有两种画法,第一种是展开画的,第二种是画成循环的,两种都可以,课程中吴恩达选择画展开的。

RNN Forward Propagation1

RNN Forward Propagation2

其中一个参数取值\(a^{<0>}=\vec 0\),也有人取随机值。

另外还有三个参数,\(W _ {aa}\)表示输入为\(a\),输出为\(a\)的参数。剩下的\(W_{ax}、W_{ya}\)的定义一样。在网络种每个对应位置都使用相同的参数。

前向计算公式,\(a^{<t>}\)的激活函数最常使用tanh,也使用relu。\(\hat y ^{<t>}\)根据输出要求,例子里的名字判断是个二分,就是用sigmoid。
\[ a ^ { < t > } = g \left( W _ { a a } a ^ { < t - 1 > } + W _ { a x } x ^ { < t > } + b _ { a } \right) \]

\[ \hat { y } ^ { < t > } = g \left( W _ { y a } a ^ { < t > } + b _ { y } \right) \]

为了便于构造复杂的网络,简化公式表示:
\[ a ^ { \langle t \rangle } = g \left( w _ { a } \left[ a ^ { ( t - 1 ) } , x ^ { ( t ) } \right] + b _ { a } \right) \]

\[ \hat { y } ^ { < t > } = g \left( W _ { y } a ^ { < t > } + b _ { y } \right) \]

其中
\[ W_a=\left[\begin{matrix}W_{aa} & W_{ax}\end{matrix}\right] \]

\[ \left[ a ^ { ( t - 1 ) } , x ^ { ( t ) } \right]=\left[\begin{matrix} a^{<t-1>}\\x^{<t>} \end{matrix}\right] \]

1.3.3 计算图(Computational Graph)

RNN Computational Graph

1.3.4 损失函数(Loss function)

\[ L^{<t>}(\hat y^{<t>},y^{<t>})=-y^{<t>}log(\hat y^{<t>})-(1-y^{<t>})log(1-\hat y^{<t>}) \]

\[ L(\hat y,y)=\sum ^{T_y}_{t=1}L^{<t>}(\hat y^{<t>},y^{<t>}) \]

1.4 循环神经网络的反向传播

这个方法也叫,Backpropagation through time。因为反向传播是反着时序走的。

有了前面的前向传播的计算图,就能计算反向传播了。

根据课后题补充的反向传播内容:

rnn_cell_backprop

\[ a ^ { \langle t \rangle } = \tanh \left( W _ { a x } x ^ { ( t ) } + W _ { a a } a ^ { \langle t - 1 \rangle } + b \right) \]

\[ \frac { \partial \tanh ( x ) } { \partial x } = 1 - \tanh ( x ) ^ { 2 } \]

\[ \frac { \partial a ^ { ( t ) } } { \partial W _ { a x } } = ( 1 - \tanh ( W _ { a x } x ^ { ( t ) } + W _ { a a } a ^ { ( t - 1 ) } + b ) ^ { 2 }) x ^ { ( t ) T } \]

\[ \frac { \partial a ^ { ( t ) } } { \partial W _ { a a } } = ( 1 - \tanh ( W _ { a x } x ^ { ( t ) } + W _ { a a } a ^ { ( t - 1 ) } + b ) ^ { 2 } ) a ^ { ( t - 1 ) T } \]

\[ \frac { \partial a ^ { ( t ) } } { \partial b } = \sum _ { b a c c h } ( 1 - \tanh ( W _ { a x } x ^ { ( t ) } + W _ { a a } a ^ { ( t - 1 ) } + b ) ^ { 2 } ) \]

\[ \frac { \partial a ^ { ( t ) } } { \partial x ^ { ( t ) } } = W _ { a x } ^ { T } ( 1 - \tanh ( W _ { a x } x ^ { ( t ) } + W _ { a a } a ^ { ( t - 1 ) } + b ) ^ { 2 } ) \]

\[ \frac { \partial a ^ { ( t ) } } { \partial a ^ { ( t - 1 ) } } = W _ { a a } ^ { T } ( 1 - \tanh ( W _ { a x } x ^ { ( t - 1 ) } + W _ { a a } a ^ { ( t - 1 ) } + b ) ^ { 2 } ) \]

1.5 不同种类的RNN

  1. many to many。每一个块都输出。输入输出个数相同
  2. many to one。只有最后一个块有输出。例子,输出评分/感觉。
  3. one to many。只有第一个块有输入。实际上会将前一个块的输出输入给后一块。
  4. many to many。输入输出不同。一个只输入的接上一个只输出的。
  5. one to one。标准神经网络。

RNN Types

1.6 Language model and sequence generation(语言模型和序列生成)

1.6.2 语言模型

输入一句话,输出这句话出现的概率。具体是指你随机的听到/读到某句话,下一句话是输入的这句话的概率。语言模型的输入被记作\(y^{<1>},y^{<2>},...,y^{<T_y>}\),因为语言模型通常被用作输出句子,用来估计特定词序列的概率。

1.6.1 使用RNN建立语言模型

训练集:large corpus of english text.(大文集构成的训练集)

tokenize(标记化)。将每一个词对应字典索引,使用one-hot。对于字典里没有的单词使用UNK,句子的结尾使用EOS。

rnn中,\(x^{<1>}=\vec 0\)\(a^{<0>}=\vec 0\)\(\hat y ^{<1>}\)使用softmax输出字典表中每一个单词的概率。\(x^{<t>}=y^{<t-1>}\),第二个块使用正确的句子中的第一个输入,输出\(y^{<2>}\)是在第一个单词为cats情况下的其他单词的概率(\(P(\_|cats)\)),还使用softmax。第三个是在cats average下的概率(\(P(\_|cats\ average)\))。

loss function使用softmax的。
\[ L \left( \hat { y } ^ { < t > } , y ^ { < t > } \right) = - \sum _ { i } y _ { i } ^ { < t > } \log \hat { y } _ { i } ^ { < t > } \]

\[ L = \sum _ { t } L ^ { < t > } \left( \hat { y } ^ { < t > } , y ^ { < t > } \right) \]

当计算一个句子的概率时,相当于计算每个词在前面词出现后的概率相乘。
\[ P ( y ^ { < 1 > } , y ^ { < 2 > } , y ^ { < 3 > } ) = P ( y ^ { < 1 > })P ( y ^ { < 2 > } | y ^ { < 1 > }) P ( y ^ { < 3 > } | y ^ { < 1 > } , y ^ { < 2 > } ) \]

Language Model

吴恩达上课手画的还是让我理解出现了些偏差,这里再放上课程作业里的图,这个图更加的清晰,让我知道在哪个地方sample。图中的cell可以使用RNN/GRU/LSTM。其中的公式如下。
\[ a^{\langle t+1 \rangle} = \tanh(W_{ax} x^{\langle t \rangle } + W_{aa} a^{\langle t \rangle } + b) \]

\[ z^{\langle t + 1 \rangle } = W_{ya} a^{\langle t + 1 \rangle } + b_y \]

\[ \hat{y}^{\langle t+1 \rangle } = softmax(z^{\langle t + 1 \rangle }) \]

sample使用的python代码:

np.random.choice(range(vocab_size), p = y.ravel())

sample

1.7 Sampling novel sequences(采样)

在一个训练好的RNN语言模型上,第一个输入为\(\vec 0\),会有一个softmax输出,表示每个单词的概率,使用softmax的分布去随机采样,得到一个输出\(\hat y\),然后给下一循环做输入,循环。出现EOS或者输出个数超过设定的N个词后结束。出现UNK可以重新采样,也可以就放在里面。

从字母层面的语言模型。不使用单词,使用字母。训练的时候也要用字母。优势是不需要担心不认识的单词,劣势是会是序列变长,更多的算力。

1.8 Vanishing/Exploding gradients with RNNs(梯度消失)

1.8.1 梯度消失

语言中一个单词可能会影响很多单词之后出现的单词。例如单复数对应的be动词。但是RNN在传播中会遇到梯度爆炸或梯度消失问题,导致RNN不能很好的处理这个。梯度消失比梯度爆炸更难解决,可以使用GRU/LSTM解决。

1.8.2 梯度爆炸

RNN也会出现梯度爆炸,但是这个很容易被察觉,出现NaN。对于梯度爆炸,可以使用gradient clipping解决,clipping就是个限幅。当梯度超过某个最大阈值或低于最小阈值,使其等于最大/最小。

clip

1.9 Gated Recurrent Unit(GRU)

1.9.1 标准RNN

标准RNN的单元可以使用下面的图描述。
\[ a ^ { < t > } = g \left( W _ { a } \left[ a ^ { < t - 1 > } , x ^ { < t > } \right] + b _ { a } \right) \]

RNN unit

课后题里的图和公式:
\[ \begin{array} { l } { a ^ { ( t ) } = \tanh \left( W _ { a x } x ^ { ( t ) } + W _ { a a } a ^ { ( t - 1 ) } + b _ { a } \right) } \\ { \hat { y } ^ { ( t ) } = s o f t \max \left( W _ { y a } a ^ { ( t ) } + b _ { y } \right) } \end{array} \]

rnn_step_forward

1.9.2 简化的GRU

引入一个c(memory cell),实际上就是原来的a。
\[ c^{<t>}=a^{<t>} \]
然后引入一个c的候选人\(\tilde c\)
\[ \tilde c^{<t>}=tanh(W_c[c^{<t-1>},x^{<t>}]+b_c) \]
一个门(gate)\(\Gamma _ u\),数值在0-1之间。但是一般都是很接近0或者很接近1。使用sigmoid函数。sigmoid的参数一般都比较大,所以很接近0或1。gate决定是否使用\(\tilde c\)更新\(c\)
\[ \Gamma_u=\sigma(W_u[c^{<t-1>},x^{<t>}]+b_u) \]
\(c^{<t>}\)的更新
\[ c^{<t>}=\Gamma_u * \tilde c^{<t>}+(1-\Gamma_u)*c^{<t-1>} \]
GRU的结构图如下所示,紫色部分代表了\(c^{<t>}\)的更新。GRU能够保留部分的内容。而且因为gate使用了sigmoid,所以对于要保留记忆部分的gate\(\Gamma_u\)将很小很小,例如0.00001,所以在更新\(c^{<t>}\)时不会出现梯度消失的问题。所以RNN可以经过很多很多步。在实际中\(c^{<t>}\)是个向量,能保留许多不同的内容,\(\Gamma_u\)\(\tilde c^{<t>}\)也是个向量。更新\(c^{<t>}​\)的乘法是元素相乘。

GRU

1.9.3 full GRU

实际使用中还有一个门\(\Gamma_r\),可以认为它表示相关性。
\[ \tilde c^{<t>}=tanh(W_c[\Gamma_r*c^{<t-1>},x^{<t>}]+b_c) \]

\[ \Gamma_u=\sigma(W_u[c^{<t-1>},x^{<t>}]+b_u) \]

\[ \Gamma_r=\sigma(W_r[c^{<t-1>},x^{<t>}]+b_r) \]

\[ c^{<t>}=\Gamma_u * \tilde c^{<t>}+(1-\Gamma_u)*c^{<t-1>} \]

论文人们常用,\(\tilde h\)表示\(\tilde c^{<t>}\)\(u\)表示\(\Gamma_u\),r表示\(\Gamma_r\)\(h\)表示\(c^{<t>}\)。吴恩达在课程中这么表示是为了统一和LSTM的公式,更便于理解。

1.10 Long Short Term Memory (LSTM)

1.10.1 前向传播

LSTM使用了三个门,遗忘(forgot)、更新(update)、输出(output),并且\(c \neq a​\)
\[ \begin{array} { l } { \tilde { c } ^ { < t > } = \tanh \left( W _ { c } \left[ a ^ { < t - 1 > } , x ^ { < t > } \right] + b _ { c } \right) } \\ { \Gamma _ { u } = \sigma \left( W _ { u } \left[ a ^ { < t - 1 > } , x ^ { < t > } \right] + b _ { u } \right) } \\ { \Gamma _ { f } = \sigma \left( W _ { f } \left[ a ^ { < t - 1 > } , x ^ { < t > } \right] + b _ { f } \right) } \\ { \Gamma _ { o } = \sigma \left( W _ { o } \left[ a ^ { < t - 1 > } , x ^ { < t > } \right] + b _ { o } \right) } \\ { c ^ { < t > } = \Gamma _ { u } * \tilde { c } ^ { < t > } + \Gamma _ { f } * c ^ { < t - 1 > } } \\ { a ^ { < t > } = \Gamma _ { o } * \tanh c ^ { < t > } } \end{array} \]
LSTM的结构图如下。使用时将多个单元串联就行。LSTM这里c单独一条先来传递。LSTM/GRU能够很好的记忆,因为c一直在传递。

LSTM unit

LSTM有很多变种,其中一个peephole connection(窥孔链接),窥孔连接中,同时将c加入到门的求解中,每个c只会影响相对应的门变量的值。

LSTM和GRU先用哪个没有明确的结果,但是吴恩达认为GRU更简单,构造更大的网络很简单,因为只有两个门,从计算的角度看更高效;LSTM更强大更有效,是经过历史检验的方法,被很多人作为默认。GRU也在快速发展,很多团队都在使用。使用这两个都可以构造更深的神经网络。

1.10.2 反向传播

反向传播在吴恩达课程的练习中算的是不对的,这里复制了社区的内容。我还没有自己求解。

The LSTM backward pass is slighltly more complicated than the forward one. We have provided you with all the equations for the LSTM backward pass below. (If you enjoy calculus exercises feel free to try deriving these from scratch yourself.)

gate derivatives

\[d \Gamma_o^{\langle t \rangle} = da_{next}*\tanh(c_{next}) * \Gamma_o^{\langle t \rangle}*\left(1-\Gamma_o^{\langle t \rangle}\right)\tag{7}\]

\[d\widetilde{c}^{\langle t \rangle} = \left(dc_{next}*\Gamma_u^{\langle t \rangle}+ \Gamma_o^{\langle t \rangle}* (1-\tanh(c_{next})^2) * \Gamma_u^{\langle t \rangle} * da_{next} \right) * \left(1-\left(\widetilde c^{\langle t \rangle}\right)^2\right) \tag{8}\]

\[d\Gamma_u^{\langle t \rangle} = \left(dc_{next}*\widetilde{c}^{\langle t \rangle} + \Gamma_o^{\langle t \rangle}* (1-\tanh(c_{next})^2) * \widetilde{c}^{\langle t \rangle} * da_{next}\right)*\Gamma_u^{\langle t \rangle}*\left(1-\Gamma_u^{\langle t \rangle}\right)\tag{9}\]

\[d\Gamma_f^{\langle t \rangle} = \left(dc_{next}* c_{prev} + \Gamma_o^{\langle t \rangle} * (1-\tanh(c_{next})^2) * c_{prev} * da_{next}\right)*\Gamma_f^{\langle t \rangle}*\left(1-\Gamma_f^{\langle t \rangle}\right)\tag{10}\]

parameter derivatives

\[ dW_f = d\Gamma_f^{\langle t \rangle} \begin{bmatrix} a_{prev} \\ x_t\end{bmatrix}^T \tag{11} \]
\[ dW_u = d\Gamma_u^{\langle t \rangle} \begin{bmatrix} a_{prev} \\ x_t\end{bmatrix}^T \tag{12} \]
\[ dW_c = d\widetilde c^{\langle t \rangle} \begin{bmatrix} a_{prev} \\ x_t\end{bmatrix}^T \tag{13} \]
\[ dW_o = d\Gamma_o^{\langle t \rangle} \begin{bmatrix} a_{prev} \\ x_t\end{bmatrix}^T \tag{14}\]

To calculate \(db_f, db_u, db_c, db_o\) you just need to sum across the horizontal (axis= 1) axis on \(d\Gamma_f^{\langle t \rangle}, d\Gamma_u^{\langle t \rangle}, d\widetilde c^{\langle t \rangle}, d\Gamma_o^{\langle t \rangle}\) respectively. Note that you should have the keep_dims = True option.

Finally, you will compute the derivative with respect to the previous hidden state, previous memory state, and input.

\[ da_{prev} = W_f^T d\Gamma_f^{\langle t \rangle} + W_u^T d\Gamma_u^{\langle t \rangle}+ W_c^T d\widetilde c^{\langle t \rangle} + W_o^T d\Gamma_o^{\langle t \rangle} \tag{15}\]
Here, the weights for equations 15 are the first n_a, (i.e. \(W_f = W_f[:,:n_a]\) etc...)

\[ dc_{prev} = dc_{next}*\Gamma_f^{\langle t \rangle} + \Gamma_o^{\langle t \rangle} * (1- \tanh(c_{next})^2)*\Gamma_f^{\langle t \rangle}*da_{next} \tag{16}\]
\[ dx^{\langle t \rangle} = W_f^T d\Gamma_f^{\langle t \rangle} + W_u^T d\Gamma_u^{\langle t \rangle}+ W_c^T d\widetilde c^{\langle t \rangle} + W_o^T d\Gamma_o^{\langle t \rangle}\tag{17} \]
where the weights for equation 17 are from n_a to the end, (i.e. \(W_f = W_f[:,n_a:]\) etc...)

1.11 Bidirectional RNN(双向RNN)

有些内容只看过去的无法判断,例子中判断Teddy是否为名字,所以需要未来的信息。

在原始的RNN中,加入将未来数据向之前传播的过程(后向连接)。这不是反向传播,而是前向传播的一部分。结构如下图所示,紫色的为前向连接,绿色的为后向连接。图中的每个块可以是RNN、GRU、LSTM。最后输出变为如下形式。
\[ \hat y^{<t>}=g(W_y[{\overset{\rightarrow}{a}}^{<t>},{\overset{\leftarrow}{a}}^{<t>}]+b_y) \]

Bidirectional RNN

BRNN的缺点是需要整个句子才能做预测。

1.12 Deep RNNs

深度RNN就是将每一个块在纵向上增加层数。每一层公用一个权重W。因为RNN本来就要走很多步,已经算深度网络了,所以一般只再加上3层。结构图如下所示。

Deep RNN

最后在输出层加上没有横向连接的深度网络也比较常见。

2 Natural Language Processing & Word Embeddings

2.1 Word Representation(单词表达)

vocabulary,每个单词可以使用1-hot表示,写作\(O^{5391}\)之类,上标可以变。只是用1-hot,不能知道任意两个单词的关系,例如man/woman;king/queen;apple/orange。

特征化表示:词嵌入(Featurized representation:word embedding)。一个特征,使用-1到1表示单词和特征的关系,例如性别/王室的/年龄等。写作\(e_{5391}\)之类,下标可以变,是个向量,表达了和每个特征的关系。特征化在不同的单词中有更好的泛化能力。在实际中,每个向量表示的内容是被训练出来的,所以每个特征并不像前面所说的有具体的内容,会很难理解,但是还是能很容易的表达出单词之间的关系。

可视化,将高维降(embed)到2维。例如t-SNE。

embedding这个词,相当于是有一个高位空间,然后将词嵌入到该空间的某个位置。

2.2 Using word embeddings

word embedding可以表示大量的词。而且有利于迁移学习,例如人名学习中。

迁移学习和词嵌入

  1. 从大量的文集中学习词嵌入(1-100 billion)/从网上下载预训练好的embedding
  2. 将embedding迁移到新的只有少量(100k)训练集的任务。这里还能降低维度,例如原来1-hot每个单词是10,000维,现在变为300维,而且包含内容更多。
  3. 可选:如果说迁移的任务有很多很多的训练集,可以使用训练集继续调整embedding

这个方法在命名实体识别、文本摘要、指代消解、语法分析等标准nlp任务有用,在语言建模、机器翻译也有用。

回想到之前人脸识别问题,编码一个128维的向量,来表示一个人脸,跟embedding很类似。区别是,人脸识别会将任意一张图片输出一个编码,而embedding只会训练固定单词的编码。实际中encoding/embedding两个词意思相近,可以被替换。

2.3 Properties of word embeddings

embedding可以帮助进行analogy reasoning(类型推理)。这有利于理解embedding。

一直man-women,那么king-?。问题。使用特征相减的值分辨,看相近,就可以找出类比的queen。计算相似度:\(\operatorname { sim } \left( e _ { w } , e _ { k i n g } - e _ { m a n } + e _ { \text { woman } } \right)\),这个计算的实际是向量夹角的cos,具体公式在下面。实际也有使用欧式距离(\(| | u - v | | ^ { 2 }\))判断相似度的。
\[ sim ( u , v ) = \frac { u ^ { T } \cdot v } { \| u \| _ { 2 } * \| v \| _ { 2 } } \]

推理只能在原始的高维信息上进行,在降维的t-SNE就不行。

2.4 Embedding matrix

假设10,000个单词,矩阵维度是30*10,000。使用one-hot和e相乘\(e_{6257}=E*O_{6257}\),就可以获得一个词的embedding。实际使用切片列就行了。

2.5 Learning word embeddings

最基础的语言模型:输入句子是单词在词汇表中的索引,然后使用这个索引获得其embedding。作为神经网络输入,最后使用softmax输出下一个词。

historical window(历史窗口),一个超参数,表达向前看几个单词。例如前四个。

使用大量词汇训练embedding。

改进:使用前后几个单词;只是用前一个单词;nearby 1 word(临近的一个词)。

2.6 Word2Vec

2.6.1 skip-grams

两种类型,context和target。随机选择一个单词作为context,在某个窗口(例如+/-5)内随机的选一个单词作为target。

Model:输入一个context的one-hot,使用E计算出embedding,输出一个softmax,和target的one-hot比较。计算公式如下,其中\(\theta ^ T\)是和softmax输出有关的变量。\(\theta ^ T\)\(e_c\)维度相同,不然也没法乘。
\[ p ( t | c ) = \frac { e ^ { \theta _ { t } ^ { T } e _ { c } } } { \sum _ { j = 1 } ^ { 10,000 } e ^ { \theta _ { j } ^ { T } e _ { c } } } \]

\[ L ( \hat { y } , y ) = - \sum _ { i = 1 } ^ { 10000 } y _ { i } \cdot \log \hat { y } _ { i } \]

这个模型有缺点:计算量,因为需要求和。可以使用hierarchical softmax classifier,二叉树,常见的早靠前的节点。还可用下一节的Negative Sampling。

怎么生成context?随机的话有些常见单词太容易被选出来。不能用均匀随机。要用一些别的分布。

2.7 Negative Sampling

解决softmax计算量大的问题。

重新定义问题。包含context,word,target。context(c)和word(t)是单词,target(y)表示他俩是否在同一个窗口,为0/1。

训练时,使用窗口得到的单词target为1,在字典中随机的单词k个单词,target设置为0,不管这个单词在不在窗口内。模型的输入为context和word,输出为target。数据集小k取5-20,数据集大k取2-5。

构造的模型是一个逻辑回归模型。
\[ p ( y = 1 | c , t ) = \sigma \left( \theta _ { t } ^ { T } e _ { c } \right) \]
假设单词表有10,000个单词,这个方法相当于把10,000维的softmax变成10,000个二分类问题。而且我们每次训练,只训练其中k+1个,包括1个正样本,k个负样本。

如何选择负样本?可以使用出现频率,但是很极端,the、of等会出现多次。或者均匀分布也太极端,不能表示分布。常用的方法是下式。其中\(f(w_i)\)是单词的出现频率。
\[ p(w_i)=\frac{f(w_i)^{\frac {3}{4}}}{\sum ^{10,000} _{j=1}f(w_i)^{\frac {3}{4}}} \]

2.8 GloVe word vectors

不如skip-grams常用,但是也有很多支持者。方法简单。

\(X_{ij}\)表示\(i\)出现在\(j\)上下文的次数。\(i/j\)可以理解成上面的\(c/t\)。如果设定上下文为前后10个词,则\(X_{ij}=X_{ji}\),如果只关心向后的词,那么两者可能不等。

模型减小模型预测的词的关系和实际上下文次数log的差,为了防止log里出现0,添加一个权重项\(f(x_{ij})\)来保证当\(X_{ij}=0\)时,公式等于0,即\(f(0)=0\),同时对于不常见的单词给出有意义的权重,常见单词给出更大但不过大的权重。在模型中\(\theta\)\(e\)是对称的,有相同作用,所以最后算出的\(e\)是两者求平均。\(\theta _ i\)\(e_j\)应被随机初始化。模型公式如下。
\[ minimize\ \sum ^ {10,000} _ {i = 1} \sum ^ {10,000} _ {j = 1}f(x_{ij})(\theta ^ T _ ie_j+b_i+b_j^{\prime}-logX{ij})^2 \]

\[ e^{(final)} _ w = \frac {e_w +\theta _ w}{2} \]

这个模型是从上面一步一步简化下来的。

模型计算出来的特征并不一定可解释,人类可理解。吴恩达解释了一个线性代数方向的理解\((A \theta_i) ^ T (A ^ {-T} e_j)=\theta ^ T A ^ T A ^ {-T} e_j=\theta ^T e _ j\),如果认为θ和e可理解,但是变换后的并不可理解,但是作用相同。

2.9 Sentiment Classification(情感分类)

分析一段文本,判断人类的喜好。情感分类可能没有太大的数据集,但是使用词嵌入,可以依靠中等数据集构造好的分类器。

将句子打分。模型1:句子单词embedding,然后求平均,softmax,输出。

但是如果句子中否定词跟good,会影响上面模型的判断,因为上面的模型并不考虑单词的组合。可以使用RNN来改进,进行情感分类。模型2:RNN,many-to-one。

两个模型都有很好的泛化能力,因为有词嵌入,有词的关系,哪怕没见过的词也能很好的判断。

2.10 Debiasing word embeddings

这里bias是指偏见,不是之前模型里的bias(偏差)。性别、种族、年龄、性取向、社会经济学地位。比方说类比时,输入男人/程序员,可能类比出女人/家庭主妇。这个不对。

解决偏见的方法:

  1. 辨别出偏见方向。找出某维度是表现某情况的偏见,例如图中有两个轴,实际上是为了画图,画成了2维,可以认为其中一个轴(\(g_{\perp}\))是许多无偏见的维度组成的,另一个轴(\(g\))是一些有偏见的维度组成的,性别偏见的方向。

  2. 中和(中立化),对于没有定义的词,设置来使其摆脱偏见。除了man/woman,girl/boy这些本身就带有性别特性的词之外,doctor/nurse这类没有性别定义的词,映射到无偏见的轴,来消除偏见。实际操作是计算一个关于偏见的成分,将当当前的embedding减去组件。这个成分实际是在偏见轴上的投影。
    \[ e^{bias\_component} = \frac{e \cdot g}{||g||_2^2} * g \]

    \[ e^{debiased} = e - e^{bias\_component} \]

  3. 相同配对(Equalize pairs、均匀化)。让性别相关的词只在相关的轴上不同,其他轴相同。例如下面girl/boy相对于babysitter的距离。如果不这样,即使之前将性别无关的词(babysitter)映射到了无偏轴,距离还是不同。

\[ \mu = \frac{e_{w1} + e_{w2}}{2} \]

\[ \mu_{B} = \frac {\mu \cdot \text{bias_axis}}{||\text{bias_axis}||_2^2} *\text{bias_axis} \]

\[ \mu_{\perp} = \mu - \mu_{B} \]

\[ e_{w1B} = \frac {e_{w1} \cdot \text{bias_axis}}{||\text{bias_axis}||_2^2} *\text{bias_axis} \]

\[ e_{w2B} = \frac {e_{w2} \cdot \text{bias_axis}}{||\text{bias_axis}||_2^2} *\text{bias_axis} \]

\[ e_{w1B}^{corrected} = \sqrt{ |{1 - ||\mu_{\perp} ||^2_2} |} * \frac{e_{\text{w1B}} - \mu_B} {||(e_{w1} - \mu_{\perp}) - \mu_B)||_2} \]

\[ e_{w2B}^{corrected} = \sqrt{ |{1 - ||\mu_{\perp} ||^2_2} |} * \frac{e_{\text{w2B}} - \mu_B} {||(e_{w2} - \mu_{\perp}) - \mu_B)||_2} \]

\[ e_1 = e_{w1B}^{corrected} + \mu_{\perp} \]

\[ e_2 = e_{w2B}^{corrected} + \mu_{\perp} \]

debias

对于如何判断哪些词中立,需要训练一个分类器去做。在性别这个例子,只有少量的词是由性别定义的。

3 Sequence models & Attention mechanism

3.1 Basic Models

序列到序列模型。

输入记为\(x^{<1>}\),输出记为\(y^{<1>}\)

可以用于机器翻译,many-to-many不等长模型。

或者图像说明(输入一个图片,输出说明),图像输入到卷积网络,最后输出从softmax改为RNN输出。

序列到序列模型和之前讲的生成有区别,生成是随机的选,但是这里希望是最好的输出。

3.2 Picking the most likely sentence

可以认为机器翻译是有附加条件的语言模型。机器翻译后部分输出的地方和语言模型基本一样,区别只是机器学习的\(a^{<0>}\)不再使用\(\vec 0\),而是根据前面输入的待翻译句子决定,相当于条件概率。

可以将机器翻译理解为\(P(y^{<1>},...,y^{<T_y})|x)\),在x的条件下的概率,这里x就是待翻译的句子。这里的输出希望是最好的,不是随机采样一个相关数据,而是找到一个英语使得其概率最高。一个可以使用的方法是beam search。

为什么不用贪心搜索(greed search)?因为效果不好,会有一些常用的单词出现,句子有可能是对的,但是冗余,不是最好的。一般贪心获得的不是全局最优,搜索空间太大了,一般是找近似最优解。

3.3 Beam Search(集束搜索)

第一步,输入,获得输出。beam width。B=3,不是贪心只选一个,而是选B个候选。会尝试每一种选择。

第二步,分别计算再前面B种情况下的RNN输出,将会有\(B*10,000\)个结果,从中选择概率最高的B个可能,其中10,000为单词表的词量。为了衡量句子的概率,使用下面的公式。
\[ P(y^{<1>}, y^{<2>}|x)=P(y^{<1>}|x)P(y^{<2>}|x, y^{<1>}) \]
第三步,使用前面的情况,继续计算。选择。一直重复知道EOS。

B=1就是贪心搜索。

Length normalization:当计算概率是,因为每个概率都很小,一直相乘可能会小于浮点数能表达的。选择使用log后的值表示。因为log单调递增的,所以能表示。
\[ \arg \max _ { y } \prod _ { t = 1 } ^ { T _ { y } } P \left( y ^ { < t > } | x , y ^ { < 1 > } , \ldots , y ^ { < t - 1 > } \right) \]

\[ \arg \max _ { y } \sum _ { t = 1 } ^ { T _ { y } } \log P \left( y ^ { < t > } | x , y ^ { < 1 > } , \ldots , y ^ { < t - 1 > } \right) \]

由于P小于等于1,多次相乘会十分接近0,但是在较短的句子中影响不大。logP在0-1是负数,一直累加会十分小。会影响较长的翻译。考虑引入归一化。这大大降低输出较长翻译的惩罚。一般会用些柔和的方法,对\(T_y\)引入一个幂。一般取\(\alpha=0.7\)\(\alpha\)范围在0到1之间。如果取1就是标准归一化,0就是不归一,\(\alpha\)是个超参数。
\[ \frac { 1 } { T _ { y } ^ {\alpha} } \sum _ { t = 1 } ^ { T _ { y } } \log P \left( y ^ { < t > } | x , y ^ { < 1 > } , \ldots , y ^ { < t - 1 > } \right) \]
在Beam Search最后使用上式选择一个最优的句子。

怎么选择B?B越大,考虑更多情况,更好的结果,计算量越大,慢。B小则相反。当B大了之后,影响就小了。一般到10就行了,文章中最大的就100。再大很少见。

Beam Search与DFS/BFS不同,是启发式算法,不是找到全局最优,而是找到局部最优。

找到问题更多的是在beam search还是RNN中。

增加B一般不会影响模型,就像增加数据集。

比较两个结果人类的翻译(\(y^*\))和算法的结果(\(\hat y\))。

判断在算法中期望值的概率和输出的概率,\(P(y^*|x)\)\(P(\hat y|x)\)的大小,来发现是RNN还是Beam search的问题。

情况1:\(P(y^*|x)>P(\hat y|x)\),虽然期望值的p算出来更高,但是beam search没有选择期望值,所以是beam search错了。可以通过增加B来改善。

情况2:\(P(y^*|x) \leq P(\hat y|x)\),RNN给出了错误的概率p,给了好的句子小的概率p。可以通过加上正则化,更多训练数据,不同网络结构等方法改进。

如果用了长度归一化,要用归一化之后的值判断。

3.6 Bleu Score(Bleu指数)

对于一个句子,可能有多个不同的很好的翻译,如何评判准确度?使用Bleu(blingual evaluation understudy)指数,双语评估替补指数,可以将与任意人类翻译结果相近的机器翻译结果给出高的评分。

判断机器学习准确度:

方法1:机器翻译的词在期望结果中出现的词的个数除以机器翻译句子的总词数,但是这个有弊端,就是the the ...例子,判断错误。这个判断方法不常用。

方法2:使用单词在期望句子中出现的次数的最大值(比较不同的期望句子),除以单词在机器翻译句子中的个数。

方法3:bigram(成对出现的词)。使用biagram定义Bleu。两个词的滑动窗,在机器翻译的句子上滑动,并统计bigram个数。然后使用滑动传来的词,在期望句子上统计最大值(clip)。将期望句子的bigram个数除以机器翻译句子的bigram个数。

方法4:unigram(单字组)
\[ p_1=\frac{ \sum \limits _{unigram \in y^*} Count_{clip}(unigram)}{\sum \limits _{unigram \in \hat y} Count_{clip}(unigram)} \]

方法5:n-gram。\(p_n\)

上面的方法当完全相同时,\(p=1\)

Bleu 实现。BP(简洁惩罚),用来惩罚非常短的翻译,当机器翻译长度大于等于参考,则惩罚为1。综合前面几个概率
\[ BP\ exp(\frac{1}{4} \sum ^4 _ {n=1}p_n) \]

3.7 Attention Model

人类翻译不是读取一整段,然后翻译,是一部分一部分翻译。不是像之前的模型,全部输入,然后输出。当句子长度变长,翻译准确度会下降。使用注意力模型,准确度不会随着长度而下降。

attention weight,\(\alpha<1, 2>\),对于第1个单词,原句子中第2个单词的权重。权重是根据BRNN的a和生成部分的s决定的。

Attention Model

计算attention。\(a^{<t,t^{\prime}>}\)\(y^{<t>}\)\(a^{<t^{\prime}>}\)的注意度。\(a^{<t,t^{\prime}>}\)求和为1。
\[ \alpha ^ { < t , t ^ { \prime } > } = \frac { \exp \left( e ^ { < t , t ^ { \prime } > } \right) } { \sum _ { t ^ { \prime } = 1 } ^ { T _ { X } } \exp \left( e ^ { < t , t ^ { \prime } > } \right) } \]
使用softmax训练\(e^{<t,t^{\prime}>}\),输入为\(s^{<t-1>}\)\(a^{<t^{\prime}>}\)

这个注意力模型的时间是平方级别的。但是机器翻译句子不长,能接受。

3.8 Speech recognition

音频输入变成文本。人不直接处理声音,而是频率。可以把声音变为频率,做预处理。之前人工处理还考虑phonemes(音素),而深度学习不需要了。

可以使用注意力模型。

CTC cost(Connectionists temporal classification 联结主义时间分类)。因为采样的问题,语音的输入量会比输出大很多,这个方法可以折叠输出中没有被空白隔开的重复字符。

3.9 Trigger Word Detection(激活词汇检测)

现在检测算法还在进化。这里只是讲一个算法。

使用RNN,输入音频,当检测到激活词,输出一个1其他输出0。但是这样数据不平衡,改成连续几个1会好一点。找到trigger word。

训练这个模型时,训练集使用了生成的音频,因为易于实现,并且易于打标签。而开发集使用了实际录制的激活词语音,因为这样和实际使用中的情况更相近。

猜你喜欢

转载自www.cnblogs.com/huipengly/p/10301416.html