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

GridSearchCV多次运行结果不一致的随机性来源排查

问题分析:GridSearchCV搭配KFold(无shuffle)仍存在随机性的原因

你已经做了不少固定随机性的操作,但仍出现结果不一致,以下是几个可能的遗漏点:

1. 模型权重初始化未显式绑定随机种子

你在全局设置了TensorFlow和numpy的种子,但make_model函数中创建的Dense层没有显式指定初始化器的种子。虽然全局种子理论上会控制默认初始化器的随机行为,但Keras的部分初始化逻辑可能存在全局种子覆盖或未完全生效的情况,尤其是当代码中存在多次种子设置时(你代码里先后设置了seed=1和seed=7两次TensorFlow种子,可能导致种子状态混乱)。

2. random_state参数未实际作用于模型

你在param_grid中加入了random_state,但make_model函数只是接收了这个参数,并没有将其用于控制模型的随机性(比如初始化器的种子),相当于这个参数是无效的,没有起到固定随机性的作用。

3. 优化器的隐性随机性

部分优化器(比如Adam)的内部状态初始化可能存在隐性随机性,即使权重初始化固定,优化器的动量项、自适应学习率的初始计算可能受线程调度或底层TensorFlow操作的影响,尤其是当GridSearchCV启用多线程(n_jobs>1)时,线程执行顺序的差异会导致结果不一致。

4. 重复设置种子导致状态混乱

你的代码中先后两次设置了TensorFlow种子:

# 第一次
seed(1)
tf.random.set_seed(seed)
# 第二次
seed = 7
tf.random.set_seed(seed)

重复设置种子会打乱随机数生成器的状态,可能导致之前的种子设置失效,反而引入随机性。


解决步骤

  1. 统一种子设置,只在代码最开始执行一次:

    import numpy as np
    import tensorflow as tf
    import random
    
    # 全局固定种子,放在所有代码最前面
    SEED = 42
    np.random.seed(SEED)
    tf.random.set_seed(SEED)
    random.seed(SEED)
    
  2. 将random_state参数实际用于模型初始化:
    修改make_model函数,把random_state传给Dense层的初始化器:

    def make_model(optimizer="adam", hidden_size1=32, hidden_size2=32, hidden_size3=32, random_state=42):
        model = tf.keras.Sequential()
        # 显式设置初始化器的种子
        init = tf.keras.initializers.GlorotUniform(seed=random_state)
        model.add(tf.keras.layers.Dense(hidden_size1, activation=activation, 
                                        input_shape=(X_train.shape[1],),
                                        kernel_initializer=init)) 
        model.add(tf.keras.layers.Dense(hidden_size2, activation=activation, kernel_initializer=init)) 
        model.add(tf.keras.layers.Dense(hidden_size3, activation=activation, kernel_initializer=init)) 
        model.add(tf.keras.layers.Dense(y_train.shape[1], activation='linear'))
    
        model.compile(loss='mse', optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate), metrics=['accuracy'])
        return model
    
  3. 禁用GridSearchCV的多线程:
    创建GridSearchCV实例时,设置n_jobs=1,避免多线程调度带来的随机性:

    grid = GridSearchCV(clf, param_grid=param_grid, cv=cv, return_train_score=True, n_jobs=1)
    
  4. 确认数据无意外修改:
    确保每次运行前X_train和y_train都是完全相同的数据集,没有在其他代码块中被打乱或修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:45:32