Keras: BiLSTM работает только когда return_sequence = True - PullRequest
0 голосов
/ 15 апреля 2019

Я пытался реализовать этот BiLSTM в Керасе: https://github.com/ffancellu/NegNN

Вот где я нахожусь, и это вроде работает:

inputs_w = Input(shape=(sequence_length,), dtype='int32')
inputs_pos = Input(shape=(sequence_length,), dtype='int32')
inputs_cue = Input(shape=(sequence_length,), dtype='int32')

w_emb = Embedding(vocabulary_size+1, embedding_dim, input_length=sequence_length, trainable=False)(inputs_w)
p_emb = Embedding(tag_voc_size+1, embedding_dim, input_length=sequence_length, trainable=False)(inputs_pos)
c_emb = Embedding(2, embedding_dim, input_length=sequence_length, trainable=False)(inputs_cue)

summed = keras.layers.add([w_emb, p_emb, c_emb])

BiLSTM = Bidirectional(CuDNNLSTM(hidden_dims, return_sequences=True))(summed)

DPT = Dropout(0.2)(BiLSTM)

outputs = Dense(2, activation='softmax')(DPT)

checkpoint = ModelCheckpoint('bilstm_one_hot.hdf5', monitor='val_loss', verbose=1, save_best_only=True, mode='auto')
early = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=5, verbose=1, mode='auto')

model = Model(inputs=[inputs_w, inputs_pos, inputs_cue], outputs=outputs)

model.compile('adam', loss='categorical_crossentropy', metrics=['accuracy'])

model.summary()

model.fit([X_train, X_pos_train, X_cues_train], Y_train, batch_size=batch_size, epochs=num_epochs, verbose=1, validation_split=0.2, callbacks=[early, checkpoint])

В исходном коде, в Tensorflow, автор использует маску и перекрестную энтропию softmax с логитами. Я пока не понимаю, как реализовать это в Керасе. Если у вас есть какие-либо советы, не стесняйтесь.

Моя главная проблема здесь с return_sequence = True. Автор, кажется, не использует его в своей реализации tenorflow, и когда я поворачиваю его в False, я получаю эту ошибку:

ValueError: Error when checking target: expected dense_1 to have 2 dimensions, but got array with shape (820, 109, 2)

Я также пытался использовать:

outputs = TimeDistributed(Dense(2, activation='softmax'))(BiLSTM)

, который возвращает и AssertionError без какой-либо информации.

Есть идеи?

Спасибо

Ответы [ 2 ]

1 голос
/ 15 апреля 2019

Автор использует маску и кросс-энтропию softmax с логитами. Я пока не понимаю, как реализовать это в Керасе.

Что касается кросс-энтропии softmax с логитами, вы делаете это правильно. softmax_cross_entropy_with_logits как функция потерь + отсутствие функции активации на последнем слое - это то же самое, что ваш подход с categorical_crossentropy в качестве потери + softmax активации на последнем слое. Разница лишь в том, что последний численно менее стабилен. Если это окажется проблемой для вас, вы можете (если ваш сервер Keras имеет тензор потока) просто передать tf.softmax_cross_entropy_with_logits в качестве вашей потери. Если у вас есть другой бэкэнд, вам придется искать там эквивалент.

Что касается маскировки, я не уверен, полностью ли я понимаю, что делает автор. Однако в Keras слой Embedding имеет параметр mask_zero, который можно установить на True. В этом случае все временные шаги, которые имеют 0, будут игнорироваться во всех дальнейших вычислениях. В вашем источнике маскируется не 0, поэтому вам придется соответствующим образом скорректировать индексы. Если это не сработает, в Keras есть слой Masking, который вы можете поместить перед своим повторяющимся слоем, но у меня мало опыта с этим.

Моя главная проблема здесь с return_sequence = True. Автор не кажется, что он использует

Что заставляет вас думать, что он им не пользуется? То, что это ключевое слово не появляется в коде, ничего не значит. Но я тоже не уверен. Код довольно старый, и я больше не нахожу его в документах, которые могли бы сказать, каковы значения по умолчанию.

В любом случае, если вы хотите использовать return_sequences=False (по любой причине), имейте в виду, что это меняет форму вывода слоя:

  • с return_sequences=True форма вывода (batch_size, timesteps, features)
  • с return_sequences=False выходная форма (batch_size, features)

Ошибка, которую вы получаете, в основном говорит о том, что выход вашей сети имеет на одно измерение меньше целевых значений y, которые вы передаете. Поэтому мне кажется, что return_sequences=True - это то, что вам нужно, но без дополнительной информации трудно сказать.

Тогда относительно TimeDistributed . Я не совсем уверен, чего вы добиваетесь, но цитирую документы:

Эта оболочка применяет слой к каждому временному фрагменту ввода.

Ввод должен быть не менее 3D , а размер индекса один будет считаться временным измерением.

(ударение мое)

Я не уверен из вашего вопроса, в каком случае происходит пустое утверждение.

Если у вас есть рекуррентный слой с return_sequences=False ранее, вы снова пропускаете измерение (хотя я не могу сказать вам, почему утверждение пусто).

Если у вас есть рекуррентный слой с return_sequences=True ранее, он должен работать, но он будет совершенно бесполезен, так как Dense в любом случае применяется с распределением времени. Если я не ошибаюсь, это поведение слоя Dense было изменено в некоторых старых версиях Keras (они действительно должны обновить пример и перестать использовать Dense!). Поскольку код, на который вы ссылаетесь, довольно старый, вполне возможно, что TimeDistributed тогда был необходим, но больше не нужен.

Если ваш план состоял в том, чтобы восстановить недостающее измерение, TimeDistributed вам не поможет, но RepeatVector поможет. Но, как уже говорилось, в этом случае лучше использовать return_sequences=True в первую очередь.

1 голос
/ 15 апреля 2019

Проблема в том, что ваши целевые значения кажутся распределенными по времени. Таким образом, у вас есть 109 временных шагов с единичным целевым вектором размера два. Вот почему вам нужно return_sequence = True. В противном случае вы просто передадите последний временной шаг слою Плотный, и у вас будет только один выход.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...