Использование Keras для построения модели LSTM + Conv2D - PullRequest
0 голосов
/ 23 декабря 2018

Я хочу построить модель, подобную этой архитектуре: - enter image description here

Моя текущая модель 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?

Ответы [ 2 ]

0 голосов
/ 22 мая 2019

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

Вот сама модель, созданная с использованием функционального 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

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

enter image description here

0 голосов
/ 23 декабря 2018

Conv2d требуется четырехмерный тензор с формой: (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)
...