我的原文:2019-CS224n-Assignment4

这一次的内容甚至可以作为一个项目了,我最终得到BLEU是22.66。

点击 这里 下载实验指导文档,这里 下载实验的预备代码

RNN和神经机器翻译

机器翻译是指,给定一个源句子(比如西班牙语),输出一个目标句子(比如英语)。本次作业中要实现的是一个带注意力机制的Seq2Seq神经模型,用于构建神经机器翻译(NMT)系统。首先我们来看NMT系统的训练过程,它用到了双向LSTM作为编码器(encoder)和单向LSTM作为解码器(decoder)。

mark

给定长度为m的源语言句子(source),经过嵌入层,得到输入序列 x1,x2,...,xm∈Re×1x_1, x_2, ..., x_m \in R^{e \times 1}x1,x2,...,xmRe×1,e是词向量大小。经过双向Encoder后,得到前向(→)和反向(←)LSTM的隐藏层和神经元状态,将两个方向的状态连接起来得到时间步 iii 的隐藏状态 hiench_i^{enc}hiencciencc_i^{enc}cienc

mark

接着我们使用一个线性层来初始化Decoder的初始隐藏、神经元的状态:

mark

Decoder的时间步 ttt 的输入为 yˉt\bar{y}_tyˉt ,它由目标语言句子 yty_tyt 和上一神经元的输出 ot−1o_{t-1}ot1 经过连接得到,o0o_0o0 是0向量,所以 $ \bar{y}_t \in R^{(e + h) \times 1}$

mark

接着我们使用 htdech^{dec}_thtdec 来计算在 h0enc,h1enc,...,hmench^{enc}_0, h^{enc}_1, ..., h^{enc}_mh0enc,h1enc,...,hmenc 的乘积注意力(multiplicative attention):

mark

然后将注意力 αt\alpha_tαt 和解码器的隐藏状态 htdech^{dec}_thtdec 连接,送入线性层,得到 combined-output 向量 oto_tot

mark

这样以来,目标词的概率分布则为:

mark

使用交叉熵做目标函数即可。

关键在于每个向量的维度,把维度搞清楚,整个过程就清晰了。

实现

在写完代码后,需要训练很久才能得到结果,这是因为翻译系统比较复杂,所以建议在GPU上跑,可以试试CoLab,而我是在实验室的TeslaP100上跑的,所以比较快。

问题(b)

model_embeddings.py的__init__函数:

self.source = nn.Embedding(len(vocab.src), embed_size, padding_idx=src_pad_token_idx)
self.target = nn.Embedding(len(vocab.tgt), embed_size, padding_idx=tgt_pad_token_idx)

注意一定要把padding_idx参数填进去

问题©

nmt_model.py的__init__函数:

self.encoder = nn.LSTM(embed_size, hidden_size, bias=True, bidirectional=True)
self.decoder = nn.LSTMCell(embed_size + hidden_size, hidden_size, bias=True)
self.h_projection = nn.Linear(2*hidden_size, hidden_size , bias=False)
self.c_projection = nn.Linear(2*hidden_size, hidden_size, bias=False)
self.att_projection = nn.Linear(2*hidden_size, hidden_size, bias=False)
self.combined_output_projection = nn.Linear(3*hidden_size, hidden_size, bias=False)
self.target_vocab_projection = nn.Linear(hidden_size, len(vocab.tgt), bias=False)
self.dropout = nn.Dropout(p=dropout_rate)

特别要注意各个维度的变化

原始的数据是词索引,经过embedding,每个词变成了大小为 embed_size 的向量,所以encoder的输入大小为 embed_size ,隐藏层大小为 hidden_size

decoder的输入是神经元输出和目标语言句子的嵌入向量,所以输入大小为 embed_size + hidden_size

h_projection、c_projection的作用是将encoder的隐藏层状态降维,所以输入大小是 2*hidden_size,输出大小是hidden_size

att_projection的作用也是降维,以便后续与decoder的隐藏层状态做矩阵乘法

combined_output_projection的作用也将解码输出降维,输入是注意力向量和隐藏层状态连接得到的向量,大小为3*hidden_size,并保持输出大小为 hidden_size

target_vocab_projection是将输出投影到词库的词中去

问题(d)

nmt_model.py 的encode函数:

X = self.model_embeddings.source(source_padded) # (src_len, b, e)
X = pack_padded_sequence(X, source_lengths)
enc_hiddens, (last_hidden, last_cell) = self.encoder(X) # hidden/cell = (2, b, h)
enc_hiddens = pad_packed_sequence(enc_hiddens)[0] # (src_len, b, 2*h)
enc_hiddens = enc_hiddens.permute(1, 0, 2) # (b, src_len, 2*h)init_decoder_hidden = self.h_projection(torch.cat((last_hidden[0], last_hidden[1]), dim=1))
init_decoder_cell = self.c_projection(torch.cat((last_cell[0], last_cell[1]), dim=1))
dec_init_state = (init_decoder_hidden, init_decoder_cell) # (b, h)

再次说明,一定要注意各个向量的维度。维度搞清楚了,过程就明了了。

这里用到了 padpack 两个概念。

pad :填充。将几个大小不一样的Tensor以最长的tensor长度为标准进行填充,一般是填充 0

pack:打包。将几个 tensor打包成一个,返回一个PackedSequence 对象。

经过pack后,RNN可以对不同长度的样本数据进行小批量训练,否则就只能一个一个样本进行训练了。

torch.cat 可以将两个tensor拼接成一个

torch.Tensor.permute 可以变换矩阵的维度比如 shape=(1,2,3) -> shape=(3,2,1)

问题(e)

nmt_model.py的decode函数:

enc_hiddens_proj = self.att_projection(enc_hiddens) # (b, src_len, h)
Y = self.model_embeddings.target(target_padded) # (tgt_len, b, e)
for Y_t in torch.split(Y, 1):Y_t = torch.squeeze(Y_t, dim=0) # (b, e)Ybar_t = torch.cat((Y_t, o_prev), dim=1) # (b, e + h)dec_state, o_t, e_t = self.step(Ybar_t, dec_state, enc_hiddens, enc_hiddens_proj, enc_masks)o_prev = o_tcombined_outputs.append(o_t)
combined_outputs = torch.stack(combined_outputs, dim=0) # (tgt_len, b, h)

还是强调一句,一定要注意向量的维度。

torch.stack 可以将一个list里的长度一样的tensor堆叠成一个tensor

torch.squeeze 可以将tensor里大小为1的维度给删掉,比如shape=(1,2,3) -> shape=(2,3)

问题(f)

nmt_model.py的step函数:

首先计算注意力系数

dec_state = self.decoder(Ybar_t, dec_state)
dec_hidden, dec_cell = dec_state # (b, h)
e_t = torch.bmm(enc_hiddens_proj, torch.unsqueeze(dec_hidden, dim=2)) # (b, src_len, 1)
e_t = torch.squeeze(e_t, dim=2) # (b, src_len)

接着计算注意力和combined output,并输出

alpha_t = torch.unsqueeze(F.softmax(e_t, dim=1), dim=1)
a_t = torch.squeeze(torch.bmm(alpha_t, enc_hiddens), dim=1) # (b, 2*h)
u_t = torch.cat((a_t, dec_hidden), dim=1) # (b, 3*h)
v_t = self.combined_output_projection(u_t) # (b, h)
O_t = self.dropout(torch.tanh(v_t))

一定要使用 torch.bmm小批量 数据进行矩阵乘法运算,不能用通常意义上的矩阵乘法

至此所有代码都写完了,运行

python sanity_check.py 1d
python sanity_check.py 1e
python sanity_check.py 1f

进行初步测试

完成后运行下述代码进行冒烟测试:

sh run.sh train_local

经过10或20次迭代后程序没崩,那就可以正式进行测试了:

sh run.sh train

参考资料

[1] CS224n: Natural Language Processing with Deep Learning, 2019-03-21.

2019-CS224n-Assignment4相关推荐

  1. CS224n Assignment4解读 · 上

    NMT中的一个问题 problem: 输入的句子长短不一,如果要将所有的长短的输入都提炼为同样长度的向量,是比较难的. solution: 实际工程中较多的会通过堆叠RNN来解决不定长的input s ...

  2. 2019 CS224N Assignment 1: Exploring Word Vectors

    文章目录 包的导入 Part 1: Count-Based Word Vectors Question 1.1: Implement distinct_words Question 1.2: Impl ...

  3. cs224n上完后会会获得证书吗_斯坦福NLP组-CS224n: NLP与深度学习-2019春全套资料分享...

    斯坦福自然语言处理小组2019年的最新课程<CS224n: NLP与深度学习>春季课程已经全部结束了,课程内容囊括了深度学习在各项NLP任务中应用的最新技术,非常值得一看.本文整理本期课程 ...

  4. CS224n 2019 Winter 笔记(一):Word Embedding:Word2vec and Glove

    CS224n笔记:Word2Vec:CBOW and Skip-Gram 摘要 一.语言模型(Language Model) (一)一元模型(Unary Language Model) (二)二元模型 ...

  5. Task 4: Contextual Word Embeddings (附代码)(Stanford CS224N NLP with Deep Learning Winter 2019)

    Task 4: Contextual Word Embeddings 目录 Task 4: Contextual Word Embeddings 词向量的表示 一.Peters et al. (201 ...

  6. CS224n 2019 Winter 笔记(三):句子依存分析(Dependency Parsing)

    CS224n 2019 Winter 笔记(三):句子依存分析(Dependency Parsing) 一.概述 二.语言结构的两种Views (一)成分分析(constituent parsing) ...

  7. cs224n 2019 Lecture 9: Practical Tips for Final Projects

    主要内容: 项目的选择:可以选择默认的问答项目,也可以自定义项目 如何发现自定义项目 如何找到数据集 门神经网络序列模型的复习 关于机器翻译的一些话题 查看训练结果和进行评估 一.项目的选择 默认项目 ...

  8. Task 2: Word Vectors and Word Senses (附代码)(Stanford CS224N NLP with Deep Learning Winter 2019)

    Task 2: Word Vectors and Word Senses 目录 Task 2: Word Vectors and Word Senses 一.词向量计算方法 1 回顾word2vec的 ...

  9. Task 3: Subword Models (附代码)(Stanford CS224N NLP with Deep Learning Winter 2019)

    Task 3: Subword Models 目录 Task 3: Subword Models 回顾:Word2vec & Glove 一.人类语言声音:语音学和音系学 二.字符级模型(Ch ...

  10. 【2019斯坦福CS224N笔记】(5)The probability of a sentence Recurrent Neural Networks and Language Models

    这部分内容主要研究语言模型及循环神经网络在语言模型中的应用. 目录 1.语言模型 2.经典n-gram模型 3.Window-based DNN 4.Recurrent Neural Networks ...

最新文章

  1. ajax 示例代码,Ajax的简单实用实例代码
  2. 0.IDA-基本的反汇编算法
  3. matlab幂法的瑞利商加速,瑞利商加速定理14.PPT
  4. 腾讯技术峰会:从模型部署到算法应用,云计算时代下的人工智能
  5. mgo和mongo-go-driver使用心得比较
  6. 禁用Win7自动更新后的重启提示
  7. JAVA小白启蒙篇:第一个SSM框架搭建示例(附源码下载)
  8. U大师U盘启动盘制作工具(V1.1.0版)——升级U盘
  9. unity shader可视化工具——Shader Graph
  10. Delphi教程推荐
  11. 怎样修改MTK Scatter 文件
  12. win10删除账户文件夹(C:\Users\***)后,无法登录账户的解决方法
  13. 绿皮车里的温馨服务 情暖回家路
  14. 脑部神经系统结构模式图,大脑的神经结构示意图
  15. 如何同时训练左手灵活性和音阶思维
  16. 网络安全规范(范例)
  17. 《算法竞赛入门经典(第2版)》——学习记录
  18. Linux tar命令详解
  19. C# Bitmap转Mat类型
  20. 【系统分析师之路】2015年系统分析师上午综合知识真题

热门文章

  1. Redis常用命令总结,java开发流程面试
  2. 对皮尔逊相关系数进行假设检验
  3. 3GPP LTE/NR信道模型
  4. al换脸一键生成_使用al生成详细的课程计划
  5. android刷步工具,公益步数刷步助手
  6. PHP-利用阿里云邮件推送免费发邮件详细步骤
  7. win7无法连接打印机拒绝访问_win7 无法连接到打印机 添加本地打印机拒绝访问 - 卡饭网...
  8. esp_wifi_repeater, 全功能WiFi中继器
  9. 几何学在计算机中应用,分形几何在计算机图形学中的应用
  10. jQuery实现选择“学科门类”、“学科大类(一级学科)”、“专业”(二级学科)实现三级联动