Сбрасывается ли исходное состояние RNN для последующих мини-пакетов?

time-series tensorflow recurrent-neural-network

14456 просмотра

2 ответа

541 Репутация автора

Может ли кто-нибудь уточнить, сбрасывается ли начальное состояние RNN в TF для последующих мини-пакетов, или используется последнее состояние предыдущего мини-пакета, как упомянуто в Ilya Sutskever et al., ICLR 2015 ?

Автор: VM_AI Источник Размещён: 18.07.2016 04:18

Ответы (2)


20 плюса

15018 Репутация автора

Решение

tf.nn.dynamic_rnn()Или tf.nn.rnn()операции позволяют задать начальное состояние RNN с помощью initial_stateпараметра. Если вы не укажете этот параметр, скрытые состояния будут инициализироваться нулевыми векторами в начале каждой обучающей партии.

В TensorFlow вы можете обернуть тензоры, tf.Variable()чтобы сохранить их значения в графике между несколькими запусками сеанса. Просто пометьте их как необучаемые, поскольку оптимизаторы настраивают все обучаемые переменные по умолчанию.

data = tf.placeholder(tf.float32, (batch_size, max_length, frame_size))

cell = tf.nn.rnn_cell.GRUCell(256)
state = tf.Variable(cell.zero_states(batch_size, tf.float32), trainable=False)
output, new_state = tf.nn.dynamic_rnn(cell, data, initial_state=state)

with tf.control_dependencies([state.assign(new_state)]):
    output = tf.identity(output)

sess = tf.Session()
sess.run(tf.initialize_all_variables())
sess.run(output, {data: ...})

Я не проверял этот код, но он должен дать вам подсказку в правильном направлении. Существует также объект, tf.nn.state_saving_rnn()к которому можно предоставить объект сохранения состояния, но я еще не использовал его.

Автор: danijar Размещён: 19.07.2016 06:11

9 плюса

3025 Репутация автора

В дополнение к ответу Данижара, здесь приведен код для LSTM, состояние которого равно tuple ( state_is_tuple=True). Он также поддерживает несколько слоев.

Мы определили две функции - одну для получения переменных состояния с начальным нулевым состоянием и одну функцию для возврата операции, которую мы можем передать session.run, чтобы обновить переменные состояния с последним скрытым состоянием LSTM.

def get_state_variables(batch_size, cell):
    # For each layer, get the initial state and make a variable out of it
    # to enable updating its value.
    state_variables = []
    for state_c, state_h in cell.zero_state(batch_size, tf.float32):
        state_variables.append(tf.contrib.rnn.LSTMStateTuple(
            tf.Variable(state_c, trainable=False),
            tf.Variable(state_h, trainable=False)))
    # Return as a tuple, so that it can be fed to dynamic_rnn as an initial state
    return tuple(state_variables)


def get_state_update_op(state_variables, new_states):
    # Add an operation to update the train states with the last state tensors
    update_ops = []
    for state_variable, new_state in zip(state_variables, new_states):
        # Assign the new state to the state variables on this layer
        update_ops.extend([state_variable[0].assign(new_state[0]),
                           state_variable[1].assign(new_state[1])])
    # Return a tuple in order to combine all update_ops into a single operation.
    # The tuple's actual value should not be used.
    return tf.tuple(update_ops)

Как и в ответе Даниира, мы можем использовать его для обновления состояния LSTM после каждого пакета:

data = tf.placeholder(tf.float32, (batch_size, max_length, frame_size))
cells = [tf.contrib.rnn.GRUCell(256) for _ in range(num_layers)]
cell = tf.contrib.rnn.MultiRNNCell(cells)

# For each layer, get the initial state. states will be a tuple of LSTMStateTuples.
states = get_state_variables(batch_size, cell)

# Unroll the LSTM
outputs, new_states = tf.nn.dynamic_rnn(cell, data, initial_state=states)

# Add an operation to update the train states with the last state tensors.
update_op = get_state_update_op(states, new_states)

sess = tf.Session()
sess.run(tf.global_variables_initializer())
sess.run([outputs, update_op], {data: ...})

Основное различие заключается в том, что state_is_tuple=Trueсостояние LSTM превращается в LSTMStateTuple, содержащий две переменные (состояние ячейки и скрытое состояние) вместо одной переменной. Использование нескольких слоев делает состояние LSTM кортежем LSTMStateTuples - по одному на слой.

Автор: Kilian Batzner Размещён: 20.12.2016 10:20
Вопросы из категории :
32x32