Tensorflow dynamic_rnn deprecation - PullRequest
       23

Tensorflow dynamic_rnn deprecation

2 голосов
/ 20 марта 2019

Кажется, что tf.nn.dynamic_rnn устарело:

Предупреждение: ЭТА ФУНКЦИЯ УСТАРЕЛА.Он будет удален в следующей версии.Инструкции по обновлению: Пожалуйста, используйте keras.layers.RNN (ячейка), который эквивалентен этому API

Я проверил keras.layers.RNN (ячейка), и он говорит, что он может использовать маскированиекоторый, я полагаю, может служить заменой для параметра dynamic_rnn sequence_length?

Этот слой поддерживает маскирование для входных данных с переменным числом временных шагов.Чтобы ввести маски в ваши данные, используйте слой Embedding с параметром mask_zero, установленным в True.

Но даже в документах Embedding нет дополнительной информации о том, как я могу использовать mask_zero=True для размещения переменнойдлины последовательности.Кроме того, если я использую слой встраивания просто для добавления маски, как я могу предотвратить встраивание, чтобы изменить мой ввод и обучение?

Аналогично этому вопросу RNN в Tensorflow vs Keras, амортизация tf.nn.dynamic_rnn () , но я хочу знать, как использовать маску для замены sequence_length

1 Ответ

1 голос
/ 19 июня 2019

Мне тоже нужен был ответ на этот вопрос, и я понял, что мне нужно, по ссылке внизу вашего вопроса.

Короче говоря, вы делаете, как говорит ответ в ссылке, но вы просто'пропустите слой для встраивания, если вы не заинтересованы в его использовании.Я настоятельно рекомендую прочитать и понять связанный ответ , поскольку он более детален, и документы по Masking , но вот модифицированная версия, которая использует маскирующий слой поверх входов последовательностидля замены «sequence_length»:

import numpy as np
import tensorflow as tf

pad_value = 0.37
# This is our input to the RNN, in [batch_size, max_sequence_length, num_features] shape
test_input = np.array(
[[[1.,   1.  ],
  [2,    2.  ],
  [1.,   1.  ],
  [pad_value, pad_value], # <- a row/time step which contains all pad_values will be masked through the masking layer
  [pad_value, pad_value]],

 [[pad_value, pad_value],
  [1.,   1.  ],
  [2,    2.  ],
  [1.,   1.  ],
  [pad_value, pad_value]]])

# Define the mask layer, telling it to mask all time steps that contain all pad_value values
mask = tf.keras.layers.Masking(mask_value=pad_value)
rnn = tf.keras.layers.GRU(
    1,
    return_sequences=True,
    activation=None, # <- these values and below are just used to initialise the RNN in a repeatable way for this example
    recurrent_activation=None,
    kernel_initializer='ones',
    recurrent_initializer='zeros',
    use_bias=True,
    bias_initializer='ones'
)

x = tf.keras.layers.Input(shape=test_input.shape[1:])
m0 = tf.keras.Model(inputs=x, outputs=rnn(x))
m1 = tf.keras.Model(inputs=x, outputs=mask(x))
m2 = tf.keras.Model(inputs=x, outputs=rnn(mask(x)))

print('raw inputs\n', test_input)
print('raw rnn output (no mask)\n', m0.predict(test_input).squeeze())
print('masked inputs\n', m1.predict(test_input).squeeze())
print('masked rnn output\n', m2.predict(test_input).squeeze())

out:

raw inputs
 [[[1.   1.  ]
  [2.   2.  ]
  [1.   1.  ]
  [0.37 0.37]
  [0.37 0.37]]

 [[0.37 0.37]
  [1.   1.  ]
  [2.   2.  ]
  [1.   1.  ]
  [0.37 0.37]]]
raw rnn output (no mask)
 [[  -6.        -50.       -156.       -272.7276   -475.83362 ]
 [  -1.2876     -9.862801  -69.314    -213.94202  -373.54672 ]]
masked inputs
 [[[1. 1.]
  [2. 2.]
  [1. 1.]
  [0. 0.]
  [0. 0.]]

 [[0. 0.]
  [1. 1.]
  [2. 2.]
  [1. 1.]
  [0. 0.]]]
masked rnn output
 [[  -6.  -50. -156. -156. -156.]
 [   0.   -6.  -50. -156. -156.]]

Обратите внимание, что при применении маски вычисления не выполняются на временном шаге, когда маска активна (т.е. гдепоследовательность дополняется).Вместо этого переносится состояние с предыдущего временного шага.

Несколько других моментов, на которые следует обратить внимание:

  • В связанном (и этом) примере RNN создается с различной активациейи параметры инициализатора.Я предполагаю, что это для инициализации RNN в известное состояние для повторяемости для примера.На практике вы бы инициализировали RNN так, как вам хотелось бы.
  • Значение пэда может быть любым заданным вами значением.Обычно используется заполнение нулями.В связанном (и этом) примере используется значение 0,37.Я могу только предположить, что это произвольное значение, чтобы показать разницу в необработанных и замаскированных выходах RNN, так как нулевое входное значение в этом примере инициализации RNN дает небольшую / никакую разницу в выходных данных, поэтому значение 'some' (т.е. 0,37) демонстрируетэффект маскирования.
  • В документах Masking указано, что строки / временные шаги маскируются, только если все значений для этого временного шага содержат значение маски.Например, как указано выше, шаг по времени [0.37, 2] будет по-прежнему подаваться в сеть с этими значениями, однако шаг по времени [0.37, 0.37] будет пропущен.
  • Альтернативный подход к этомупроблема вместо маскировки состоит в том, чтобы тренироваться несколько раз, объединяя различные длины последовательности.Например, если у вас есть смесь длин последовательностей 10, 20 и 30, вместо того, чтобы заполнять их до 30 и маскировать, тренируйтесь, используя все 10 длин последовательностей, затем свои 20, а затем 30.Или, если вы скажете, много последовательностей длиной 100, а также много последовательностей длиной 3, 4, 5, вы можете добавить свои меньшие ко всем 5 длинам и тренироваться дважды, используя 100 с и дополненные / замаскированные 5 с.Скорее всего, вы наберете скорость обучения, но при меньшем компромиссе вы не сможете перетасовывать партии разных серий.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...