风油精,当Attention遇上RNN:动画图解怎么运用attention构建Transformer,炸蘑菇

频道:科研发现 日期: 浏览:295

作者:William Fal严嵩con

编译:ronghuaiyang

导读

之前经过动画介绍了RNN,介绍了attention,那么,今日再用动画给咱们介绍下如安在RNN中运用attention来构建transformer。

给你的神经网络添加留意力机制有点像想在作业的时分睡个午觉。你知道这样对你更好,每个人都想做,可是每个人都惧怕

我今日的方针是不做任何假定,用动画来解说细节,让数学再次变得巨大!

循环神经网络(RNN)

RNNs让咱们在神经网络中对序列建模。尽管还有其他序列建模的办法,可是RNNs特别有用。RNNs有两种类型,LSTMs和GRUs。

让咱们来看看机器翻译,这是一个RNN的详细比如。

1. 幻想一下咱们有一个具有56个躲藏单元的RNN。

rnn_cell = rnn_ce风油精,当Attention遇上RNN:动画图解怎样运用attention构建Transformer,炸蘑菇ll(input_dim=100, output_dim=56)

2. 咱们有个单词“NYU”,用一个整数11来表明,意思是这是我自己构建的词典中的第12个单词。

# 'NYU' is the 12th word in my vocab
word = 'NYU'
word = VOCAB[word]
print(word)
# 11

咱们不在RNN里边运用这样的整数,咱们运用了一个更高维度的表明,咱们现在经过embeddings取得这个表明。嵌入使咱们能够将离散的序列映射到接连空间。

embedding_layer = Embedding(vocab_size=120, embedding_dim=10)
# project our word韩国化妆品品牌 to 10 dimensions
x = embedding_layer(x)

RNN单元承受两个输入,一个单词x,和一个垚怎样读来自前一个时刻进程h的躲藏状况。在每个时刻步上,它输出一个新的h

RNN CELL: next h= f(x, prevh).

提示:榜首步的h通常是全0

# 1 word, RNN has 56 hidden units 
h_0 = np.zeros(1, 56)

有一点重要:RNN单元与RNN是不一样的

RNN术语中有一个首要的困惑点。在PyTorch和TensorFlow这样的深层学习结构中,RNN单元是进行这种核算的单元:

h1 = rnn_cell(x, h0)

RNN网络是RNN单元在时刻步上的循环

def RNN(sentence): 
prev_h = h_0
all_h =
for word in sentence:
# use the RNN CELL at each time step
current_h = rnn_cell(embed(word), prev_h)
all_h.append(current_h)
# RNNs output a hidden vector h at each time step
return all_h

下面是一个RNN随时刻移动相同RNN单元的比如:

RNN灰色会跟着时刻移动RNN单元。留意,咱们将运用每一步生成的一切h

序列到序列的模型(Seq2Seq)

现在你现已是RNNs的专家了,可是让咱们放松一下。

RNNs能够作为更大的深度学习体系的模块。

其间一个体系是Bengio的团队和谷歌引进的Seq2Seq模型,该模型可用于将序列翻译成另一个序列。你能够把许多问题归结为翻译:

  1. 英语翻译成西班牙语
  2. 视频序列转换成别的一种序列
  3. 把指令序列转换成代码
  4. 把用户行为转换成用户行为特征
  5. 仅有的约束便是你的发明力!

seq2seq模型其实便是2个RNNs、一个编码器(E)和一个解码器(D)。

class Seq2S风油精,当Attention遇上RNN:动画图解怎样运用attention构建Transformer,炸蘑菇eq(object):
def __init__:
self.encoder = RNN(...)
self.decoder = RNN(...)

seq2seq模型有两个首要进程:

Step 1: 对序列进行编码:

sentence = ["NYU", "NLP", "rocks", "!"]
all_h = Seq2Seq.encoder(sentence)
# all_h now has 4 h (activations)

Encoding

Step 2: 解码并生成“translation.”

这部分十分杂乱。前一步中的编码器一次性处理了整个序列(即:它是粥鬲一吉安县气候个一般的RNN)。

在第二步苏芮中,咱们每次运转解码器RNN的一个时刻步,以生成自回归猜测(运用上一步的输出作为下一步的输入是很风趣的)。

解码有两种首要办法:

Option 1: 贪心解码

  1. 运转佟含月解码器的一个时刻步
  2. 挑选概率最高的输出
  3. 把这个输出作为下个时刻步的输入
# you have to seed the first x since there are no predictions yet
# SOS means start of sentence
current_X_token = ''
# we also use the last hidden output of the encoder (or set to zero)
h_option_1 = hs[-1]
h_option_2 = zeros(...)
# let's use option 1 where it's the last h produced by the encoder
dec_h = h_option_1
# run greedy search until the RNN generates an End-of-Sentence token
while current_X_token != 'EOS':
# keep the output h for next step
next_h = decoder(dec_h, current_X_token)
# use new h to find most probable next word using classifier
next_token = max(softm北极光ax(fully_connected_lay风油精,当Attention遇上RNN:动画图解怎样运用attention构建Transformer,炸蘑菇er(next_h)))
# *KEY* prepare for next pass by updating pointers
current_X_token = next_token
dec_h = next_h

这叫做贪心算法,由于咱们总是用概率最高的作为下一个词。

Option 2: Beam炒葱椒鸡 Search

还有一种更好的技能叫做Beam Search,它考虑解码进程中的多条途径。浅显地说,宽度为5的Beam Search意味艾希着咱们考虑具有最大对数似然的5个或许序列(5个最或许序列的数学言语)。

在高层次上,咱们不进行最高概率的猜测,而是保存前k个(beam size = k)。请留意,在每个时刻步中咱们有5个选项(概率最高的前5个)。

因而,完好的seq2seq进程,把贪心解码办法经过动画来描绘,将“NYU NLP is awesome”* 翻译成西班牙语,是这样的:

Seq2Seq由2个RNNs,一个编码器和一个解码器组成该模型由以下几个部分组成:

  1. 蓝色RNN是编码器。
  2. 赤色RNN是解码器。
  3. 解码器上方的蓝色矩形是带softmax的全衔接层,挑选概率最大的最为下一个单词。

留意力机制

好了,现在咱们现已评论了一切的先决条件,让咱们来看看好的方面。

假如你留意到前面的动画,解码器只检查由编码器生成的最终一个躲藏向量。

成果,RNN很难记住在这个向量序列上发作的一切作业 。例如,当编码器处理完输入序列时,或许现已忘记了“NYU”这个单词。

Attention试着去处理这个问题

当你给一个模型加上留意力机制时,你答应它在每一个解码步中检查编码器发生的一切h。

为了做到这一点,咱们运用一个独自的网络,通常是一个全衔接的层来核算解码器想要检查一切h的哪些内容。这便是所谓的“留意机制”。

幻想一下,关于咱们生成的一切h,咱们实践上只取其间的一小部分。它们的和称为上下文向量c.

标量0.3、0.2、0.4、0.1称为留意力权重,在原始论文中,你会在第三页找到相同的方程:

是经过神经网络+softmax生成的

这些权值是由一个小的神经网络以这种办法发生的:

# attention is just a fully connected layer and a final projection
attention_mechanism = nn.Linear(input=h_size+x_size, attn_dim=20)
final_proj_V = weight_matrix(attn_dim)
# encode the full input sentence to get the hs we want to attend to
all_h = encoder(["NYU", "NLP", "is", "awesome"]
# greedy decoding 1 step at a time until end of sentence token
current_token = ''
while current_token != '':
# attend to the hs first
attn_energies =
for h in all_h:
attn_score = attention_mechanism([hrio鸡尾酒,current_token])
attn_score = tanh(attn_score)
attn_score肺癌症状 = final_proj_V.dot(attn_score)
# attn_score i风油精,当Attention遇上RNN:动画图解怎样运用attention构建Transformer,炸蘑菇s now a scalar (called an attn energy)
attn_energies.append(attn_score)
# turn the at避孕办法tention energies into weights by normalizing
attn_weights = softmax(attn_energies)
# attn_weights = [0.3, 0.2, 0.4, 0.1]

现在咱们有了权值,咱们运用它们来提取h,这或许与正在解码的特定token有关

context_vector = attn_weights.dot(all_h)
# this is now a vector which mixes a bit of all the h's

让咱们把它分红几个进程:

  1. 咱们编码了完好的输入序列,并生成了h的列表。
  2. 咱们开端解码,解码器运用贪心查找。
  3. 咱们没有把h4给解码器,而是给它一个上下文向量。
  4. 为了生成上下文向量,咱们运用另一个网络和可学习权值V来评价每个h与当时解码token的相关性。
  5. 咱们将这些留意力能量归一化,并运用它们将一切的h综合到一个h中,希望能捕捉到一切h的相关部分,即上下文向量
  6. 现在咱们再次履行解码进程,但这次运用上下文向量而不是h4。

Attention可视化

留意力权重通知咱们每个h有多重要。这意味着咱们还能够在每个解码进程中可视化权重。这里有一个比如,来自开始的留意力论文:

在榜首行中,为了翻译“L’”,网络在“the”这个词上运用了alpha,并将其他部分归零。

为了发生“economique”这个词,该网络实践上把alphas的一些权重放在了“European Economic”上,并将其他权重归零。这表明当翻译联系是多对一或一对多时,留意力是有用的。

Attention能够变得很杂乱

不同类型的Attention

这种类型的留意力只运用由编码器生成的h。有很多的研讨在改善这个进程。例如:

  1. 只运用其间一些h,或许是你当时解码的时刻步周围的那些h(部分留意)。
  2. 除了h的运用解码器现已生成的那些h,咱们之前扔掉了。
  3. ...

怎样核算attention energies

另一个研讨范畴是怎样核算留意力得分。除了和V做点积,研讨人员还尝试了:

  1. 对点积进行缩放。
  2. Cosine(s, h)
  3. 不运用V矩阵,而是将softmax王阳应用于全衔接层。风油精,当Attention遇上RNN:动画图解怎样运用attention构建Transformer,炸蘑菇
  4. ...

在核算attention energies的时分需求用些什么

这个研讨的最终一个范畴是研讨究竟该用什么来和h向量作比较。

为了给咱们对我要表达的意思有一些直观的知道,能够把核算留意力看作是一个键值字典。要害是要给你的留意力网络“查”到最相关的上下文。字典的值便是最相关的上下文。

我在这里描绘的办法只运用当时token和每个h来核算留意力得分。那便是:

# calculate how relevant that h is
score_1 = attn_netw风油精,当Attention遇上RNN:动画图解怎样运用attention构建Transformer,炸蘑菇ork([embed("
score_2 = attn_network([embed("
score_3 = attn_network([embed("
score_4 = attn_network([embed("

但实践上咱们能够给它任何咱们以为有用的东西来协助留意力网络做出最好的决议。或许我直插式们还能够给它最终一个上下文向量!

score_1 = attn_network([embed(""), h1, last_context])

或许咱们给它一些不同的东西,或许是一个token让它知道它在解码西班牙语

score_1 = attn_network([embed(""), h1, last_context, embed('')])

有无量多的或许性!

完成细节

假如你决议自己完成一下,这里有一些主张供你参阅。

Here are some tips to think about if you decide to implement your own.

  1. 运用Facebook的完成,这个的确优化的很好了。

好吧,那仅仅个托言。下面是一些实践的主张。

  1. 记住seq2seq有两个部分:解码器RNN和编码器RNN。这两个是分隔的。
  2. 大部分作业都用于构建解码器,编码器仅仅在整个输入序列上运转编码器。
  3. 记住,解码器RNN每次只履行一个时刻步。这是要害!
  4. 记住,解码器RNN每次只深圳市深迈医疗设备有限公司履行一个进程。重要的作业值得再说一遍:)
  5. 解码算法有两种挑选,贪心查找或beam search。贪心更简单完成,可是大多数时分,beam search会给你更好的成果。
  6. Attention是可选的!可是,当你用它的时分,影响是巨大的。
  7. Attention是一个独立的网络……把attention网络幻想成字典,其间的key是一组标签,你能够用来决议网络关于特定的h有多相关。
  8. 请记住,你正在核算每个h的留意力。这意味着你有一个for循环用于[h~1~,…,h~n~]。
  9. 留意网络嵌入的亮度能够恣意调高。这会炸掉ua你的内存。保证把它放在一个独自的GPU或坚持昏cure暗小。
  10. 让大型模型运转的一个技巧是将编码器放在一个gpu上,解码器放在第二个gpu上,留意力网络放在第三个gpu上。这样就能够坚持较低的内存占用。风油精,当Attention遇上RNN:动画图解怎样运用attention构建Transformer,炸蘑菇
  11. 假如要实践布置此模型,则需求批量完成它。我在这里解说的都是批量=1时的状况,可是你能够经过变换成张量积来扩展到更大的批量,而且要对线性代数很内行。

相同,在大多数状况下,你应该只运用开放源码完成,但这是一个很好的学习经历,能够自己试试!

Attention之后的日子

事实证明,留意力网络自身是十分强壮的。

样一来,研讨人员决议脱节RNNs和序列对序列的办法。相反,他们发明了一种叫做Transformer模型的东西。

在高层次上,transformer依然有一个编码器和解码器,仅仅各个层是全衔接的,并一起检查完好的输入。然后,当输入在网络中移动时,留意力就会会集在重要的作业上。

Transformer的图

这个模型现已在翻译中很大程度上替代了seq2seq模型,而且是当时最强壮的模型BERT和OpenAI的GPT的背面的模型。

英文原文:https://towardsdatascience.com/attention-craving-rnns-a-journey-into-attention-mechanisms-eec840fbc26f

更多内容,请重视微信大众号:AI公园

热门
最新
推荐
标签