如果Keras结果无法再现,那么比较模型和选择超参数的最佳实践是什么?

发布于 2021-01-29 18:06:15

更新:这个问题是针对Tensorflow 1.x的。
我升级到2.0,并且(至少在下面的简单代码上)重现性问题似乎在2.0上已解决。这样就解决了我的问题;但是我仍然对1.x上的此问题使用什么“最佳实践”感到好奇。

在keras /tensorflow上训练完全相同的模型/参数/数据不会产生可重复的结果,并且每次训练模型时,损失都会大不相同。关于此问题,有很多问题,但是建议的解决方法似乎对我或上的许多其他人员不起作用。好,就是这样。

但是考虑到keras对张量流的不可重现性限制-
比较模型和选择超参数的最佳实践是什么?我正在测试不同的体系结构和激活,但是由于每次损失估计都不同,因此我不确定一个模型是否优于另一个模型。有什么最佳实践可以解决这个问题?

我认为该问题与我的代码无关,但以防万一。这是一个示例程序:

import os
#stackoverflow says turning off the GPU helps reproducibility, but it doesn't help for me
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = ""
os.environ['PYTHONHASHSEED']=str(1)

import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers 
import random
import pandas as pd
import numpy as np

#StackOverflow says this is needed for reproducibility but it doesn't help for me
from tensorflow.keras import backend as K
config = tf.ConfigProto(intra_op_parallelism_threads=1,inter_op_parallelism_threads=1)
sess = tf.Session(graph=tf.get_default_graph(), config=config)
K.set_session(sess)

#make some random data
NUM_ROWS = 1000
NUM_FEATURES = 10
random_data = np.random.normal(size=(NUM_ROWS, NUM_FEATURES))
df = pd.DataFrame(data=random_data, columns=['x_' + str(ii) for ii in range(NUM_FEATURES)])
y = df.sum(axis=1) + np.random.normal(size=(NUM_ROWS))

def run(x, y):
    #StackOverflow says you have to set the seeds but it doesn't help for me
    tf.set_random_seed(1)
    np.random.seed(1)
    random.seed(1)
    os.environ['PYTHONHASHSEED']=str(1)

    model = keras.Sequential([
            keras.layers.Dense(40, input_dim=df.shape[1], activation='relu'),
            keras.layers.Dense(20, activation='relu'),
            keras.layers.Dense(10, activation='relu'),
            keras.layers.Dense(1, activation='linear')
        ])
    NUM_EPOCHS = 500
    model.compile(optimizer='adam', loss='mean_squared_error')
    model.fit(x, y, epochs=NUM_EPOCHS, verbose=0)
    predictions = model.predict(x).flatten()
    loss = model.evaluate(x,  y) #This prints out the loss by side-effect

#Each time we run it gives a wildly different loss. :-(
run(df, y)
run(df, y)
run(df, y)

考虑到不可重现性,我如何评估超参数和体系结构的更改是否有帮助?

关注者
0
被浏览
44
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    该问题似乎在Tensorflow 2.0中得以解决(至少在简单模型上如此)!这是一个似乎可以产生可重复结果的代码段。

    import os
    ####*IMPORANT*: Have to do this line *before* importing tensorflow
    os.environ['PYTHONHASHSEED']=str(1)
    
    import tensorflow as tf
    import tensorflow.keras as keras
    import tensorflow.keras.layers 
    import random
    import pandas as pd
    import numpy as np
    
    def reset_random_seeds():
       os.environ['PYTHONHASHSEED']=str(1)
       tf.random.set_seed(1)
       np.random.seed(1)
       random.seed(1)
    
    #make some random data
    reset_random_seeds()
    NUM_ROWS = 1000
    NUM_FEATURES = 10
    random_data = np.random.normal(size=(NUM_ROWS, NUM_FEATURES))
    df = pd.DataFrame(data=random_data, columns=['x_' + str(ii) for ii in range(NUM_FEATURES)])
    y = df.sum(axis=1) + np.random.normal(size=(NUM_ROWS))
    
    def run(x, y):
        reset_random_seeds()
    
        model = keras.Sequential([
                keras.layers.Dense(40, input_dim=df.shape[1], activation='relu'),
                keras.layers.Dense(20, activation='relu'),
                keras.layers.Dense(10, activation='relu'),
                keras.layers.Dense(1, activation='linear')
            ])
        NUM_EPOCHS = 500
        model.compile(optimizer='adam', loss='mean_squared_error')
        model.fit(x, y, epochs=NUM_EPOCHS, verbose=0)
        predictions = model.predict(x).flatten()
        loss = model.evaluate(x,  y) #This prints out the loss by side-effect
    
    #With Tensorflow 2.0 this is now reproducible! 
    run(df, y)
    run(df, y)
    run(df, y)
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看