正如标题所说。我目前正在使用 python (3.11) 和 keras (2.12.0) 和 tensorflow (2.12.1,仅 cpu 包) 库,并且我面临着神经网络可重复性的一些问题;目前在 jupyter 笔记本中编码。由于我在一个环境中工作,因此我使用的库数量有限。这是场景:
现在,我想我已经正确地播种了。我阅读了 keras 文档、有关如何获得可重现结果的常见问题解答部分 (https://keras.io/getting_started/faq/),以及此处提出的类似问题 (How to get reproducible results in keras, 为什么即使我设置了随机种子,我也无法在 Keras 中获得可重现的结果?),但似乎没有任何效果。
我相信我做的一切都是正确的,特别是:
每次重新启动内核时,都会发生以下情况:
最后一点是让我困惑的一点。当我不重新启动内核并运行模型定义+估计时,我每次都会得到完全相同的拟合历史记录(正如我所说,它是种子)。当我重新启动内核时,我再次运行所有内容,并且一切正常,直到最后一个列表的第 3 点,但随后拟合历史记录发生了变化。这是如何运作的?我以为是编译器的问题,我用的是ADAM,但我不知道?为什么这会导致问题?
我目前很困惑,我希望每次运行脚本时一切都一样,因为我正在进行模拟,并且我需要结果是可重现的。
import os #Necessario per la riproducibilità
os.environ['PYTHONHASHSEED'] = '0'
import random #Random seed
random.seed(5014)
import numpy as np
np.random.seed(5014)
#Pacchetti generici
import sys
import feather #Per leggere i dataset
import time
#Reti neurali
import pandas as pd
import tensorflow as tf
tf.random.set_seed(5014)
#tf.compat.v1.set_random_seed(5014)
import keras
keras.utils.set_random_seed(5014) #This should set again all of the seeds above, I know, but I'm trying everything.
from sklearn.model_selection import train_test_split
import math
print(sys.version)
#This isn't enough to get the same results.
tf.config.experimental.enable_op_determinism()
from keras import backend as K
session_conf = tf.compat.v1.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)
sess = tf.compat.v1.Session(graph=tf.compat.v1.get_default_graph(), config=session_conf)
tf.compat.v1.keras.backend.set_session(sess)
#Loading the data
data = feather.read_dataframe("dataset1.feather") #pd.DataFrame
data.shape
#This is to get the model
def create_model(size, n_input):
#Per rendere la stima replicabile
seeds= [1000,1001,1002,1003]
print("\nSemi utilizzati per l'iniz: ")
print(seeds)
#Struttura del modello
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(size[0], input_shape=(n_input,), activation ="relu", name="Hidden1", kernel_initializer=tf.keras.initializers.RandomNormal(seed = seeds[0])))
model.add(tf.keras.layers.Dense(size[1], activation='relu', name="Hidden2", kernel_initializer=tf.keras.initializers.RandomNormal(seed = seeds[1])))
model.add(tf.keras.layers.Dense(size[2], activation='relu', name="Hidden3", kernel_initializer=tf.keras.initializers.RandomNormal(seed = seeds[2])))
model.add(tf.keras.layers.Dense(1, activation="linear", name="Output", kernel_initializer=tf.keras.initializers.RandomNormal(seed = seeds[3])))
#Metodo di stima da utilizzare
model.compile(loss='mean_squared_error', optimizer='Adam', metrics = ["mean_squared_error"])
return model
这些是代码中使用的函数。
vars = set(data.columns)
escluse = {"output","Days"}
X = vars.difference(escluse)
#Le posizioni di Days e output
days_pos = data.shape[1]
out_pos = data.shape[1]-1
#Specifiche della rete neurale
reps = 3 #Numero di punti di partenza per ciascuna rete.
size = [200,200,200]
i = 365
print("\nCurrently: ",i)
data_to_use = data.loc[(data["Days"]<=i) & (data["Days"] >= (i-364))]
#Definire i dataset da usare per stima
train, val = train_test_split(data_to_use, test_size=0.2)
x_train = train[list(X)]
y_train = train["output"]
x_val = val[list(X)]
y_val = val["output"]
model_nn = create_model(size,data_to_use.shape[1] - 2)
直到上面几行,一切都按预期工作,每次重新启动内核时模型都是相同的。 但是,到了
的时候storia = model_nn.fit(x = x_train, y = y_train, batch_size = math.ceil(x_train.shape[0]/2), epochs = 1000, validation_data=(x_val,y_val), verbose =0,
callbacks = tf.keras.callbacks.EarlyStopping(monitor ="val_mean_squared_error", min_delta =0, patience =8))
storia.history["val_mean_squared_error"][0:5]
历史改变了。为什么?如果我重复模型定义+拟合,我会得到相同的精确结果。如果我重新启动内核并再次运行所有内容,结果就会改变。有谁知道如何解决它?数据在这里:https://github.com/marco-pll/data-STACKoverflow。
谢谢您的帮助。我快要哭了
编辑:事实上,它是 PYTHONHASHSEED。只需将其作为环境变量即可。将帖子留在这里,因为它可能对其他人有帮助。
由于 @twallow 和 @mhenning 所说的原因以及其他原因,神经网络训练的可重复性有点误导。
搜索“统计神经网络基准”会发现一篇 IEEE 文章,该文章显示神经网络根据初始化和超参数在训练中产生一系列准确度。
也许记录神经网络产生的准确度范围是一种压力较小的方法?