为何设置随机种子后仍无法复现Keras神经网络网格搜索的实验结果
问题核心原因
你遇到的无法复现结果的问题由多个错误共同导致:
- 随机种子调用位置错误:你仅在网格搜索代码的最外层调用了一次
set_seed(),每次循环训练模型的过程都会消耗随机数、改变全局随机状态,因此网格搜索中第二轮(神经元数为2、学习率为0.08889的那组)训练开始时的随机状态,和你单独跑模型时重新调用set_seed()后的初始随机状态完全不同,模型权重初始化、训练过程的随机逻辑都不一致,结果自然有差异。 - 验证集切分逻辑随机:你使用了Keras的
validation_split=0.5参数,该参数会在每次调用fit()时根据当前随机状态随机切分训练集和验证集,网格搜索中每一轮的验证集都不相同,和你单独跑时的验证集也不一致,MSE的计算基准本来就不同。 set_seed()函数本身存在错误和疏漏:- 代码中
tf1.get_default_graph()存在未定义变量tf1的笔误,应该改为tf.compat.v1.get_default_graph() - 缺少计算图和会话清空逻辑,旧模型的残留变量会影响后续训练的随机状态
- 代码中
- 学习率精度偏差:你打印出来的最优学习率
0.088890是截断后的值,实际np.linspace生成的学习率精度更高,手动输入的截断值和实际最优参数存在偏差,也会影响训练结果。
修复方案
- 修正
set_seed()函数,增加清空逻辑:
def set_seed(seed_value=42): # 先清空现有会话和计算图,避免残留变量影响 K.clear_session() tf.compat.v1.reset_default_graph() os.environ['PYTHONHASHSEED'] = str(seed_value) session_conf = tf.compat.v1.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1) sess = tf.compat.v1.Session(graph=tf.compat.v1.get_default_graph(), config=session_conf) np.random.seed(seed_value) random.seed(seed_value) tf.random.set_seed(seed_value) K.set_session(sess)
- 提前固定验证集:不要使用
validation_split,手动提前切分好固定的训练集和验证集,每次训练都传入固定的validation_data参数,保证验证集一致。 - 调整种子调用位置:网格搜索的每一轮循环开始前、单独跑模型前都调用
set_seed(),保证每次训练的初始随机状态完全一致。 - 直接使用精确参数:不要手动抄写打印的截断学习率,直接取用
learning_rates数组中对应索引的精确值传入优化器。
内容的提问来源于stack exchange,提问作者Lucian
相关产品推荐
相关产品推荐

