自定义数据集超参数调优模型编译失败:NotImplementedError报错求助
解决Kerastuner超参数调优中ANN模型无法编译的问题
嘿,我帮你找出了代码里导致模型编译失败的几个关键问题,尤其是触发NotImplementedError的核心bug,下面一步步给你讲清楚怎么修复:
核心问题:HyperModel的方法名不符合要求
Kerastuner的HyperModel类有个硬性要求——必须实现**build(hp)**方法,因为框架会自动调用这个方法来构建模型。但你写的是buildModel(hp),框架找不到正确的构建入口,直接抛出了NotImplementedError,这就是反复报错的根源。
其他需要修复的细节问题
除了核心方法名的问题,还有几个小错误也会影响模型编译:
- TensorFlow/Keras命名空间不一致:你导入了
tensorflow,但代码里却用keras.Sequential这种写法,容易导致命名冲突,建议统一使用tensorflow.keras的完整命名空间。 - 输入形状错误:
x_train.shape返回的是(样本数, 特征数),而模型的input_shape只需要特征维度(比如(10,)如果有10个特征),所以应该改成x_train.shape[1:]。 - 类属性引用错误:循环添加中间层时,你直接用了
layers,但这是类的初始化参数,应该用self.layers来引用类实例的属性。 - API拼写/格式错误:
- Kerastuner的超参数方法都是大写开头,
hp.float要改成hp.Float - 编译模型时的
metrcis是拼写错误,正确写法是metrics - 单个损失函数不需要用列表包裹,
loss=['sparse_categorical_crossentropy']可以简化为loss='sparse_categorical_crossentropy'
- Kerastuner的超参数方法都是大写开头,
- 超参数命名重复:循环中如果直接用
units、dropout这类名称,会导致超参数命名冲突,建议给每个层的超参数加索引后缀(比如units_0、dropout_1)
修复后的完整代码
import tensorflow as tf import pandas as pd from kerastuner import HyperModel from tensorflow.keras.layers import Dense, Dropout # 加载数据 ds = pd.read_csv("datasets/ds1.csv") # 预处理数据 jaartallen = ds.pop("jaartallen") y = ds.pop("inkomstenbelasting") y_train = y.drop(index=[6, 15, 19, 23], axis=0) y_test = y.loc[[6, 15, 19, 23]] x_train = ds.drop(index=[6, 15, 19, 23], axis=0) x_test = ds.loc[[6, 15, 19, 23]] print(x_train.shape) # ANN超模型 class ANNHyperModel(HyperModel): def __init__(self, input_shape, num_classes, layers): self.input_shape = input_shape self.num_classes = num_classes self.layers = layers # 核心修改:方法名改为build def build(self, hp): model = tf.keras.Sequential() # 添加输入层 model.add(Dense( units=6, input_shape=self.input_shape, activation='relu')) # 添加中间层 for i in range(self.layers): model.add( Dense( units=hp.Int( f'units_{i}', # 给超参数加索引后缀,避免命名冲突 min_value=1, max_value=10, step=5, default=30 ), activation=hp.Choice( f'dense_activation_{i}', values=['relu', 'tanh', 'sigmoid'], default='relu' ) ) ) model.add( Dropout( rate=hp.Float( f'dropout_{i}', min_value=0.0, max_value=0.5, default=0.25, step=0.05 ) ) ) # 添加输出层 model.add(Dense(self.num_classes, activation='softmax')) # 编译模型 model.compile( optimizer=tf.keras.optimizers.Adam( hp.Float( 'learning_rate', min_value=2E-2, max_value=4E-2, sampling='LOG', default=3E-2) ), loss='sparse_categorical_crossentropy', metrics=['accuracy'] ) return model NUM_CLASSES = 65000 # 修正输入形状:只取特征维度 INPUT_SHAPE = x_train.shape[1:] LAYERS = 5 hypermodel = ANNHyperModel(num_classes=NUM_CLASSES, input_shape=INPUT_SHAPE, layers=LAYERS) from kerastuner.tuners import RandomSearch MAX_TRIALS = 20 EXECUTION_PER_TRIAL = 2 tuner = RandomSearch( hypermodel, objective='val_accuracy', seed=1, max_trials=MAX_TRIALS, executions_per_trial=EXECUTION_PER_TRIAL, directory='random_search', project_name='inkomstenbelasting' )
另外提个小建议:你的NUM_CLASSES设置为65000,看起来更像是回归任务(预测收入数值),但目前用了分类任务的sparse_categorical_crossentropy损失函数和softmax激活。如果是回归任务,建议把输出层改成Dense(1, activation='linear'),损失函数用mean_squared_error,这样更符合任务逻辑。
内容的提问来源于stack exchange,提问作者IzzyGiessen
相关产品推荐
相关产品推荐

