李沐66_使用注意力机制的seq2seq——自学笔记

news/2024/11/20 17:39:24/

加入注意力

1.编码器对每次词的输出作为key和value

2.解码器RNN对上一个词的输出是query

3.注意力的输出和下一个词的词嵌入合并进入RNN

一个带有Bahdanau注意力的循环神经网络编码器-解码器模型

总结

1.seq2seq通过隐状态在编码器和解码器中传递信息

2.注意力机制可以根据解码器RNN的输出来匹配到合适的编码器RNN的输出来更有效的传递信息。

python">pip install d2l==0.17.6  ### 很重要,不要下载错了,对于colab
python">import torch
from torch import nn
from d2l import torch as d2l

注意力解码器

AttentionDecoder类定义了带有注意力机制解码器的基本接口

python">class AttentionDecoder(d2l.Decoder):"""带有注意力机制解码器的基本接口"""def __init__(self, **kwargs):super(AttentionDecoder, self).__init__(**kwargs)@propertydef attention_weights(self):raise NotImplementedError

Seq2SeqAttentionDecoder类中 实现带有Bahdanau注意力的循环神经网络解码器。

1.编码器在所有时间步的最终层隐状态,将作为注意力的键和值;

2.上一时间步的编码器全层隐状态,将作为初始化解码器的隐状态;

3.编码器有效长度(排除在注意力池中填充词元)。

python">class Seq2SeqAttentionDecoder(AttentionDecoder):def __init__(self, vocab_size, embed_size, num_hiddens, num_layers,dropout=0, **kwargs):super(Seq2SeqAttentionDecoder, self).__init__(**kwargs)self.attention = d2l.AdditiveAttention(num_hiddens,num_hiddens,num_hiddens, dropout)self.embedding = nn.Embedding(vocab_size, embed_size)self.rnn = nn.GRU(embed_size + num_hiddens, num_hiddens, num_layers,dropout=dropout)self.dense = nn.Linear(num_hiddens, vocab_size)def init_state(self, enc_outputs, enc_valid_lens, *args):# outputs的形状为(batch_size,num_steps,num_hiddens).# hidden_state的形状为(num_layers,batch_size,num_hiddens)outputs, hidden_state = enc_outputsreturn (outputs.permute(1, 0, 2), hidden_state, enc_valid_lens)def forward(self, X, state):# enc_outputs的形状为(batch_size,num_steps,num_hiddens).# hidden_state的形状为(num_layers,batch_size,# num_hiddens)enc_outputs, hidden_state, enc_valid_lens = state# 输出X的形状为(num_steps,batch_size,embed_size)X = self.embedding(X).permute(1, 0, 2)outputs, self._attention_weights = [], []for x in X:# query的形状为(batch_size,1,num_hiddens)query = torch.unsqueeze(hidden_state[-1], dim=1)# context的形状为(batch_size,1,num_hiddens)context = self.attention(query, enc_outputs, enc_outputs, enc_valid_lens)# 在特征维度上连结x = torch.cat((context, torch.unsqueeze(x, dim=1)), dim=-1)# 将x变形为(1,batch_size,embed_size+num_hiddens)out, hidden_state = self.rnn(x.permute(1, 0, 2), hidden_state)outputs.append(out)self._attention_weights.append(self.attention.attention_weights)# 全连接层变换后,outputs的形状为# (num_steps,batch_size,vocab_size)outputs = self.dense(torch.cat(outputs, dim=0))return outputs.permute(1, 0, 2), [enc_outputs, hidden_state,enc_valid_lens]@propertydef attention_weights(self):return self._attention_weights

使用包含7个时间步的4个序列输入的小批量测试Bahdanau注意力解码器。

python">encoder = d2l.Seq2SeqEncoder(vocab_size=10, embed_size=8, num_hiddens=16,num_layers=2)
encoder.eval()
decoder = Seq2SeqAttentionDecoder(vocab_size=10, embed_size=8, num_hiddens=16,num_layers=2)
decoder.eval()
X = d2l.zeros((4, 7), dtype=torch.long)  # (batch_size,num_steps)
state = decoder.init_state(encoder(X), None)
output, state = decoder(X, state)
output.shape, len(state), state[0].shape, len(state[1]), state[1][0].shape
(torch.Size([4, 7, 10]), 3, torch.Size([4, 7, 16]), 2, torch.Size([4, 16]))

实例化一个带有Bahdanau注意力的编码器和解码器, 并对这个模型进行机器翻译训练。

python">embed_size, num_hiddens, num_layers, dropout = 32, 32, 2, 0.1
batch_size, num_steps = 64, 10
lr, num_epochs, device = 0.005, 250, d2l.try_gpu()train_iter, src_vocab, tgt_vocab = d2l.load_data_nmt(batch_size, num_steps)
encoder = d2l.Seq2SeqEncoder(len(src_vocab), embed_size, num_hiddens, num_layers, dropout)
decoder = Seq2SeqAttentionDecoder(len(tgt_vocab), embed_size, num_hiddens, num_layers, dropout)
net = d2l.EncoderDecoder(encoder, decoder)
d2l.train_seq2seq(net, train_iter, lr, num_epochs, tgt_vocab, device)
loss 0.020, 7390.3 tokens/sec on cuda:0

在这里插入图片描述

模型训练后,我们用它将几个英语句子翻译成法语并计算它们的BLEU分数。

python">engs = ['go .', "i lost .", 'he\'s calm .', 'i\'m home .']
fras = ['va !', 'j\'ai perdu .', 'il est calme .', 'je suis chez moi .']
for eng, fra in zip(engs, fras):translation, dec_attention_weight_seq = d2l.predict_seq2seq(net, eng, src_vocab, tgt_vocab, num_steps, device, True)print(f'{eng} => {translation}, ',f'bleu {d2l.bleu(translation, fra, k=2):.3f}')
go . => va !,  bleu 1.000
i lost . => j'ai perdu .,  bleu 1.000
he's calm . => il est mouillé .,  bleu 0.658
i'm home . => je suis chez moi .,  bleu 1.000
python">attention_weights = torch.cat([step[0][0][0] for step in dec_attention_weight_seq], 0).reshape((1, 1, -1, num_steps))

训练结束后,下面通过可视化注意力权重 会发现,每个查询都会在键值对上分配不同的权重,这说明 在每个解码步中,输入序列的不同部分被选择性地聚集在注意力池中。

python"># 加上一个包含序列结束词元
d2l.show_heatmaps(attention_weights[:, :, :, :len(engs[-1].split()) + 1].cpu(),xlabel='Key positions', ylabel='Query positions')

在这里插入图片描述


http://www.ppmy.cn/news/1443601.html

相关文章

21 Debian如何配置Apache2(1)配置文件摊开看

作者:网络傅老师 特别提示:未经作者允许,不得转载任何内容。违者必究! Debian如何配置DNS服务(2)主从服务器 《傅老师Debian小知识库系列之20》——原创 前言 傅老师Debian小知识库特点: 1、…

OpenCV如何模板匹配

返回:OpenCV系列文章目录(持续更新中......) 上一篇:OpenCV如何实现背投 下一篇 :OpenCV在图像中寻找轮廓 目标 在本教程中,您将学习如何: 使用 OpenCV 函数 matchTemplate()搜索图像贴片和输入图像之间…

STM32中UART通信的完整C语言代码范例

UART(通用异步收发器)是STM32微控制器中常用的外设,用于与其他设备进行串行通信。本文将提供一个完整的C语言代码范例,演示如何在STM32中使用UART进行数据传输。 硬件配置 在开始编写代码之前,需要确保以下硬件配置&…

聚观早报 | 生数科技推出Vidu;2024款欧拉好猫正式上市

聚观早报每日整理最值得关注的行业重点事件,帮助大家及时了解最新行业动态,每日读报,就读聚观365资讯简报。 整理丨Cutie 4月28日消息 生数科技推出Vidu 2024款欧拉好猫正式上市 雷诺与小米汽车洽谈技术合作 微软张祺谈未来AI如何发展 …

Mac环境安装任意版本的node

背景 由于在使用node的时候需要频繁的切换node的版本。在windows上可以通过安装不同版本的软件进行实现,在mac上可以更加方便快捷的实现这个过程哦! 全局安装n npm install -g n选择不同的版本 # 安装最新稳定版 node n stable # 安装最新版本 node …

商城数据库(77-80)

77——店铺职员表(wang_shop_users) CREATE TABLE wang_shop_users (id int(11) NOT NULL AUTO_INCREMENT COMMENT 自增ID,shopld int(11) NOT NULL DEFAULT 0 COMMENT 店铺ID,userld int(11) NOT NULL DEFAULT 0 COMMENT 用户ID,roleld int(11) NOT NU…

富格林:虚假交易明晰安全应对方法

富格林悉知,在金融市场中,炒黄金作为一种广受欢迎的投资方式,凭借其避险属性和潜在收益吸引了众多投资者。然而在想要取得不错的投资收益,投资者不仅要对市场深入的学习理解,还需要遵循一系列投资原则已经做好风险控制…

探索洗牌算法的魅力与杨辉三角的奥秘:顺序表的实际运用

目录 目录 前言~🥳🎉🎉🎉 洗牌算法 准备工作 买一副牌 洗牌 发牌 测试整体 🎯🎯很重要的一点 杨辉三角 总结 前言~🥳🎉🎉🎉 Hello, Hello~ …