对多个 TensorFlow Keras 层使用相同的初始化器、正则器和约束是否安全?

Mao*_*hen 5 keras tensorflow

我担心使用相同的初始化器、正则化器和约束在(张量流)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,
  ...
  )
Run Code Online (Sandbox Code Playgroud)

这安全吗?

Ove*_*gon 3

是的,可能,但不确定这是否是最好的主意;我运行了它 - 结果:

  • .fit()两者的损失相同:(1)相同的对象;(2) 不同的(initializer_2等)对象 - 所以每个对象都独立工作
  • 层权重初始化不同(应该如此)但相同initializer_1
  • 模型保存并加载成功。

但是,每一层的对象都是相同的- 您可以从它们的内存占用中看出:

print(layer_A.kernel_regularizer)
print(layer_B.kernel_regularizer)
Run Code Online (Sandbox Code Playgroud)
<tensorflow.python.keras.regularizers.L1L2 object at 0x7f211bfd0c88>
<tensorflow.python.keras.regularizers.L1L2 object at 0x7f211bfd0c88>
Run Code Online (Sandbox Code Playgroud)

那么某种形式的模型序列化可能会被抛弃,特别是那些涉及模型图的序列化——但我什么也没发现。最佳实践是为每个层使用唯一的层对象,但您的方法似乎也没有害处。

因此:你可以“一直做到坏为止”。(但是您可能不知道它何时会损坏,例如何时会导致模型输出不同 - 除非您测试再现性)。


完整测试示例

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')
Run Code Online (Sandbox Code Playgroud)