如何获得可重复的结果(Keras、Tensorflow):

问题描述 投票:0回答:5

为了使结果可重现,我红色了 20 多篇文章,并向我的脚本中添加了最多的函数……但失败了。

在我红色的官方来源中,有两种种子 - 全局种子和操作种子。也许,解决我的问题的关键是设置操作种子,但我不明白在哪里应用它。

您能帮我用tensorflow(版本> 2.0)实现可重现的结果吗?非常感谢。

from keras.models import Sequential
from keras.layers import Dense
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
from keras.optimizers import adam
from sklearn.preprocessing import MinMaxScaler


np.random.seed(7)
import tensorflow as tf
tf.random.set_seed(7) #analogue of set_random_seed(seed_value)
import random
random.seed(7)
tf.random.uniform([1], seed=1)
tf.Graph.as_default #analogue of  tf.get_default_graph().finalize()

rng = tf.random.experimental.Generator.from_seed(1234)
rng.uniform((), 5, 10, tf.int64)  # draw a random scalar (0-D tensor) between 5 and 10

df = pd.read_csv("s54.csv", 
                 delimiter = ';', 
                 decimal=',', 
                 dtype = object).apply(pd.to_numeric).fillna(0)

#data normalization
scaler = MinMaxScaler() 
scaled_values = scaler.fit_transform(df) 
df.loc[:,:] = scaled_values


X_train, X_test, y_train, y_test = train_test_split(df.iloc[:,1:],
                                                    df.iloc[:,:1],
                                                    test_size=0.2,
                                                    random_state=7,
                                                    stratify = df.iloc[:,:1])

model = Sequential()
model.add(Dense(1200, input_dim=len(X_train.columns), activation='relu'))  
model.add(Dense(150, activation='relu'))
model.add(Dense(80, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='sigmoid')) 

loss="binary_crossentropy"
optimizer=adam(lr=0.01)
metrics=['accuracy']
epochs = 2
batch_size = 32
verbose = 0

model.compile(loss=loss,  
              optimizer=optimizer, 
              metrics=metrics) 
model.fit(X_train, y_train, epochs = epochs, batch_size=batch_size, verbose = verbose)
predictions = model.predict(X_test)
tn, fp, fn, tp = confusion_matrix(y_test, predictions>.5).ravel()
tensorflow keras neural-network tensorflow2.0
5个回答
13
投票

从 TensorFlow 2.8 开始,有

tf.config.experimental.enable_op_determinism()

即使在 GPU 上,您也可以通过

确保可重复性
import tensorflow as tf

tf.keras.utils.set_random_seed(42)  # sets seeds for base-python, numpy and tf
tf.config.experimental.enable_op_determinism()

但请注意,这会带来显着的性能损失。


12
投票

作为文档的参考
依赖随机种子的操作实际上源自两个种子:全局种子和操作级种子。这设置了全局种子。

它与运营级种子的交互如下:

  1. 如果未设置全局种子和操作种子:此操作将使用随机选取的种子。
  2. 如果未设置操作种子但设置了全局种子:系统从全局种子确定的种子流中选取操作种子。
  3. 如果设置了操作种子,但未设置全局种子:使用默认的全局种子和指定的操作种子来确定随机序列。
  4. 如果同时设置了全局种子和操作种子:两个种子结合使用来确定随机序列。

第一个场景

默认选择随机种子。从结果中可以很容易地注意到这一点。 每次重新运行程序或多次调用代码时,它都会有不同的值。

x_train = tf.random.normal((10,1), 1, 1, dtype=tf.float32)
print(x_train)

第二个场景

全局已设置,但操作尚未设置。 尽管它生成了与第一次和第二次随机不同的种子。如果重新运行或重新启动代码。两者的种子仍然相同。 它一次又一次地产生相同的结果。

tf.random.set_seed(2)
first = tf.random.normal((10,1), 1, 1, dtype=tf.float32)
print(first)
sec = tf.random.normal((10,1), 1, 1, dtype=tf.float32)
print(sec)

第三个场景

对于这种情况,设置了操作种子但不是全局的。 如果您重新运行代码,它将给出不同的结果,但如果您重新启动运行时,它将给出与上次运行相同的结果序列。

x_train = tf.random.normal((10,1), 1, 1, dtype=tf.float32, seed=2)
print(x_train)

第四个场景

两个种子都将用于确定随机序列。 更改全局和操作种子将给出不同的结果,但使用相同的种子重新启动运行时仍将给出相同的结果。

tf.random.set_seed(3)
x_train = tf.random.normal((10,1), 1, 1, dtype=tf.float32, seed=1)
print(x_train) 

创建了一个可重现的代码作为参考。
通过设置全局种子,它总是给出相同的结果。

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler

## GLOBAL SEED ##                                                   
tf.random.set_seed(3)
x_train = tf.random.normal((10,1), 1, 1, dtype=tf.float32)
y_train = tf.math.sin(x_train)
x_test = tf.random.normal((10,1), 2, 3, dtype=tf.float32)
y_test = tf.math.sin(x_test)

model = Sequential()
model.add(Dense(1200, input_shape=(1,), activation='relu'))  
model.add(Dense(150, activation='relu'))
model.add(Dense(80, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='sigmoid')) 

loss="binary_crossentropy"
optimizer=tf.keras.optimizers.Adam(lr=0.01)
metrics=['mse']
epochs = 5
batch_size = 32
verbose = 1

model.compile(loss=loss,  
              optimizer=optimizer, 
              metrics=metrics) 
histpry = model.fit(x_train, y_train, epochs = epochs, batch_size=batch_size, verbose = verbose)
predictions = model.predict(x_test)
print(predictions)


注意:如果您使用的是 TensorFlow 2 更高版本,Keras 已经在 API 中,因此您应该使用 TF.Keras 而不是原生的。
所有这些都是在 google colab 上模拟的。


2
投票

您可以通过以下方式为所有随机数设置种子

import numpy as np
np.random.seed(0)
import random
random.seed(0)
import tensorflow
tensorflow.random.set_seed(0)
import tensorflow as tf
tf.random.set_seed(0)
tf.keras.utils.set_random_seed(0)   
tf.config.experimental.enable_op_determinism()

0
投票

当我们使用层数 >= 3 和神经元 >= 100 时,处理器核心的数量是有意义的。我的问题是在两台不同的服务器上运行脚本:

-32核

-16核

当我在 32 核服务器(甚至 32 核和 24 核)上运行脚本时,结果是相同的。


0
投票

为了使结果具有可重复性,我只需要在使用

tensorflow
keras
执行任何操作之前添加 1 行额外的代码。

random_state = 1234
import tensorflow as tf
tf.keras.utils.set_random_seed(random_state)   

我在Google Colab中测试了4次(包括“断开连接并删除运行时”一次和“重新启动”会话一次)。我发现每次预测的表现都是一样的。

为什么会这样?

请检查此(https://www.tensorflow.org/api_docs/python/tf/keras/utils/set_random_seed)了解详细信息。

它设置所有随机种子(Python、NumPy 和后端框架,例如 TF)。调用此实用程序相当于以下内容:

import random
random.seed(seed)

import numpy as np
np.random.seed(seed)

import tensorflow as tf  # Only if TF is installed
tf.random.set_seed(seed)

import torch  # Only if the backend is 'torch'
torch.manual_seed(seed)

您也可以阅读这篇文章(https://www.tensorflow.org/api_docs/python/tf/random/set_seed),它帮助我获得有关张量流随机化的更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.