Neural Machine Translation by Jointly Learning to Align and Translate 的模型主要部分实现 TensorFlow

本文深入解析Seq2Seq模型及其注意力机制,探讨如何通过动态权重分配改善翻译精度,特别是在处理长句子时的对齐问题。通过实例代码,详细说明了如何在神经网络翻译中实现这一机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考github: https://github.com/graykode/nlp-tutorial?tdsourcetag=s_pctim_aiomsg中的seq2seq attention部分
就是读懂了他的代码又自己写了一遍

原理

整个的神经网络翻译的结构是seq2seq ,原句从encode部分进入,每一步都会输出一个状态hj,结合每一步的hj可以得到一个综合输入信息的山下文向量context vector c
用这个context vector可以传给decode部分,在decode的第i步,结合当前要参考的输入上下文向量、上一步输出的词yi-1和当前的decode输出状态可以预测当前的词汇yi
在这里插入图片描述
而当前的输出状态si由上一步的输出状态si-1,上一步的输出yi-1和当前的上下文向量共同决定
在这里插入图片描述
attention机制是作用在求这个context vector上。如果不考虑注意力机制,那么输入句子得到的上下文状态是一样的(可以认为每一步的hj权重都是1,求和得到总的向量),那么在翻译时,翻译每个词的时候参考的都是这个向量。
但是实际上翻译后的语言中的每个词对应着翻译前句子中的不同的词(或词组),比如中文的“啤酒”对应的其实是英文的“beer”一个词,那么在翻译时,“啤酒”和’beer"应该是对齐的,也就是翻译时应该分配更多的权重在beer上面

所以attention机制实质上就是对输入的h1…hT计算一个权重得分,最后的加权和就是为了翻译当前词yi的输入上下文向量ci
前面那个系数就是权重前面那个
在这里插入图片描述这实际是过了一个softmax,使得原始计算的得分加起来等于1,也就是权重,eij就是在decode第i步时对hj重要程度的打分
在这里插入图片描述
这里就是每一步的hj与每一步的decode si-1一个函数关系,在代码里为点乘(加系数)

代码

主要架构就是:

  • 准备参数和数据
  • 处理成批处理的数据
  • 计算attention的权重
  • encode-decode框架
  • feed数据训练和测试

参数和数据部分

由于不是重点,就只用一个数组存了三句话,分别是input,output和target
batch_size = 1,词表就是这个数组中全部的词(n_class),词的表示用的one-hot而不是embedding,每句话的最大长度也就是n_step = max_sent_len = 5; 隐藏状态数n_hidden = 128
在计算attention权重时用到两个参数,att_p : [n_hidden,n_hidden]和根据si-1和context_vector计算输出的时候用到的参数out_P :[2*n_hidden,n_class]

由于这里batch_size=1,所以处理成批处理的数据只是将单词转化为对应的id,然后在转化成词表长度的one-hot矩阵,最后加一层括号表示batchsize
encoder_inputs: [batch_size,max_sent_len,n_class]

计算attention权重

这包括两部分
一个是get_attn_score(dec_output,enc_output) 也就是计算原理中得分eij的部分
dec_output是decode每一步的输出,[batch_size,1,n_hidden]
这里的参数enc_output并非全部h,而是一步的输出hj
计算的方式是:dec_output,att_P,enc_output的点乘

另一部分是最红的结果,也就是每一步的权重全部返回:
get_attn_weights(dec_output,enc_output)
这里的enc_output: [batch_size,n_step,n_hidden] dec_output [batch_size, 1,n_hidden]
这里经过一些transpose变换,让enc_output变成[n_step,batch_size,n_hidden],这样就循环每一step,调用get_attn_score计算得分
最后将这些得分经过softmax得到归一化的权重返回

encode decode 框架

encode 部分比较简单:
就是准本一个cell
然后dynamic_rnn,得到enc_outputs和最后一步的状态enc_state
enc_ouputs, enc_state = tf.nn.dynamic_rnn(cell,inputs=encoder_inputs,dtype=tf.float32)
decode部分,要再次基础上对每一步计算权重分布,从而计算上下文向量,有了上下文向量和rnn的输出状态,才能计算最终的概率分布:

 for i in range(n_step):
        # dec_outputs: [batchsize,1,n_hidden]
        dec_outputs, dec_state = tf.nn.dynamic_rnn(cell=cell,inputs=tf.expand_dims(inputs[i],1),
                                                  initial_state=enc_state,dtype=tf.float32, time_major=True)
        attn_weights = get_attn_weights(dec_outputs,enc_ouputs)  
         # [batchsize,1,n_step] [batchsize,n_step,n_hidden] ==> [batchsize,1,n_hidden]
        context =  tf.matmul(attn_weights,enc_ouputs )
        context = tf.squeeze(context,axis=1)  # [batchsize,n_hidden]
        dec_outputs = tf.squeeze(dec_outputs,axis=1)
        concat = tf.concat((dec_outputs,context),axis=1)  # [batchsize,2*n_hidden]  [2*hidden,n_class]
        # [batchsize,n_class]
        model.append(tf.matmul(concat,out_P))

feed数据训练和测试

prediction = tf.argmax(model,2)
cost = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=model,labels=targets))
optimizer = tf.AdamOptimizer(lr).minimize(cost)
在Session里面
多个epoch,读入批处理的数据,喂进去,得到这里的cost和optimizer

测试部分就是上面填进去的数据不一样,训练prediction

具体代码可见:https://github.com/JoJoJun/NLP_Study.git

### 中国国标 GB/T 7714 参考文献格式规范 中国国家标准 GB/T 7714-2015 是针对参考文献著录的权威规范,适用于各类学术出版物。此标准规定了参考文献的编排方式、标注方法以及具体格式要求[^1]。 #### 基本格式要求 按照 GB/T 7714 的规定,参考文献应按文中引用次序排列,并采用阿拉伯数字加方括号的形式表示。以下是不同类型文献的具体格式: 1. **期刊文章** ``` [序号]作者. 题名[J]. 刊名, 年份, 卷(期): 起止页码. ``` 示例: ```plaintext [1]李四. 数据挖掘技术及其应用研究[J]. 计算机科学, 2020, 47(8): 123-129. ``` 2. **书籍** ``` [序号]作者. 书名[M]. 版本(第1版不标注). 出版地: 出版社, 出版年: 起止页码. ``` 示例: ```plaintext [2]王五. Python编程基础[M]. 北京: 清华大学出版社, 2019: 56-67. ``` 3. **学位论文** ``` [序号]作者. 题目[D]. 学校所在地: 授予单位, 年份. ``` 示例: ```plaintext [3]张三. 大数据环境下隐私保护机制的研究[D]. 上海: 复旦大学, 2021. ``` 4. **会议论文** ``` [序号]作者. 题名[C]//会议名称. 出版地: 出版者, 出版年: 起止页码. ``` 示例: ```plaintext [4]刘六. 新一代人工智能发展趋势[C]//国际人工智能大会. 杭州: 浙江科学技术出版社, 2022: 89-95. ``` 5. **电子资源** ``` [序号]主要责任者. 题名[EB/OL]. (发表日期)[引用日期]. 获取路径或URL地址. ``` 示例: ```plaintext [5]赵七. 开源软件的发展现状与未来趋势[EB/OL]. (2023-01-15)[2023-03-01]. https://www.example.com/article.html. ``` #### 使用工具实现自动排版 为了更高效地完成参考文献的格式化工作,可以利用专业的文献管理工具,例如 EndNote 或 Zotero。这些工具有助于快速生成符合 GB/T 7714 标准的参考文献列表[^2][^3]。 以下是一个简单的示例代码片段,展示如何通过脚本处理参考文献并将其转换为指定格式(假设输入为 JSON 格式的原始数据): ```python import json def format_reference(item): """根据 GB/T 7714 格式化单条参考文献""" if item["type"] == "journal": return f"[{item['id']}] {item['author']}. {item['title']}[J]. {item['journal']}, {item['year']}, {item['volume']}({item['issue']}): {item['pages']}." elif item["type"] == "book": edition = "" if not item.get("edition") or int(item["edition"]) == 1 else f"{item['edition']}版." return f"[{item['id']}] {item['author']}. {item['title']}[M]. {edition} {item['publisher_location']}: {item['publisher']}, {item['year']}: {item['pages']}." # 添加更多类型的格式化逻辑... # 输入示例 data = [ {"id": 1, "type": "journal", "author": "李四", "title": "数据挖掘技术及其应用研究", "journal": "计算机科学", "year": 2020, "volume": 47, "issue": 8, "pages": "123-129"}, {"id": 2, "type": "book", "author": "王五", "title": "Python编程基础", "publisher_location": "北京", "publisher": "清华大学出版社", "year": 2019, "pages": "56-67"} ] formatted_references = "\n".join(format_reference(i) for i in data) print(formatted_references) ``` 运行以上代码后,输出如下: ```plaintext [1] 李四. 数据挖掘技术及其应用研究[J]. 计算机科学, 2020, 47(8): 123-129. [2] 王五. Python编程基础[M]. 北京: 清华大学出版社, 2019: 56-67. ``` #### 注意事项 在实际操作中需要注意以下几点: - 如果存在多位作者,则需遵循“姓前名后”的原则,并用逗号分隔。 - 当作者超过三位时,可用“等”代替后续作者名单[^3]。 - 对于外文文献,“et al.”用于替代多余作者的名字。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值