2016-12-21 2 views
2

Tensorflow에서 LSTM을 사용하여 분류 할 길이가 다른 시퀀스가 ​​있습니다. 분류를 위해서 각 시퀀스의 마지막 타임 스텝의 LSTM 출력 만 있으면됩니다.Tensorflow에서 LSTM 시퀀스의 최종 값 검색

max_length = 10 
n_dims = 2 
layer_units = 5 
input = tf.placeholder(tf.float32, [None, max_length, n_dims]) 
lengths = tf.placeholder(tf.int32, [None]) 
cell = tf.nn.rnn_cell.LSTMCell(num_units=layer_units, state_is_tuple=True) 

sequence_outputs, last_states = tf.nn.dynamic_rnn(cell, sequence_length=lengths, inputs=input) 
내가 NumPy와 표기법으로 좀하고 싶습니다

: Tensorflow에서이 동작을 얻을 수있는 방법 또는 해결 방법이 output = sequence_outputs[:,lengths]

있습니까?

--- UPDATE ---

이 게시물 How to select rows from a 3-D Tensor in TensorFlow? 다음은 그 tf.gather 및 인덱스를 조작하여 효율적인 방법으로 문제를 해결할 수있다 보인다. 유일한 요구 사항은 배치 크기를 사전에 알고 있어야한다는 것입니다. 다음은이 구체적인 문제에 대한 언급 이후의 적응은 다음과 같습니다

max_length = 10 
n_dims = 2 
layer_units = 5 
batch_size = 2 
input = tf.placeholder(tf.float32, [batch_size, max_length, n_dims]) 
lengths = tf.placeholder(tf.int32, [batch_size]) 
cell = tf.nn.rnn_cell.LSTMCell(num_units=layer_units, state_is_tuple=True) 

sequence_outputs, last_states = tf.nn.dynamic_rnn(cell, 
                sequence_length=lengths, inputs=input) 

#Code adapted from @mrry response in StackOverflow: 
#https://stackoverflow.com/questions/36088277/how-to-select-rows-from-a-3-d-tensor-in-tensorflow 
rows_per_batch = tf.shape(input)[1] 
indices_per_batch = 1 

# Offset to add to each row in indices. We use `tf.expand_dims()` to make 
# this broadcast appropriately. 
offset = tf.range(0, batch_size) * rows_per_batch 

# Convert indices and logits into appropriate form for `tf.gather()`. 
flattened_indices = lengths - 1 + offset 
flattened_sequence_outputs = tf.reshape(self.sequence_outputs, tf.concat(0, [[-1], 
          tf.shape(sequence_outputs)[2:]])) 

selected_rows = tf.gather(flattened_sequence_outputs, flattened_indices) 
last_output = tf.reshape(selected_rows, 
          tf.concat(0, [tf.pack([batch_size, indices_per_batch]), 
          tf.shape(self.sequence_outputs)[2:]])) 

@petrux 옵션 (Get the last output of a dynamic_rnn in TensorFlow는) 작업도 보인다하지만 난하지 않았다하더라도 for 루프 내에서 목록을 구축의 필요성이 적은 최적화 할 수있다 이 성명을 뒷받침하는 벤치 마크를 수행하십시오.

답변

1

This이 답이 될 수 있습니다. 당신이 지적한 NumPy 표기법과 비슷한 것이 있다고 생각하지 않지만 그 효과는 같습니다.

+0

작동하는 것 같습니다. 내가 찾고 있던 사전 인덱싱은 공개 된 문제인 것처럼 보입니다. https://github.com/tensorflow/tensorflow/issues/4638 구현이 효율성을 많이 저하 시킬지 아니면 합리적인 것인지 궁금합니다. – pabaldonedo

0

다음은 gather_nd을 사용하는 해결책입니다. 배치 크기를 사전에 알아야 할 필요는 없습니다.

def extract_axis_1(data, ind): 
    """ 
    Get specified elements along the first axis of tensor. 
    :param data: Tensorflow tensor that will be subsetted. 
    :param ind: Indices to take (one for each element along axis 0 of data). 
    :return: Subsetted tensor. 
    """ 

    batch_range = tf.range(tf.shape(data)[0]) 
    indices = tf.stack([batch_range, ind], axis=1) 
    res = tf.gather_nd(data, indices) 

    return res 

output = extract_axis_1(sequence_outputs, lengths - 1) 

지금 output는 차원 [batch_size, num_cells]의 텐서이다.

관련 문제