tensorflow变量正则化

正则化(regularization)machine learning种非常常见的减少过拟合、降低泛化误差的方法。对deep learning模型,过多的参数增加了过拟合的风险,常见的降低过拟合风险的方法包括数据扩增、dropout以及添加正则约束,本文主要对tensorflow中的变量正则化进行介绍。


​​​​​​​​​正则化介绍:

  • L1正则

对模型添加L1范数约束,即:

对于变量集合W=[w1, w2, ..., wn],L1正则作用结果为: 

L_{w} = \left | w1 \right | + \left | w2 \right |+...+\left | wn \right |

当L1正则在变量参数w较小的情况下,能够直接缩减至0,这个性质常被用于降低数据维度(特征筛选),就是我们常说的LASSO方法。

  • L2正则

变量参数添加L2正则,在tensorflow超参数设置中就是常见的Weight Decay参数所对应的方法,另外也有岭回归、Tikhonov regularization等名称。

 对于变量集合W=[w1, w2, ..., wn],L2正则作用结果为:

L_{w} =w1^{2} + w2^{2}+...+wn^{2}

 变量的L2正则loss即为Weight Decay * Lw(计算结果添加到总体loss,那么训练过程对该节点参数自然会增加约束)

  • L0正则

L0正则方法表示的是计算变量集合中非零元素的个数,这种方法在稀疏表示算法中比较常用。


Tensorlow相关

tensorflow中对参数使用正则项分为两步:

  1. 创建正则化方法;
  2. 将正则化方法应用到参数上。

在tensorflow中实现上述两步,可以自己手动定义(麻烦 ╯□╰ ...)或者直接使用tensorflow内带的实现方法.

  • tf.contrib.layers.l2_regularizer(lambda)(w)

这个函数直接为w变量计算L2正则项,可以在创建变量时使用。

def create_variable(name, shape, weight_decay):
    initializer = tf.contrib.layers.xavier_initializer()

    regularizer = tf.contrib.layers.l2_regularizer(scale=weight_decay)
    new_variables = tf.get_variable(name, shape=shape, initializer=initializer,
                                    regularizer=regularizer)
    return new_variables

之后所有的变量创建直接使用上述接口函数就可以。

看到这里,其实想重新审视一下tf.get_variables()和tf.Variables()这两个函数,在传入参数里面又很多细节需要注意的地方,这里把源码里面相关的参数贴出来看一下:

get_variable(
    name,
    shape=None,
    dtype=None,
    initializer=None,
    regularizer=None,
    trainable=True,
    collections=None,
    caching_device=None,
    partitioner=None,
    validate_shape=True,
    use_resource=None,
    custom_getter=None,
    constraint=None
)

Args:

  • name:新变量或现有变量的名称。
  • shape:新变量或现有变量的形状。
  • dtype:新变量或现有变量的类型(默认为DT_FLOAT)。
  • ininializer:如果创建了则用它来初始化变量。
  • regularizer:A(Tensor - > Tensor或None)函数;将它应用于新创建的变量的结果将添加到集合tf.GraphKeys.REGULARIZATION_LOSSES中,并可用于正则化。
  • trainable:如果为True,还将变量添加到图形集合GraphKeys.TRAINABLE_VARIABLES(参见tf.Variable)。
  • collections:要将变量添加到的图表集合列表。默认为[GraphKeys.GLOBAL_VARIABLES](参见tf.Variable)。
  • caching_device:可选的设备字符串或函数,描述变量应被缓存以供读取的位置。默认为Variable的设备。如果不是None,则在另一台设备上缓存。典型用法是在使用变量驻留的Ops的设备上进行缓存,以通过Switch和其他条件语句进行重复数据删除。
  • partitioner:可选callable,接受完全定义的TensorShape和要创建的Variable的dtype,并返回每个轴的分区列表(当前只能对一个轴进行分区)。
  • validate_shape:如果为False,则允许使用未知形状的值初始化变量。如果为True,则默认为initial_value的形状必须已知。
  • use_resource:如果为False,则创建常规变量。如果为true,则使用定义良好的语义创建实验性ResourceVariable。默认为False(稍后将更改为True)。在Eager模式下,此参数始终强制为True。
  • custom_getter:Callable,它将第一个参数作为true getter,并允许覆盖内部get_variable方法。 custom_getter的签名应与此方法的签名相匹配,但最适合未来的版本将允许更改:def custom_getter(getter,* args,** kwargs)。也允许直接访问所有get_variable参数:def custom_getter(getter,name,* args,** kwargs)。一个简单的身份自定义getter只需创建具有修改名称的变量是:python def custom_getter(getter,name,* args,** kwargs):return getter(name +'_suffix',* args,** kwargs)

标红加粗的几个参数是个人认为比较重要和常用的,这一块涉及到tensorflow管理的方法,详细的介绍打算之后再写文介绍,下面需要用到的会涉及tenorflow的collection概念,大概就是tensorflow在管理图的时候定义的一些集合空间,tensorflow在创建图的过程中,会自动用一些collection来对图节点(op)进行分类,方便之后的调用,类似name_scope,这部分collection被称为tf.GraphKeys,常见的GraphKeys有:

  • GLOBAL_VARIABLES: 该collection默认加入所有的Variable对象,并且在分布式环境中共享。一般来说,包含在MODEL_VARIABLES中,MODEL_VARIABLES包含在GLOBAL_VARIABLES中。
  • LOCAL_VARIABLES: 与GLOBAL_VARIABLES不同的是,它只包含本机器上的Variable,即不能在分布式环境中共享。
  • MODEL_VARIABLES: 顾名思义,模型中的变量,在构建模型中,所有用于正向传递的Variable都将添加到这里。
  • TRAINALBEL_VARIABLES: 所有用于反向传递的Variable,即可训练(可以被optimizer优化,进行参数更新)的变量。
  • SUMMARIES: 跟Tensorboard相关,这里的Variable都由tf.summary建立并将用于可视化。
  • QUEUE_RUNNERS: the QueueRunner objects that are used to produce input for a computation.
  • MOVING_AVERAGE_VARIABLES: the subset of Variableobjects that will also keep moving averages.
  • REGULARIZATION_LOSSESregularization losses collected during graph construction.

我们为变量创建的正则项都是被collect或者说需要被collect在regularization_losses中,因此自己写正则项定义好了之后利用tf.add_to_collection就可以。

  • tf.add_to_collection和tf.get_collection

tf.add_to_collectiontf.get_collection是将变量加入Graph集合和根据key从集合中取出内容的操作,tf.get_collection返回一个列表,内容是这个集合的所有元素。

自定义好变量正则项之后再把正则项添加进loss集合就行。

def get_weight(shape, lambda):
    var = tf.Variable(tf.random_normal(shape),dtype=tf.float32)
    tf.add_to_collection("losses",tf.contrib.layers.l2_regularizer(lambda)(var)) #losses是
                                                                              #损失函数集合
    return var

损失函数的定义实际上我觉得也是一种正则项(例如一些任务使用L2距离作为损失函数),也就是作用在所有变量空间的一种约束条件。

以上是自己的一些学习记录,如果由不正确的地方还请见谅~~

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值