当使用model.fit_on_batch方法和自定义训练循环时,我意识到在自定义训练循环代码中,损失和梯度没有考虑任何l1-l2正则化器,因此optimizer.apply_gradients方法不考虑正则化器。下面是展示这一点的代码,但这个想法非常简单。所以我的问题是是否有一种方法以优化器详细信息不可知的方式使用所有这些优化器来考虑正则化器。在Keras中如何实现?另外,model.fit_on_batch返回一个值,而不是文档字符串中所述的损失。我想知道这个返回值是什么。
并创建一个函数来制作可复制的模型。
现在运行Keras的train_on_batch函数。
除非l1==0且l2==0,否则您会发现这两个结果是不同的。
代码
为了看到这个效果,首先创建一些数据
x=tf.constant([[1]])
y=tf.constant([[1]])
并创建一个函数来制作可复制的模型。
def make_model(l1=.01,l2=.01):
tf.random.set_seed(42)
np.random.seed(42)
model=tf.keras.models.Sequential([
tf.keras.layers.Dense(2,'softmax',
use_bias=False,
kernel_regularizer=tf.keras.regularizers.l1_l2(l1=l1,l2=l2),
input_shape=(1,))
])
return model
现在运行Keras的train_on_batch函数。
model=make_model()
loss_object=tf.keras.losses.SparseCategoricalCrossentropy()
optimizer=tf.keras.optimizers.RMSprop()
model.compile(loss=loss_object,optimizer=optimizer)
model.train_on_batch(x,y)
并将输出与上面链接中解释的自定义训练循环以及此处进行比较。
model=make_model()
loss_object=tf.keras.losses.SparseCategoricalCrossentropy()
optimizer=tf.keras.optimizers.RMSprop()
@tf.function
def train_step(x,y):
with tf.GradientTape() as tape:
predictions = model(x)
loss = loss_object(y, predictions)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
return loss
train_step(x,y).numpy()
除非l1==0且l2==0,否则您会发现这两个结果是不同的。