Использование Keras для построения модели LSTM + Conv2D

Я хочу построить модель, похожую на эту архитектуру: - Использование Keras для построения модели LSTM + Conv2D

Моя текущая модель LSTM выглядит следующим образом: -

x = Embedding(max_features, embed_size, weights=[embedding_matrix],trainable=False)(inp)
x = SpatialDropout1D(0.1)(x)
x = Bidirectional(CuDNNLSTM(128, return_sequences=True))(x)
x = Bidirectional(CuDNNLSTM(64, return_sequences=True))(x)
avg_pool = GlobalAveragePooling1D()(x)
max_pool = GlobalMaxPooling1D()(x)
conc = concatenate([avg_pool, max_pool])
conc = Dense(64, activation = "relu")(conc)
conc = Dropout(0.1)(conc)
outp = Dense(1, activation = "sigmoid")(conc) 
model = Model(inputs=inp, outputs=outp)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=[f1])

Как использовать слой Conv2D после BiLSTM позже со слоем 2D Max Pooling?

Это рисунок из бумаги? Если да, не могли бы вы дать ссылку на это?

Lafayette 22.05.2019 12:12

да, было бы хорошо увидеть, почему они решили использовать Conv2D вместо Conv1D?

VnC 23.05.2019 14:23
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
1 178
2

Ответы 2

Conv2d нужен 4D тензор с формой: (batch, rows, col, channel). В задачах НЛП, в отличие от компьютерного зрения, у нас нет канала. Что можно сделать?

Мы можем добавить дополнительное измерение с функцией expand_dims к нашим тензорам, которые действуют как канал. Например, если наш тензор имеет форму (batch, seq, dim), то после расширения он преобразуется в (batch, seq, dim, 1).

lstm = Bidirectional(LSTM(128, return_sequences=True))(embed)
lstm = K.expand_dims(lstm, axis=-1)
conv2d = Conv2D(filters=128, kernel_size=2, padding='same')(lstm)

Есть несколько важных моментов, на которые нужно обратить внимание, чтобы создать эту (довольно сложно) модель.

Вот сама модель, созданная с помощью функционального API:

def expand_dims(x):
    return K.expand_dims(x, -1)

inp = Input(shape=(3,3))
lstm = Bidirectional(LSTM(128, return_sequences=True))(inp)
lstm = Lambda(expand_dims)(lstm)
conv2d = Conv2D(filters=128, kernel_size=2, padding='same')(lstm)
max_pool = MaxPooling2D(pool_size=(2, 2),)(conv2d)
predictions = Dense(10, activation='softmax')(max_pool)
model = Model(inputs=inp, outputs=predictions)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])

Пошаговое объяснение

Первый, создайте форму ввода. Из изображения выше похоже, что вы работаете с 7 образцами, окном из 3 и 3 функций -> тензор формы (7, 3, 3). Очевидно, вы можете измениться на все, что захотите. Используйте входной слой для двунаправленного слоя LSTM.

inp = Input(shape=(3,3))
lstm = Bidirectional(LSTM(128, return_sequences=True))(inp)

Второй, как упоминал @Amir, вам нужно расширить размеры, если вы хотите использовать слой Conv2D. Однако только использования бэкэнда keras недостаточно, так как модель, созданная функциональным API, потребует, чтобы в ней были только слои keras. Проверьте этот ответ здесь на наличие ошибки NoneType' object has no attribute '_inbound_nodes. Следовательно, вам нужно извлечь ваш expand_dim в его собственную функцию и обернуть слой Lambda:

def expand_dims(x):
    return K.expand_dims(x, -1)

lstm = Lambda(expand_dims)(lstm)

Остальные становится довольно простым после сортировки вышеуказанного:

conv2d = Conv2D(filters=128, kernel_size=2, padding='same')(lstm)
max_pool = MaxPooling2D(pool_size=(2, 2),)(conv2d)
predictions = Dense(10, activation='softmax')(max_pool)
model = Model(inputs=inp, outputs=predictions)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy')

резюме модели выглядит так:

Layer (type)                 Output Shape              Param #   
=================================================================
input_67 (InputLayer)        (None, 3, 3)              0         
_________________________________________________________________
bidirectional_29 (Bidirectio (None, 3, 256)            135168    
_________________________________________________________________
lambda_7 (Lambda)            (None, 3, 256, 1)         0         
_________________________________________________________________
conv2d_19 (Conv2D)           (None, 3, 256, 128)       640       
_________________________________________________________________
max_pooling2d_14 (MaxPooling (None, 1, 128, 128)       0         
_________________________________________________________________
dense_207 (Dense)            (None, 1, 128, 10)        1290      
=================================================================
Total params: 137,098
Trainable params: 137,098
Non-trainable params: 0
_________________________________________________________________
None

А вот и визуализация:

Другие вопросы по теме