tf.compat.v1.nn.raw_rnn
Создает RNN, определяемый RNNCell cell и функцией цикла loop_fn.
tf.compat.v1.nn.raw_rnn(
cell, loop_fn, parallel_iterations=None, swap_memory=False, scope=None
)
Примечание: Этот метод все еще находится на стадии тестирования, API может измениться.**
Эта функция представляет собой более низкоуровневую версию dynamic_rnn, обеспечивающую более прямой доступ к входным данным на каждой итерации. Кроме того, она дает больше возможностей управлять началом и завершением чтения последовательности, а также тем, что выводить в качестве результата.
Например, ее можно использовать для реализации динамического декодера модели seq2seq.
Вместо работы с объектами Tensor большинство операций работают непосредственно с объектами TensorArray.
Работу raw_rnn можно в общих чертах описать следующим псевдокодом:
time = tf.constant(0, dtype=tf.int32)
(finished, next_input, initial_state, emit_structure, loop_state) = loop_fn(
time=time, cell_output=None, cell_state=None, loop_state=None)
emit_ta = TensorArray(dynamic_size=True, dtype=initial_state.dtype)
state = initial_state
while not all(finished):
(output, cell_state) = cell(next_input, state)
(next_finished, next_input, next_state, emit, loop_state) = loop_fn(
time=time + 1, cell_output=output, cell_state=cell_state,
loop_state=loop_state)
# Emit zeros and copy forward state for minibatch entries that are finished.
state = tf.where(finished, state, next_state)
emit = tf.where(finished, tf.zeros_like(emit_structure), emit)
emit_ta = emit_ta.write(time, emit)
# If any new minibatch entries are marked as finished, mark these.
finished = tf.logical_or(finished, next_finished)
time += 1
return (emit_ta, state, loop_state)
с дополнительными свойствами: выходные данные и состояние могут быть (возможно, вложенными) кортежами, как определено в cell.output_size и cell.state_size, поэтому итоговые state и emit_ta также могут быть кортежами.
Простая реализация dynamic_rnn с помощью raw_rnn выглядит так:
inputs = tf.compat.v1.placeholder(shape=(max_time, batch_size, input_depth),
dtype=tf.float32)
sequence_length = tf.compat.v1.placeholder(shape=(batch_size,),
dtype=tf.int32)
inputs_ta = tf.TensorArray(dtype=tf.float32, size=max_time)
inputs_ta = inputs_ta.unstack(inputs)
cell = tf.compat.v1.nn.rnn_cell.LSTMCell(num_units)
def loop_fn(time, cell_output, cell_state, loop_state):
emit_output = cell_output # == None for time == 0
if cell_output is None: # time == 0
next_cell_state = cell.zero_state(batch_size, tf.float32)
else:
next_cell_state = cell_state
elements_finished = (time >= sequence_length)
finished = tf.reduce_all(elements_finished)
next_input = tf.cond(
finished,
lambda: tf.zeros([batch_size, input_depth], dtype=tf.float32),
lambda: inputs_ta.read(time))
next_loop_state = None
return (elements_finished, next_input, next_cell_state,
emit_output, next_loop_state)
outputs_ta, final_state, _ = raw_rnn(cell, loop_fn)
outputs = outputs_ta.stack()
| Аргументы | |
|---|---|
cell | Экземпляр RNNCell. |
loop_fn | Вызываемый объект, принимающий входные данные (time, cell_output, cell_state, loop_state) и возвращающий кортеж (finished, next_input, next_cell_state, emit_output, next_loop_state). Здесь time — скаляр int32 Tensor, cell_output — это Tensor или (возможно, вложенный) кортеж тензоров, определяемый с помощью cell.output_size, а cell_state — это Tensor или (возможно, вложенный) кортеж тензоров, определяемый с помощью loop_fn при первом вызове (и должен соответствовать cell.state_size). Возвращаются следующие значения: finished — логический Tensor формы [batch_size]; next_input — следующий вход, передаваемый в cell; next_cell_state — следующее состояние, передаваемое в cell; emit_output — выходные данные, сохраняемые для этой итерации. Обратите внимание, что emit_output должен быть Tensor или (возможно, вложенным) кортежем тензоров, который накапливается в emit_ta внутри while_loop. При первом вызове loop_fn значение emit_output соответствует emit_structure, которое затем используется для определения размера zero_tensor для emit_ta (по умолчанию — cell.output_size). При последующих вызовах loop_fn значение emit_output соответствует фактическому выходному тензору, который накапливается в emit_ta. Параметр cell_state и выходное значение next_cell_state могут быть одиночными тензорами или (возможно, вложенными) кортежами тензоров. Параметр loop_state и выходное значение next_loop_state могут быть одиночными объектами Tensor или TensorArray либо (возможно, вложенными) кортежами таких объектов. Этот последний параметр может игнорироваться функцией loop_fn, и возвращаемым значением может быть None. Если значение не None, то loop_state будет передаваться через цикл RNN исключительно для того, чтобы функция loop_fn могла отслеживать собственное состояние. Возвращаемый параметр next_loop_state может быть None. При первом вызове loop_fn значения будут time = 0, cell_output = None, cell_state = None и loop_state = None. Для этого вызова значение next_cell_state должно быть значением, используемым для инициализации состояния ячейки. Это может быть конечное состояние предыдущей RNN или результат cell.zero_state(). Оно должно иметь структуру (возможно, вложенного) кортежа тензоров. Если cell.state_size — целое число, это должен быть Tensor соответствующего типа и формы [batch_size, cell.state_size]. Если cell.state_size — это TensorShape, это должен быть Tensor соответствующего типа и формы [batch_size] + cell.state_size. Если cell.state_size — это (возможно, вложенный) кортеж целых чисел или TensorShape, он будет кортежем с соответствующими формами. Значение emit_output может быть либо None, либо структурой (возможно, вложенного) кортежа тензоров, например (tf.zeros(shape_0, dtype=dtype_0), tf.zeros(shape_1, dtype=dtype_1)). Если это первое возвращаемое значение emit_output равно None, результат emit_ta функции raw_rnn будет иметь ту же структуру и типы данных, что и cell.output_size. В противном случае emit_ta будет иметь ту же структуру, формы (с добавленным измерением batch_size) и типы данных, что и emit_output. Фактические значения, возвращаемые для emit_output при этом вызове инициализации, игнорируются. Обратите внимание: структура выдаваемых данных должна быть согласованной на всех временных шагах. |
parallel_iterations | (По умолчанию: 32). Число итераций, выполняемых параллельно. Операции, не имеющие временных зависимостей и допускающие параллельное выполнение, будут выполняться параллельно. Этот параметр задает компромисс между временем и объемом памяти. Значения >> 1 требуют больше памяти, но сокращают время выполнения; меньшие значения требуют меньше памяти, но увеличивают время вычислений. |
swap_memory | Прозрачно перемещает тензоры, созданные при прямом проходе и необходимые для обратного распространения ошибки, с GPU на CPU. Это позволяет обучать RNN, которые обычно не помещаются на одном GPU, практически без снижения производительности или вовсе без него. |
scope | VariableScope для создаваемого подграфа; по умолчанию — "rnn". |
| Возвращает | |
|---|---|
Кортеж (emit_ta, final_state, final_loop_state), содержащий:
|
| Вызывает исключения | |
|---|---|
TypeError | Если cell не является экземпляром RNNCell или loop_fn не является callable. |
© 2022 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 4.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/api_docs/python/tf/compat/v1/nn/raw_rnn