You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用cross_val_predict时Keras模型无法克隆的报错原因排查

自定义损失函数的MLP回归任务中cross_val_predict报错原因

问题背景

正在实现一个MLP对数据集执行回归任务,在model.compile()中使用了自定义损失函数,相关代码如下:

input_dim = 24
output_dim = 1

# 定义Spearman秩相关系数作为自定义损失函数
def spearman_rank_correlation(y_true, y_pred):
    corr = tfp.stats.correlation(y_true, y_pred)
    return -corr

def rank_loss(y_true, y_pred):
    true_ranks = tf.argsort(tf.argsort(y_true, axis=1), axis=1)
    pred_ranks = tf.argsort(tf.argsort(y_pred, axis=1), axis=1)
    return tf.keras.losses.mean_squared_error(true_ranks, pred_ranks)


model = tf.keras.models.Sequential([
  tf.keras.layers.Dense(64, activation='relu', input_dim=input_dim),
  tf.keras.layers.Dense(64, activation='relu'),
  tf.keras.layers.Dense(output_dim, activation='linear')
])
model.compile(optimizer='adam', loss=tfp.stats.correlation)

model.fit(X_train_fr, Y_train, epochs=100, batch_size=32)

pred_train = cross_val_predict(model, X_train_fr, Y_train, cv=5)

调用cross_val_predict()时出现如下报错:

Cannot clone object '<keras.engine.sequential.Sequential object at 0x0000021DFE729190>' (type    <class 'keras.engine.sequential.Sequential'>): it does not seem to be a scikit-learn estimator as it does not implement a 'get_params' method.

报错原因

  • scikit-learn的cross_val_predict()函数要求传入的模型必须符合scikit-learn estimator接口规范,核心要求是模型必须实现get_params()和set_params()方法——交叉验证过程中需要为每个fold克隆独立的模型实例,这两个方法是克隆操作的基础。
  • 原生的Keras Sequential模型并没有实现scikit-learn的estimator接口,因此无法被scikit-learn的交叉验证函数识别和处理,从而抛出该错误。
  • 额外提示:你直接使用tfp.stats.correlation作为损失函数的写法存在问题,该函数返回的是相关系数,损失函数需要是可微分的优化目标,应该使用你定义的spearman_rank_correlation(取负后让优化器最大化相关系数),不过这不是当前报错的直接原因。

快速解决方向

要在Keras模型上使用scikit-learn的交叉验证工具,需要用tf.keras.wrappers.scikit_learn.KerasRegressor将Keras模型包装成符合scikit-learn接口的estimator,示例代码如下:

from tensorflow.keras.wrappers.scikit_learn import KerasRegressor

def build_model():
    model = tf.keras.models.Sequential([
      tf.keras.layers.Dense(64, activation='relu', input_dim=input_dim),
      tf.keras.layers.Dense(64, activation='relu'),
      tf.keras.layers.Dense(output_dim, activation='linear')
    ])
    model.compile(optimizer='adam', loss=spearman_rank_correlation)
    return model

# 包装Keras模型
sk_model = KerasRegressor(build_fn=build_model, epochs=100, batch_size=32)

# 现在可以正常调用cross_val_predict
pred_train = cross_val_predict(sk_model, X_train_fr, Y_train, cv=5)

内容的提问来源于stack exchange,提问作者Virgile BRIAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:13:39