You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将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_length and target_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_attention and attention_decoder_fn functions with BahdanauAttention (matches your original attention type) and AttentionWrapper—this is the standard attention implementation in TF 1.7+.
  • Decoder Helpers:
    • TrainingHelper replaces the old training decoder function—it feeds ground-truth embeddings during training.
    • GreedyEmbeddingHelper replaces the inference decoder function—it generates tokens greedily during test time.
  • Unified Dynamic Decode:
    • tf.contrib.seq2seq.dynamic_decode replaces dynamic_rnn_decoder—it handles both training and inference decoding in a consistent, modular way.
  • Modern Output Layer:
    • Switched from tf.contrib.layers.fully_connected to tf.layers.Dense for better consistency with TF 1.x's modern API.

内容的提问来源于stack exchange,提问作者Dilean Barroso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:19:11