【问题标题】:How to get reproducible result when running Keras with Tensorflow backend使用 Tensorflow 后端运行 Keras 时如何获得可重现的结果
【发布时间】:2017-12-27 01:54:53
【问题描述】:

每次我在 jupyter notebook 中使用 Keras 运行 LSTM 网络时,我都会得到不同的结果,并且我在 google 上搜索了很多,我尝试了一些不同的解决方案,但它们都不起作用,以下是我尝试的一些解决方案:

  1. 设置 numpy 随机种子

    random_seed=2017 from numpy.random import seed seed(random_seed)

  2. 设置张量流随机种子

    from tensorflow import set_random_seed set_random_seed(random_seed)

  3. 设置内置随机种子

    import random random.seed(random_seed)

  4. 设置 PYTHONHASHSEED

    import os os.environ['PYTHONHASHSEED'] = '0'

  5. 在 jupyter notebook kernel.json 中添加 PYTHONHASHSEED

    { "language": "python", "display_name": "Python 3", "env": {"PYTHONHASHSEED": "0"}, "argv": [ "python", "-m", "ipykernel_launcher", "-f", "{connection_file}" ] }

我的环境版本是:

Keras: 2.0.6
Tensorflow: 1.2.1
CPU or GPU: CPU

这是我的代码:

model = Sequential()
model.add(LSTM(16, input_shape=(time_steps,nb_features), return_sequences=True))
model.add(LSTM(16, input_shape=(time_steps,nb_features), return_sequences=False))
model.add(Dense(8,activation='relu'))        
model.add(Dense(1,activation='linear'))
model.compile(loss='mse',optimizer='adam')

【问题讨论】:

  • 结果可能因不同的原因而有所不同(例如随机启动变量)。所以除非你提供一些模型代码,否则我们只能提供这么多帮助
  • 请在此处查看我的回复 (stackoverflow.com/a/52897216/9024698),了解使用 CPU 时的情况。
  • 您尚未接受任何答案。以下哪项对您有用或您找到了更好的解决方案?

标签: tensorflow deep-learning keras lstm


【解决方案1】:

您的模型定义中肯定缺少种子。可以在此处找到详细文档:https://keras.io/initializers/

本质上,您的层使用随机变量作为其参数的基础。因此,您每次都会得到不同的输出。

一个例子:

model.add(Dense(1, activation='linear', 
               kernel_initializer=keras.initializers.RandomNormal(seed=1337),
               bias_initializer=keras.initializers.Constant(value=0.1))

Keras 自己在其常见问题解答部分中有一个关于获得可重现结果的部分:(https://keras.io/getting-started/faq/#how-can-i-obtain-reproducible-results-using-keras-during-development)。他们有以下代码 sn-p 来产生可重现的结果:

import numpy as np
import tensorflow as tf
import random as rn

# The below is necessary in Python 3.2.3 onwards to
# have reproducible behavior for certain hash-based operations.
# See these references for further details:
# https://docs.python.org/3.4/using/cmdline.html#envvar-PYTHONHASHSEED
# https://github.com/fchollet/keras/issues/2280#issuecomment-306959926

import os
os.environ['PYTHONHASHSEED'] = '0'

# The below is necessary for starting Numpy generated random numbers
# in a well-defined initial state.

np.random.seed(42)

# The below is necessary for starting core Python generated random numbers
# in a well-defined state.

rn.seed(12345)

# Force TensorFlow to use single thread.
# Multiple threads are a potential source of
# non-reproducible results.
# For further details, see: https://stackoverflow.com/questions/42022950/which-seeds-have-to-be-set-where-to-realize-100-reproducibility-of-training-res

session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)

from keras import backend as K

# The below tf.set_random_seed() will make random number generation
# in the TensorFlow backend have a well-defined initial state.
# For further details, see: https://www.tensorflow.org/api_docs/python/tf/set_random_seed

tf.set_random_seed(1234)

sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
K.set_session(sess)

【讨论】:

  • 为清楚起见:keras.io 常见问题解答让您为所有涉及的随机数生成器提供种子,因此无需另外为层初始化提供种子参数以创建可重现的结果。 (我的理解,但不能保证。)
  • 给每一层添加种子参数太多了,所以我们需要在笔记本的开头粘贴上面的代码吗?由于非编程背景,我很难理解这段代码。
  • @DrNishaArora 是的。它们是伪随机数。伪随机数为相同的种子生成相同的数列。通常,当您启动 Python 脚本时,种子由当前时间戳初始化。因此,每次运行都以不同的种子开始。此代码通过您的常量值覆盖来自时间戳的初始化种子。 @ThomasPintez 请更新 v2.x:它们可以工作,但我们必须使用 tf.compat.v1
【解决方案2】:

Keras + TensorFlow。

第 1 步,禁用 GPU。

import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = ""

第 2 步,为您的代码中包含的那些库提供种子,例如“tensorflow、numpy、random”。

import tensorflow as tf
import numpy as np
import random as rn

sd = 1 # Here sd means seed.
np.random.seed(sd)
rn.seed(sd)
os.environ['PYTHONHASHSEED']=str(sd)

from keras import backend as K
config = tf.ConfigProto(intra_op_parallelism_threads=1,inter_op_parallelism_threads=1)
tf.set_random_seed(sd)
sess = tf.Session(graph=tf.get_default_graph(), config=config)
K.set_session(sess)

确保这两条代码包含在代码的开头,然后结果将是可重现的。

【讨论】:

  • 这对我不起作用。我在 Google Co-lab 中使用来自 tensorflow (1.14.0) 的 keras (2.2.4-tf)。请提出建议。
  • 为什么禁用 GPU 以实现重现性?
  • @DrNishaArora 请使用tf.compat.v1。例如,请使用:tf.compat.v1.set_random_seed 而不是 tf.set_random_seed。在 2.7.0 上测试。不需要禁用 GPU。
【解决方案3】:

我通过添加os.environ['TF_DETERMINISTIC_OPS'] = '1'解决了这个问题

这里是一个例子:

import os
os.environ['TF_DETERMINISTIC_OPS'] = '1'
#rest of the code
#TensorFlow version 2.3.1

【讨论】:

    猜你喜欢
    • 2020-07-19
    • 2019-12-06
    • 1970-01-01
    • 2018-02-02
    • 2015-12-01
    • 2016-11-12
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    相关资源
    最近更新 更多