(注意:在每个模型创建之前正确修复RNG状态,如评论中的评论几乎修复我的问题,因为3位小数内的结果是一致的,但是并非完全如此,所以在某处隐藏的随机性来源无法通过播种RNG来修复...可能有些lib使用时间milisecs或smth ... 如果有人对此有所了解,知道会很酷,所以我会等待而不是关闭问题:))
我创建 Keras LSTM模型(用于预测某些时间序列数据,不重要的是什么),每次我尝试重新创建相同模型(相同的模式配置从json加载,相同的权重从文件加载,相同的args到编译功能),我在相同的列车和测试数据上得到了截然不同的结果。为什么?
代码大致如下:
# fix random
import random
random.seed(42)
# make model & compile
model = Sequential([
LSTM(50, input_shape=(None, 1), return_sequences=True),
LSTM(100, return_sequences=False),
Dense(1),
Activation("linear")
])
model.compile(loss="mse", optimizer="rmsprop")
# save it and its initial random weights
model_json = model.to_json()
model.save_weights("model.h5")
# fit and predict
model.fit(x_train, y_train, epochs=3)
r = model.predict(x_test)
# create new "identical" model
model2 = model_from_json(model_json)
model2.load_weights("model.h5")
model2.compile(loss="mse", optimizer="rmsprop")
# fit and predict "identical" model
model2.fit(x_train, y_train, epochs=3)
r2 = model2.predict(x_test)
# ...different results :(
我知道该模型具有初始随机权重,因此我将它们保存并重新加载它们。我也很偏执,认为有一些"隐藏"我可能不知道的参数,所以我将模型序列化为json并重新加载而不是手动重新创建相同的模型(尝试过,同样的事情顺便说一下)。我还修复了随机数生成器。
这是我第一次与Keras合作,而且我也是神经网络的初学者。但这让我疯狂...... wtf可能会有所不同?!
在修复随机数生成器时:我使用TensorFlow后端运行Keras,我在开始时使用这些代码行来尝试修复RNG以用于实验目的:
import random
random.seed(42)
import numpy
numpy.random.seed(42)
from tensorflow import set_random_seed
set_random_seed(42)
......但他们仍然没有解决随机性。
我明白,我的目标是让我的模型非随机行为,尽管 NN的固有随机性。但我需要暂时将其修复用于实验目的(我甚至可以在一台机器上重现它!)。
答案 0 :(得分:4)
机器学习算法通常是非确定性。这意味着每次运行它们时,结果都会有所不同。这与权重的随机初始化有关。如果要使结果可重现,则必须从表中消除随机性。一种简单的方法是使用随机种子。
import numpy as np
np.random.seed(1234)
# rest of your code
如果你想要输出中的随机因子而不是那么高的方差,我会建议你降低你的学习率或改变你的优化器(我会建议学习率相对较低的SGD优化器)。有关梯度下降优化的详细概述here!
答案 1 :(得分:2)
此代码适用于使用tensorflow后端的keras
这是因为权重是使用随机数初始化的,因此每次都会得到不同的结果。这是预期的行为。要获得可重现的结果,您需要将随机种子设置为。下面的示例设置操作级别和图级别种子,以获取更多信息,请查看here
import tensorflow as tf
import random as rn
os.environ['PYTHONHASHSEED'] = '0'
# Setting the seed for numpy-generated random numbers
np.random.seed(37)
# Setting the seed for python random numbers
rn.seed(1254)
# Setting the graph-level random seed.
tf.set_random_seed(89)
from keras import backend as K
session_conf = tf.ConfigProto(
intra_op_parallelism_threads=1,
inter_op_parallelism_threads=1)
#Force Tensorflow to use a single thread
sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
K.set_session(sess)
# Rest of the code follows from here on ...
答案 2 :(得分:1)
我通过添加 os.environ['TF_DETERMINISTIC_OPS'] = '1'
这里有一个例子:
import os
os.environ['TF_DETERMINISTIC_OPS'] = '1'
#rest of the code
# tf version 2.3.1