在张量流中对神经网络中的所有权重(而不是权重和偏差)进行L1正则化

时间:2018-10-19 07:26:22

标签: python tensorflow keras

我正在使用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)

1 个答案:

答案 0 :(得分:0)

由于您使用的是Keras图层,因此权重的名称通常带有“ kernel”。使用它可以从所有训练对象中分出权重。

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())
  ])