Как правильно настроить RNN в Keras для моделирования последовательности? - PullRequest
0 голосов
/ 26 августа 2018

Хотя я не новичок в машинном обучении, я все еще относительно новичок в нейронных сетях, более конкретно, как их реализовать (в Keras / Python).Прямая и сверточная архитектура довольно просты, но у меня проблемы с RNN.

Мои X данные состоят из последовательностей переменной длины, каждая точка данных в этой последовательности имеет 26 объектов.Мои y данные, хотя и переменной длины, каждая пара X и y имеют одинаковую длину, например:

X_train[0].shape: (226,26)
y_train[0].shape: (226,)
X_train[1].shape: (314,26)
y_train[1].shape: (314,)
X_train[2].shape: (189,26)
y_train[2].shape: (189,)

И моя цель состоит в том, чтобы классифицировать каждый элемент в последовательности в одиниз 39 категорий.

Что я могу почерпнуть из чтения примера кода, так это то, что мы делаем что-то вроде следующего:

encoder_inputs = Input(shape=(None, 26))
encoder = GRU(256, return_state=True)
encoder_outputs, state_h = encoder(encoder_inputs)
decoder_inputs = Input(shape=(None, 39))
decoder_gru= GRU(256, return_sequences=True)
decoder_outputs, _ = decoder_gru(decoder_inputs, initial_state=state_h)
decoder_dense = Dense(39, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)

model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer=keras.optimizers.Adadelta(),
                  metrics=['accuracy'])

Что имеет смысл для меня, потому что каждая из последовательностейимеют разные длины.Таким образом, с циклом for, который проходит по всем последовательностям, мы используем None во входной форме первого слоя GRU, потому что мы не уверены, какой будет длина последовательности, а затем возвращаем скрытое состояние state_h этого кодировщика.Со вторым уровнем, возвращающим последовательности GRU, и начальным состоянием, являющимся состоянием, возвращаемым из кодера, мы затем передаем выходные данные в конечный уровень активации Softmax.

decoder_outputs, _ = decoder_gru(decoder_inputs, initial_state=state_h)
File "/usr/local/lib/python3.6/dist- 
packages/tensorflow/python/framework/ops.py", line 458, in __iter__
"Tensor objects are only iterable when eager execution is "
TypeError: Tensor objects are only iterable when eager execution is 
enabled. To iterate over this tensor use tf.map_fn.

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

Мне действительно нужна помощь, чтобы успешно написать этот RNN для выполнения этой задачи, но также и понимание.Я очень заинтересован в RNN и хочу понять их более подробно, чтобы я мог применить их к другим задачам.

В качестве дополнительного примечания каждая последовательность имеет форму (sequence_length, 26), но я расширяю размер, чтобы(1, sequence_length, 26) для X и (1, sequence_length) для y, а затем передайте их в цикл for, который нужно подогнать, на decoder_target_data на один шаг впереди текущего входа:

for idx in range(X_train.shape[0]):
    X_train_s = np.expand_dims(X_train[idx], axis=0)
    y_train_s = np.expand_dims(y_train[idx], axis=0)
    y_train_s1 = np.expand_dims(y_train[idx+1], axis=0)

    encoder_input_data = X_train_s
    decoder_input_data = y_train_s
    decoder_target_data = y_train_s1
    model.fit([encoder_input_data, decoder_input_data], decoder_target_data,
          epochs=50,
          validation_split=0.2)

В других сетях, которые я написал (FeedForward и CNN), я определяю модель, добавляя слои поверх класса Serastial от Keras.Из-за присущей RNN сложности я вижу общий формат использования класса Input Keras, подобного приведенному выше, и извлечение скрытых состояний (и состояний ячеек для LSTM) и т. Д. ... логичным, но я также видел их построенные на основе последовательного класса Keras.,Хотя это были задачи типа «один-на-один», мне было бы интересно, как бы вы написали это так.

1 Ответ

0 голосов
/ 26 августа 2018

Проблема в том, что слой decoder_gru не возвращает свое состояние, поэтому не следует использовать _ в качестве возвращаемого значения для состояния (т. Е. Просто удалить , _):

decoder_outputs = decoder_gru(decoder_inputs, initial_state=state_h)

Поскольку длина входных и выходных данных одинакова, и между элементами ввода и вывода есть взаимно-однозначное соответствие, вы можете альтернативно построить модель следующим образом:

inputs = Input(shape=(None, 26))
gru = GRU(64, return_sequences=True)(inputs)
outputs = Dense(39, activation='softmax')(gru)

model = Model(inputs, outputs)

Теперь вы можете сделать эту модель более сложной (т.е. увеличить ее емкость), уложив несколько слоев GRU друг на друга:

inputs = Input(shape=(None, 26))
gru = GRU(256, return_sequences=True)(inputs)
gru = GRU(128, return_sequences=True)(gru)
gru = GRU(64, return_sequences=True)(gru)
outputs = Dense(39, activation='softmax')(gru)

model = Model(inputs, outputs)

Далее, вместо использования слоев GRU, вы можете использовать слои LSTM, которые обладают большей репрезентативной способностью (конечно, это может происходить за счет увеличения вычислительных затрат). И не забывайте, что когда вы увеличиваете емкость модели, вы также увеличиваете вероятность переоснащения. Поэтому вы должны помнить об этом и обдумывать решения, которые предотвращают переоснащение (например, добавление регуляризации).

Примечание: Если у вас есть графический процессор, вы можете вместо этого использовать слой CuDNNGRU (или CuDNNLSTM), который был оптимизирован для графических процессоров, поэтому он работает намного быстрее по сравнению с GRU.

...