我正在尝试使用不同的参数多次运行神经网络,以便校准网络参数(丢失概率,学习率e.d.)。但是我遇到的问题是,当我在循环中运行网络时,运行网络同时保持参数相同仍然给我一个不同的解决方案:
filename = create_results_file()
for i in range(3):
g = tf.Graph()
with g.as_default():
accuracy_result, average_error = network.train_network(
parameters, inputHeight, inputWidth, inputChannels, outputClasses)
f, w = get_csv_writer(filename)
w.writerow([accuracy_result, "did run %d" % i, average_error])
f.close()
在设置网络的图层和错误功能之前,我在train_network函数的开头使用以下代码:
np.random.seed(1)
tf.set_random_seed(1)
我还尝试在创建TensorFlow图形之前添加此代码,但我在结果输出中不断获得不同的解决方案。
我正在使用AdamOptimizer并使用tf.truncated_normal
初始化网络权重。另外,我正在使用np.random.permutation
来为每个纪元改变传入的图像。
答案 0 :(得分:36)
设置当前TensorFlow随机种子仅影响当前默认图形。由于您要为培训创建新图表并将其设置为默认值(with g.as_default():
),因此必须在with
块的范围内设置随机种子。
例如,您的循环应如下所示:
for i in range(3):
g = tf.Graph()
with g.as_default():
tf.set_random_seed(1)
accuracy_result, average_error = network.train_network(
parameters, inputHeight, inputWidth, inputChannels, outputClasses)
请注意,这将对外部for
循环的每次迭代使用相同的随机种子。如果您想在每次迭代中使用不同但仍具有确定性的种子,则可以使用tf.set_random_seed(i + 1)
。
答案 1 :(得分:13)
Tensorflow 2.0兼容答案:对于大于2.0的Tensorflow版本,如果我们要设置全局随机种子,则使用的命令为 tf.random.set_seed
。< / p>
如果我们要从 Tensorflow Version 1.x to 2.x
进行迁移,则可以使用以下命令,
tf.compat.v2.random.set_seed
。
请注意,在这种情况下, tf.function
就像重新运行程序一样。
要设置“操作级别种子”(如上所述),我们可以使用命令 tf.random.uniform([1], seed=1)
。
有关更多详细信息,请参阅此firebase documentation。
答案 2 :(得分:12)
可以通过提供图表级别或操作级别种子来获得确定性行为。两者都适合我。图表级种子可以与tf.set_random_seed一起放置。操作级种子可以放在例如变量初始化器中,如下所示:
myvar = tf.Variable(tf.truncated_normal(((10,10)), stddev=0.1, seed=0))
答案 3 :(得分:7)
由于CuDNN中潜在的实现问题,这些答案似乎都不起作用。
通过添加一个额外的标志,您可以得到更多的确定性
os.environ['PYTHONHASHSEED']=str(SEED)
os.environ['TF_CUDNN_DETERMINISTIC'] = '1' # new flag present in tf 2.0+
random.seed(SEED)
np.random.seed(SEED)
tf.set_random_seed(SEED)
但是,这仍然不是完全确定的。要获得更精确的解决方案,您需要使用此nvidia repo中概述的过程。
答案 4 :(得分:7)
后端设置:cuda:10.1
、cudnn: 7
、tensorflow-gpu: 2.1.0
、keras: 2.2.4-tf
和 vgg19
自定义模型
在通过 GPU 训练和基于 keras 的大型神经网络模型研究 tensorflow 后端结果不稳定的问题后,我终于能够获得可重现(稳定)的结果,如下所示:
import tensorflow as tf
import os
import numpy as np
import random
SEED = 0
def set_seeds(seed=SEED):
os.environ['PYTHONHASHSEED'] = str(seed)
random.seed(seed)
tf.random.set_seed(seed)
np.random.seed(seed)
Tensorflow
确定性行为def set_global_determinism(seed=SEED):
set_seeds(seed=seed)
os.environ['TF_DETERMINISTIC_OPS'] = '1'
os.environ['TF_CUDNN_DETERMINISTIC'] = '1'
tf.config.threading.set_inter_op_parallelism_threads(1)
tf.config.threading.set_intra_op_parallelism_threads(1)
# Call the above function with seed value
set_global_determinism(seed=SEED)
答案 5 :(得分:1)
请在代码之前添加所有随机种子函数:
tf.reset_default_graph()
tf.set_random_seed(0)
random.seed(0)
np.random.seed(0)
我认为,TensorFlow中的某些模型正在使用numpy或python随机函数。
答案 6 :(得分:0)
我正在使用TensorFlow 2(2.2.0),并且正在JupyterLab中运行代码。我已经在macOS Catalina和Google Colab中测试了此结果。我将在Tensorflow Support's答案中添加一些内容。
当我使用model.fit()方法进行一些训练时,我会在单元格中进行训练。我在其他单元格中进行其他处理。这是我在提到的单元格中运行的代码:
# To have same results always place this on top of the cell
tf.random.set_seed(1)
(x_train, y_train), (x_test, y_test) = load_data_onehot_grayscale()
model = get_mlp_model_compiled() # Creates the model, compiles it and returns it
history = model.fit(x=x_train, y=y_train,
epochs=30,
callbacks=get_mlp_model_callbacks(),
validation_split=.1,
)
这是我的理解:
tf.random.set_seed(1)
设置种子时,可以使那些进程使用它,并且如果设置了种子并且进程没有更改,结果将是相同的。tf.random.set_seed(1)
更改为行model = get_mlp_model_compiled()
之下,我的结果就会更改,我相信这是因为get_mlp_model_compiled()
使用随机性而不是使用种子我想要。get_mlp_model_compiled()
中,我的种子没有使用TensorFlow的内部计数器。在nº2运行中,它将使用种子,所有后续运行也将使用种子,因此在nº2运行之后,结果将相同。我的某些信息可能有误,请随时纠正我。
要了解正在发生的事情,您应该阅读the docs,它们不那么长而且有点容易理解。
答案 7 :(得分:-1)
此答案是对Luke's answer和TF v2.2.0的补充
import numpy as np
import os
import random
import tensorflow as tf # 2.2.0
SEED = 42
os.environ['PYTHONHASHSEED']=str(SEED)
os.environ['TF_CUDNN_DETERMINISTIC'] = '1' # TF 2.1
random.seed(SEED)
np.random.seed(SEED)
tf.random.set_seed(SEED)