CenterCrop与Resizing层为何自动将training设为true?
为什么CenterCrop和Resizing层会自动将training设置为True?
这个现象是Keras 3对数据预处理类层的设计特性导致的,具体原因和解决方式如下:
核心原因
CenterCrop和Resizing属于预处理层,它们的call方法在定义时默认将training参数设为True,而卷积、池化等常规层的call方法中training参数默认是None(由模型的训练/推断上下文自动传递)。
在Keras的源码实现中,这两个层的调用逻辑类似:
def call(self, inputs, training=True): # 层的具体处理逻辑
而像Conv2D这类层的调用逻辑是:
def call(self, inputs, training=None): # 层的具体处理逻辑
当构建模型时,层的节点会记录调用时传入的参数值,因此CenterCrop和Resizing的节点会固定training=True,而其他层因为training未被显式设置,所以节点中不会有这个参数。
为什么构造函数不能设置training?
training是层的call方法参数,而非构造函数的初始化参数。这两个层的构造函数没有定义training参数,直接在创建层时传入training=False自然会触发参数不识别的错误。
如何修改training状态?
如果需要让这两个层在推断模式下运行,可以在**调用层(即连接输入时)**显式传递training参数,而非在构造层时传递:
from keras import Model from keras.layers import Conv2D, CenterCrop, Input, GlobalMaxPooling2D, Resizing inputs = [Input(shape=(256, 256, 3))] outputs = [ Conv2D(8, (3, 3))(inputs[0]), GlobalMaxPooling2D()(inputs[0]), # 调用时显式设置training=False CenterCrop(128, 128)(inputs[0], training=False), Resizing(64, 64)(inputs[0], training=False), ] model = Model(inputs=inputs, outputs=outputs) # 验证输出 layers = model.layers for layer in layers: layer_type = type(layer).__name__ for node in layer._inbound_nodes: training_flag = None if "training" in node.arguments.kwargs: training_flag = node.arguments.kwargs["training"] print(layer_type, training_flag)
修改后的输出结果:
InputLayer None Conv2D None GlobalMaxPooling2D None CenterCrop False Resizing False
内容的提问来源于stack exchange,提问作者Tobias Hermann
相关产品推荐
相关产品推荐

