首页 文章

如何在keras中获得可重现的结果

提问于
浏览
46

每次从Keras框架(https://github.com/fchollet/keras/blob/master/examples/imdb_lstm.py)运行 imdb_lstm.py 示例时,我得到不同的结果(测试准确性)在任何keras导入之前,代码在顶部包含 np.random.seed(1337) . 它应该防止它为每次运行生成不同的数字 . 我错过了什么?

更新:如何重新制作:

UPDATE2:我在带有MinGW / msys的模块版本的Windows 8.1上运行它:
theano 0.7.0
numpy 1.8.1
scipy 0.14.0c1

更新3:我把问题缩小了一点 . 如果我用GPU运行示例(设置theano flag device = gpu0),那么每次都会得到不同的测试精度,但是如果我在CPU上运行它,那么一切都按预期工作 . 我的显卡:NVIDIA GeForce GT 635)

6 回答

  • 0

    我同意之前的评论,但可重现的结果有时需要相同的环境(例如已安装的软件包,机器特性等) . 因此,我建议将您的环境复制到其他地方,以便获得可重现的结果 . 尝试使用以下技术之一:

    • Docker . 如果你有Linux,这很容易将你的环境转移到其他地方 . 您也可以尝试使用DockerHub .

    • Binder . 这是一个用于复制科学实验的 Cloud 平台 .

    • Everware . 这是"reusable science"的另一个 Cloud 平台 . 请参阅Github上的project repository .

  • 1

    我终于用我的代码获得了可重现的结果 . 这是我在网上看到的答案的组合 . 首先是做@alex所说的:

    • 设置 numpy.random.seed ;

    • 使用 PYTHONHASHSEED=0 for Python 3 .

    然后你必须通过调用你的Keras代码解决有关cuDNN的@ user2805751注意到的问题,其中包含以下附加内容: THEANO_FLAGS

    • dnn.conv.algo_bwd_filter=deterministic,dnn.conv.algo_bwd_data=deterministic

    最后,您必须根据this comment修补您的Theano安装,其基本包括:

    • *_dev20 运算符的所有调用替换为 theano/sandbox/cuda/opt.py 中的常规版本 .

    这应该会为同一种子获得相同的结果 .

    请注意,可能会放缓 . 我看到运行时间增加了大约10% .

  • 12

    我想在之前的答案中添加一些东西 . 如果您使用 python 3 并且希望每次运行都能获得可重现的结果,那么您必须这样做

    • 在代码的开头设置numpy.random.seed

    • 将PYTHONHASHSEED = 0作为python解释器的参数

  • 9

    Theano的documentation讨论了随机变量播种的困难,以及为什么他们用自己的随机数生成器为每个图形实例播种 .

    在不同的{{}}实例之间共享随机数生成器,无论图中的其他操作如何,都难以生成相同的流,并使{{}}保持隔离状态 . 因此,图中的每个{{}}实例都有自己的随机数生成器 . 该随机数生成器是该函数的输入 . 在典型用法中,我们将使用函数输入的新功能({{}},{{}})来传递和更新每个{{}}的rng . 通过将RNG作为输入,可以使用访问函数输入的常规方法来访问每个{{}}的rng . 在这种方法中,没有预先存在的机制来处理整个图的组合随机数状态 . 因此,提议是通过辅助函数提供缺少的功能(最后三个要求):{{{seed,getstate,setstate}}} .

    他们还提供了关于如何为所有随机数生成器播种的examples .

    您还可以通过该对象的种子方法为RandomStreams对象分配的所有随机变量播种 . 该种子将用于为临时随机数生成器播种,该生成器将为每个随机变量生成种子 .

    >>> srng.seed(902340)  # seeds rv_u and rv_n with different seeds each
    
  • 0

    你可以在Keras docs找到答案:https://keras.io/getting-started/faq/#how-can-i-obtain-reproducible-results-using-keras-during-development .

    简而言之,要绝对确保使用python脚本 on one computer's/laptop's CPU 可以获得可重现的结果,那么您必须执行以下操作:

    • PYTHONHASHSEED 环境变量设置为固定值

    • python 内置伪随机生成器设置为固定值

    • numpy 伪随机生成器设置为固定值

    • tensorflow 伪随机生成器设置为固定值

    • 配置新的全局 tensorflow 会话

    在顶部的 Keras 链接之后,我使用的源代码如下:

    # Seed value
    # Apparently you may use different seed values at each stage
    seed_value= 0
    
    # 1. Set `PYTHONHASHSEED` environment variable at a fixed value
    import os
    os.environ['PYTHONHASHSEED']=str(seed_value)
    
    # 2. Set `python` built-in pseudo-random generator at a fixed value
    import random
    random.seed(seed_value)
    
    # 3. Set `numpy` pseudo-random generator at a fixed value
    import numpy as np
    np.random.seed(seed_value)
    
    # 4. Set `tensorflow` pseudo-random generator at a fixed value
    import tensorflow as tf
    tf.set_random_seed(seed_value)
    
    # 5. Configure a new global `tensorflow` session
    from keras import backend as K
    session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)
    sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
    K.set_session(sess)
    

    不用说,您不必在python脚本中使用的 numpyscikit-learntensorflow / keras 函数中指定任何 seedrandom_state ,因为使用上面的源代码我们全局设置它们的伪随机生成器在一个固定的 Value .

  • 3

    我使用Keras训练和测试了 Sequential() 种神经网络 . 我表演非噪声语音数据的线性回归 . 我使用以下代码生成随机种子:

    import numpy as np
    seed = 7
    np.random.seed(seed)
    

    每次我训练和测试相同的数据时,我得到完全相同的 val_loss 结果 .

相关问题