首页 > 解决方案 > 对张量流中神经网络中所有权重(不是权重和偏差)的 L1 正则化

问题描述

我正在使用 TensorFlow 的急切执行。

对于 L1 正则化,我正在使用tf.contrib.layers.l1_regularizer. 我不知道如何将正则化器仅应用于权重。tf.contrib.layers.apply_regularization(l1_regularizer, model.trainable_weights)也将正则化应用于偏差,因为model.trainable_weights也会返回偏差。但我不知道如何从模型中获取权重。

这是我的代码:

import tensorflow as tf
import tensorflow.contrib.eager as tfe
import numpy as np

tf.enable_eager_execution()

#create loss function with regularizer
def loss(model, x, y, l1_regularizer):
   y_ = model(x)
   weights = model.trainable_weights
   return tf.losses.mean_squared_error(labels=y, predictions=y_)+tf.contrib.layers.apply_regularization(l1_regularizer, weights)

 #function for gradient calculation
  def grad(model, inputs, targets, l1_regularizer):
  with tf.GradientTape() as tape:
    loss_value = loss(model, inputs, targets, l1_regularizer)
  return loss_value, tape.gradient(loss_value, model.trainable_variables)


  optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.5)
  global_step = tf.train.get_or_create_global_step()

  model = tf.keras.Sequential([
  tf.keras.layers.Dense(2, activation=tf.sigmoid, input_shape=(2,)),  # input shape required
  tf.keras.layers.Dense(2, activation=tf.sigmoid)
  ])    

 #set weights
  weights=[np.array([[0.15, 0.25],[0.2,0.3]]),np.array([0.35,0.35]),np.array([[0.4,0.5],[0.45, 0.55]]),np.array([0.6,0.6])]

model.set_weights(weights)

model.get_weights()

 features = tf.convert_to_tensor([[0.05,0.10 ]])
 labels =  tf.convert_to_tensor([[0.01,0.99 ]])  


 model(features) 
 #calculate the loss
 loss(model, features, labels,l1_regularizer)
  #calculate the gradients
 loss, grads = grad(model, features, labels,l1_regularizer)
 #optimization step
 optimizer.apply_gradients(zip(grads, model.variables),
                                      global_step)

标签: pythontensorflowkeras

解决方案


由于您使用的是 Keras 层,因此权重通常会在其名称中包含“内核”。使用它从所有可训练项中提取权重。

weights = [x for x in model.trainable_weights if 'kernel' in x.name]
tf.contrib.layers.apply_regularization(l1_regularizer, weights)

确保使用正确的名称大小写,如果它是“内核”而不是“内核”,它将不起作用。

如果您不想将 L1 应用于特定的偏见

weights = [x for x in model.trainable_weights if 'bias' not in x.name]
tf.contrib.layers.apply_regularization(l1_regularizer, weights)

或者,Keras 层还可以选择为权重、偏差或激活添加正则化器。从Dense的文档中:

kernel_regularizer:应用于内核权重矩阵的正则化函数。

bias_regularizer:应用于偏置向量的正则化函数。

activity_regularizer:应用于层输出的正则化函数(它的“激活”)..

因此,您需要从 keras 导入正则化器并将它们作为选项添加到您的图层中。

from tf.keras import regularizers
    ....
    ....

 model = tf.keras.Sequential([
  tf.keras.layers.Dense(2, activation=tf.sigmoid, input_shape=(2,), kernel_regularizer=regularizers.l1()),  # input shape required
  tf.keras.layers.Dense(2, activation=tf.sigmoid, kernel_regularizer=regularizers.l1())
  ])    

推荐阅读