Neu*_*onQ 8 python machine-learning neural-network lstm keras
(注意:在每个模型创建之前正确修复 RNG 状态,如评论中的评论中所述实际上解决了我的问题,因为小数点后 3 位内的结果是一致的,但它们并非完全如此,因此在某处存在未修复的隐藏随机源播种 RNG ......可能有些库使用时间毫秒或 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 :(
Run Code Online (Sandbox Code Playgroud)
我知道模型具有初始随机权重,因此我将它们保存并重新加载。我也很偏执,假设有一些我可能不知道的“隐藏”参数,所以我将模型序列化为 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)
Run Code Online (Sandbox Code Playgroud)
...但他们仍然没有解决随机性。
而且我知道目标是让我的模型表现出非随机性,尽管NN 具有固有的随机性。但是我需要为了实验目的暂时修复这个问题(我什至可以在一台机器上重现它!)。
机器学习算法通常是非确定性的。这意味着每次运行它们时,结果都应该有所不同。这与权重的随机初始化有关。如果您想让结果可重复,您必须消除表格中的随机性。一个简单的方法是使用随机种子。
import numpy as np
import tensorflow as tf
np.random.seed(1234)
tf.random.set_seed(1234)
# rest of your code
Run Code Online (Sandbox Code Playgroud)
如果您想要随机因子但输出中的方差不那么大,我建议您降低学习率或更改优化器(我建议使用学习率相对较低的 SGD 优化器)。梯度下降优化清凉的概述,请点击这里!
关于 TensorFlow 随机生成器的一个说明是,除了全局种子(即tf.random.set_seed()),它们还使用内部计数器,因此如果您运行
tf.random.set_seed(1234)
print(tf.random.uniform([1]).numpy())
print(tf.random.uniform([1]).numpy())
Run Code Online (Sandbox Code Playgroud)
你会分别得到0.5380393和0.3253647。但是,如果您重新运行相同的代码段,您将再次获得相同的两个数字。
可以在此处找到有关 TensorFlow 中随机种子如何工作的详细说明。
对于较新的 TF 版本,也要注意这一点: TensorFlow 2.2 附带一个 os 环境变量TF_DETERMINISTIC_OPS,如果设置为'1',将确保仅使用确定性 GPU 操作。
此代码适用于使用tensorflow后端的keras
这是因为权重是使用随机数初始化的,因此每次都会得到不同的结果。这是预期的行为。为了获得可重现的结果,您需要将随机种子设置为。下面的示例设置了操作级别和图形级别种子以获取更多信息,请参见此处
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 ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9963 次 |
| 最近记录: |