TensorFlow自定义Layer模型无参数显示,无法正常工作问题排查
自定义Keras Layer在model.summary()中显示为TFOpLambda且参数为0的问题
我正在为模型自定义一个Layer,核心部分是call函数,代码如下:
class Custom_Layer(Layer): # some code def call(self, inputs, **kwargs): kernel = mul(self.base, self.diag_start - self.diag_end) outputs = matmul(a=inputs, b=kernel) if self.use_bias: outputs = tf.nn.bias_add(outputs, self.bias) if self.activation is not None: outputs = self.activation(outputs) return outputs # some code
我将其用于一个简单模型中:
inputs = tf.keras.layers.Input(shape=(784,),dtype='float32') layer1 = Custom_layer(2000, **Custom_layer_config, activation='tanh')(inputs) layer2 = Custom_layer(200, **Custom_layer_config, activation='tanh')(layer1) output_lay = Custom_layer(10, **Custom_layer_config, activation='softmax')(layer2) model = tf.keras.models.Model(inputs=inputs, outputs=output_lay) opt = tf.keras.optimizers.Adamax(learning_rate=0.02) model.compile(optimizer=opt, loss='sparse_categorical_crossentropy', metrics=['accuracy']) model.summary()
预期的model.summary()输出应包含自定义层及对应参数,但实际输出仅显示TFOpLambda层且参数总数为0。我运行的是作者仓库的原代码,未做修改,想询问该问题的原因。
问题原因分析
- 未正确注册可训练参数:Keras要求自定义层必须通过
add_weight()方法注册可训练参数(比如self.base、self.bias等),如果你的Custom_Layer在__init__或build方法中没有做这件事,Keras无法识别这些参数属于该层,会把整个层的逻辑当作普通TensorFlow操作,包装成TFOpLambda,自然不会统计参数。 - 类名与实例化名称不匹配:自定义类名为
Custom_Layer,但实例化时用了Custom_layer(首字母L小写),如果这不是笔误,Python会认为这是两个不同的类,你实例化的可能不是你定义的那个自定义层,而是其他未正确实现的类。 - 缺失
build方法实现:如果自定义层的参数依赖输入张量的形状,必须在build方法中初始化权重。跳过这一步的话,Keras在模型构建阶段无法确定层的参数数量,会导致层无法被正确识别为标准Keras层。 - 激活函数参数处理错误:实例化层时传入了字符串格式的激活函数(比如
activation='tanh'),如果自定义层内部没有通过tf.keras.activations.get()将字符串转换为对应的激活函数对象,会导致层的逻辑异常,被Keras当作普通操作处理。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

