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

Waa*_*ers 56 python numpy tensorflow

我试图用不同的参数多次运行神经网络,以便校准网络参数(丢失概率,学习率ed).但是我遇到的问题是,当我在循环中运行网络时,运行网络同时保持参数相同仍然给我一个不同的解决方案,如下所示:

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()
Run Code Online (Sandbox Code Playgroud)

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

np.random.seed(1)
tf.set_random_seed(1)
Run Code Online (Sandbox Code Playgroud)

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

我正在使用AdamOptimizer并使用初始化网络权重tf.truncated_normal.此外,我正在使用np.random.permutation为每个纪元改变传入的图像.

mrr*_*rry 42

设置当前TensorFlow随机种子仅影响当前默认图形.由于您要为训练创建新图并将其设置为default(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)
Run Code Online (Sandbox Code Playgroud)

请注意,这将为外for循环的每次迭代使用相同的随机种子.如果要在每次迭代中使用不同但仍具有确定性的种子,则可以使用tf.set_random_seed(i + 1).

  • 原因将取决于您的函数是什么,但精度计算中的微小差异可能是由于像`tf.reduce_sum()`这样的操作中的非确定性并行减少引起的.(这些操作将浮点加法视为可交换,实际上它不是,并且还原顺序的变化可能导致结果中的轻微错误....) (5认同)
  • 我相信我的set_random_seed(1)已经在g.as_default()块中,因为它是train_network代码中的第一行.尽管如此,我已尝试将代码放在您的示例中,但我仍然得到不稳定的结果:>准确性标签错误> 0.9805确实运行0 2.96916> 0.9807运行1 2.96494> 0.9804运行2 2.95215 (4认同)

Ten*_*ort 16

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 页面


sse*_*vic 13

可以通过提供图级或操作级种子来获得确定性行为.两者都适合我.可以使用tf.set_random_seed放置图级别种子.操作级种子可以放置在例如变量初始化器中,如下所示:

myvar = tf.Variable(tf.truncated_normal(((10,10)), stddev=0.1, seed=0))
Run Code Online (Sandbox Code Playgroud)


小智 8

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

tf.reset_default_graph()
tf.random.set_seed(0)
random.seed(0)
np.random.seed(0)
Run Code Online (Sandbox Code Playgroud)

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


Luk*_*uke 7

由于 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)
Run Code Online (Sandbox Code Playgroud)

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


Dan*_*Dan 7

后端设置:cuda:10.1cudnn: 7tensorflow-gpu: 2.1.0keras: 2.2.4-tf,和vgg19定制模式

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

  1. 仅导入设置种子和初始化种子值所需的那些库
import tensorflow as tf
import os
import numpy as np
import random

SEED = 0
Run Code Online (Sandbox Code Playgroud)
  1. 为所有可能具有随机行为的库初始化种子的函数
def set_seeds(seed=SEED):
    os.environ['PYTHONHASHSEED'] = str(seed)
    random.seed(seed)
    tf.random.set_seed(seed)
    np.random.seed(seed)
Run Code Online (Sandbox Code Playgroud)
  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)
Run Code Online (Sandbox Code Playgroud)

重要笔记:

  • 请在执行任何其他代码之前调用上面的代码
  • 由于代码是确定性的,模型训练可能会变慢,因此需要权衡
  • 我用不同数量的 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