Итак, я хочу построить модель автоэнкодера для данных последовательности. Я начал строить последовательную модель keras в python, и теперь я хочу добавить слой внимания посередине, но не знаю, как к этому подойти. Моя модель на данный момент:
from keras.layers import LSTM, TimeDistributed, RepeatVector, Layer
from keras.models import Sequential
import keras.backend as K
model = Sequential()
model.add(LSTM(20, activation="relu", input_shape=(time_steps,n_features), return_sequences=False))
model.add(RepeatVector(time_steps, name="bottleneck_output"))
model.add(LSTM(30, activation="relu", return_sequences=True))
model.add(TimeDistributed(Dense(n_features)))
model.compile(optimizer="adam", loss="mae")
До сих пор я пытался добавить функцию внимания, скопированную с здесь
class attention(Layer):
def __init__(self,**kwargs):
super(attention,self).__init__(**kwargs)
def build(self,input_shape):
self.W=self.add_weight(name="att_weight",shape=(input_shape[-1],1),initializer="normal")
self.b=self.add_weight(name="att_bias",shape=(input_shape[1],1),initializer="zeros")
super(attention, self).build(input_shape)
def call(self,x):
et=K.squeeze(K.tanh(K.dot(x,self.W)+self.b),axis=-1)
at=K.softmax(et)
at=K.expand_dims(at,axis=-1)
output=x*at
return K.sum(output,axis=1)
def compute_output_shape(self,input_shape):
return (input_shape[0],input_shape[-1])
def get_config(self):
return super(attention,self).get_config()
и добавил его после первого LSTM, перед повторным вектором, то есть:
model = Sequential()
model.add(LSTM(20, activation="relu", input_shape=(time_steps,n_features), return_sequences=False))
model.add(attention()) # this is added
model.add(RepeatVector(time_steps, name="bottleneck_output"))
model.add(LSTM(30, activation="relu", return_sequences=True))
model.add(TimeDistributed(Dense(n_features)))
model.compile(optimizer="adam", loss="mae")
но код дает ошибку, потому что размеры как-то не подходят, и проблема заключается в том, чтобы вывести вывод внимания () для повторения вектора:
ValueError: Input 0 is incompatible with layer bottleneck_output: expected ndim=2, found ndim=1
.... но в соответствии с model.summary()
выходной размер слоя внимания равен (None, 20)
, что то же самое и для первого слоя lstm_1. Код работает без слоя внимания.
Я был бы признателен также за некоторое объяснение, почему решение является решением проблемы, я довольно новичок в python и у меня проблемы с пониманием того, что делает класс attention()
. Я просто скопировал его и попытался использовать, но он не работает....