将TensorFlow 1.0.12版Seq2Seq聊天机器人代码升级至1.7+
TensorFlow 1.0.12 to 1.7+ Seq2Seq Chatbot Code Adaptation
Hey there! Let's get your Seq2Seq chatbot code upgraded from TensorFlow 1.0.12 to 1.7+. The biggest changes come from TensorFlow's revamped tf.contrib.seq2seq API—old attention decoder functions were replaced with more modular wrapper classes. Below is the fully adapted code, along with clear explanations of the key changes.
Fully Adapted Code
import tensorflow as tf # Creating placeholders for the inputs and the targets def model_inputs(): inputs = tf.placeholder(tf.int32, [None, None], name='input') targets = tf.placeholder(tf.int32, [None, None], name='target') lr = tf.placeholder(tf.float32, name='learning_rate') keep_prob = tf.placeholder(tf.float32, name='keep_prob') sequence_length = tf.placeholder(tf.int32, [None], name='sequence_length') target_sequence_length = tf.placeholder(tf.int32, [None], name='target_sequence_length') return inputs, targets, lr, keep_prob, sequence_length, target_sequence_length # Preprocessing the targets def preprocess_targets(targets, word2int, batch_size): left_side = tf.fill([batch_size, 1], word2int['<SOS>']) right_side = tf.strided_slice(targets, [0, 0], [batch_size, -1], [1, 1]) preprocessed_targets = tf.concat([left_side, right_side], 1) return preprocessed_targets # Creating the Encoder RNN def encoder_rnn(rnn_inputs, rnn_size, num_layers, keep_prob, sequence_length): lstm = tf.contrib.rnn.BasicLSTMCell(rnn_size) lstm_dropout = tf.contrib.rnn.DropoutWrapper(lstm, input_keep_prob=keep_prob) encoder_cell = tf.contrib.rnn.MultiRNNCell([lstm_dropout] * num_layers) # Unpack bidirectional RNN outputs and states explicitly (encoder_fw_outputs, encoder_bw_outputs), (encoder_fw_state, encoder_bw_state) = tf.nn.bidirectional_dynamic_rnn( cell_fw=encoder_cell, cell_bw=encoder_cell, sequence_length=sequence_length, inputs=rnn_inputs, dtype=tf.float32 ) # Combine forward/backward outputs for attention, use forward state as decoder init (matches your original logic) encoder_outputs = tf.concat([encoder_fw_outputs, encoder_bw_outputs], axis=-1) encoder_state = encoder_fw_state return encoder_outputs, encoder_state # Helper to create attention-wrapped decoder cell def create_attention_decoder_cell(encoder_outputs, encoder_state, decoder_cell, rnn_size, sequence_length, keep_prob): # Bahdanau attention (matches your original "bahdanau" attention type) attention_mechanism = tf.contrib.seq2seq.BahdanauAttention( num_units=rnn_size, memory=encoder_outputs, memory_sequence_length=sequence_length ) # Wrap decoder cell with attention logic decoder_cell = tf.contrib.seq2seq.AttentionWrapper( cell=decoder_cell, attention_mechanism=attention_mechanism, attention_layer_size=rnn_size, name='attention_wrapper' ) # Initialize attention-wrapped cell state decoder_initial_state = decoder_cell.zero_state(batch_size=tf.shape(encoder_outputs)[0], dtype=tf.float32) decoder_initial_state = decoder_initial_state.clone(cell_state=encoder_state) return decoder_cell, decoder_initial_state # Decoding the training set def decode_training_set(encoder_outputs, encoder_state, decoder_cell, decoder_embedded_input, target_sequence_length, decoding_scope, output_function, keep_prob, sequence_length): decoder_cell, decoder_initial_state = create_attention_decoder_cell(encoder_outputs, encoder_state, decoder_cell, decoder_cell.output_size, sequence_length, keep_prob) # Training helper feeds ground-truth embeddings training_helper = tf.contrib.seq2seq.TrainingHelper( inputs=decoder_embedded_input, sequence_length=target_sequence_length, name='training_helper' ) # Basic decoder with attention wrapper training_decoder = tf.contrib.seq2seq.BasicDecoder( cell=decoder_cell, helper=training_helper, initial_state=decoder_initial_state, output_layer=output_function ) # Run dynamic decode for training decoder_outputs, _, _ = tf.contrib.seq2seq.dynamic_decode( decoder=training_decoder, scope=decoding_scope ) decoder_output_dropout = tf.nn.dropout(decoder_outputs.rnn_output, keep_prob) return output_function(decoder_output_dropout) # Decoding the test/validation set def decode_test_set(encoder_outputs, encoder_state, decoder_cell, decoder_embeddings_matrix, sos_id, eos_id, maximum_length, num_words, decoding_scope, output_function, keep_prob, sequence_length): decoder_cell, decoder_initial_state = create_attention_decoder_cell(encoder_outputs, encoder_state, decoder_cell, decoder_cell.output_size, sequence_length, keep_prob) # Greedy helper generates tokens one by one during inference test_helper = tf.contrib.seq2seq.GreedyEmbeddingHelper( embedding=decoder_embeddings_matrix, start_tokens=tf.fill([tf.shape(encoder_outputs)[0]], sos_id), end_token=eos_id ) # Basic decoder for inference test_decoder = tf.contrib.seq2seq.BasicDecoder( cell=decoder_cell, helper=test_helper, initial_state=decoder_initial_state, output_layer=output_function ) # Run dynamic decode with max iteration limit test_outputs, _, _ = tf.contrib.seq2seq.dynamic_decode( decoder=test_decoder, maximum_iterations=maximum_length, scope=decoding_scope ) return test_outputs.sample_id # Creating the Decoder RNN def decoder_rnn(decoder_embedded_input, decoder_embeddings_matrix, encoder_outputs, encoder_state, num_words, target_sequence_length, rnn_size, num_layers, word2int, keep_prob, sequence_length): with tf.variable_scope("decoding") as decoding_scope: lstm = tf.contrib.rnn.BasicLSTMCell(rnn_size) lstm_dropout = tf.contrib.rnn.DropoutWrapper(lstm, input_keep_prob=keep_prob) decoder_cell = tf.contrib.rnn.MultiRNNCell([lstm_dropout] * num_layers) # Modern dense layer for output projection weights = tf.truncated_normal_initializer(stddev=0.1) biases = tf.zeros_initializer() output_function = tf.layers.Dense( num_words, kernel_initializer=weights, bias_initializer=biases, name='output_layer' ) # Get training predictions training_predictions = decode_training_set(encoder_outputs, encoder_state, decoder_cell, decoder_embedded_input, target_sequence_length, decoding_scope, output_function, keep_prob, sequence_length) # Reuse variables for test inference decoding_scope.reuse_variables() # Get test predictions test_predictions = decode_test_set(encoder_outputs, encoder_state, decoder_cell, decoder_embeddings_matrix, word2int['<SOS>'], word2int['<EOS>'], target_sequence_length - 1, num_words, decoding_scope, output_function, keep_prob, sequence_length) return training_predictions, test_predictions # Building the seq2seq model (completed the unfinished original function) def seq2seq_model(inputs, targets, keep_prob, batch_size, sequence_length, target_sequence_length, answers_num_words, questions_num_words, encoder_embedding_size, decoder_embedding_size, rnn_size, num_layers, word2int): # Encoder embedding layer encoder_embeddings = tf.Variable(tf.random_uniform([questions_num_words, encoder_embedding_size], -1, 1)) encoder_embedded_input = tf.nn.embedding_lookup(encoder_embeddings, inputs) # Get encoder outputs and state encoder_outputs, encoder_state = encoder_rnn(encoder_embedded_input, rnn_size, num_layers, keep_prob, sequence_length) # Preprocess targets for training preprocessed_targets = preprocess_targets(targets, word2int, batch_size) # Decoder embedding layer decoder_embeddings = tf.Variable(tf.random_uniform([answers_num_words, decoder_embedding_size], -1, 1)) decoder_embedded_input = tf.nn.embedding_lookup(decoder_embeddings, preprocessed_targets) # Generate training and test predictions training_predictions, test_predictions = decoder_rnn(decoder_embedded_input, decoder_embeddings, encoder_outputs, encoder_state, answers_num_words, target_sequence_length, rnn_size, num_layers, word2int, keep_prob, sequence_length) return training_predictions, test_predictions
Key Changes Explained
- Added Critical Placeholders: We added
sequence_lengthandtarget_sequence_length—these are required by the new seq2seq helpers to handle variable-length sequences correctly. - Encoder RNN Refactor:
- Explicitly unpacked bidirectional RNN outputs and states for clarity. We kept using the forward state as the decoder initial state to match your original code's behavior.
- Returned combined encoder outputs (forward + backward) since the new attention mechanism needs access to all encoder hidden states.
- Attention Mechanism Overhaul:
- Replaced the deprecated
prepare_attentionandattention_decoder_fnfunctions withBahdanauAttention(matches your original attention type) andAttentionWrapper—this is the standard attention implementation in TF 1.7+.
- Replaced the deprecated
- Decoder Helpers:
TrainingHelperreplaces the old training decoder function—it feeds ground-truth embeddings during training.GreedyEmbeddingHelperreplaces the inference decoder function—it generates tokens greedily during test time.
- Unified Dynamic Decode:
tf.contrib.seq2seq.dynamic_decodereplacesdynamic_rnn_decoder—it handles both training and inference decoding in a consistent, modular way.
- Modern Output Layer:
- Switched from
tf.contrib.layers.fully_connectedtotf.layers.Densefor better consistency with TF 1.x's modern API.
- Switched from
内容的提问来源于stack exchange,提问作者Dilean Barroso
相关产品推荐
相关产品推荐

