Lingmoumou's Blog

きっといつかって愿うまま

0%

Task4 机器翻译及相关技术;注意力机制与Seq2seq模型;Transformer

机器翻译及相关技术

笔记整理

数据预处理

  1. 读取数据,处理数据中的编码问题,并将无效的字符串删除
  2. 分词,分词的目的就是将字符串转换成单词组成的列表。目前有很多现成的分词工具可以直接使用,也可以直接按照空格进行分词(不推荐,因为分词不是很准确)
  3. 建立词典,将单词组成的列表编程单词id组成的列表,这里会得到如下几样东西
    1. 去重后词典,及其中单词对应的索引列表
    2. 还可以得到给定索引找到其对应的单词的列表,以及给定单词得到对应索引的字典。
    3. 原始语料所有词对应的词典索引的列表
  4. 对数据进行padding操作。
  5. 制作数据生成器,但是需要注意的是对于翻译任务的数据格式,机器翻译的输入是一段文本序列,输出也是一段文本序列。

Seq2Seq模型的构建

  1. Seq2Seq模型由很多钟,但是整体框架都是基于先编码后解码的框架。也就是先对输入序列使用循环神经网络对他进行编码,编码成一个向量之后,再将编码得到的向量作为一个新的解码循环神经网络的隐藏状态的输入,进行解码,一次输出一个序列的元素,再将模型训练输出的序列元素与真实标签计算损失进行学习。
  2. 词嵌入,一般情况下输入到编码网络中的数据不是一个onehot向量而是经过了编码之后的向量,比如由word2vec技术,让编码后的向量由更加丰富的含义。
  3. 在进行编码和解码的过程中数据都是以时间步展开,也就是(Seq_len,)这种形式的数据进行处理的
  4. 对于编码与解码的循环神经网络,可以通过控制隐藏层的层数及每一层隐藏层神经元的数量来控制模型的复杂度
  5. 编码部分,RNN的用0初始化隐含状态,最后的输出主要是隐藏状态,编码RNN输出的隐含状态认为是其对应的编码向量
  6. 解码器的整体形状与编码器是一样的,只不过解码器的模型的隐藏状态是由编码器的输出的隐藏状态初始化的。

损失函数

  1. 解码器的输出是一个和词典维度相同的向量,其每个值对应与向量索引位置对应词的分数,一般是选择分数最大的那个词作为最终的输出。
  2. 在计算损失函数之前,要把padding去掉,因为padding的部分不参与计算

测试

  1. 解码器在测试的时候需要将模型的输出作为下一个时间步的输入
  2. Beam Search搜索算法。
    1. 假设预测的时候词典的大小为3,内容为a,b,c. beam size为2,解码的时候过程如下
    2. 生成第一个词的时候,选择概率最大的两个词,假设为a,c.那么当前的两个序列就是a和c。
    3. 生成第二个词的时候,将当前序列a和c,分别与此表中的所有词进行组合,得到新的6个序列aa ab ac ca cb cc,计算每个序列的得分,并选择得分最高的2个序列,作为新的当前序列,假如为aa cb
    4. 后面不断重复这个过程,直到遇到结束符或者达到最大长度为止,最终输出得分最高的2个序列。

想问问大家 做word_embedding 为什么会用到训练过程呀?一感觉就是一个词 转成 索引 再根据字典大小 转成词向量 ,字典大小应该是固定的,那不就可以直接得出,为何训练呢~ 类比前面学到的 把词转换成索引再转成one hot向量 (字符级时)

训练了才能获取嵌入词向量啊
通用任务是可以不训练,用别人训好的,但是要想取得更好的效果,最好还是在实际数据分布下训一个word-embedding“过拟合”一下。
举个形象点的例子,某一通用点的语料库上训的embedding可能在检测辱骂场景就很不好用,有些很关键的词分布是差异很大的,甚至没出现过。
假设使用one hot编码的话,那些词的表示是没有语义的,比如representation(男人) - representation(女人) = representation(男孩) - representation(女孩) 是得不到的。word embedding中最常见的word2vev使用语料库训练的时候,实际在进行两个事情,一个是根据前一个词猜后一个词,还有一个是某个词的上下文,也就是前后词猜中间这个。这样的方式得到表示会包含语义,但是也会有其他问题,所以word embedding也有很多不同的方法。

1.为何代码处source和target分别不同方式预处理数据(增加start/end),而不统一用True
src_array, src_valid_len = build_array(source, src_vocab, max_len, True)
tgt_array, tgt_valid_len = build_array(target, tgt_vocab, max_len, False)

2.如何设定max_len?
src_vocab, tgt_vocab, train_iter = load_data_nmt(batch_size=2, max_len=8)

3.在encoder和decoder会分别设置embedding层,如果导入已训练好的word embedding,希望参数不参加训练,该如何设置?

1.build_array中,你所说的True的parameter是is_source…所以在生成target数据的时候要设定为False。可以去看build_array函数的定义。
2.max_len的选取要看source和target数据集的句长统计. 可以选择所有句长平均值。
3.
self.embed = nn.Embedding(vocab_size, embedding_size)
self.embed.weight.data.copy_(torch.from_numpy(pretrained_embeddings))
self.embed.weight.requires_grad = False
这里pretrained_embeddings就是预训练好的词向量array

在进行word_embedding的时候应该要把参数padding_index设置为pad的token吧..这样pad对应的词向量就不会参与训练了?
是的,此时padding_idx所在的行初始化为0 ,并且不会反向传播

这里都默认大家知道lstm是什么了,然而我忘了。。。decoder的初始输入包含encoder最后一个hidden state以及一个memory cell
这个memory cell是什么?
memory cell就是LSTM的基本单元

注意力机制与Seq2seq模型

笔记整理

那个masked_softmax为什么要repeat?
X shape: (batch_size, seq_length, input_dim)
valid_length指一个sequence的有效长度,所以shape应该为(batch_size, seq_length)
当valid_length是一个1-D tensor的时候,表示同一个batch的每个sequence有效长度相同,因此要在同一batch内进行repeat

Transformer

笔记整理

我在transpose_qkv函数里输出原始的X的形状是[2,4,9]和注释里写的[batch_size,sql_len,hidden_sizenum_heads]不一样,,这是为什么?
MultiHeadAttention层初始化的hidden_size其实是hidden_size
num_heads
例子里num_heads=3, hidden_size=3,总的all_hidden_size=9