这一节我们主要学习

  • RNN原理
  • 解决梯度消失或者梯度爆炸的方法
  • RNN 应用
  • Sequence to sequence
  • 基于注意力模型
  • RNN与结构化学习的联系与区别

1. RNN原理

1.1 损失函数

RNN 的输出结果 $y^1,y^2,y^3,…$ 与参考结果 $\hat y^1,\hat y^2,\hat y^3…$ 比较,

计算交叉熵函数,即损失函数;我们需要通过训练使损失函数最小。

1.2 学习过程

我们通过BPTT演算法来训练RNN网络的参数,使损失函数达到最小。

有了这个loss function以后,对于training,也是用梯度下降来做。
也就是说我们现在定义出了loss function(L),我要update这个neural network里面的某个参数w,
就是计算对w的偏微分,偏微分计算出来以后,就用GD的方法去update里面的参数。
在讲feedforward neural network的时候,
我们说GD用在feedforward neural network里面你要用一个有效率的算法叫做Backpropagation。
那Recurrent Neural Network里面,为了要计算方便,所以也有开发一套算法是Backpropagation的进阶版,叫做BPTT。
它跟Backpropagation其实是很类似的,只是Recurrent Neural Network它是在high sequence上运作,
所以BPTT它要考虑时间上的information。

不幸地是:

  • 基于RNN的训练是比较困难的

语言模型的真实实验结果:

一般而言,你在做training的时候,你会期待,你的learning curve是像蓝色这条线,
这边的纵轴是total loss,横轴是epoch的数目,你会希望说:
随着epoch的数目越来越多,随着参数不断的update,loss会慢慢的下降最后趋向收敛。
但是不幸的是你在训练Recurrent Neural Network的时候,你有时候会看到绿色这条线。
学习曲线产生剧烈的抖动,出现不平滑的情况。

1.3 error surface

误差曲面面要么非常平坦,要么异常陡峭。这样会造成什么样的问题呢?
假设你从橙色的点当做你的初始点,用GD开始调整你的参数(updata你的参数,可能会跳过一个悬崖,
这时候你的loss会突然爆长,loss会非常上下剧烈的震荡)。
有时候你可能会遇到更惨的状况,就是以正好你一脚踩到这个悬崖上,会发生这样的事情,
因为在悬崖上的gradient很大,之前的gradient会很小,所以你措手不及,
因为之前gradient很小,所以你可能把learning rate调的比较大。
很大的gradient乘上很大的learning rate结果参数就update很多,整个参数就飞出去了。

用工程的思想来解决就是采用clipping(当gradient大于某一个threshold的时候,不要让它超过那个threshold),
当gradient大于15时,让gradient等于15结束。
因为gradient不会太大,所以你要做clipping的时候,就算是踩着这个悬崖上,也不飞出来,会飞到一个比较近的地方,
这样你还可以继续做你得RNN的training。

由图中的例子,我们可以看出:损失函数的梯度在同一个点附近可能有着巨大的差别,

有时候非常大,有时候非常小。

2.解决RNN梯度消失或者梯度爆炸问题

2.1 LSTM

有什么样的技巧可以告诉我们可以解决这个问题呢?
其实广泛被使用的技巧就是LSTM,LSTM可以让你的error surface不要那么崎岖。
它可以做到的事情是,它会把那些平坦的地方拿掉,解决gradient vanish的问题,不会解决gradient explode的问题。
有些地方还是非常的崎岖的(有些地方仍然是变化非常剧烈的,但是不会有特别平坦的地方)。

如果你要做LSTM时,大部分地方变化的很剧烈,所以当你做LSTM的时候,
你可以放心的把你的learning rate设置的小一点,保证在learning rate很小的情况下进行训练。

那为什么LSTM 可以解决梯度消失的问题呢,为什么可以避免gradient特别小呢?

RNN与LSTM在面对memory的时候,处理操作不一样;

RNN 里面每一个时间点,memory里面的值都会被覆盖掉;
而 LSTM 是把原来的memory里面的值乘以一个值与 input 的值之和放在cell中,即LSTM的memory input 是相加的。
所以今天它和RNN不同的是,如果今天你的weight可以影响到memory里面的值的话,一旦发生影响会永远都存在。
不像RNN在每个时间点的值都会被format掉,所以只要这个影响被format掉它就消失了。
但是在LSTM里面,一旦对memory造成影响,那影响一直会被留着。

现在有另外一个版本用gate操控memory cell,叫做Gates Recurrent Unit(GRU),
LSTM有三个Gate,而GRU有两个gate,所以GRU需要的参数是比较少的。
因为它需要的参数量比较少,所以它在training的时候是比较鲁棒的。

如果你今天在train LSTM,你觉得overfitting的情况很严重,你可以试下GRU。
GRU的精神就是:旧的不去,新的不来。
它会把input gate跟forget gate联动起来,
也就是说当input gate打开的时候,forget gate会自动的关闭(format存在memory里面的值),
当forget gate没有要format里面的值,input gate就会被关起来。
也就是说你要把memory里面的值清掉,才能把新的值放进来。

2.2 其他技巧

其实还有其他的technique是来handle gradient vanishing的问题。
比如说clockwise RNN或者说是Structurally Constrained Recurrent Network (SCRN)等等。

3. RNN 的应用

3.1 多对一序列

  • 输入是矢量序列,但输出只是一个矢量

sentiment analysis所做的事就是给machine 看很多的文章,
然后machine要自动的说,哪些文章是正类,哪些文章是负类。
在这个过程中,RNN的输入是 character sequence,
然后Recurrent Neural Network把这个sequence读过一遍。
在最后一个时间点,把hidden layer拿出来,在通过几个transform,
然后你就可以得到最后的sentiment analysis
(这是一个分类的问题,但是因为input是sequence,所以用RNN来处理)

key term extraction意思就是说给machine看一个文章,machine要预测出这篇文章有哪些关键词汇。

3.2 多对多序列

  • 输入和输出都是序列,但输出比输入短。

语音辨识中输入是一段语音信号,每一个 vector 是信号的非常小的一小段时间(例如0.1s)所以一段信号中会有很多 vector
都会输出相同的字 (如上图所示),用 trimming 的方法把重复的输出去掉,但是这样会出现无法区分“好棒”(褒义)和“好棒棒”(贬义)的问题。

需要把“好棒”跟“好棒棒”分开来,怎么办,我们有一招叫做“CTC”(这招很神妙),它说:
我们在output时候,我们不只是output所有中文的character,我们还有output一个符号,叫做”null”“(没有任何东西)。
所以我今天input一段acoustic feature sequence,它的 output 是“好 null null 棒 null null null null”,
然后我就把“null”的部分拿掉,它就变成“好棒”。如果我们输入另外一个sequence,
它的output是“好 null null 棒 null 棒 null null”,然后把“null”拿掉,所以它的output就是“好棒棒”。
这样就可以解决叠字的问题了。

  • CTC的训练过程:

CTC在做training的时候,你手上的train data就会告诉你说,
这一串acoustic features对应到这一串character sequence,
但它不会告诉你说“好”是对应第几个character 到第几个character。
这该怎么办呢,穷举所有可能的alignments。
简单来说就是,我们不知道“好”对应到那几个character,“棒”对应到哪几个character。
假设我们所有的状况都是可能的。
可能第一个是“好 null 棒 null null null”,可能是“好 null null 棒 null null”,
也可能是“好 null null null 棒 null”。我们不知道哪个是对的,那假设全部都是对的。
在training的时候,全部都当做是正确的,然后一起train。

  • CTC 实例:

在做英文辨识的时候,你的RNN output target 就是character(英文的字母+空白)。
直接output字母,然后如果字和字之间有boundary,就自动有空白。

假设有一个例子,第一个frame是output h,第二个frame是output null,
第三个frame是output null,第四个frame是output I等等。
如果你看到output是这样子话,那最后把“null”的地方拿掉,那这句话的辨识结果就是“HIS FRIEND’S”。
你不需要告诉machine说:”HIS”是一个词汇,“FRIEND’s”是一个词汇,machine通过training data会自己学到这件事情。
传说 Google 的语音辨识系统已经全面换成CTC来做语音辨识。如果你用CTC来做语音辨识的话,
就算是有某一个词汇(比如是:英文中人名,地名)在training data中从来没有出现过,machine也是有机会把它辨识出来。

3.3 多对多(Sequence to sequence learning)

  • 输入和输出长度之间没有关系限制。

输入英文词汇序列,输出中文词汇序列,二者的长度不一样。例如:machine learning 翻为:机器学习。

把输入 machine learning 用 RNN 读一遍,在最后一个时间点的 memory 里面就存了整个 input sequence 的信息。

最后输出第一个词“机”,然后把“机”作为下一个网络的输入,然后就会推出一系列的词汇。

问题点:不知道什么时候停下来

推文接龙:

解决办法:

增加一个“断”标志。

直接输入英文的声音信号,输出另一种语言的文字,

而不必先将语音信号转换成文字。

这篇的papre是这样做的,sequence to sequence learning我们原来是input
某种语言的文字翻译成另外一种语言的文字(假设做翻译的话)。
那我们有没有可能直接input某种语言的声音讯号,
output另外一种语言的文字呢?我们完全不做语音辨识。
比如说你要把英文翻译成中文,你就收集一大堆英文的句子,
看看它对应的中文翻译。你完全不要做语音辨识,
直接把英文的声音讯号丢到这个model里面去,

看它能不能output正确的中文。这一招居然是行得通的。
假设你今天要把台语转成英文,但是台语的语音辨识系统不好做,
因为台语根本就没有standard文字系统,所以这项技术可以成功的话,
未来你在训练台语转英文语音辨识系统的时候,你只需要收集台语的声音讯号跟它的英文翻译就可以刻了。
你就不需要台语语音辨识的结果,你也不需要知道台语的文字,也可以做这件事。

利用sequence to sequence的技术,甚至可以做到Beyond Sequence。这个技术也被用到syntactic parsing。
synthetic parsing这个意思就是说,让machine看一个句子,它要得到这个句子的结构树,得到一个树状的结构。
怎么让machine得到这样的结构呢?
过去你可能要用structured learning的技术能够解这个问题。
但是现在有了 sequence to sequence learning的技术以后,
你只要把这个树状图描述成一个sequence(具体看图中 john has a dog)。
所以今天是sequence to sequence learning 的话,
你就直接learn 一个sequence to sequence model。
它的output直接就是syntactic parsing tree。这个是可以train的起来的,非常的surprised

有兴趣的同学可以看下论文:
Oriol Vinyals, Lukasz Kaiser, Terry Koo, Slav Petrov, Ilya Sutskever, Geoffrey Hinton, Grammar as a Foreign Language, NIPS 2015

3.4 Document转成Vector

那我们要将一个document表示成一个vector的话,往往会用bag-of-word的方法,
用这个方法的时候,往往会忽略掉 word order information。
举例来说,有一个word sequence是“white blood cells destroying an infection”,
另外一个word sequence是:“an infection destroying white blood cells”,这两句话的意思完全是相反的。
但是我们用bag-of-word的方法来描述的话,他们的bag-of-word完全是一样的。它们里面有完全一摸一样的六个词汇,
因为词汇的order是不一样的,所以他们的意思一个变成positive,一个变成negative,他们的意思是很不一样的。

那我们可以用sequence to sequence Auto-encoder这种做法来考虑word sequence order的情况下
把一个document变成一个vector。

4. Sequence-to-sequence -Text

input一个word sequence,通过Recurrent Neural Network变成一个invalid vector,
然后把这个invalid vector当做decoder的输入,然后让这个decoder,找回一模一样的句子。
如果今天Recurrent Neural Network可以做到这件事情的话,
那Encoding这个vector就代表这个input sequence里面重要的information。
在trian Sequence-to-sequence Auto-encoder的时候,
不需要label data,你只需要收集大量的文章,然后直接train下去就好。

Sequence-to-sequence 还有另外一个版本叫skip thought,
如果用Sequence-to-sequence的,输入输出都是同一个句子,
如果用skip thought的话,输出的目标就会是下一个句子,
用sequence-to-sequence得到的结果通常容易表达,
如果要得到语义的意思的,那么skip thought会得到比较好的结果。

这个结构甚至可以是hierarchical,你可以每一个句子都先得到一个vector
(Mary was hungry得到一个vector,she didn’t find any food得到一个vector),
然后把这些vector加起来,然后变成一个整个 document high label vector,
在让这整个vector去产生一串sentence vector,
在根据每一个sentence vector再去解回word sequence。
这是一个四层的LSTM(从word 变成sentence sequence ,
变成document lable,再解回sentence sequence,再解回word sequence)

5 Sequence-to-sequence -Speech

在语音上,它可以把一段audio segment变成一个fixed length vector。
比如说,左边有一段声音讯号,长长短短都不一样,那你把他们变成vector的话,
可能dog跟dogs比较接近,never和ever比较接近。我称之为audio auto vector。
一般的auto vector它是把word变成vector,这个是把一段声音讯号变成一个vector。

  • 语音搜索:

将语音库中的语音信号全部转换为向量,输入信号也转换为向量,

在语音库中寻找最相似的向量,得到搜寻结果。

如何将音频段转化为向量?

通过 RNN Encoder 将音频信号进行训练,最后存到 memory 中的信息就是向量;

我们将 encoder 和 decoder 放在一起训练,希望最终的输出结果 $y_1,y_2,y_3,..$和$x_1,x_2,x_3,…$ 接近。

  • 嵌入向量的可视化

我们在实验上得到一些有趣的结果,图上的每个点其实都是一段声音讯号,
你把声音讯号用刚才讲的 Sequence-to-sequence Auto-encoder技术变成平面上一个vector。
发现说:fear这个位置在左上角,near的位置在右下角,他们中间这样的关系(fame在左上角,name在右下角)。
你会发现说:把fear的开头f换成n,跟fame的开头f换成n,它们的word vector的变化方向是一样的。
现在这个技术还没有把语义加进去。

训练聊天机器人,模仿人类对话。

这个demo是用Sequence-to-sequence Auto-encoder来训练一个chat-bot(聊天机器人)。
怎么用sequence to sequence learning来train chat-bot呢?
你就收集很多的对话,比如说电影的台词,在电影中有一个台词是“How are you”,另外一个人接“I am fine”。
那就告诉machine说这个sequence to sequence learning
当它input是“How are you”的时候,这个model的output就要是“I am fine”。
你可以收集到这种data,然后就让machine去 train。
这里我们就收集了四万句和美国总统辩论的句子,然后让machine去学这个sequence to sequence这个model。

6.基于注意力的模型(RNN进阶版本)

RNN 的进阶版本,先给出了人类脑袋可以记忆很多东西,从今天的早餐,到 10 年前的夏天,还可以根据记忆进行归纳整理知识

机器也可以做类似的事情,大体结构如下图所示,输入经过 DNN 或 RNN(相当于 CPU),然后操控读写头,
读取相应位置的数据(整个过程类似电脑读取硬盘),不具体展开。
大家可以参考相关资料: Attention-Based Model李宏毅精讲

当得到新的输入信号时,我们使用 DNN 或者 RNN 训练该数据,得到机器内存中相应位置的信息并输出。

其实machine也可以做到类似的事情,machine也可以有很大的记忆的容量。
它可以有很大的data base,在这个data base里面,每一个vector就代表了某种information被存在machine的记忆里面。

当你输入一个input的时候,这个input会被丢进一个中央处理器,这个中央处理器可能是一个DNN/RNN,
那这个中央处理器会操控一个Reading Head Controller,
这个Reading Head Controller会去决定这个reading head放的位置。
machine再从这个reading head 的位置去读取information,然后产生最后的output

这个model还有一个2.0的版本,它会去操控writing head controller。
这个writing head controller会去决定writing head 放的位置。
然后machine会去把它的information通过这个writing head写进它的data base里面。
所以,它不仅有读的功能,还可以discover出来的东西写入它的memory里面去。
这个就是大名鼎鼎的Neural Turing Machine。

6.1 阅读理解

将Text中的句子变成一个个句子,根据输入的队列,经过 RNN 或者 DNN 处理,找到最合适的答案。

结果:

https://github.com/fchollet/keras/blob/master/examples/babi_memnn.py 上图是在baby corpus上的结果,baby corpus是一个Q&A的一个简单的测试。
我们需要做的事就是读过这五个句子,然后说:what color is Grey?,得到正确的答案,yes。
那你可以从machine attention的位置(也就是reading head 的位置)看出machine的思路。
图中蓝色代表了machine reading head 的位置,Hop1,Hop2,Hop3代表的是时间,
在第一个时间点,machine先把它的reading head放在“greg is a frog”,把这个information提取出来。
接下来提取“brian is a frog” information ,再提取“brian is yellow”information。
最后它得到结论说:greg 的颜色是yellow。这些事情是machine自动learn出来的。
也就是machine attention在哪个位置,这些通过neural network学到该怎么做,并不是去写程序,
你要先看这个句子,在看这个句子。这是machine自动去决定的。
#### 6.2 视觉问题回答(Visual Question Answering) 判断胡子是什么构成的? ![](http://imgbed.momodel.cn/37-34 visual question.png) 与阅读理解的问题类似,每一个向量代表图片中的某一部分的区域; 通过 RNN 的处理,找到最相似的部分。 ![](http://imgbed.momodel.cn/37-35 answer.png) 这个Visual Question Answering该怎么做呢?
先让machine看一张图,然后通过CNN你可以把这张图的一小块region用一小块的vector来表示。
接下里,输入一个query,这个query被丢到中央处理器中,这个中央处理器去操控这个reading head controller,
这个reading head controller决定读取的位置(是跟现在输入的问题是有关系的,
这个读取的process可能要好几个步骤,machine会分好几次把information读到中央处理器,最后得到答案。
#### 6.3 Speech Question Answering + 让机器进行托福的听力测试 ![](http://imgbed.momodel.cn/37-36 model test.png) **模型结构**: + 将问题进行语义分析,得到问题的语义; + 将音频故事先进行语音识别转换为文字在进行语义分析; + 将问题和文章故事做 “attention” 处理找到答案,找到答案之后还可以将答案和原文在比较找到最合适的答案。 ![](http://imgbed.momodel.cn/37-37 model architecture.png) 实验结果: ![](http://imgbed.momodel.cn/37-38 experiment result.png) 这些是一些实验结果,这个实验结果是:random 正确率是25 percent。有两个方法要比25 percent要强的。
这五个方法都是naive的方法,也就是完全不管文章的内容,直接看问题跟选项就猜答案。
我们发现说,如果你选最短的那个选项,你就会得到35 percent的正确率。
如果分析四个选项的semantic,用sequence-to-sequence autoencoder,去把一个选项的semantic找出来,
然后再去看某个选项和另外三个选项的相似度,如果比较高的话,那就把该选项选出来。
和人的直觉是相反的,直觉应该是选一个语义和另外三个语义是不像的,但是别人已经计算到会这么做的了,
所以用了计中计,如果要选和其他选项语义比较相似的答案,反而比随便选得到正确答案的概率要高,
如果选最不像的那个选项,得到的答案就会接近随机,都是设计好的。

Memory Network 的正确率为 39.2%。
![](http://imgbed.momodel.cn/37-39 memory network.png) Attention-based Model 的正确率为 48.8% ![](http://imgbed.momodel.cn/37-40 proposed approach.png) 参考资料: + 循环神经网络的不合理有效性 http://karpathy.github.io/2015/05/21/rnn-effectiveness/ + 了解 LSTM 网络 http://colah.github.io/posts/2015-08-Understanding-LSTMs/ #### 6.4 RNN与结构化学习的联系与区别 ![](http://imgbed.momodel.cn/37-41 RNN vs Structed learning.png) 使用deep learning跟structure learning的技术有什么不同呢?
首先假如我们用的是unidirectional RNN/LSTM,当你在 decision的时候,你只看了sentence的一半,
而你是用structure learning的话,比如用Viterbi algrithm你考虑的是整个句子。
从这个结果来看,也许HMM,SVM等还是占到一些优势的。
但是这个优势并不是很明显,因为RNN和LSTM他们可以做Bidirectional ,
所以他们也可以考虑一整个句子的information。
在HMM/SVM里面,你可以explicitly的考虑label之间的关系
举例说,如果做inference的时候,再用Viterbi algrithm求解,
(假设每个label出现的时候都要出现五次)这个算法可以轻松做到,
因为可以修改机器在选择分数最高的时候,排除掉不符合constraint的那些结果,
但是如果是LSTM/RNN,直接下一个constraint进去是比较难的,
因为没办法让RNN连续吐出某个label五次才是正确的,
所以在这点上,structured learning似乎是有点优势的。
如果是RNN/LSTM,你的cost function跟你实际上要考虑的error往往是没有关系的,
当你做RNN/LSTM的时候,考虑的cost是每一个时间点的cross entropy(每一个时间的RNN的output cross entropy),
它跟你的error不见得是直接相关的。但是你用structure learning的话,structure learning 的cost会影响你的error,
从这个角度来看,structured learning也是有一些优势的。
最重要的是,RNN/LSTM可以是deep,HMMM,SVM等它们其实也可以是deep,但是它们要想拿来做deep learning 是比较困难的。
在我们上一堂课讲的内容里面。它们都是linear,因为他们定义的evaluation函数是线性的。
如果不是线性的话也会很麻烦,因为只有是线性的我们才能套用上节课讲的那些方法来做inference。

最后来看,RNN/LSTM在deep这件事的表现其实会比较好,同时这件事也很重要,
如果只是线性的模型,function space就这么大,可以直接最小化一个错误的上界,
但是这样没什么,因为所有的结果都是坏的,所以相比之下,deep learning占到很大的优势。
### 7.Integerated Together ![](http://imgbed.momodel.cn/37-42 integrated.png) deep learning和structured learning结合起来。
input features 先通过RNN/LSTM,然后RNN/LSTM的output再做为HMM/svm的input。
用RNN/LSTM的output来定义HMM/structured SVM的evaluation function,
如此就可以同时享有deep learning的好处,也可以有structure learning的好处。
+ 语音识别:CNN/LSTM/DNN + HMM ![](http://imgbed.momodel.cn/37-43 speech recognize.png) + 语义标记:Bi-directional LSTM + CRF/Structured SVM ![](http://imgbed.momodel.cn/37-44 semantic tagging.png) 先用Bi-directional LSTM做feature,然后把这些feature拿来在做CRF或者Structured SVM,
然后学习一个权重w,这个$\phi(x,y)$的feature,要直接从Bidirectional LSTM的输出可以得到比较好的结果。 ![](http://imgbed.momodel.cn/37-45 GAN.png) 有人说structured learning是否现实?
structured learning需要解三个问题,其中input的问题往往很困难,
因为要穷举所有的y让其最大,解一个optimization的问题,
其实大部分状况都没有好的解决办法,只有少数有,其他都是不好的状况。
所以有人说structured learning应用并不广泛,但是未来未必是这样的。
其实GAN就是一种structured learning,
可以把discriminator看做是evaluation function(也就是problem 1)最后要解一个inference的问题,
我们要穷举我们未知的东西,看看哪个可以让我们的evaluation function最大。
这步往往比较困难,因为x的可能性太多了。
但其实这个可以就是generator,我们可以想成generator就是用所给的noise,输出一个update,
它输出的这个高斯模型,就是让discriminator分辨不出的高斯模型,
如果discriminator就是evaluation function的话,
那output的值就是让evaluation function的值很大的那个对应值,
所以这个generator就是在解这个问题,
其实generator的输出就是argmax的输出,可以把generator当做在解inference这个问题,然后就直接求problem 3。
structured learning过程和GAN模型generator不断产生让discriminator最大的那个值,
然后再去训练discriminator不断识别真实值,然后更新值的过程是异曲同工的。

![](http://imgbed.momodel.cn/37-46 conditional gan.png) GAN也可以是conditional的GAN,现在的任务是给定x,找出最有可能的y,想成语音辨识,x是声音讯号,y是辨识出来的文字,
如果是用conditional的概念,generator输入一个x,就会output一个y,discriminator是去检查y的pair是不是对的,
如果给他一个真正的x,y的pair,会得到一个比较高的分数,给一个generator输出的一个y配上输入的x,
所产生的一个假的pair,就会给他一个比较低的分数。
训练的过程就和原来的GAN就是一样的,这个已经成功运用在文字产生图片这个task上面。
这个task的input就是一句话,output就是一张图,
generator做的事就是输入一句话,然后产生一张图片,
而discriminator要做的事就是给他一张图片,要他判断这个x,y的pair是不是真的,
如果把 discriminator换成evaluation function,把generator换成解inference的problem,
其实conditional GAN和structured learning就是可以类比,或者说GAN就是训练structured learning的一种方法。
![](http://imgbed.momodel.cn/37-47 future.png) 很多人都有类似的想法,比如GAN可以和Energy—based模型一起做。这里给出一些Reference。