Keras在LSTM层后添加自定义Attention层出现ValueError报错如何解决?
问题原因
报错根源在于自定义注意力层的偏置参数形状绑定了动态可变的序列长度维度:
你定义的输入层Input(shape=(None, 1))中第一个None代表支持任意长度的输入序列,属于动态未知维度;而注意力层build方法中给偏置b设置的形状为(input_shape[1], 1),其中input_shape[1]就对应这个动态的序列长度,值为None。Keras的可训练参数形状必须是固定的,不允许存在未知维度,因此触发了形状转换错误。
前面的CUDA相关警告属于环境无GPU配置的提示,和本次报错无关,不影响代码运行。
解决方案
修改自定义注意力层的偏置定义,利用广播机制避免绑定序列长度维度,修改后的代码如下:
class attention(Layer): def __init__(self, **kwargs): super(attention, self).__init__(**kwargs) def build(self, input_shape): self.W = self.add_weight(shape=(input_shape[-1], 1), initializer='random_normal', trainable=True) # 偏置形状调整为(1,),计算时自动广播适配任意长度的时间步 self.b = self.add_weight(shape=(1,), initializer='zeros', trainable=True) super(attention, self).build(input_shape) def call(self, x): e = K.tanh(K.dot(x, self.W) + self.b) e = K.squeeze(e, axis=-1) alpha = K.softmax(e) alpha = K.expand_dims(alpha, axis=-1) context = x * alpha context = K.sum(context, axis=1) return context
如果你实际使用的输入序列长度是固定值,也可以直接将输入层的形状修改为固定长度,比如序列长度为100时,将Input_rnn = keras.Input(shape=(None, 1))改为Input_rnn = keras.Input(shape=(100, 1)),原有注意力层代码也可正常运行。
内容的提问来源于stack exchange,提问作者mark Lan
相关产品推荐
相关产品推荐

