对权重的正则化是怎么实施的?

在真实的应用中想要的并不是让模型尽量模拟训练数据的行为,而是希望通过训练出来的模型对未知的数据给出判断。模型在训练数据上的表现并不一定代表了它在未知数据上的表现。
所谓过拟合指的是当一个模型过为复杂之后,它可以很好地“记忆”每一个训练数据中随机噪声的部分而忘记要去“学习”训练数据中通用的趋势。
为了避免过拟合,非常常用的方法是正则化,,正则化的思想是在损失函数中加入刻画模型复杂程度的指标。假设用于刻画模型在训练数据上表现的损失函数为 J ( θ ) J(\theta) J(θ),而不是优化 J ( θ ) + λ R ( w ) J(\theta)+\lambda R(w) J(θ)+λR(w)。其中 R ( w ) R(w) R(w)刻画的是模型的复杂程度,而 λ \lambda λ表示模型复杂损失在总损失中的比例。 θ \theta θ表示的是神经网络中的所有参数,包括权重 w w w和偏置项 b b b。一般来说模型复杂度只由权重 w w w决定。
常用的刻画模型复杂程度的函数有两种,一种是L1正则化,一种是L2正则化,也可以将二者结合使用。
R l 1 ( w ) = ∑ i ∣ w i ∣ R_{l1}(w) =\sum_i|w_i| Rl1(w)=iwi
R l 2 ( w ) = ∑ i w i 2 R_{l2}(w) =\sum_iw_i^2 Rl2(w)=iwi2
R l 1 l 2 ( w ) = ∑ i ∣ w i ∣ + ∑ i w i 2 R_{l1_l2}(w) =\sum_i|w_i| + \sum_iw_i^2 Rl1l2(w)=iwi+iwi2
L1正则化会让参数变得更稀疏,即让参数变为0得到类似特征选取的功能,而L2正则化不会,只会让参数很小,比如0.001。
L1正则化的计算公式不可导,L2正则化公式可导,因此优化带L1正则化的损失函数要更加复杂,对含有L2正则化损失函数的优化要更加简洁。

将对权重的正则化作为loss的一部分
import tensorflow as tf

# 定义函数用于生成权重变量并将对权重的正则化加入tf.GraphKeys.LOSSES
def get_weight(shape):
    var = tf.Variable(initial_value=tf.random_normal(shape=shape,mean=0.0,stddev=1.0,dtype=tf.float32,seed=12),trainable=True)
    tmp = tf.contrib.layers.l1_l2_regularizer(scale_l1=1.0,scale_l2=1.0)(var)
    tf.add_to_collection(tf.GraphKeys.LOSSES,tmp)

    return var

x = tf.placeholder(dtype=tf.float32,shape=(None,2),name='x')
y_gt = tf.placeholder(dtype=tf.float32,shape=(None,1),name='y_gt')

# 每层神经元个数
layer_dim = [2,10,10,10,1]   # 对应上面输入2个神经元和输出1个神经元
# 网络层数
num = len(layer_dim)
# 当前层
cur_layer = x
# 当前层输入维度
in_dimension = layer_dim[0]
# 构建网络
for i in range(1, num):
    # layer_dim[i]表示下一层节点个数
    out_dimension = layer_dim[i]
    weight = get_weight([in_dimension,out_dimension])
    bias = tf.Variable(tf.constant(0.1, dtype=tf.float32,shape=[out_dimension]))
    cur_layer = tf.nn.relu(tf.matmul(cur_layer,weight) + bias)
    in_dimension = out_dimension

mse_loss = tf.reduce_mean(tf.square(y_gt-cur_layer))
tf.add_to_collection(tf.GraphKeys.LOSSES,mse_loss)

loss = tf.add_n(tf.get_collection(tf.GraphKeys.LOSSES))
print(loss)

for i in tf.get_collection(tf.GraphKeys.LOSSES):
    print(i)

'''
Tensor("AddN:0", shape=(), dtype=float32)
Tensor("l1_l2_regularizer:0", shape=(), dtype=float32)
Tensor("l1_l2_regularizer_1:0", shape=(), dtype=float32)
Tensor("l1_l2_regularizer_2:0", shape=(), dtype=float32)
Tensor("l1_l2_regularizer_3:0", shape=(), dtype=float32)
Tensor("Mean:0", shape=(), dtype=float32)
'''
L1、L2正则化实施示例
import tensorflow as tf

weight = tf.constant([[1.0,-2.0],[-3.0,4.0]])

with tf.Session(graph=tf.get_default_graph()) as sess:
     # 输出为(|1|+|-2|+|-3|+|4|)*0.5=5
    print(sess.run(tf.contrib.layers.l1_regularizer(0.5)(weight)))
     # 输出为(1²+(-2)²+(-3)²+4²)/2*0.5=7.5,注意实现中有除以2
    print(sess.run(tf.contrib.layers.l2_regularizer(0.5)(weight)))
    # l1_regularizer+l2_regularizer=12.5
    print(sess.run(tf.contrib.layers.l1_l2_regularizer(0.5,0.5)(weight)))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值