import numpy as np
import tensorflow as tf
from tensorflow import layers
from tensorflow.python.ops import array_ops
from tensorflow.contrib import seq2seq
from tensorflow.contrib.seq2seq import BahdanauAttention
from tensorflow.contrib.seq2seq import LuongAttention
from tensorflow.contrib.seq2seq import AttentionWrapper
from tensorflow.contrib.seq2seq import BeamSearchDecoder
from tensorflow.contrib.rnn import LSTMCell
from tensorflow.contrib.rnn import GRUCell
from tensorflow.contrib.rnn import MultiRNNCell
from tensorflow.contrib.rnn import DroputWrapper
from tensorflow.contrib.rnn import ResidualWrapper
from word_sequence import WordSequence
from data_utils import _get_embed_device
class SequenceToSequence(object):
"""
基本流程
__init__基本参数的保存,参数验证(验证参数的合法性)
build_model 构建模型
init_placeholders初始化一些TensorFlow的变量的占位符
build_encoder初始化编码器
build_single_cell
build_decoder_cell
init_optimizer如果是在训练模式下进行,那么则需要初始化优化器
train训练一个batch数据
predict预测一个batch数据
"""
def __init__(self,
input_vocab_size, #输入词表的大小
target_vocab_size, #输出词表的大小
batch_size=32, #数据batch的大小
embedding_size=300, #输入词表与输出词表embedding的维度
mode='train', #取值为train,代表训练模式,取值为decode,代表是预训练模式
hidden_units=256, #RNN模型的中间层大小,encoder和decoder层相同
depth=1, #encoder和decoder的RNN层数
beam_width=0, #是beamsearch的超参数,用于解码
cell_type='lstm', #RNN的神经元类型,lstm, gru
dropout=0.2, #随机丢弃数据的比例,是要0到1之间
use_dropout=False, #是否使用dropout
use_residual=False, #是否使用residual
optimizer='adam', #使用哪一个优化器
learning_rate=1e-3, #学习率
min_learning_rate=1e-6, #最小学习率
decay_steps=50000, #衰减步数
max_gradient_norm=5.0, #梯度正则裁剪的系数
max_decode_step=None, #最大decode长度,可以非常大
attention_type='Bahdanau', #使用attention类型
bidirectional=False, #是否双向的encoder
time_major=False, #是否在计算过程中使用时间作为主要的批量数据
seed=0, #一些层间的操作的随机数
parallel_iterations=None, #并行执行RNN循环的个数
share_embedding=False, #是否让encoder和decoder公用一个embedding
pretrained_embedding=False): # 是不是要使用预训练的embedding
self.input_vocab_size=input_vocab_size
self.target_vocab_size=target_vocab_size
self.batch_size=batch_size
self.embedding_size=embedding_size
self.hidden_units=hidden_units
self.depth=depth
self.cell_type=cell_type.lower()
self.use_dropout=use_dropout
self.use_residual=use_residual
self.attention_type=attention_type
self.mode=mode
self.optimizer=optimizer
self.learning_rate=learning_rate
self.min_learning_rate=min_learning_rate
self.decay_steps=decay_steps
self.max_gradient_norm=max_gradient_norm
self.keep_prob=1.0-dropout
self.bidirectional=bidirectional
self.seed=seed
self.pretrain_embedding=pretrained_embedding
if isinstance(parallel_iterations, int):
self.parallel_interations=parallel_iterations
else:
self.parallel_interations=batch_size
self.time_major=time_major
self.share_embedding=share_embedding
#生成均匀分布的随机数,有四个参数,最小值、最大值、随机种子数(可以为空),类型
self.initializer=tf.random_uniform_initializer(
-0.05,0.05,dtype=tf.float32
)
assert self.cell_type in ('gru','lstm'),'cell type应该是GRU或者LSTM'
if share_embedding:
assert input_vocab_size==target_vocab_size, '如果share_embedding为True,那么两个vocab_size必须一样'
assert mode in ('train','decode'),'mode必须是train,或者是decode,而不是{}'.format(mode)
assert dropout >=0.0 and dropout<1.0, 'dropout 必须大于等于0且小于等于1'
assert attention_type.lower() in ('bahdanau','luong'),'attention_type必须是bahdanau或者是luong,而不是{}'.format(attention_type)
assert beam_width<target_vocab_size, 'beam_width{}应该小于target_vocabsize{}'.fromat(beam_width,target_vocab_size)
self.keep_prob_placeholder=tf.placeholder(
tf.float32,
shape=[],
name='keep_prob'
)
self.global_step=tf.Variable(
0,trainable=False, name='global_step'
)
self.use_beamsearch_decode=False
self.beam_width=beam_width
self.use_beamsearch_decode=True if self.beam_width >0 else False
self.max_decode_step=max_decode_step
assert self.optimizer.lower() in ('adaelta','adam','rmsprop','momentum','sgd'),\
'optimizer必须是下列之一;adaelta, adam, rmsprop, momentum, sgd'
self.build_model()
def build_model(self):