Python 这些模型等效吗?

Python 这些模型等效吗?,python,tensorflow,keras,neural-network,Python,Tensorflow,Keras,Neural Network,主要问题:我用两种不同的方式定义同一个模型。为什么我会得到不同的结果?他们似乎是同一型号 第二个问题(回答如下)如果我再次运行代码,我会再次得到不同的结果。我在一开始就设定了种子来修正随机性。为什么会这样 将numpy导入为np np.随机种子(1) 从keras.models导入模型,顺序 从keras.layers导入输入,密集 模式1=顺序([ 密集型(20,激活='sigmoid',内核初始化器='glorot\u normal', 输入_形状=(2,), 稠密(2,激活为线性,内核初始

主要问题:我用两种不同的方式定义同一个模型。为什么我会得到不同的结果?他们似乎是同一型号

第二个问题(回答如下)如果我再次运行代码,我会再次得到不同的结果。我在一开始就设定了种子来修正随机性。为什么会这样

将numpy导入为np
np.随机种子(1)
从keras.models导入模型,顺序
从keras.layers导入输入,密集
模式1=顺序([
密集型(20,激活='sigmoid',内核初始化器='glorot\u normal',
输入_形状=(2,),
稠密(2,激活为线性,内核初始化为glorot-normal),
])
模型1.编译(优化器='adam',loss='mean_squared_error')
ipt=输入(形状=(2,))
x=密集(20,激活='sigmoid',内核初始化器='glorot\u normal')(ipt)
out=density(2,activation='linear',kernel\u initializer='glorot\u normal')(x)
模型2=模型(ipt,out)
模型2.编译(优化器='adam',loss='mean_squared_error')
x_列=np.数组([[1,2],[3,4],[3,4]]
模型1.fit(x_序列,x_序列,epochs=2,validation_split=0.1,shuffle=False)
模型2.fit(x_序列,x_序列,epochs=2,validation_split=0.1,shuffle=False)
第一次,输出为:

2/2 [==============================] - 0s 68ms/step - loss: 14.4394 - val_loss: 21.5747
Epoch 2/2

2/2 [==============================] - 0s 502us/step - loss: 14.3199 - val_loss: 21.4163
Train on 2 samples, validate on 1 samples
Epoch 1/2

2/2 [==============================] - 0s 72ms/step - loss: 11.0523 - val_loss: 17.7059
Epoch 2/2

2/2 [==============================] - 0s 491us/step - loss: 10.9833 - val_loss: 17.5785
2/2 [==============================] - 0s 80ms/step - loss: 14.4394 - val_loss: 21.5747
Epoch 2/2

2/2 [==============================] - 0s 501us/step - loss: 14.3199 - val_loss: 21.4163
Train on 2 samples, validate on 1 samples
Epoch 1/2

2/2 [==============================] - 0s 72ms/step - loss: 11.0523 - val_loss: 17.6733
Epoch 2/2

2/2 [==============================] - 0s 485us/step - loss: 10.9597 - val_loss: 17.5459
第二次,输出为:

2/2 [==============================] - 0s 68ms/step - loss: 14.4394 - val_loss: 21.5747
Epoch 2/2

2/2 [==============================] - 0s 502us/step - loss: 14.3199 - val_loss: 21.4163
Train on 2 samples, validate on 1 samples
Epoch 1/2

2/2 [==============================] - 0s 72ms/step - loss: 11.0523 - val_loss: 17.7059
Epoch 2/2

2/2 [==============================] - 0s 491us/step - loss: 10.9833 - val_loss: 17.5785
2/2 [==============================] - 0s 80ms/step - loss: 14.4394 - val_loss: 21.5747
Epoch 2/2

2/2 [==============================] - 0s 501us/step - loss: 14.3199 - val_loss: 21.4163
Train on 2 samples, validate on 1 samples
Epoch 1/2

2/2 [==============================] - 0s 72ms/step - loss: 11.0523 - val_loss: 17.6733
Epoch 2/2

2/2 [==============================] - 0s 485us/step - loss: 10.9597 - val_loss: 17.5459

阅读答案后更新:下面的答案回答了我的一个问题。我将代码的开头更改为:

import numpy as np
np.random.seed(1)
import random
random.seed(2)
import tensorflow as tf
tf.set_random_seed(3)
现在我得到的数字和以前一样。因此,它是稳定的。但是,我的主要问题仍然没有得到回答。为什么每次,两个等效模型给出不同的结果

以下是我每次得到的结果:

结果1:

Epoch 1/2

2/2 [==============================] - 0s 66ms/sample - loss: 11.9794 - val_loss: 18.9925
Epoch 2/2

2/2 [==============================] - 0s 268us/sample - loss: 11.8813 - val_loss: 18.8572
Epoch 1/2

2/2 [==============================] - 0s 67ms/sample - loss: 5.4743 - val_loss: 9.3471
Epoch 2/2

2/2 [==============================] - 0s 3ms/sample - loss: 5.4108 - val_loss: 9.2497
结果2:

Epoch 1/2

2/2 [==============================] - 0s 66ms/sample - loss: 11.9794 - val_loss: 18.9925
Epoch 2/2

2/2 [==============================] - 0s 268us/sample - loss: 11.8813 - val_loss: 18.8572
Epoch 1/2

2/2 [==============================] - 0s 67ms/sample - loss: 5.4743 - val_loss: 9.3471
Epoch 2/2

2/2 [==============================] - 0s 3ms/sample - loss: 5.4108 - val_loss: 9.2497

问题的根源在于模型定义和随机性的预期与实际行为。要了解发生了什么,我们必须了解“RNG”是如何工作的:

  • “随机数生成器”(RNG)实际上是一个函数,它生成的数字能够“长期”映射到概率分布上
  • 当调用RNG函数时,例如
    RNG()
    ,它返回一个“随机”值并将其内部计数器递增1。调用此计数器
    n
    -然后:
    random\u value=RNG(n)
  • 设置种子时,根据该种子的值(但不针对该种子)设置
    n
    ;我们可以通过计数器中的
    +c
    来表示这种差异
  • c
    将是由种子的非线性但确定性函数产生的常数:
    f(种子)
将numpy导入为np
np.random.seed(4)#内部计数器=0+c
打印(np.random.random())#内部计数器=1+c
打印(np.random.random())#内部计数器=2+c
打印(np.random.random())#内部计数器=3+c
np.random.seed(4)#内部计数器=0+c
打印(np.random.random())#内部计数器=1+c
打印(np.random.random())#内部计数器=2+c
打印(np.random.random())#内部计数器=3+c
0.9670298390136767
0.5472322491757223
0.9726843599648843
0.9670298390136767
0.5472322491757223
0.9726843599648843
假设
model1
有100个权重,您设置了一个种子(
n=0+c
)。在
model1
构建之后,您的计数器位于
100+c
。如果不重置种子,即使使用完全相同的代码构建
model2
,模型也会有所不同-因为
model2
的权重根据
n
100+c
初始化到
200+c


其他信息:

Epoch 1/2

2/2 [==============================] - 0s 66ms/sample - loss: 11.9794 - val_loss: 18.9925
Epoch 2/2

2/2 [==============================] - 0s 268us/sample - loss: 11.8813 - val_loss: 18.8572
Epoch 1/2

2/2 [==============================] - 0s 67ms/sample - loss: 5.4743 - val_loss: 9.3471
Epoch 2/2

2/2 [==============================] - 0s 3ms/sample - loss: 5.4108 - val_loss: 9.2497
有三种种子可以确保更好的随机性:

将numpy导入为np
np.random.seed(1)#用于Numpy ops
随机输入
随机种子(2)#用于Python操作
导入tensorflow作为tf
tf.为tensorfow ops设置随机种子(3)#-例如,退出遮罩
这将提供相当好的再现性,但如果你使用的是GPU,这并不完美——因为操作的并行性;解释得很好。为了获得更好的再现性,请在官方文件中设置您的
PYHTONHASHSEED
-以及其他信息

“完美”的再现性是相当多余的,因为你的结果在大多数情况下都应该在.1%之内一致——但如果你真的需要,目前唯一的方法可能是切换到CPU并停止使用CUDA——但这将大大降低训练速度(x10+)


随机性的来源

  • 权重初始化(每个默认Keras初始值设定项使用随机性)
  • 噪声层(衰减、高斯噪声等)
  • 用于基于散列的操作,例如集合或dict中的项目顺序
  • GPU并行性(参见链接视频)

模型随机性演示

将numpy导入为np
np.随机种子(4)
model1_init_weights=[np.random.random(),np.random.random(),np.random.random()]
model2_init_weights=[np.random.random(),np.random.random(),np.random.random()]
打印(“模型1初始权重:”,模型1初始权重)
打印(“模型2初始权重:”,模型2初始权重)
model1_初始_权重:[0.9670298390136767、0.5472322491757223、0.9726843599648843]
模型2初始权重:[0.7148159936743647,0.6977288245972708,0.216089499558037638]
重新启动内核。现在运行以下命令:

将numpy导入为np
np.随机种子(4)
model2_init_weights=[np.random.random(),np.random.random(),np.random.random()]
model1_init_weights=[np.random.random(),np.random.random(),np.random.random()]
打印(“模型1初始权重:”,模型1初始权重)
打印(“模型2初始权重:”,模型2初始权重)
model1的初始权重:[0.7148159936743647、0.6977288245972708、0.216089499558037638]
模型2初始重量:[0.9670298390136767,0.5472322491757223,0.9726843599648843]
因此,在代码中翻转
model1
model2
的顺序也会翻转损失。这是因为种子