zoukankan      html  css  js  c++  java
  • Transformer 模型

    What is TRANSFORMER?

    今天学一下变形金刚,transformer是一个很有用的模型,尤其会为我们后面学习BERT model打好基础。文章如有不当之处,请不吝赐教。下面来看一下这个神奇的工具吧。

    李宏毅老师transformer课程:https://www.youtube.com/watch?v=ugWDIIOHtPA

    用CNN代替RNN

    Seq2Seq模型是一个很常用的东西,它能处理的问题类型很广泛,包括翻译、命名体识别等NLP领域的火热话题。这里有一篇关于Seq2Seq的教程,希望能够帮助不是很熟悉Seq2Seq的朋友,下文假设大家已经都比较清楚Seq2Seq model了,至少比我要强

    应该说Seq2Seq模型很不错,但是我们还是有不满意的地方。哪里不满意呢?

    其实很多人都很注意模型是否能够在数据并行、计算并行的条件下工作,能够得到一个高效的训练方法。RNN就暴露了一个很显然的问题,那就是它并不能并行计算。那我们看看有没有什么其他的方案可以替代它呢?CNN行不行呢?当然可以,要不然这段标题就没有意义了。

    纯手绘图,有点丑请见谅。

    在图中象征性的画了几个CNN,用(a_1, a_2, .. a_n)作3个一起的inner product,得到第一层之后的节点,用第一层的输出继续CNN,以此类推我们可以得到(b_1, b_2, ..b_n)。可以看出,虽然一次CNN计算只能考虑附近的三个点的输入,但是多几层就可以考虑整个序列,能起到和bi-RNN类似的效果,更重要的是,你在计算下一层的部分节点时候不需要本层所有节点都算完,计算第(i)个节点不需要算出本层的第(i - 1)个节点,这让我们的并行成为了可能。

    缺点

    上面提到的这个做法的缺陷也很明显,就是你必须要加很多层CNN,才可以达到查看整个序列的信息的目的。为了做出改进,有了下面的self-attention。

    Self-Attention

    我们先给Self-Attention layer一个概念性的定义。

    自注意力机制最早来源于Google的一篇论文,这篇论文的名字估计很多人听过,叫'Attention Is All You Need',文中阐述了这个模型的工作原理。总体的来讲,他也是一个Sequential Model,适合处理序列性问题。从论文标题我们就可以看出,文章告诉我们,不再需要RNN,不需要CNN,这个模型也可以input一个sequence,output一个sequence,并且能像bi-directional RNN一样,输出是看过整个输入的,而且还可以parallel!

    How to do attention

    假设我们的输入还是最原始的one-hot vector,首先通过embedding。即:

    [x^i ightarrow a^i ]

    然后我们有三个矩阵(q,k,v),分别再得到(q^i, k^i, v^i):

    [q: query(to match others)\ k: key(to be matched)\ v: information to be extracted ]

    attention

    然后我们做的一件事情,就是对于每一个(query)去和别的(key)作attention。我们得到attention后的结果。

    [alpha^{ij} = attention(q^i, k^j) ]

    其中一种可以选用的attention做法,也是paper中的做法:

    [attention(q^i, k^i) = frac{q^i cdot k^i}{sqrt d} ]

    其中(d)(q,k)的维度,为了保证dot product的结果不会大到超出我们的预期,可以直观的感受一下这一部分的作用。当然,其他的运算方法也是可以的,在'attention is all you need'中并没有对运算方法的不同对模型效率的影响做评估。

    对上面的结果作softmax:

    [hat alpha^{ij} = softmax(alpha^{ij}) ]

    我们这样就计算出了注意力下的各个(x_j)(x_i)的重要性。

    计算output

    得到的注意力权重已经是看过整个序列之后的结果了,只要我们的(v^i)也是正确的,我们有理由得到:

    [b^i = sum_j hat alpha^{ij} v^i ]

    在这个计算过程中,大家看的出来,两个点不过距离多远,只要注意力足够,我们都能保证一定的关联度。

    Matrix计算

    现在我们看看整个过程是怎么parallel的。

    [I = (a^1 a^2..a^n)\ Q = (q^1q^2..q^n) = W^q I\ K = (k^1k^2..k^n) = W^k I\ V = (v^1v^2..v^n) = W^v I\ ]

    attention过程:

    [egin{pmatrix} alpha^{1, 1} & alpha^{1, 2} & alpha^{1, 3}\ alpha^{2, 1} & alpha^{2, 2} & alpha^{2, 3}\ alpha^{3, 1} & alpha^{3, 2} & alpha^{3, 3} end{pmatrix} = egin{pmatrix} k^1 \ k^2 \ k^3 end{pmatrix} egin{pmatrix} q^1 & q^2 & q^3 end{pmatrix}\ hat A = softmax(A)\ O = egin{pmatrix} b^1 & b^2 & b^3 end{pmatrix} = egin{pmatrix} v^1 & v^2 & v^3 end{pmatrix} hat{A} ]

    上面的一连串运算都是矩阵乘法,可以使用GPU加速。

    变种:Multi-Head self-attention

    所谓Multi-Head Self-Attention呢,就是在原来(q)的基础上,我们继续分:

    [Q^{1} = W^{q,1} q^i\ Q^2 = W^{q,2} q^i\ ]

    (k,v)也如此做,这样就得到了多个(b),最后再做结合并降维就可以了。

    引入多个head的好处是,不同的注意力头可能会注意不同的地方,Google的论文中提到,他们各司其职,可能有的比较注意附近的点,有的比较注意离得远的。

    位置信息

    如果你还记得,上面说self-attention的这种做法是远处和进出一视同仁,并不考虑各种顺序关系。我们知道这肯定是不合理的,为了让它考虑位置信息,我们再加上position的内容。

    做法是用一个包含位置内容的向量(e^i)来表示,这个(e^i)并不是学习出来的,而是人为规定的。

    其实这个位置信息更直观的添加方法是在(x^i)那里concat一个表示位置的one-hot对吧?不用担心,实际上道理上是都可行的,而且论文中已经证明了后者做法效果不会比前者更好。

    In this work, we use sine and cosine functions of different frequencies:

    [P E(pos,2i) = sin(pos/10000^{2i/d_{model} })\ P E(pos,2i+1) = cos(pos/10000^{2i/d_{model} } ) ]

    where pos is the position and i is the dimension.

    Seq2Seq with Attention

    现在回忆一下你熟悉的Seq2Seq模型,其中的encoder和decoder,不管是有没有attention,我们都用上面讲的self-attention layer代替。下面是来自Google AI Blog的动画:

    一个做翻译任务的transformer的完整结构图如下:

    encoder

    首先inputs做Embedding,然后用包含位置信息的Positional Encoding加到Embeded input中去,作为整个encoder的输入。

    encoder由(N)个sublayers组成,每个sublayer又有一个Multi-Head Attention layer和Feed Forward layer组成,其中的Add是把输入和输出加在一起,Norm是做了一次layer Normalization

    decoder

    decoder相比encoder,多了一层Masked Multi-Head Attention。解码时,所有的已经预测出的结果和输入的Context Vector都会参与Attention,因为只计算已经得到的output的key,所以要这遮住一部分。

    应用

    基本上所有Seq2Seq用的东西,Transformer都可以应用。可以用它替代RNN,并且能够实现更好的效果。比如文章摘要自动生成,不管输入还是输出,在数量级上都比RNN的应用阶段提升了不少。

    Universal Transformers,更加扩展了transformer的应用范围,弥补了其缺点。

    一个人没有梦想,和咸鱼有什么区别!
  • 相关阅读:
    Java基础-String、StringBuffer、StringBuilder的区别
    Java基础-String类能被继承吗,为什么
    Java基础-Java中的基本数据类型是什么,各自占用多少字节
    JAVA关键字
    Java 栈(stack)与堆(heap) 详解
    Hibernate--hibernate.hbm.xml详解
    Hhibernate--映射继承关系
    C--c语言模拟java的linkedList
    C--调试基本命令
    C--指针
  • 原文地址:https://www.cnblogs.com/TABball/p/12727174.html
Copyright © 2011-2022 走看看