如何在不使用任何 keras.compile 方法的情况下训练批处理规范层?通常,层具有可访问的损失。这里的 loss 方法是空的。
更新:
似乎对此有很多困惑,甚至 BatchNorm 的实现方式也很混乱。
首先,只有训练在线参数(在 training=False 模式下使用)来缩放和移动特征:在 training=True 模式下调用层。而且,如果您从不想使用批处理规范化的“批处理”部分(即,您只想要一个在线规范化器以正常对数概率损失进行自我训练,那么您基本上不能在一次调用 AFAIK 中做到这一点。
使用 training=False 调用层不会更新参数。用 training=True 调用它会更新参数,但随后你会得到批量标准化层(不使用在线 loc 和 scale)。
import tensorflow as tf
class Model(tf.keras.models.Model):
def __init__(self):
super().__init__()
self.dense = tf.keras.layers.Dense(4)
self.bn = tf.keras.layers.BatchNormalization()
def call(self, x, training=False):
x = self.dense(x)
x = self.bn(x, training=training)
return x
model = Model()
x = 10 * np.random.randn(30, 4).astype(np.float32)
print(tf.math.reduce_std(model(x)))
tf.keras.backend.set_learning_phase(1)
print(tf.math.reduce_std(model(x)))
print(tf.math.reduce_std(model(x)))
tf.keras.backend.set_learning_phase(0)
print(tf.math.reduce_std(model(x)))
print(tf.math.reduce_std(model(x)))
tf.Tensor(9.504262, shape=(), dtype=float32)
tf.Tensor(0.99999136, shape=(), dtype=float32)
tf.Tensor(0.99999136, shape=(), dtype=float32)
tf.Tensor(5.4472375, shape=(), dtype=float32)
tf.Tensor(5.4472375, shape=(), dtype=float32)
更新:
显示 keras 层有时会有损失(当子任务存在时,如规则化):
In [335]: l = tf.keras.layers.Dense(8, kernel_regularizer=tf.keras.regularizers.L1L2())
In [336]: l(np.random.randn(2, 4))
Out[336]:
<tf.Tensor: id=2521999, shape=(2, 8), dtype=float32, numpy=
array([[ 1.1332406 , 0.32000083, 0.8104123 , 0.5066328 , 0.35904446, -1.4265257 , 1.3057183 , 0.34458983],
[-0.23246719, -0.46841025, 0.9706465 , 0.42356712, 1.705613 , -0.08619405, -0.5261058 , -1.1696107 ]], dtype=float32)>
In [337]: l.losses
Out[337]: [<tf.Tensor: id=2522000, shape=(), dtype=float32, numpy=0.0>]
In [338]: l = tf.keras.layers.Dense(8)
In [339]: l(np.random.randn(2, 4))
Out[339]:
<tf.Tensor: id=2522028, shape=(2, 8), dtype=float32, numpy=
array([[ 1.0674231 , -0.13423748, 0.01775402, 2.5400681 , -0.53589094, 1.4460006 , -1.7197075 , 0.3285858 ],
[ 2.2171447 , -1.7448915 , 0.4758569 , 0.58695656, 0.32054698, 0.7813705 , -2.3022552 , 0.44061095]], dtype=float32)>
In [340]: l.losses
Out[340]: []