使用Tensorflow后端运行Keras如何获得可重复的结果

19
每次在jupyter笔记本中运行Keras的LSTM网络时,我得到不同的结果,我已经搜索了很多并尝试了一些不同的解决方案,但它们都没有起作用,这是我尝试过的一些解决方案:
  1. 设置numpy随机种子

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

  2. 设置tensorflow随机种子

    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')

结果可能因为不同的原因而有所不同(例如变量的随机初始化)。因此,除非您提供一些模型代码,否则我们只能提供有限的帮助。 - dv3
请查看我在这里的回答(https://dev59.com/slwY5IYBdhLWcg3wnY13#52897216),关于使用CPU的问题。 - Outcast
您尚未接受任何答案。以下哪个对您起作用了,或者您找到了更好的解决方案? - Dr Nisha Arora
3个回答

13

您的模型定义中明确缺少种子。详细文档可以在此处找到: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在其常见问题解答(FAQ)部分中有关于如何获得可重现结果的说明: (https://keras.io/getting-started/faq/#how-can-i-obtain-reproducible-results-using-keras-during-development)。他们提供以下代码片段以产生可重复的结果:

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://dev59.com/l57ha4cB1Zd3GeqPo9B0

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)

3
为了清晰明确,keras.io的常见问题解答要求您使涉及的所有随机数生成器都具备种子,这样无需“额外”提供种子参数来初始化层以创建可重现的结果。(我的理解,但不做任何保证。) - tanius
每个层都添加种子参数会太麻烦,所以我们需要将上述代码粘贴到笔记本的开头吗?作为非编程背景的人,我很难理解这段代码。 - Dr Nisha Arora
@DrNishaArora 是的。它们是伪随机数。伪随机数为相同的种子生成相同的数字序列。通常,当您启动Python脚本时,种子会通过当前时间戳进行初始化。因此,每次运行都会以不同的种子开始。此代码通过您的常量值覆盖了从时间戳初始化的种子。@ThomasPintez 请更新到v2.x:它们可以工作,但我们必须使用tf.compat.v1 - Dzwiedziu-nkg

0

Keras + Tensorflow。

第一步,禁用GPU。

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

第二步,对包含在您的代码中的库进行初始化,例如“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)。请提供建议。 - Dr Nisha Arora
为什么禁用GPU对于可重复性很重要? - James Mishra
1
@DrNishaArora 请使用 tf.compat.v1。例如,请使用:tf.compat.v1.set_random_seed 而不是 tf.set_random_seed。已在2.7.0上测试通过。禁用GPU是不必要的。 - Dzwiedziu-nkg

0

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

以下是一个示例:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接