构建Keras项目以在GPU中获得可重现的结果

时间:2019-03-16 19:41:12

标签: python tensorflow keras gpu random-seed

我正在编写一个tensorflow.Keras包装器来进行ML实验。

我需要我的框架能够执行配置yaml文件中指定的实验并在GPU中并行运行。

那么我需要保证,如果我再次运行实验,即使结果不完全相同,也会得到相当接近的结果。

为确保这一点,我的训练脚本首先按照official documentation中的指南包含以下几行:

# Set up random seeds
random.seed(seed)
np.random.seed(seed)
tf.set_random_seed(seed)

事实证明这还不够。

我运行相同的配置4次,并绘制了结果:

enter image description here

如您所见,每次运行之间的结果差异很大。

如何在Keras中设置培训课程,以确保在GPU中进行培训时得到合理相似的结果?这有可能吗?

完整的培训脚本可以在here中找到。

我的一些同事正在使用just pure TF,他们的结果似乎更加一致。而且,除了确保训练和验证拆分始终相同之外,他们似乎没有任何随机性。

2 个答案:

答案 0 :(得分: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)

确保这两段代码都包含在代码的开头,那么结果将是可重复的。

答案 1 :(得分:0)

尝试将种子参数添加到权重/偏差初始值设定项。只是为了在Alexander Ejbekov的评论中添加更多细节。

Tensorflow具有两个随机种子图级别和op级别。如果使用多个图形,则需要在每个图形中指定种子。您可以通过在函数内设置种子参数来用操作级别覆盖图形级别的种子。如果设置了相同的种子,甚至可以使来自不同图形的两个函数输出相同的值。 考虑以下示例:

g1 = tf.Graph()
with g1.as_default():
    tf.set_random_seed(1)
    a = tf.get_variable('a', shape=(1,), initializer=tf.keras.initializers.glorot_normal())
    b = tf.get_variable('b', shape=(1,), initializer=tf.keras.initializers.glorot_normal(seed=2))
with tf.Session(graph=g1) as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(a)) 
    print(sess.run(b))
g2 = tf.Graph()
with g2.as_default():
    a1 = tf.get_variable('a1', shape=(1,), initializer=tf.keras.initializers.glorot_normal(seed=1))

with tf.Session(graph=g2) as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(a1))

在此示例中,a的输出与a1相同,但是b的输出不同。