如何利用 TensorFlow 获得稳定的结果,设置随机种子

2025-04-16 08:58:00
admin
原创
9
摘要:问题描述:我正在尝试使用不同的参数多次运行神经网络,以便校准网络参数(例如dropout概率、学习率等)。然而,我遇到了一个问题:即使参数保持不变,当我循环运行网络时,仍然会得到不同的结果,如下所示:filename = create_results_file() for i in range(3): g...

问题描述:

我正在尝试使用不同的参数多次运行神经网络,以便校准网络参数(例如dropout概率、学习率等)。然而,我遇到了一个问题:即使参数保持不变,当我循环运行网络时,仍然会得到不同的结果,如下所示:

filename = create_results_file()
for i in range(3):
  g = tf.Graph()
  with g.as_default():
    accuracy_result, average_error = network.train_network(
        parameters, inputHeight, inputWidth, inputChannels, outputClasses)
    f, w = get_csv_writer(filename)
    w.writerow([accuracy_result, "did run %d" % i, average_error])
    f.close()

在设置网络的层和错误函数之前,我在 train_network 函数的开始处使用以下代码:

np.random.seed(1)
tf.set_random_seed(1)

我也尝试过在 TensorFlow 图形创建之前添加此代码,但我在结果输出中不断得到不同的解决方案。

我正在使用 AdamOptimizer,并使用 初始化网络权重tf.truncated_normal。此外,我还使用np.random.permutation来对每个时期的传入图像进行打乱。


解决方案 1:

设置当前 TensorFlow 随机种子仅影响当前默认计算图。由于您正在为训练创建新计算图并将其设置为默认计算图 ( with g.as_default():),因此必须在该块的范围内设置随机种子with

例如,您的循环应如下所示:

for i in range(3):
  g = tf.Graph()
  with g.as_default():
    tf.set_random_seed(1)
    accuracy_result, average_error = network.train_network(
        parameters, inputHeight, inputWidth, inputChannels, outputClasses)

请注意,外层循环的每次迭代都会使用相同的随机种子for。如果希望每次迭代使用不同的(但仍然确定的)种子,可以使用tf.set_random_seed(i + 1)

解决方案 2:

后端设置:cuda:10.1、、、和自cudnn: 7定义tensorflow-gpu: 2.1.0模型keras: 2.2.4-tf`vgg19`

在研究了使用 GPU 训练的 tensorflow 后端和基于 keras 的大型神经网络模型的结果不稳定的问题后,我终于能够获得可重复(稳定)的结果,如下所示:

  1. 仅导入设置种子所需的库并初始化种子值

import tensorflow as tf
import os
import numpy as np
import random

SEED = 0
  1. 用于初始化所有可能具有随机行为的库的种子的函数

def set_seeds(seed=SEED):
    os.environ['PYTHONHASHSEED'] = str(seed)
    random.seed(seed)
    tf.random.set_seed(seed)
    np.random.seed(seed)
  1. 激活Tensorflow确定性行为

def set_global_determinism(seed=SEED):
    set_seeds(seed=seed)

    os.environ['TF_DETERMINISTIC_OPS'] = '1'
    os.environ['TF_CUDNN_DETERMINISTIC'] = '1'
    
    tf.config.threading.set_inter_op_parallelism_threads(1)
    tf.config.threading.set_intra_op_parallelism_threads(1)

# Call the above function with seed value
set_global_determinism(seed=SEED)

重要提示:

  • 请在执行任何其他代码之前调用上述代码

  • 由于代码是确定性的,模型训练可能会变慢,因此需要权衡

  • 我多次尝试了不同数量的 epoch 和不同的设置(包括带有 shuffle=True 的 model.fit()),上述代码给了我可重复的结果。

参考文献:

  1. https://suneeta-mall.github.io/2019/12/22/Reproducible-ml-tensorflow.html

  2. https://keras.io/getting_started/faq/#how-can-i-obtain-reproducible-results-using-keras-during-development

  3. https://www.tensorflow.org/api_docs/python/tf/config/threading/set_inter_op_parallelism_threads

  4. https://www.tensorflow.org/api_docs/python/tf/random/set_seed?version=nightly

解决方案 3:

可以通过提供图级或操作级种子来获得确定性行为。对我来说,两种方法都有效。图级种子可以通过tf.set_random_seed来设置。操作级种子可以放置在变量初始化器中,例如:

myvar = tf.Variable(tf.truncated_normal(((10,10)), stddev=0.1, seed=0))

解决方案 4:

Tensorflow 2.0 兼容答案:对于大于 2.0 的 Tensorflow 版本,如果我们要设置全局随机种子,使用的命令是tf.random.set_seed

如果我们从 迁移Tensorflow Version 1.x to 2.x,我们可以使用命令
tf.compat.v2.random.set_seed

请注意,tf.function在这种情况下,其作用就像程序的重新运行。

要设置操作级别种子(如上所述),我们可以使用命令tf.random.uniform([1], seed=1)

有关更多详细信息,请参阅此Tensorflow 页面。

解决方案 5:

由于 CuDNN 中潜在的实现问题,这些答案似乎都不起作用。

你可以通过添加额外的标志来获得更多的确定性

os.environ['PYTHONHASHSEED']=str(SEED)
os.environ['TF_CUDNN_DETERMINISTIC'] = '1'  # new flag present in tf 2.0+
random.seed(SEED)
np.random.seed(SEED)
tf.set_random_seed(SEED)

但这仍然不是完全确定的。为了获得更精确的解决方案,您需要使用此 nvidia repo中概述的步骤。

解决方案 6:

请在代码前添加所有随机种子函数:

tf.reset_default_graph()
tf.random.set_seed(0)
random.seed(0)
np.random.seed(0)

我认为,TensorFlow 中的某些模型正在使用 numpy 或 python 随机函数。

解决方案 7:

我正在使用 TensorFlow 2 (2.2.0),并在 JupyterLab 中运行代码。我在 macOS Catalina 和 Google Colab 中测试过,结果相同。我会在TensorFlow 支持人员的回答中添加一些内容。

当我使用 model.fit() 方法进行训练时,我会在一个单元格中进行。我在其他单元格中执行其他操作。这是我在上述单元格中运行的代码:

# To have same results always place this on top of the cell
tf.random.set_seed(1)

(x_train, y_train), (x_test, y_test) = load_data_onehot_grayscale()
model = get_mlp_model_compiled() # Creates the model, compiles it and returns it

history = model.fit(x=x_train, y=y_train,
                    epochs=30,
                    callbacks=get_mlp_model_callbacks(),
                    validation_split=.1,
                   )

我的理解是这样的:

  1. TensorFlow 会在不同的阶段(初始化、重排等)执行一些随机过程,每次执行这些过程时,TensorFlow 都会使用一个随机函数。当您设置种子时,tf.random.set_seed(1)这些过程也会使用它。如果种子已设置,而这些过程保持不变,则结果将保持不变。

  2. 现在,在上面的代码中,如果我更改tf.random.set_seed(1)为低于该线,model = get_mlp_model_compiled()我的结果就会改变,我相信这是因为get_mlp_model_compiled()使用了随机性并且没有使用我想要的种子。

  3. 关于第 2 点的注意事项:如果我连续运行该单元 3 次,我会得到相同的结果。我认为这是因为第一次运行get_mlp_model_compiled()没有使用 TensorFlow 的内部计数器和我的种子。第二次运行会使用种子,并且所有后续运行也会使用这个种子,所以第二次运行之后的结果会相同。

我可能有一些信息错误,所以请随时纠正我。

要了解发生了什么,您应该阅读文档,它们不太长并且很容易理解。

解决方案 8:

这个答案是对Luke 的答案的补充,也是针对 TF v2.2.0 的

import numpy as np
import os
import random
import tensorflow as tf # 2.2.0

SEED = 42
os.environ['PYTHONHASHSEED']=str(SEED)
os.environ['TF_CUDNN_DETERMINISTIC'] = '1'  # TF 2.1
random.seed(SEED)
np.random.seed(SEED)
tf.random.set_seed(SEED)
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2329  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1502  
  在当今快速变化的商业环境中,项目管理工具已成为企业提升效率、优化资源分配和确保项目成功的关键。无论是初创公司还是大型企业,选择合适的项目管理软件都能显著提高团队协作和项目交付的质量。本文将为您推荐2025年不同规模企业的10个专业项目管理工具,帮助您找到最适合的解决方案。信创国产项目管理软件 - 禅道禅道是一款国产开源...
项目管理平台   1  
  工程项目管理涉及众多环节与复杂流程,从项目规划、资源分配到进度跟踪、成本控制等,每一步都对项目的成功交付起着关键作用。在数字化时代,借助专业的工程项目管理软件能极大提升管理效率与质量。然而,面对市场上琳琅满目的软件产品,如何选择适合的软件并熟练运用,成为众多工程项目管理者亟待解决的问题。明确自身需求在选择工程项目管理软...
项目风险管理   1  
  PLM(产品生命周期管理)项目管理旨在确保产品从概念到退役的整个生命周期内的有效规划、执行和控制。然而,在项目推进过程中,黑天鹅事件的出现往往会打乱原有的计划和节奏。黑天鹅事件具有意外性、重大影响和事后可解释性的特点,给PLM项目管理带来巨大挑战。如何有效应对这些难以预测的事件,制定合理的应急计划,成为项目管理者必须面...
plm研发管理系统   20  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用