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 相关文章推荐
Python中bisect的用法
Sep 23 Python
Python使用random和tertools模块解一些经典概率问题
Jan 28 Python
Python的Flask框架应用程序实现使用QQ账号登录的方法
Jun 07 Python
深入理解Python分布式爬虫原理
Nov 23 Python
Python日期时间对象转换为字符串的实例
Jun 22 Python
Python全局变量与局部变量区别及用法分析
Sep 03 Python
计算机二级python学习教程(3) python语言基本数据类型
May 16 Python
python实现音乐播放器 python实现花框音乐盒子
Feb 25 Python
python使用梯度下降算法实现一个多线性回归
Mar 24 Python
python实现从ftp上下载文件的实例方法
Jul 19 Python
如何用python 操作zookeeper
Dec 28 Python
python向xls写入数据(包括合并,边框,对齐,列宽)
Feb 02 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
php图片加水印原理(超简单的实例代码)
2013/01/18 PHP
Apache服务器下防止图片盗链的办法
2015/07/06 PHP
PHP实现关键字搜索后描红功能示例
2019/07/03 PHP
Yii框架的redis命令使用方法简单示例
2019/10/15 PHP
JavaScript 学习笔记一些小技巧
2010/03/28 Javascript
innerHTML与jquery里的html()区别介绍
2012/10/12 Javascript
技术男用来对妹子表白的百度首页
2014/07/23 Javascript
extjs 如何给column 加上提示
2014/07/29 Javascript
Javascript实现div的toggle效果实例分析
2015/06/09 Javascript
JS实现简单的tab切换选项卡效果
2016/09/21 Javascript
javascript常用经典算法详解
2017/01/11 Javascript
Javascript ES6中对象类型Sets的介绍与使用详解
2017/07/17 Javascript
vue-router的使用方法及含参数的配置方法
2018/11/13 Javascript
微信小程序中网络请求缓存的解决方法
2019/12/29 Javascript
利用vue3+ts实现管理后台(增删改查)
2020/10/30 Javascript
使用python实现扫描端口示例
2014/03/29 Python
简单介绍Python中的try和finally和with方法
2015/05/05 Python
Django contenttypes 框架详解(小结)
2018/08/13 Python
Python flask框架post接口调用示例
2019/07/03 Python
Django项目中实现使用qq第三方登录功能
2019/08/13 Python
Python操作Mongodb数据库的方法小结
2019/09/10 Python
python GUI库图形界面开发之PyQt5拖放控件实例详解
2020/02/25 Python
windows10环境下用anaconda和VScode配置的图文教程
2020/03/30 Python
Python获取android设备cpu和内存占用情况
2020/11/15 Python
Python Http请求json解析库用法解析
2020/11/28 Python
移动端适配 使px自动转换rem
2019/08/26 HTML / CSS
捷克购买家具网站:JENA nábytek
2020/03/19 全球购物
国际花店:Pickup Flowers
2020/04/10 全球购物
屈臣氏泰国官网:Watsons TH
2021/02/23 全球购物
成功的餐厅经营创业计划书
2014/01/15 职场文书
竞争上岗实施方案
2014/03/21 职场文书
交通安全标语
2014/06/06 职场文书
如何签定毕业生就业协议书
2014/09/28 职场文书
《雪地里的小画家》教学反思
2016/02/16 职场文书
CSS 一行代码实现头像与国旗的融合
2021/10/24 HTML / CSS
美国运营商 T-Mobile 以 117.83Mb/s 的速度排第一位
2022/04/21 数码科技