美文网首页李宏毅深度学习(2017)
11.Conditional Generation by RNN

11.Conditional Generation by RNN

作者: SpareNoEfforts | 来源:发表于2019-02-21 23:19 被阅读27次

    outline

    • Generation
    • Attention
    • Tips for Generation
    • Pointer Network


    Generation

    以下是使用RNN来生成句子的例子:

    Tips:英文中的characters指的是:abc……z,words是 单词
    中文中的characters指的是一个一个的字;words指的是词语,比如“葡萄”

    RNN也可以用来生成图片:方法是将像素转化为句子,训练基于句子的语言模型

    但是这个方法是有缺陷的,因为没有考虑到图像的几何关系,就比如下图:蓝色对下面灰色是有影响的,然而上一行的黄色对下一行的灰色是没有什么影响的。其实,如果使用的是RNN,在产生灰色的时候其实也已经考虑了前面所有的像素颜色,如果RNN 训练的够好,它可以学到三个像素之前的那个像素影响比较大。

    一个比较理想的产生像素的方法是如右下角所示:

    以下是一些其他的引用,比如说:

    • 图像:
      • Aaron van den Oord, Nal Kalchbrenner, Koray Kavukcuoglu, Pixel Recurrent Neural Networks, arXiv preprint, 2016
      • Aaron van den Oord, Nal Kalchbrenner, Oriol Vinyals, Lasse Espeholt, Alex Graves, Koray Kavukcuoglu, Conditional Image Generation with PixelCNN Decoders, arXiv preprint, 2016
    • 视频:
      • Aaron van den Oord, Nal Kalchbrenner, Koray Kavukcuoglu, Pixel Recurrent Neural Networks, arXiv preprint, 2016
    • 手写体:
      • Alex Graves, Generating Sequences With Recurrent Neural Networks, arXiv preprint, 2013
    • 语音:
      • Aaron van den Oord, Sander Dieleman, Heiga Zen, Karen Simonyan, Oriol Vinyals, Alex Graves, Nal Kalchbrenner, Andrew Senior,Koray Kavukcuoglu, WaveNet: A Generative Model for Raw Audio, 2016

    Conditional Generation

    但是只能用RNN 生成的东西仅仅是不够的,为什么呢?因为只用RNN生成的东西,比如一个句子,看起来是合乎文法的句子,但是你没有办法控制要说什么;很多场合,我们需要的不是一个句子,而是一个和场景有关的句子或者是我们想要machine说的句子。如下图所示:


    基于这种情况,我们需要将问题或者是需要被翻译的句子的所有信息丢到网络中,得到对应的答案或者翻译结果,这样的思想就是Encoder/Decoder思想,换句话说,就是我们的Seq2Seq
    首先,我们把问题或者需要被翻译的句子通过一个RNN或者LSTM进行Encoder最后一个的输出就包含了这个句子的全部信息,然后我们把这个句子当作初始输入丢到另一个RNN或者LSTM中,然后通过这个得到对应的输出


    同样的方法,我们可以拿来做其他事情,比如:机器翻译/对话机器人等等。
    考虑更长久的文本内容:

    Attention——Dynamic Conditional Generation

    机器翻译

    我们以机器翻译作为例子:

    基于注意力的模型:

    • 输入一个经过RNN 处理的句子,每一个时间点每一个词汇都可以用一个vactor进行表示,这个vector就是RNN的隐藏层的输出;
    • 接下来,有一个初始的vector z^0,可以当作network的初始参数,可以根据训练数据学习出来。
    • 如上图所示,我们有个函数match,我们把z^0h^1丢进去match,得到\alpha _0^1,上标1的意思是z^0是和h^1算匹配度,下标0的意思是在时间为0的时候算相匹配的程度。match函数可以自己设计。
    • 举例来说:
      ①可以说match其实是算zh的Cosine similarity ;
      ②也可以说match其实是一个神经网络,输入是zh的连接,输出就是一个scalar;
      ③也可以说match里面有一个参数W,是一个matrix,是被学出来的,把zW相乘,再乘以h^T,会得到一个scalar :\alpha,即\alpha _0^1
      如果match里面有参数的话,那么会跟network里面的其他部分一起学出来。

    接下来,我们把得到的
    同理,得到:
    重复这个生成的过程:

    我们也可以把这个技术应用到语音识别当中:输入声音讯号,算match score,丢进去decoder;

    Image Caption Generation 图像标题生成

    那么在图像标题生成中怎么加上基于Attention的模型呢?如果image用一个vector来做是没法描述的,所以你可以用一组vector来进行描述:

    如下图所示,假设这个图象是由六个vector描述的话,先算出来和第一个filter的匹配分数,假设为0.7;
    同时,在算出其他的匹配分数,做加权和,然后丢进去RNN里面,得到第一个单词:
    同理:

    以下是从一些文献中找出来的结果:这个图怎么看呢?

    下面是machine看到图片以后产生的句子,右边这个图亮的地方是machine在产生画底线的那个词的时候Attend的位置。以下是一些好的例子:
    以下是一些不好的失败的例子:

    Memory Network

    Memory Network是在memory上面做attention,Memory Network最开始也是最常见的应用是在阅读理解上面,如下图所示:一篇文章,有问题,肯能不能生成答案,文章里面有很多句子组成,每个句子表示成一个vector,假设有N个句子,向量表示成x^1,x^2……x^N,问题也用一个向量描述出来,接下来算问题与句子的匹配分数\alpha,然后做加权和,然后丢进去DNN里面,最后就可以得到答案了。

    Memory Network有一个更复杂的版本,这个版本是这样的,算match的部分跟抽取infromation的部分不见得是一样的,如果他们是不一样的,其实你可以得到更好的performance。把文档中的同一句子用两组向量表示;Queryx这一组vector算Attention,但是它是用h这一组向量来表示infromation,把这些Attention乘以h的加和得到提取的信息,放入DNN,得到答案。Hopping是指的是反复进行。


    上图中Hopping是指的是反复进行运算,我们可以任认为machine在反复思考答案对不对。下面我们用下图来进一步解释一下Hopping
    如下图所示,我们用蓝色的vector计算attention,用橙色的vector做提取information。蓝色和蓝色,橙色和橙色的vector不一定是一样的。以下是两次加和后丢进去DNN得到答案。所以整件事情可以看作两个layer的神经网络。

    Neural Turing Machine

    刚刚讲的Memory Network是在memory上面做attention,然后从memory里面把information抽取出来,然而 Neural Turing Machine不仅仅从memory里抽取information,他还可以根据你的match score去修改存在memory里面的内容(具备读和写的功能)如下图:



    怎么去实现这个呢?

    • 首先,有一组memory,即一组vector序列m_0^1,m_0^2,m_0^3,m_0^4

    • 接下来,有一组初始的attention的weight,\hat \alpha _0^1,\hat \alpha _0^2,\hat \alpha _0^3,\hat \alpha _0^4

    • 根据初始的attention的weight和memory的vector序列,可以提取出information,得到vector r^0,把它交给另外一个神经网络,即一个函数,你可以任意设计这个函数,然后这个会输出几个vector,他们会去操控memory;

    • k^1的作用就是用来产生attention的,把它与m_0^1,m_0^2,m_0^3,m_0^4做cosine similarity,得到四个match score,接下来,在做softmax,就可以得到新的attention的distribution了。


      其实这是一个简化再简化的版本,真正的Neural Turing Machine它从k^1m_0^1,m_0^2,m_0^3,m_0^4产生attention的步骤有五步:
    • 我们产生了attention之后,另外两个vector e^1a^1就回去修改memory中的值, e^1的作用是把原来memory里面的值清空; a^1的作用是要把新的值写进去。怎么去做呢?用这个公式: m_0^i - \hat \alpha _1^i{e^1} \odot m_0^i

    • 接下来,根据中间的四个vector m_1^1,m_1^2,m_1^3,m_1^4可以得到r^1,然后加上新的人输入x^2,然后就可以得到新的输出;
      注意:这个函数f可以是recurrent network,前一个时间点的f不止会输出control memory的那些vector,他还会输出另外一个vector h^1,丢进去下一个f中,产生操控memory的参数

    Tips for Generation

    接下来要讲training,如果要产生句子的时候有哪些技巧。
    举例来说我们今天要做vedio的generation,我们给machine看一段如下的视频,如果你今天用的是Attention-based model的话,那么machine在每一个时间点会给vedio里面的每一帧(每一张image)一个attention,那我们 用\alpha _t^i来代表attention,上标i代表是第i个component,下标t代表是时间点。那么下标是1的四个\alpha会得到w_1,下标是2的四个\alpha会得到w_2,下标是3的四个\alpha会得到w_3,下标是4的四个\alpha会得到w_4

    但是可能会有Bad Attention,如下图所示,举个例子,在得到第二个词的时候,attention(柱子最高的地方)主要在woman那儿,得到第四个词的时候,attention主要也在woman那儿,这样子得到的就不是一个好句子。

    一个好的attention应该cover input所有的帧,而且每一帧的cover最好不要太多。最好的是:每一个input 组件有大概相同attention 权重。举一个最简单的例子,在本例中,希望在处理过程中所有attention的加和接近于一个值:\tau ,这里的\tau 是类似于learning rate的一个参数。用这个正则化的目的是可以调整比较小的attention,使得整个的performance达到最好。

    Mismatch between Train and Test

    你可能觉得生成一个句子听起来没什么,但是里面其实有很多枝枝节节的技巧是你没有发掘出来的。你有没有发现在training和testing的时候是有一个mismatch的?
    在training的时候:假设我们有个句子叫做A B B,那我们希望说machine在第一时间点越接近A越好,加一个粉色的condition,第一时间点RNN要输出A,同理,如下图所示:


    上面需要做的就是 minimize这三个()交叉熵的和

    那么想想看在generation的时候会怎么做?
    假设世界上只有两个word AB,这样子能简化我们的图示。我们来看产生的第一个词,颜色越深代表几率越大,所以产生B的几率更大,machine输出B;
    我们再生成的时候,不知道reference,Testing的时候:模型的输出是下一步的输入;Training的时候 输入就是reference.

    这听起来貌似没有什么,但是下面会告诉大家这件事情的影响。
    如下图所示:上面这个case是training的时候,你直接把正确答案接下来; 下面这个case是testing的时候,你把machine的output接到下一个时间点;到底有何不同呢?



    我们先来看上面这个case,我们用一个树状图来表示这个RNN,最下面的root是我们初始的state,输出哪个就走哪个路径,在training的时候根据reference我们正确的走法:
    在上面提到过,在使用RNN生成句子的时候,通过初始的输入得到生成的第一个词,然后把这个词当作下一次的输入得到第二个词,依次类推,那么问题就来了,当这个序列中有一个词错误的时候,那么其实后面的整个句子序列就错了,就是所谓的一步错,步步错。

    那么我们如何来解决这个一步错,步步错的问题呢?

    Scheduled Sampling

    Scheduled Sampling通过修改我们的训练过程来解决上面的问题,一开始我们只用真实的句子序列进行训练,而随着训练过程的进行,我们开始慢慢加入模型的输出作为训练的输入这一过程。

    解释:我们纠结的点就是到底下一个时间点的input到底是从模型的output来呢,还是从reference来呢?这个Scheduled Sampling方法就说给他一个几率,几率决定以哪个作为input,以下是形象的图示: 几率的设计是这样的:指数衰退、反转sigmoid衰退、线性衰退;很明显,如上图右上角所示:这个几率是下降的,纵轴是reference的几率。一开始我们只用真实的句子序列(reference)进行训练,而随着训练过程的进行,我们开始慢慢加入模型的输出作为训练的输入这一过程。如果这样train的话,就可能得到更好的效果:

    Beam Search

    Beam Search方法不再是只得到一个输出放到下一步去训练了,我们可以设定一个值,拿多个值放到下一步去训练,这条路径的概率等于每一步输出的概率的乘积,大家看下面的图就很容易理解Beam Search的过程啦。


    Beam Search方法是指在某个时间只pick几个分数最高的路径;选择一个beam size,即选择size个路径最佳。

    下一张图是如果使用beam search的时候,应该是怎么样的;
    假设世界上只有三个词

    我们的猜测如下:右边的结果不好:
    如下图所示:对于左边,高兴和难过的几率几乎是一样的,所以我们现在选择高兴丢进去,后面接想笑的几率会很大;
    对于右边,高兴和难过的几率几乎是一样的,想笑和想哭的几率几乎是一样的,那么就可能出现高兴想哭和难过想笑这样的输出。


    对象级别和组件级别
    我们现在要生成的是整个句子,而不是单一的词语,所以我们在考量生成的结果好不好的时候,我们应该看一整个句子,而不是看单一的词汇。举例来说,这张图是说:The dog is running fast; 我们一般训练的时候使用的都是交叉熵加和作为loss,如下:纵轴就是交叉熵,横轴就是training的时间;第二个和第三个的句子loss十分小,因此要一直train,一直train;

    Reinforcement learning


    下面是一些paper里面的效果:
    如下图纵轴是相对传统方法的差异:


    另外一张图:比较


    Pointer Network

    什么是Pointer Network?

    Pointer Network最早是用来解决演算法(电脑算数学的学问)的问题。
    举个例子:如下图所示,给出十个点,让你连接几个点能把所有的点都包含在区域内。拿一个NN出来,它的input就是10个坐标,我们期待它的输出是
    427653,就可以把十个点圈起来。那就要准备一大堆的训练数据;


    这个 Neural Network 的输入是所有点的坐标,输出是构成凸包的点的合集。

    如何求解Pointer Network?

    输入一排sequence,输出另一个sequence,理论上好像是可以用Seq2Seq解决的。那么这个 Network 可以用 seq2seq 的模式么?
    答案是不行的,因为,我们并不知道输出的数据的多少。更具体地说,就是在 encoder 阶段,我们只知道这个凸包问题的输入,但是在 decoder 阶段,我们不知道我们一共可以输出多少个值。举例来说就是,第一次我们的输入是 50 个点,我们的输出可以是 0-50 (0 表示 END);第二次我们的输入是 100 个点,我们的输出依然是 0-50, 这样的话,我们就没办法输出 51-100 的点了。

    为了解决这个问题,我们可以引入 Attention 机制。
    引入 Attention 机制,让network可以动态决定输出有多大。现在用Attention模型把这个sequence读取进来,第1-4个点h^1,h^2,h^3,h^4,在这边我们要加一个特殊的点h^0,代表END的点。
    接下来,我们就采用我们之前讲过的attention-based model,初始化一个key,即为z^0,然后用这个key去做attention-based model,用z^0对每一input做attention,每一个input都产生有一个Attention Weight,举例来说,在(x^1,y^1)这边attention的weight是0.5,在(x^2,y^2)这边attention的weight是0.3,在(x^3,y^3)这边attention的weight是0.2,在(x^4,y^4)这边attention的weight是0,在(x^0,y^0)这边attention的weight是0.0。这个attention weight就是我们输出的distribution,我们根据这个weight的分布取argmax,在这里,我取到(x^1,y^1),然后得到下一个key,即z^1;同理,算权重,取argmax,得到下一个key,即z^2,循环以上。以下是原理图:

    应用——总结(Summarization)

    我们先来看:



    更多的应用:


    image.png

    相关文章

      网友评论

        本文标题:11.Conditional Generation by RNN

        本文链接:https://www.haomeiwen.com/subject/agfryqtx.html