Pav*_*nok 62 python numpy theano keras
每次我imdb_lstm.py
从Keras框架运行示例时,我得到不同的结果(测试准确性)(https://github.com/fchollet/keras/blob/master/examples/imdb_lstm.py)代码包含np.random.seed(1337)
在顶部,在任何keras之前进口.它应该防止它为每次运行生成不同的数字.我错过了什么?
更新:如何重现:
UPDATE2:我在Windows 8.1上使用MinGW/msys运行它,模块版本:
theano 0.7.0
numpy 1.8.1
scipy 0.14.0c1
更新3:我把问题缩小了一点.如果我用GPU运行示例(设置theano flag device = gpu0),那么每次都会得到不同的测试精度,但是如果我在CPU上运行它,那么一切都按预期工作.我的显卡:NVIDIA GeForce GT 635)
Poe*_*dit 31
您可以在Keras docs找到答案:https://keras.io/getting-started/faq/#how-can-i-obtain-reproducible-results-using-keras-during-development .
简而言之,为了确保您可以在一台计算机/笔记本电脑的CPU上使用python脚本获得可重现的结果,那么您将不得不执行以下操作:
PYTHONHASHSEED
环境变量设置为固定值python
以固定值设置内置伪随机生成器numpy
伪随机生成器设置为固定值tensorflow
伪随机生成器设置为固定值tensorflow
会话在Keras
顶部的链接后,我使用的源代码如下:
# Seed value
# Apparently you may use different seed values at each stage
seed_value= 0
# 1. Set the `PYTHONHASHSEED` environment variable at a fixed value
import os
os.environ['PYTHONHASHSEED']=str(seed_value)
# 2. Set the `python` built-in pseudo-random generator at a fixed value
import random
random.seed(seed_value)
# 3. Set the `numpy` pseudo-random generator at a fixed value
import numpy as np
np.random.seed(seed_value)
# 4. Set the `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)
Run Code Online (Sandbox Code Playgroud)
这是不用说,你不必指定任何seed
或random_state
在numpy
,scikit-learn
或tensorflow
/ keras
你正在使用完全相同在你的python脚本的功能,因为与源代码上面我们在一个固定值全局设置自己的伪随机生成.
Pab*_*rre 13
Theano的文档讨论了随机变量播种的困难以及为什么它们使用自己的随机数生成器为每个图形实例播种.
在不同的{{{RandomOp}}}实例之间共享随机数生成器,无论图中的其他操作如何,都难以生成相同的流,并使{{{RandomOps}}}保持隔离状态.因此,图中的每个{{{RandomOp}}}实例都有自己的随机数生成器.该随机数生成器是该函数的输入.在典型用法中,我们将使用函数输入的新功能({{{value}}},{{{update}}})来传递和更新每个{{{RandomOp}}}的rng.通过将RNG作为输入,可以使用访问函数输入的常规方法来访问每个{{{RandomOp}}}的rng.在这种方法中,没有预先存在的机制来处理整个图的组合随机数状态.
他们还提供了如何为所有随机数生成器播种的示例.
您还可以通过该对象的种子方法为RandomStreams对象分配的所有随机变量播种.该种子将用于为临时随机数生成器播种,该生成器将为每个随机变量生成种子.
>>> srng.seed(902340) # seeds rv_u and rv_n with different seeds each
Run Code Online (Sandbox Code Playgroud)
kep*_*ler 12
我终于用我的代码获得了可重现的结果.这是我在网上看到的答案的组合.第一件事是做@alex所说的:
numpy.random.seed
;PYTHONHASHSEED=0
的Python 3.然后你必须通过调用你的Keras代码解决有关cuDNN的@ user2805751注意到的问题,并附加以下内容THEANO_FLAGS
:
dnn.conv.algo_bwd_filter=deterministic,dnn.conv.algo_bwd_data=deterministic
最后,您必须根据此评论修补您的Theano安装,其中基本上包括:
*_dev20
其常规版本替换所有对运算符的调用theano/sandbox/cuda/opt.py
.这应该会为同一种子获得相同的结果.
请注意,可能会出现放缓.我看到运行时间增加了大约10%.
这个问题现在在 Tensorflow 2.0 中解决了!我在 TF 1.x 中遇到了同样的问题(请参阅 如果 Keras 结果不可重复,比较模型和选择超参数的最佳做法是什么?)但是
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)
Run Code Online (Sandbox Code Playgroud)
在 Tensorflow 2.0 中,您可以像这样设置随机种子:
import tensorflow as tf
tf.random.set_seed(221)
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential( [
layers.Dense(2,name = 'one'),
layers.Dense(3,activation = 'sigmoid', name = 'two'),
layers.Dense(2,name = 'three')])
x = tf.random.uniform((12,12))
model(x)
Run Code Online (Sandbox Code Playgroud)
小智 5
这对我有用:
SEED = 123456
import os
import random as rn
import numpy as np
from tensorflow import set_random_seed
os.environ['PYTHONHASHSEED']=str(SEED)
np.random.seed(SEED)
set_random_seed(SEED)
rn.seed(SEED)
Run Code Online (Sandbox Code Playgroud)