Bor*_*ury 3 python deep-learning keras tensorflow
在使用 model.fit_on_batch 方法和自定义训练循环时,我意识到在自定义训练循环代码中,损失和梯度不考虑任何 l1-l2 正则化器,因此 optimizer.apply_gradients 方法不考虑正则化器。您可以在下面找到显示这一点的代码,但这个想法非常简单。所以我的问题是,是否有一种方法可以在优化器细节不可知的方式中使用所有这些优化器来考虑正则化器。它在 Keras 中是如何实现的?在相关说明中,model.fit_on_batch 返回的值不是损失(如文档字符串中所述)而是其他值。我想知道这里是否有人知道它返回什么。
代码
要查看此效果,请先创建一些数据
x=tf.constant([[1]])
y=tf.constant([[1]])
Run Code Online (Sandbox Code Playgroud)
并创建一个函数来制作可重现的模型
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
Run Code Online (Sandbox Code Playgroud)
现在运行 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)
Run Code Online (Sandbox Code Playgroud)
并将输出与自定义训练循环进行比较,如上述链接和此处所述
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()
Run Code Online (Sandbox Code Playgroud)
你会看到两个结果是不同的,除非 l1==0 和 l2==0。
事实上,在我实现下面的代码后,我发现自定义训练的tensorflow 指南中已经涵盖了这一点(我不知道为什么它不在问题中提到的教程中,因为它很重要)。那里的解决方案比这里提到的解决方案更通用,但我保留这一点,因为它对发生的事情有更多的了解。
所以它就像修改自定义训练循环一样简单
def add_model_regularizer_loss(model):
loss=0
for l in model.layers:
if hasattr(l,'layers') and l.layers: # the layer itself is a model
loss+=add_model_loss(l)
if hasattr(l,'kernel_regularizer') and l.kernel_regularizer:
loss+=l.kernel_regularizer(l.kernel)
if hasattr(l,'bias_regularizer') and l.bias_regularizer:
loss+=l.bias_regularizer(l.bias)
return loss
def train_step(x,y):
with tf.GradientTape() as tape:
predictions = model(x)
loss = loss_object(y, predictions)
loss += add_model_regularizer_loss(model)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
return loss
Run Code Online (Sandbox Code Playgroud)
为了回答我的问题的第二部分,keras 的模型拟合方法返回的就是这个损失值。
| 归档时间: |
|
| 查看次数: |
510 次 |
| 最近记录: |