Мне тоже нужен был ответ на этот вопрос, и я понял, что мне нужно, по ссылке внизу вашего вопроса.
Короче говоря, вы делаете, как говорит ответ в ссылке, но вы просто'пропустите слой для встраивания, если вы не заинтересованы в его использовании.Я настоятельно рекомендую прочитать и понять связанный ответ , поскольку он более детален, и документы по 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 с.Скорее всего, вы наберете скорость обучения, но при меньшем компромиссе вы не сможете перетасовывать партии разных серий.