使用Keras Functional API自定义AddNL合并层时出现__getitem__属性错误
解决TypeError: 'AddNL' object has no attribute 'getitem'问题
这个错误我之前也碰到过,本质是你在代码里尝试对AddNL层的实例或者它的输出做索引操作(比如用[0]这种方括号取元素),但AddNL对象本身不支持这种行为。下面我给你拆解常见的错误场景和修复方案:
1. 错误地对AddNL层的输出做索引
最常见的情况是,你误以为AddNL的输出是一个张量列表,但实际上它返回的是单个张量,却强行加了索引。比如你的代码可能是这样:
from keras.layers.merge import AddNL # 假设x1、x2是已经定义好的输入张量 merged = AddNL()([x1, x2]) output = merged[0] # 这里触发错误!merged是单个张量,不是可索引的列表
修复方案:如果AddNL的设计就是返回单个合并后的张量,直接使用merged即可,去掉多余的[0]索引。如果你的业务确实需要AddNL返回多个张量,那就要检查层的实现是否正确(看下面的第3点)。
2. 错误地直接对AddNL层实例做索引
另一种情况是你把层的实例化和调用搞混了,直接对层类或实例用了索引,比如:
# 错误写法:直接对AddNL实例做索引 merged_layer = AddNL()[0]
修复方案:Keras Functional API的正确用法是先实例化层(AddNL()),再传入输入张量得到输出,正确写法是:
merged = AddNL()([x1, x2])
3. 自定义AddNL层的实现问题
如果AddNL是你自己编写的自定义层,那可能是层的实现不符合Keras的规范:
- 如果你的层应该返回单个张量:确保
call方法返回的是单个tf.Tensor或Keras张量,而不是列表。比如:class AddNL(Layer): def call(self, inputs): x1, x2 = inputs return x1 + x2 # 返回单个张量,不是列表 - 如果你的层需要返回多个张量:需要在层类中正确实现
compute_output_shape方法,并且call方法返回张量列表。这样Keras才会识别它是多输出层,输出才能被索引。比如:
这种情况下,你就可以安全地对输出做索引:class AddNL(Layer): def __init__(self, **kwargs): super().__init__(**kwargs) self.supports_masking = True # 可选,如果需要处理掩码 def call(self, inputs): x1, x2 = inputs add_result = x1 + x2 activated_result = tf.nn.relu(add_result) return [add_result, activated_result] # 返回张量列表 def compute_output_shape(self, input_shape): # 返回对应每个输出的形状 return [input_shape[0], input_shape[0]]merged[0]、merged[1]。
正确使用示例(单个输出场景)
from keras.layers import Input, Conv2D from keras.layers.merge import AddNL from keras.models import Model # 定义输入 input1 = Input(shape=(28, 28, 3)) input2 = Input(shape=(28, 28, 3)) # 卷积层处理 x1 = Conv2D(32, (3,3), activation='relu')(input1) x2 = Conv2D(32, (3,3), activation='relu')(input2) # 正确调用AddNL合并层 merged = AddNL()([x1, x2]) # 后续输出层 output = Conv2D(10, (1,1), activation='softmax')(merged) # 构建并查看模型 model = Model(inputs=[input1, input2], outputs=output) model.summary()
内容的提问来源于stack exchange,提问作者o12d10
相关产品推荐
相关产品推荐

