我担心使用相同的初始化程序,正则化程序和约束在(张量流)keras层中创建的变量可能会连接在层之间。如果它们可以是字符串(例如'he_normal'),那没有问题,但是对于那些带有参数的人,我必须传递实际的函数。例如,在自定义图层的__init__
中,
initializer_1 = tf.keras.initializers.he_normal()
regularizer_1 = tf.keras.regularizers.l2(l=0.001)
constraint_1 = tf.keras.constraints.MaxNorm(max_value=2, axis=[0,1,2])
layer_A = tf.keras.layers.Conv2D(
...
kernel_initializer=initializer_1,
kernel_regularizer=regularizer_1,
kernel_constraint=constraint_1,
...
)
layer_B = tf.keras.layers.Conv2D(
...
kernel_initializer=initializer_1,
kernel_regularizer=regularizer_1,
kernel_constraint=constraint_1,
...
)
这样安全吗?
答案 0 :(得分:2)
可能,但是不确定这是否是最好的主意;我运行了-结果:
.fit()
损失相同:(1)相同的对象; (2)个不同的{initializer_2
等对象-每个对象都可以独立工作initializer_1
的层权重初始化是不同的(应该是)但是,每个层的对象都是相同-您可以从它们的内存占用量中看出来:
print(layer_A.kernel_regularizer)
print(layer_B.kernel_regularizer)
<tensorflow.python.keras.regularizers.L1L2 object at 0x7f211bfd0c88>
<tensorflow.python.keras.regularizers.L1L2 object at 0x7f211bfd0c88>
然后可能会抛出某种形式的模型序列化,特别是那些与模型图有关的序列化-但我什么都没发现。最佳做法是为每个图层使用一个唯一的图层对象,但是您的方法似乎也无害。
因此:您可以“做到这一点直到崩溃”。 (但是您可能不知道何时中断,例如何时导致模型输出不同-除非您测试可重复性)。
完整测试示例:
import tensorflow as tf
import numpy as np
import random
from tensorflow.keras.models import Model, load_model
from tensorflow.keras.layers import Input
np.random.seed(1)
random.seed(2)
if tf.__version__ == '2':
tf.random.set_seed(3)
else:
tf.set_random_seed(3)
initializer_1 = tf.keras.initializers.he_normal()
regularizer_1 = tf.keras.regularizers.l2(l=0.001)
constraint_1 = tf.keras.constraints.MaxNorm(max_value=2, axis=[0,1,2])
layer_A = tf.keras.layers.Conv2D(4, (1,1),
kernel_initializer=initializer_1,
kernel_regularizer=regularizer_1,
kernel_constraint=constraint_1)
layer_B = tf.keras.layers.Conv2D(4, (1,1),
kernel_initializer=initializer_1,
kernel_regularizer=regularizer_1,
kernel_constraint=constraint_1)
ipt = Input((16,16,4))
x = layer_A(ipt)
out = layer_B(x)
model = Model(ipt, out)
model.compile('adam', 'mse')
print(model.layers[1].get_weights()[0])
print(model.layers[2].get_weights()[0])
x = np.random.randn(32, 16, 16, 4)
model.fit(x, x)
model.save('model.h5')
model = load_model('model.h5')
答案 1 :(得分:0)
简短的回答,是的,这很安全。 长答案将是为什么我们为什么需要一个初始化程序的问题的答案。 假设我们将Ax + b应用于第一个隐藏层中的所有神经元。如果我们不初始化weights(A matrix),b将是输出的结果值,并且如果我们计算导数(b是一个常数),它将为零(0)并将其反向传播到该层,因此,我们的网络不会根据实际情况调整权重。
现在我们知道了初始化权重的原因,下面我们来选择最佳的初始化器。尽管有一些研究触及了这个问题,但据我所知,答案是没有最佳的初始化方法,因为反向传播函数还取决于您拥有的数据集;简而言之,一个初始化程序可能在某些数据集上可以很好地工作(我怀疑与其他初始化程序的区别是否有意义),但在其他数据集上却变得糟糕。
在我看来,很多人选择random_normal是因为如果不是所有层,因为您更有可能找到任何过程的正确值(猜测您将选择卡片组的卡片),而不是猜测皇后永远的心。