Est-il possible d'ajouter une régularisation L2 en utilisant les calques définis dans tf.layers?
Il me semble que, puisque tf.layers est un wrapper de haut niveau, il n’existe aucun moyen facile d’avoir accès aux poids de filtrage.
Avec tf.nn.conv2d
regularizer = tf.contrib.layers.l2_regularizer(scale=0.1)
weights = tf.get_variable(
name="weights",
regularizer=regularizer
)
#Previous layers
...
#Second layer
layer 2 = tf.nn.conv2d(
input,
weights,
[1,1,1,1],
[1,1,1,1])
#More layers
...
#Loss
loss = #some loss
reg_variables = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
reg_term = tf.contrib.layers.apply_regularization(regularizer, reg_variables)
loss += reg_term
Maintenant, à quoi ressemblerait-il avec tf.layers.conv2d?
Merci!
Vous pouvez les passer dans tf.layers.conv2d
comme arguments:
regularizer = tf.contrib.layers.l2_regularizer(scale=0.1)
layer2 = tf.layers.conv2d(
inputs,
filters,
kernel_size,
kernel_regularizer=regularizer)
Ensuite, vous devriez ajouter la perte de régularisation à votre perte comme ceci:
l2_loss = tf.losses.get_regularization_loss()
loss += l2_loss
Edit: Merci Zeke Arneodo, Tom et srcolinas, j’ai ajouté, le dernier commentaire sur vos commentaires afin que la réponse acceptée apporte la solution complète.
La réponse n'est-elle pas dans votre question? Vous pouvez également utiliser tf.losses.get_regularization_loss ( https://www.tensorflow.org/api_docs/python/tf/losses/get_normalisation_loss ), qui collectera tous les REGULARIZATION_LOSSES.
...
layer2 = tf.layers.conv2d(input,
filters,
kernel_size,
kernel_regularizer= tf.contrib.layers.l2_regularizer(scale=0.1))
...
l2_loss = tf.losses.get_regularization_loss()
loss += l2_loss
Je vois deux réponses incomplètes, alors voici la complète:
regularizer = tf.contrib.layers.l2_regularizer(scale=0.1)
layer2 = tf.layers.conv2d(
inputs,
filters,
kernel_size,
kernel_regularizer=regularizer)
alternativement:
layer2 = tf.layers.conv2d(inputs,
filters,
kernel_size,
kernel_regularizer= tf.contrib.layers.l2_regularizer(scale=0.1))
n'oubliez pas de l'ajouter à la perte finale:
l2_loss = tf.losses.get_regularization_loss()
....
loss += l2_loss
En gros, ajoutez une régularisation lorsque vous définissez une couche, puis assurez-vous d’ajouter une perte de régularisation à votre perte.
Dans une exécution avide, il y a deux façons.
tf.add_n([tf.square(i) for i in layer.variables]) * l2_coef
.layer.losses
lorsque le calque est créé avec kernel_regularizer
.Comme indiqué dans les exemples officiels: densenet_test.py
Rand_input = tf.random_uniform((10, 3, 32, 32))
weight_decay = 1e-4
conv = tf.keras.layers.Conv2D(
3, (3, 3),
padding='same',
use_bias=False,
kernel_regularizer=tf.keras.regularizers.l2(weight_decay))
optimizer = tf.train.GradientDescentOptimizer(0.1)
conv(Rand_input) # Initialize the variables in the layer
def compute_true_l2(vs, wd):
return tf.reduce_sum(tf.square(vs)) * wd
true_l2 = compute_true_l2(conv.variables, weight_decay)
keras_l2 = tf.add_n(conv.losses)
self.assertAllClose(true_l2, keras_l2)
with tf.GradientTape() as tape_true, tf.GradientTape() as tape_keras:
loss = tf.reduce_sum(conv(Rand_input))
loss_with_true_l2 = loss + compute_true_l2(conv.variables, weight_decay)
loss_with_keras_l2 = loss + tf.add_n(conv.losses)
true_grads = tape_true.gradient(loss_with_true_l2, conv.variables)
keras_grads = tape_keras.gradient(loss_with_keras_l2, conv.variables)
self.assertAllClose(true_grads, keras_grads)