2016-03-07 21 views
5

Tôi đang đào tạo một ô LSTM trên các chuỗi các trình tự có độ dài khác nhau. Các tf.nn.rnn có tham số rất thuận tiện sequence_length, nhưng sau khi gọi nó, tôi không biết làm thế nào để chọn các hàng đầu ra tương ứng với bước thời gian cuối cùng của mỗi mục trong lô.Cách chọn giá trị đầu ra hợp lệ cuối cùng từ tensorflow RNN

Mã của tôi về cơ bản là như sau:

lstm_cell = tf.nn.rnn_cell.LSTMCell(num_lstm_units, input_size) 
lstm_outputs, state = tf.nn.rnn(lstm_cell, input_list, dtype=tf.float32, sequence_length=sequence_lengths) 

lstm_outputs là một danh sách với sản lượng LSTM tại mỗi bước. Tuy nhiên, mỗi mục trong nhóm của tôi có độ dài khác nhau, và vì vậy tôi muốn tạo một tensor chứa đầu ra LSTM cuối cùng hợp lệ cho mỗi mục trong lô của tôi.

Nếu tôi có thể sử dụng chỉ mục NumPy, tôi sẽ chỉ làm điều gì đó như thế này:

all_outputs = tf.pack(lstm_outputs) 
last_outputs = all_outputs[sequence_lengths, tf.range(batch_size), :] 

Nhưng nó chỉ ra rằng trong thời gian này bắt đầu tensorflow không hỗ trợ nó (tôi nhận thức được feature request) .

Vì vậy, làm cách nào tôi có thể nhận được các giá trị này?

Trả lời

5

Cách giải quyết khác có thể chấp nhận được xuất bản bởi danijar trên trang yêu cầu tính năng tôi đã liên kết trong câu hỏi. Nó không cần phải đánh giá các tensors, đó là một cộng lớn.

Tôi đã làm cho nó hoạt động với lưu lượng 0,8. Đây là mã:

def extract_last_relevant(outputs, length): 
    """ 
    Args: 
     outputs: [Tensor(batch_size, output_neurons)]: A list containing the output 
      activations of each in the batch for each time step as returned by 
      tensorflow.models.rnn.rnn. 
     length: Tensor(batch_size): The used sequence length of each example in the 
      batch with all later time steps being zeros. Should be of type tf.int32. 

    Returns: 
     Tensor(batch_size, output_neurons): The last relevant output activation for 
      each example in the batch. 
    """ 
    output = tf.transpose(tf.pack(outputs), perm=[1, 0, 2]) 
    # Query shape. 
    batch_size = tf.shape(output)[0] 
    max_length = int(output.get_shape()[1]) 
    num_neurons = int(output.get_shape()[2]) 
    # Index into flattened array as a workaround. 
    index = tf.range(0, batch_size) * max_length + (length - 1) 
    flat = tf.reshape(output, [-1, num_neurons]) 
    relevant = tf.gather(flat, index) 
    return relevant 
2

Nó không phải là giải pháp tốt nhất nhưng bạn có thể đánh giá kết quả đầu ra của bạn sau đó chỉ cần sử dụng chỉ mục numpy để có được kết quả và tạo ra một biến tensor từ đó? Nó có thể làm việc như một khoảng cách dừng cho đến khi tensorflow nhận được tính năng này. ví dụ.

all_outputs = session.run(lstm_outputs, feed_dict={'your inputs'}) 
last_outputs = all_outputs[sequence_lengths, tf.range(batch_size), :] 
use_this_as_an_input_to_new_tensorflow_op = tf.constant(last_outputs) 
+0

Vâng, chắc chắn đó sẽ không phải là giải pháp tốt nhất. Nhưng ngay bây giờ tôi không thể nhìn thấy bất kỳ cách nào khác. – erickrf

+1

Có cách nào tốt hơn bây giờ không? – Zhao

1

nếu bạn chỉ quan tâm đến kết quả hợp lệ cuối cùng bạn có thể lấy nó thông qua trạng thái được trả về bởi tf.nn.rnn() xem xét rằng nó luôn luôn là một tuple (c, h) trong đó c là trạng thái cuối cùng và h là đầu ra cuối cùng. Khi trạng thái là LSTMStateTuple, bạn có thể sử dụng đoạn mã sau (hoạt động trong tensorflow 0.12):

lstm_cell = tf.nn.rnn_cell.LSTMCell(num_lstm_units, input_size) 
lstm_outputs, state = tf.nn.rnn(lstm_cell, input_list, dtype=tf.float32, sequence_length=sequence_lengths) 
last_output = state[1] 
+0

Điều này đơn giản hơn nhiều so với câu trả lời được chấp nhận là của tensorflow 0.12 và sau đó – erickrf

Các vấn đề liên quan