新版Keras Tuner超参搜索报Unknown initializer: relu错误咨询
问题描述
使用新版Keras Tuner开展神经网络超参数搜索时,会抛出旧版本从未出现的非预期报错:
ValueError: Unknown initializer: relu. Please ensure this object is passed to the
custom_objectsargument.
存在两点明确疑问:
- 无法解释
relu被当作初始化器传入的逻辑:按照Keras Tuner官方文档写法定义学习率超参数时程序直接中断,对应代码如下:
hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4]) model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=hp_learning_rate), loss=self.loss_function, metrics=['sparse_categorical_accuracy', 'accuracy'])
将学习率改为固定值0.001后,代码可正常运行,对应代码如下:
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss=self.loss_function, metrics=['sparse_categorical_accuracy', 'accuracy'])
- 代码中未手动指定任何权重初始化器,所有初始化配置均使用框架默认值,不存在手动传入
relu作为初始化器的操作。
触发原因
该问题是Keras Tuner 1.4.x及以上版本与TensorFlow 2.10+版本存在的序列化兼容bug:
当超参数对象在模型构建作用域外提前赋值给中间变量、或未被Keras Tuner的超参数追踪逻辑正确捕获时,框架执行模型序列化保存/克隆的流程中,会错误遍历计算图节点,把层定义中以字符串形式书写的activation='relu'错误解析为初始化器对象。
学习率传入hp对象时会触发该序列化校验流程,传入固定数值时会跳过该流程,因此固定学习率的写法不会触发报错。
解决方法
- 不要提前将超参数赋值给中间变量,所有
hp.Choice、hp.Float等超参数调用直接写在模型构建函数内部,且直接作为参数传入对应组件,修改示例如下:
# 移除提前赋值的中间变量 # hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4]) model.compile(optimizer=tf.keras.optimizers.Adam( # 直接在参数位调用超参数方法 learning_rate=hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4]) ), loss=self.loss_function, metrics=['sparse_categorical_accuracy', 'accuracy'])
- 如果上述修改后仍报错,可将所有层中以字符串形式传入的激活函数改为显式的Keras激活函数对象,避免序列化时类型识别错误,例如将层定义中的
activation='relu'替换为activation=tf.keras.activations.relu。 - 临时兼容方案:将Keras Tuner版本降级至1.3.5,TensorFlow版本锁定至2.9.x,该版本区间不存在此序列化兼容问题。
内容的提问来源于stack exchange,提问作者Irina Timoshenko
相关产品推荐
相关产品推荐

