import sys
import codecs
import tensorflow as tf # 1.参数设置。
# 读取checkpoint的路径。9000表示是训练程序在第9000步保存的checkpoint。
CHECKPOINT_PATH = "F:\\temp\\attention_ckpt-9000" # 模型参数。必须与训练时的模型参数保持一致。
HIDDEN_SIZE = 1024 # LSTM的隐藏层规模。
DECODER_LAYERS = 2 # 解码器中LSTM结构的层数。
SRC_VOCAB_SIZE = 10000 # 源语言词汇表大小。
TRG_VOCAB_SIZE = 4000 # 目标语言词汇表大小。
SHARE_EMB_AND_SOFTMAX = True # 在Softmax层和词向量层之间共享参数。 # 词汇表文件
SRC_VOCAB = "F:\\TensorFlowGoogle\\201806-github\\TensorFlowGoogleCode\\Chapter09\\en.vocab"
TRG_VOCAB = "F:\\TensorFlowGoogle\\201806-github\\TensorFlowGoogleCode\\Chapter09\\zh.vocab" # 词汇表中<sos>和<eos>的ID。在解码过程中需要用<sos>作为第一步的输入,并将检查
# 是否是<eos>,因此需要知道这两个符号的ID。
SOS_ID = 1
EOS_ID = 2
# 2.定义NMT模型和解码步骤。
# 定义NMTModel类来描述模型。
class NMTModel(object):
# 在模型的初始化函数中定义模型要用到的变量。
def __init__(self):
# 定义编码器和解码器所使用的LSTM结构。
self.enc_cell_fw = tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE)
self.enc_cell_bw = tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE)
self.dec_cell = tf.nn.rnn_cell.MultiRNNCell([tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE) for _ in range(DECODER_LAYERS)]) # 为源语言和目标语言分别定义词向量。
self.src_embedding = tf.get_variable("src_emb", [SRC_VOCAB_SIZE, HIDDEN_SIZE])
self.trg_embedding = tf.get_variable("trg_emb", [TRG_VOCAB_SIZE, HIDDEN_SIZE]) # 定义softmax层的变量
if SHARE_EMB_AND_SOFTMAX:
self.softmax_weight = tf.transpose(self.trg_embedding)
else:
self.softmax_weight = tf.get_variable("weight", [HIDDEN_SIZE, TRG_VOCAB_SIZE])
self.softmax_bias = tf.get_variable("softmax_bias", [TRG_VOCAB_SIZE]) def inference(self, src_input):
# 虽然输入只有一个句子,但因为dynamic_rnn要求输入是batch的形式,因此这里
# 将输入句子整理为大小为1的batch。
src_size = tf.convert_to_tensor([len(src_input)], dtype=tf.int32)
src_input = tf.convert_to_tensor([src_input], dtype=tf.int32)
src_emb = tf.nn.embedding_lookup(self.src_embedding, src_input) with tf.variable_scope("encoder"):
# 使用bidirectional_dynamic_rnn构造编码器。这一步与训练时相同。
enc_outputs, enc_state = tf.nn.bidirectional_dynamic_rnn(self.enc_cell_fw, self.enc_cell_bw, src_emb, src_size, dtype=tf.float32)
# 将两个LSTM的输出拼接为一个张量。
enc_outputs = tf.concat([enc_outputs[0], enc_outputs[1]], -1) with tf.variable_scope("decoder"):
# 定义解码器使用的注意力机制。
attention_mechanism = tf.contrib.seq2seq.BahdanauAttention(HIDDEN_SIZE, enc_outputs,memory_sequence_length=src_size) # 将解码器的循环神经网络self.dec_cell和注意力一起封装成更高层的循环神经网络。
attention_cell = tf.contrib.seq2seq.AttentionWrapper(self.dec_cell, attention_mechanism,attention_layer_size=HIDDEN_SIZE) # 设置解码的最大步数。这是为了避免在极端情况出现无限循环的问题。
MAX_DEC_LEN=100 with tf.variable_scope("decoder/rnn/attention_wrapper"):
# 使用一个变长的TensorArray来存储生成的句子。
init_array = tf.TensorArray(dtype=tf.int32, size=0,dynamic_size=True, clear_after_read=False)
# 填入第一个单词<sos>作为解码器的输入。
init_array = init_array.write(0, SOS_ID)
# 调用attention_cell.zero_state构建初始的循环状态。循环状态包含
# 循环神经网络的隐藏状态,保存生成句子的TensorArray,以及记录解码
# 步数的一个整数step。
init_loop_var = (attention_cell.zero_state(batch_size=1, dtype=tf.float32),init_array, 0) # tf.while_loop的循环条件:
# 循环直到解码器输出<eos>,或者达到最大步数为止。
def continue_loop_condition(state, trg_ids, step):
return tf.reduce_all(tf.logical_and(tf.not_equal(trg_ids.read(step), EOS_ID),tf.less(step, MAX_DEC_LEN-1))) def loop_body(state, trg_ids, step):
# 读取最后一步输出的单词,并读取其词向量。
trg_input = [trg_ids.read(step)]
trg_emb = tf.nn.embedding_lookup(self.trg_embedding,trg_input)
# 调用attention_cell向前计算一步。
dec_outputs, next_state = attention_cell.call(state=state, inputs=trg_emb)
# 计算每个可能的输出单词对应的logit,并选取logit值最大的单词作为
# 这一步的而输出。
output = tf.reshape(dec_outputs, [-1, HIDDEN_SIZE])
logits = (tf.matmul(output, self.softmax_weight)+ self.softmax_bias)
next_id = tf.argmax(logits, axis=1, output_type=tf.int32)
# 将这一步输出的单词写入循环状态的trg_ids中。
trg_ids = trg_ids.write(step+1, next_id[0])
return next_state, trg_ids, step+1 # 执行tf.while_loop,返回最终状态。
state, trg_ids, step = tf.while_loop(continue_loop_condition, loop_body, init_loop_var)
return trg_ids.stack()
# 3.翻译一个测试句子。
def main():
# 定义训练用的循环神经网络模型。
with tf.variable_scope("nmt_model", reuse=None):
model = NMTModel() # 定义个测试句子。
test_en_text = "This is a test . <eos>"
print(test_en_text) # 根据英文词汇表,将测试句子转为单词ID。
with codecs.open(SRC_VOCAB, "r", "utf-8") as f_vocab:
src_vocab = [w.strip() for w in f_vocab.readlines()]
src_id_dict = dict((src_vocab[x], x) for x in range(len(src_vocab)))
test_en_ids = [(src_id_dict[token] if token in src_id_dict else src_id_dict['<unk>'])for token in test_en_text.split()]
print(test_en_ids) # 建立解码所需的计算图。
output_op = model.inference(test_en_ids)
sess = tf.Session()
saver = tf.train.Saver()
saver.restore(sess, CHECKPOINT_PATH) # 读取翻译结果。
output_ids = sess.run(output_op)
print(output_ids) # 根据中文词汇表,将翻译结果转换为中文文字。
with codecs.open(TRG_VOCAB, "r", "utf-8") as f_vocab:
trg_vocab = [w.strip() for w in f_vocab.readlines()]
output_text = ''.join([trg_vocab[x] for x in output_ids]) # 输出翻译结果。
print(output_text.encode('utf8').decode(sys.stdout.encoding))
sess.close() if __name__ == "__main__":
main()

吴裕雄--天生自然 pythonTensorFlow自然语言处理:Attention模型--测试的更多相关文章

  1. 吴裕雄--天生自然 pythonTensorFlow自然语言处理:Attention模型--训练

    import tensorflow as tf # 1.参数设置. # 假设输入数据已经转换成了单词编号的格式. SRC_TRAIN_DATA = "F:\\TensorFlowGoogle ...

  2. 吴裕雄--天生自然 pythonTensorFlow自然语言处理:Seq2Seq模型--训练

    import tensorflow as tf # 1.参数设置. # 假设输入数据已经用9.2.1小节中的方法转换成了单词编号的格式. SRC_TRAIN_DATA = "F:\\Tens ...

  3. 吴裕雄--天生自然 pythonTensorFlow自然语言处理:Seq2Seq模型--测试

    import sys import codecs import tensorflow as tf # 1.参数设置. # 读取checkpoint的路径.9000表示是训练程序在第9000步保存的ch ...

  4. 吴裕雄--天生自然 pythonTensorFlow自然语言处理:PTB 语言模型

    import numpy as np import tensorflow as tf # 1.设置参数. TRAIN_DATA = "F:\TensorFlowGoogle\\201806- ...

  5. 吴裕雄--天生自然 pythonTensorFlow自然语言处理:文本数据预处理--生成训练文件

    import sys import codecs # 1. 参数设置 MODE = "PTB_TRAIN" # 将MODE设置为"PTB_TRAIN", &qu ...

  6. 吴裕雄--天生自然 pythonTensorFlow自然语言处理:交叉熵损失函数

    import tensorflow as tf # 1. sparse_softmax_cross_entropy_with_logits样例. # 假设词汇表的大小为3, 语料包含两个单词" ...

  7. 吴裕雄--天生自然 pythonTensorFlow图形数据处理:循环神经网络预测正弦函数

    import numpy as np import tensorflow as tf import matplotlib.pyplot as plt # 定义RNN的参数. HIDDEN_SIZE = ...

  8. 吴裕雄--天生自然 pythonTensorFlow图形数据处理:数据集高层操作

    import tempfile import tensorflow as tf # 1. 列举输入文件. # 输入数据生成的训练和测试数据. train_files = tf.train.match_ ...

  9. 吴裕雄--天生自然 pythonTensorFlow图形数据处理:数据集基本使用方法

    import tempfile import tensorflow as tf # 1. 从数组创建数据集. input_data = [1, 2, 3, 5, 8] dataset = tf.dat ...

随机推荐

  1. EUI库 - 概述

        新特性 36k   访问EUI组件宽高时,也会跟原生显示对象的表现一致,立即能得到包含子项的宽高值   统一的显示列表  普通对象和eui对象都可用addChild来添加   一个逻辑组件只管 ...

  2. Maven:Unable to import maven project: See logs for details

    一.开发环境 idea2019.1 + apache-maven-3.6.2 + JDK 1.8.0_111 二.问题说明 导入maven 多模块工程之后,发现工程没有多模块的展开,而且也没有在 Ex ...

  3. WordPress站点绑定多个域名

    refer to https://blog.csdn.net/wzl505/article/details/54970321 打开根目录下的 wp-config.php 文件,找到 require_o ...

  4. C++程序--helloworld

    #include<iostream>using namespace std; int main(){ cout << "hello world!" < ...

  5. convolution in frequency domain

    https://blog.csdn.net/myjiayan/article/details/72427995 convolution in frequency domain convolution ...

  6. C语言之结构体概述

    C语言之结构体概述1.结构体类型是一种自定义类型(1)C语言中有2种类型:原生类型和自定义类型.2.结构体使用时先定义结构体类型再用类型定义变量(1)结构体定义时需要先定义结构体类型,再用类型来定义变 ...

  7. Firefly-RK3399 上编译安装 OpenCV 3

    原文转自:http://dev.t-firefly.com/thread-12143-1-1.html OS:官方固件 Xubuntu 16.04 1) Install 1.1) Required P ...

  8. C++交换两个变量值的方法

    简单地列一下交换两个变量值地几种方法. 1.通过第三方实现,这一种也是最最最常见普通的方法: void swap(int *a, int *b) { int tmp = *a; *a = *b; *b ...

  9. [Qt5] QSlider设置步长

    这是一个小问题,就是QSlider是一个滑动条控件,既然是个滑动条控件,就会想要用鼠标滚轮或者鼠标去移动它来实现某些功能,但是呢,我能说这个控件的一个属性函数设置也是比较奇怪的,它设置步长的函数有 s ...

  10. java线程——线程局部变量

    一,线程局部变量ThreadLocal的作用 用于实现线程内部的数据共享,既对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,在另一个线程访问的时候,访问的由是另一份数据. 每个线程调用 ...