TensorFlow神经网络优化策略学习


Posted in Python onMarch 09, 2018

在神经网络模型优化的过程中,会遇到许多问题,比如如何设置学习率的问题,我们可通过指数衰减的方式让模型在训练初期快速接近较优解,在训练后期稳定进入最优解区域;针对过拟合问题,通过正则化的方法加以应对;滑动平均模型可以让最终得到的模型在未知数据上表现的更加健壮。

一、学习率的设置

学习率设置既不能过大,也不能过小。TensorFlow提供了一种更加灵活的学习率设置方法——指数衰减法。该方法实现了指数衰减学习率,先使用较大的学习率来快速得到一个比较优的解,然后随着迭代的继续逐步减小学习率,使得模型在训练后期更加稳定,缓慢平滑得达到最优值。

tf.train.exponential_decay(learning_rate, global_step, decay_steps, decay_rate,staircase=False, name=None)

该函数会指数级减小学习率,实现每轮实际优化时的衰减后的学习率decayed_learning_rate = learning_rate * decay_rate ^ (global_step /decay_steps),learning_rate为设定的出事学习率,decay_rate为衰减系数,decay_steps为衰减速度。如下图,参数staircase=False时,学习率变化趋势为浅色部分;staircase=True时为深色部分,使得学习率变化为阶梯函数(staircase function),这种设置的常用应用场景是每完整地过完一遍训练数据,学习率就减小一次。

使用示例:learning_rate =tf.train.exponential_decay(starter_learning_rate, global_step, 100000, 0.96,staircase=True)。

TensorFlow神经网络优化策略学习

二、过拟合问题

1. 过拟合问题及其解决方法

所谓过拟合问题,指的是当一个模型过于复杂后,它可以很好地记忆每一个训练数据中随机噪声的部分而忘记了要去学习训练数据中通用的趋势。

为了避免过拟合问题,常用的方法是正则化(Regularization),思想是在损失函数中加入刻画模型复杂程度的指标,将优化目标定义为J(θ)+λR(w) ,其中R(w)刻画的是模型的复杂程度,包括了权重项w不包括偏置项b,λ表示模型复杂损失在总损失中的比例。一般来说模型复杂度只由权重w决定。常用的刻画模型复杂度的函数R(w)有两种,一种是L1正则化:

TensorFlow神经网络优化策略学习

另一种是L2正则化:

TensorFlow神经网络优化策略学习

无论哪种正则化方式,基本思想都是希望通过限制权重的大小,使得模型不能任意拟合训练数据中的随机噪音。区别:L1正则化会让参数变得更稀疏,L2则不会,所谓参数变得更稀疏是指会有更多的参数变为0,可达到类似特征选取的功能。实践中,也可以将L1正则化和L2正则化同时使用:

TensorFlow神经网络优化策略学习

2. 过拟合问题的TensorFlow解决方案

loss =tf.reduce_mean(tf.square(y_ - y) + tf.contrib.layers.l2_regularizer(lambda)(w)

以上就是一个含L2正则化项的损失函数。第一部分是均方误差损失函数,第二部分就是正则化项。lambda参数表示正则化项的权重,也就是J(θ)+λR(w)中的λ,w为需要计算正则化损失的参数。tf.contrib.layers.l2_regularize()函数可以计算给定参数的L2正则化项,类似地,tf.contrib.layers.l1_regularizer()可以就是那给定参数的L1正则化项。

# 比较L1正则化和L2正则化函数的作用效果 
w = tf.constant([[1.0, -2.0], [-3.0, 4.0]]) 
with tf.Session() as sess: 
  # 0.5*(|1|+|-2|+|-3|+|4|=5.0) 
  print(sess.run(tf.contrib.layers.l1_regularizer(0.5)(w))) # 5.0 
  # 0.5*[(1+4+9+16)/2]=7.5 TensorFlow会将L2正则化项除以2使得求导的结果更简洁 
  print(sess.run(tf.contrib.layers.l2_regularizer(0.5)(w))) # 7.5

当神经网络的参数增多以后,上面的定义损失函数的方式会导致loss的定义式很长,可读性差,另外当网络结构复杂后定义网络结构的部分和计算损失函数的部分可能不在同一个函数中,通过变量方式计算损失函数就不方便了。为解决此问题,可以使用TensorFlow中提供的集合(collection)。具体实现见代码部分。

tf.add_to_collection()将变量加入至指定集合中;tf.get_collection()返回一个列表,存储着这个集合中的元素。

三、滑动平均模型

另一个使模型在测试数据上更健壮(robust)滑动平均模型。在采用随机梯度下降算法训练神经网络时,使用滑动平均模型在很多应用中可提高最终模型在测试数据上的表现,GradientDescent和Momentum方式的训练都能够从ExponentialMovingAverage方法中获益。

在TensorFlow中提供的tf.train.ExponentialMovingAverage是一个类class,来实现滑动平均模型。初始化tf.train.ExponentialMovingAverage类对象时,须指定衰减率decay和用于动态控制衰减率的参数num_updates。tf.train.ExponentialMovingAverage对每一个变量维护一个影子变量(shadow variable),该影子变量的初始值就是相应变量的初始值,每次变量更新时,shadow_variable =decay * shadow_variable + (1 - decay) * variable。从公式中可看出,decay决定了模型更新的速度,decay越大模型越趋于稳定,实际应用中decay一般设置为接近1的数。num_updates默认是None,若设置了,则衰减率按min(decay, (1 +num_updates) / (10 + num_updates))计算。

tf.train.ExponentialMovingAverage对象的apply方法返回一个对var_list进行更新滑动平均的操作,var_list必须是list的Variable或Tensor,该操作执行会更新var_list的影子变量shadowvariable。average方法可获取滑动平均后变量的取值。

四、代码呈现

1. 复杂神经网络结构权重L2正则化方法

import tensorflow as tf 
 
''''' 
# 比较L1正则化和L2正则化函数的作用效果 
w = tf.constant([[1.0, -2.0], [-3.0, 4.0]]) 
with tf.Session() as sess: 
  # 0.5*(|1|+|-2|+|-3|+|4|=5.0) 
  print(sess.run(tf.contrib.layers.l1_regularizer(0.5)(w))) # 5.0 
  # 0.5*[(1+4+9+16)/2]=7.5 TensorFlow会将L2正则化项除以2使得求导的结果更简洁 
  print(sess.run(tf.contrib.layers.l2_regularizer(0.5)(w))) # 7.5 
''' 
 
# 复杂神经网络结构权重L2正则化方法 
# 定义各层的权重,并将该权重的L2正则化项加入至名称为‘losses'的集合 
def get_weight(shape, lambda1): 
  var = tf.Variable(tf.random_normal(shape), dtype=tf.float32) 
  tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(lambda1)(var)) 
  return var 
 
x = tf.placeholder(tf.float32, (None, 2)) 
y_ = tf.placeholder(tf.float32, (None, 1)) 
 
layer_dimension = [2,10,5,3,1] # 定义了神经网络每层的节点数 
n_layers = len(layer_dimension) 
 
current_layer = x # 将当前层设置为输入层 
in_dimension = layer_dimension[0] 
 
# 通过循环生成一个5层全连接的神经网络结构 
for i in range(1,n_layers): 
  out_dimension = layer_dimension[i] 
  weight = get_weight([in_dimension,out_dimension], 0.003) 
  bias = tf.Variable(tf.constant(0.1, shape=[out_dimension])) 
  current_layer = tf.nn.relu(tf.matmul(current_layer, weight) + bias) 
  in_dimension = layer_dimension[i] 
 
mse_loss = tf.reduce_mean(tf.square(y_ - current_layer)) 
tf.add_to_collection('losses', mse_loss) 
loss = tf.add_n(tf.get_collection('losses')) # 包含所有参数正则化项的损失函数

2. tf.train.ExponentialMovingAverage使用样例

import tensorflow as tf 
 
# tf.train.ExponentialMovingAverage使用样例 
v1 = tf.Variable(0, dtype=tf.float32) 
step = tf.Variable(0, trainable=False) # 此处step模拟神经网络迭代的轮数 
# 定义一个滑动平均的类对象,初始化衰减率decay=0.99,用于动态控制衰减率的参数num_updates 
ema = tf.train.ExponentialMovingAverage(0.99, num_updates=step) 
 
# apply方法返回一个对var_list进行更新滑动平均的操作,var_list必须是list的Variable或Tensor 
# 该操作执行会更新var_list的影子变量shadow variable 
maintain_averages_op = ema.apply(var_list=[v1]) 
 
with tf.Session() as sess: 
  init_op = tf.global_variables_initializer() 
  sess.run(init_op) 
  # average方法可获取滑动平均后变量的取值 
  print(sess.run([v1, ema.average(v1)])) # [0.0, 0.0] 
 
  sess.run(tf.assign(v1, 5)) 
  # min{0.99, (1+step)(10+step)=0.1}=0.1 
  # 更新v1的滑动平均值为 0.1*0.0+0.9*5=4.5 
  sess.run(maintain_averages_op) 
  print(sess.run([v1, ema.average(v1)])) # [5.0, 4.5] 
 
  sess.run(tf.assign(step, 10000)) 
  sess.run(tf.assign(v1, 10)) 
  # min{0.99, (1+step)(10+step)=0.999}=0.99 
  # 更新v1的滑动平均值为 0.99*4.5+0.01*10=4.555 
  sess.run(maintain_averages_op) 
  print(sess.run([v1, ema.average(v1)])) # [10.0, 4.5549998] 
 
  # 更新v1的滑动平均值为 0.99*4.555+0.01*10=4.60945 
  sess.run(maintain_averages_op) 
  print(sess.run([v1, ema.average(v1)])) # [10.0, 4.6094499]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
举例讲解Linux系统下Python调用系统Shell的方法
Nov 07 Python
Python解析json文件相关知识学习
Mar 01 Python
对比Python中__getattr__和 __getattribute__获取属性的用法
Jun 21 Python
python通过cookie模拟已登录状态的初步研究
Nov 09 Python
Python实现数据库并行读取和写入实例
Jun 09 Python
Python运维自动化之nginx配置文件对比操作示例
Aug 29 Python
python dlib人脸识别代码实例
Apr 04 Python
详解python pandas 分组统计的方法
Jul 30 Python
Python模块的制作方法实例分析
Dec 21 Python
关于Pytorch MaxUnpool2d中size操作方式
Jan 03 Python
python与c语言的语法有哪些不一样的
Sep 13 Python
Python爬虫简单运用爬取代理IP的实现
Dec 01 Python
TensorFlow实现AutoEncoder自编码器
Mar 09 #Python
TensorFlow实现MLP多层感知机模型
Mar 09 #Python
TensorFlow实现Softmax回归模型
Mar 09 #Python
用python实现百度翻译的示例代码
Mar 09 #Python
TensorFlow深度学习之卷积神经网络CNN
Mar 09 #Python
TensorFlow实现卷积神经网络CNN
Mar 09 #Python
新手常见6种的python报错及解决方法
Mar 09 #Python
You might like
ezSQL PHP数据库操作类库
2010/05/16 PHP
extjs 的权限问题 要求控制的对象是 菜单,按钮,URL
2010/03/09 Javascript
文本框输入时 实现自动提示(像百度、google一样)
2012/04/05 Javascript
Javascript selection的兼容性写法介绍
2013/12/20 Javascript
iframe里面的元素触发父窗口元素事件的jquery代码
2014/10/19 Javascript
JsRender实用入门教程
2014/10/31 Javascript
javascript实现复选框选中属性
2015/03/25 Javascript
JavaScript获取指定元素位置的方法
2015/04/08 Javascript
AngularJS中实现显示或隐藏动画效果的方式总结
2015/12/31 Javascript
jQuery Mobile开发中日期插件Mobiscroll使用说明
2016/03/02 Javascript
轻松掌握JavaScript中介者模式
2016/08/26 Javascript
JavaScript设计模式之单体模式全面解析
2016/09/09 Javascript
使用jQuery实现两个div中按钮互换位置的实例代码
2017/09/21 jQuery
十分钟带你快速了解React16新特性
2017/11/10 Javascript
js断点调试心得分享(必看篇)
2017/12/08 Javascript
浅谈JavaScript面向对象--继承
2019/03/20 Javascript
微信小程序iOS下拉白屏晃动问题解决方案
2019/10/12 Javascript
layui table 复选框跳页后再回来保持原来选中的状态示例
2019/10/26 Javascript
[02:20]DOTA2中文配音宣传片
2013/05/22 DOTA
python+splinter自动刷新抢票功能
2018/09/25 Python
用Python批量把文件复制到另一个文件夹的实现方法
2019/08/16 Python
python实现画出e指数函数的图像
2019/11/21 Python
TensorFlow tensor的拼接实例
2020/01/19 Python
python文件路径操作方法总结
2020/12/21 Python
Pytorch1.5.1版本安装的方法步骤
2020/12/31 Python
CSS3让登陆面板3D旋转起来
2016/05/03 HTML / CSS
解决H5的a标签的download属性下载service上的文件出现跨域问题
2019/07/16 HTML / CSS
澳大利亚领先的宠物用品商店:VetSupply
2017/09/08 全球购物
UNIX文件系统分类
2014/11/11 面试题
计算机专业自荐信
2013/10/14 职场文书
学校地质灾害防治方案
2014/06/10 职场文书
工厂见习报告范文
2014/10/31 职场文书
研究生就业推荐表导师评语
2014/12/31 职场文书
六一领导慰问欢迎词
2015/01/26 职场文书
应届毕业生自荐信
2015/03/04 职场文书
Vue的列表之渲染,排序,过滤详解
2022/02/24 Vue.js