代码之家  ›  专栏  ›  技术社区  ›  DeltaIV

为什么我不能在keras中获得可重复的结果,即使我设置了随机种子?

  •  3
  • DeltaIV  · 技术社区  · 8 年前

    我在mac osx上用keras训练mobilenet的虚拟数据架构。我两个都订好了 nump.random tensorflow.set_random_seed ,但由于某些原因,我无法获得可重复的结果:每次重新运行代码时,我都会得到不同的结果。为什么?这不是因为GPU,因为我运行的MacBook Pro 2017带有Radeon图形卡,因此TensorFlow没有利用它。代码是用

    python Keras_test.py
    

    所以这不是状态问题(我没有使用jupyter或ipython:每次运行代码时都应该重置环境)。

    编辑 :我通过移动所有种子的设置来更改代码 之前 正在导入Keras。结果仍不确定,但结果的方差比以前小得多。这很奇怪。

    目前的模型非常小(就深度神经网络而言),不需要繁琐,它不需要GPU运行,在现代笔记本电脑上几分钟就可以训练,所以重复我的实验是任何人都可以做到的。我邀请你这么做:我很想了解一个系统到另一个系统的变化程度。

    import numpy as np
    # random seeds must be set before importing keras & tensorflow
    my_seed = 512
    np.random.seed(my_seed)
    import random 
    random.seed(my_seed)
    import tensorflow as tf
    tf.set_random_seed(my_seed)
    
    # now we can import keras
    import keras.utils
    from keras.applications import MobileNet
    from keras.callbacks import ModelCheckpoint
    from keras.optimizers import Adam
    import os
    
    height = 224
    width = 224
    channels = 3
    epochs = 10
    num_classes = 10
    
    
    
    # Generate dummy data
    batch_size = 32  
    n_train = 256
    n_test = 64
    x_train = np.random.random((n_train, height, width, channels))
    y_train = keras.utils.to_categorical(np.random.randint(num_classes, size=(n_train, 1)), num_classes=num_classes)
    x_test = np.random.random((n_test, height, width, channels))
    y_test = keras.utils.to_categorical(np.random.randint(num_classes, size=(n_test, 1)), num_classes=num_classes)
    # Get input shape
    input_shape = x_train.shape[1:]
    
    # Instantiate model 
    model = MobileNet(weights=None,
                      input_shape=input_shape,
                      classes=num_classes)
    
    model.compile(loss='categorical_crossentropy',
                  optimizer='adam',
                  metrics=['accuracy'])
    # Viewing Model Configuration
    model.summary()
    
    # Model file name
    filepath = 'model_epoch_{epoch:02d}_loss_{loss:0.2f}_val_{val_loss:.2f}.hdf5'
    
    # Define save_best_only checkpointer
    checkpointer = ModelCheckpoint(filepath=filepath,
                                 monitor='val_acc',
                                 verbose=1,
                                 save_best_only=True)
    
    # Let's fit!
    model.fit(x_train, y_train,
              batch_size=batch_size,
              epochs=epochs,
              validation_data=(x_test, y_test),
              callbacks=[checkpointer])
    

    一如既往,这里是我的python,keras&tensorflow版本:

    python -c 'import keras; import tensorflow; import sys; print(sys.version, 'keras.__version__', 'tensorflow.__version__')'
    /anaconda2/lib/python2.7/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
      from ._conv import register_converters as _register_converters
    Using TensorFlow backend.
    ('2.7.15 |Anaconda, Inc.| (default, May  1 2018, 18:37:05) \n[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]', '2.1.6', '1.8.0')
    

    下面是多次运行此代码获得的一些结果:如您所见,代码使用描述性文件名保存了10个阶段中的最佳模型(最佳验证精度),因此通过比较不同运行中的文件名可以判断结果的可变性。

    model_epoch_01_loss_2.39_val_3.28.hdf5
    model_epoch_01_loss_2.39_val_3.54.hdf5
    model_epoch_01_loss_2.40_val_3.47.hdf5
    model_epoch_01_loss_2.41_val_3.08.hdf5
    
    2 回复  |  直到 8 年前
        1
  •  7
  •   Outcast    7 年前

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

    简言之,为了确保使用python脚本获得可重复的结果 在一台计算机/笔记本电脑的CPU上 然后您必须执行以下操作:

    1. 集合 PYTHONHASHSEED 定值环境变量
    2. 集合 python 固定值的内置伪随机发生器
    3. 集合 numpy 定值伪随机发生器
    4. 集合 tensorflow 定值伪随机发生器
    5. 配置新全局 张量流 阶段

    跟随 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)
    

    不用说,你不必指定 seed random_state 麻木的 , scikit-learn 张量流 / keras 在python脚本中使用的函数正是因为在上面的源代码中,我们将它们的伪随机生成器设置为一个固定值。

        2
  •  0
  •   guorui    7 年前

    使结果可再现的关键是禁用gpu。请看我的答案 another question (链接 https://stackoverflow.com/a/57121117/9501391 )已经被接受了。

    推荐文章