多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

序列到序列-seq2seq

序列到序列-seq2seq 编码器-解码器架构序列到序列问题的基础框架机器翻译是序列转换模型的一个核心问题 其输入和输出都是长度可变的序列编码器encoder 它接受一个长度可变的序列作为输入 并将其转换为具有固定形状的编码状态。解码器decoder 它将固定形状的编码状态映射到长度可变的序列。架构代码体现Encoder接收输入序列 X返回编码输出Decoder先用 init_state 接收编码器的状态再用 forward 逐步生成输出把前两者串联起来定义完整的数据流Seq2seq序列到序列学习核心思想是用两个循环神经网络RNN分别充当编码器和解码器以翻译模型为例特定的“eos”表示序列结束词元一旦输出序列生成此词元模型就会停止预测特定的“bos”表示序列开始词元它是解码器的输入序列的第一个词元。 其次使用循环神经网络编码器最终的隐状态来初始化解码器的隐状态。*训练翻译模型时因为知道具体的输入对应的输出可以在解码器部分连续的更新但是如果是句子推理模型就有点区别了衡量生成序列的好坏BLUEBLEU 通过比较预测序列与标签参考序列之间的n-gram 重叠程度来衡量生成质量。如何计算n-gram预测中某个 n-gram 的匹配次数不能超过它在标签中出现的次数【例】标签A,B,C,D,E,F 序列A,B,B,C,D计算n 1p1第二个B的匹配次数大于标签出现次数不能匹配当n2时p2如何计算BLUE左侧长度惩罚预测长度短于标签长度min会取负数exp一个负数就会降低分数其余min取0不会降低分数右侧加权几何平均具体的实现编码器RNN的实现嵌入层vocab_size 个词每个变成 embed_size 维向量把词元索引变成稠密向量*用低维稠密向量反应词义的远近随机的索引反应不出GRU 循环网络逐个读取词元更新隐状态最终把整句话压缩成一个状态向量X为输入一批句子每个句子有 num_steps 个词元索引embedding 嵌入后形状: (batch_size, num_steps, embed_size)output所有时间步的输出这里用不到state最后一个时间步的隐藏状态包含了对这个句子的最终理解解码器RNN的实现每个时间步t解码器输出yt的概率取决于1.已经生成的词y1,y2,...,yt′−1​2.上下文变量c 编码器给的整句语义因为要得到序列的输出所以相比于incoder多了一个dense层GRU 输入维度 embed_size num_hiddens初始的隐藏状态为incoder最后的输出statecontext state[-1].repeat(X.shape[0], 1, 1)# state[-1] 形状: (batch_size, num_hiddens) 最后一层的最终隐状态# repeat 后形状: (num_steps, batch_size, num_hiddens)为什么要repeat编码器的上下文c只有一个对应最后一个时间步但解码器要生成 num_steps 个词。每个时间步生成都需要看到源句子的语义所以把 c 复制 num_steps 次让每个时间步都能读到它。之前数据处理对于长度不足的数据进行了padding我们应该将填充词元的预测排除在损失函数的计算之外损失函数1.创建全1的权重矩阵和 label 形状相同2.用 sequence_mask 把填充位置置0有效位置1填充位置03设置 reductionnone让父类返回每个位置的损失4.计算交叉熵训练训练时解码器需要逐个词生成翻译。如果让模型自己生成第1步猜错了 - 第2步基于错误输入继续错 - 错误像滚雪球一样累积Teacher Forcing 的解决方案训练时解码器的输入不用模型自己生成的而是用真实标签ground truth。初始化参数优化器和损失函数按epoch训练构造一个bos列向量作为输入每个时间步解码器看到正确答案的上一词预测当前词。反向传播梯度裁剪参数更新预测和训练时最大的区别是没有 Teacher Forcing 了模型必须自己生成一个词再用这个词作为下一步的输入。核心部分BLUE的实现
返回列表