Пользовательский слой Внимание в Керасе
Я работаю над проблемой, в которой есть пары вопросов и ответов и метка (0,1), обозначающая, имеет ли ответ отношение к вопросу. На каждый вопрос у меня есть 9 ответов с меткой 0 и только 1 ответ с меткой 1.
Я пытаюсь реализовать настраиваемую рекуррентную сеть на основе внимания в Керасе, чтобы включить информацию о вопросе в представление ответа. Реализация основана на этом документе "R-NET: МАШИНА, ЧТИТЕЛЬНАЯ КОМПЛЕКСНОСТЬ С СЕТЬМИ СОВМЕСТИМОСТИ". Ссылка: https://www.microsoft.com/en-us/research/wp-content/uploads/2017/05/r-net.pdf Раздел 3.2 содержит подробную информацию о модели внимания.
Я новичок в keras и борюсь с этим кодом. Код может содержать и другие ошибки. Ваша помощь будет высоко ценится.
Код для модели внимания выглядит следующим образом:
from keras.models import Model
from keras import layers
from keras.layers import InputSpec
from keras import activations, initializers
from keras.engine.topology import Layer
from keras import Input
from keras.optimizers import RMSprop
from keras.layers.recurrent import GRU,LSTM,RNN,GRUCell
class QA_AttentionGRU(GRU):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.input_spec =[InputSpec(ndim=3), InputSpec(ndim=3)]
def build(self,input_shape):
if not (isinstance(input_shape, list) and len(input_shape) == 2):
raise Exception('Input must be a list of '
'two tensors [lstm_input, attn_input].')
print("Input shape",input_shape)
self.step_input_shape=self.units+input_shape[-1][-1]
print(self.step_input_shape)
self.input_length_custom= input_shape[0][1]
super().build(input_shape[0])
self.Wqu= self.add_weight(shape=(input_shape[-1][-1], self.units),
initializer='uniform',
name='Wqu')
self.Wpu= self.add_weight(shape=(input_shape[0][-1], self.units),
initializer='uniform',
name='Wpu')
self.Wpv= self.add_weight(shape=(self.units, self.units),
initializer='uniform',
name='Wpv')
self.v= self.add_weight(shape=(self.units, 1),
initializer='uniform',
name='v')
#self.trainable_weights+=[self.Wqu,self.Wpu,self.Wpv,self.v]
step_input_shape=self.units+input_shape[-1][-1]
self.built=True
def call(self, inputs,training=None):
uQ = inputs[1:]
uP = inputs[:1]
self._constants=uQ[0]
initial_states=self.get_initial_state(uP[0])
print("Initial state",initial_states)
last_output, outputs, states = K.rnn(self.step,
uP[0],
initial_states,
input_length=self.input_length_custom)
return outputs
def step(self,inputs,states):
uP_t = inputs
vP_tm1 = states[0]
uQ=self._constants
WQ_u_Dot = K.dot(self._constants, self.Wqu)
WP_v_Dot = K.dot(K.expand_dims(vP_tm1, axis=1), self.Wpv) #WP_v
WP_u_Dot = K.dot(K.expand_dims(uP_t, axis=1), self.Wpu) # WP_u
s_t_hat = K.tanh(WQ_u_Dot + WP_v_Dot + WP_u_Dot)
s_t = K.dot(s_t_hat, self.v)
s_t = K.batch_flatten(s_t)
uQ_mask=None
a_t = softmax(s_t, mask=uQ_mask, axis=1)
c_t = K.batch_dot(a_t, uQ, axes=[1, 1])
GRU_inputs = K.concatenate([uP_t, c_t])
vP_t, s = super().step(GRU_inputs, states)
return vP_t, s
attgru=QA_AttentionGRU(units=32,return_sequences=True)
uq=K.random_normal(shape=(5,2,32))
up=K.random_normal(shape=(5,8,16))
attgru(inputs=[uq,up])
`
Код выдает следующую ошибку: Error_Pic1 Error_pic2