tensorflow中的梯度求解及梯度裁剪操作


Posted in Python onMay 26, 2021

1. tensorflow中梯度求解的几种方式

1.1 tf.gradients

tf.gradients(
    ys,
    xs,
    grad_ys=None,
    name='gradients',
    colocate_gradients_with_ops=False,
    gate_gradients=False,
    aggregation_method=None,
    stop_gradients=None,
    unconnected_gradients=tf.UnconnectedGradients.NONE
)

计算ys关于xs的梯度,tf.gradients返回的结果是一个长度为len(xs)的tensor列表list,例如

tf.gradients(y, [x1, x2, x3]返回[dy/dx1, dy/dx2, dy/dx3]

当y与x无关时,即graph无x到y的路径, 则求y关于x的梯度时返回[None];参数stop_gradients指定的变量对当前梯度求解而言, 梯度求解将止于这些变量。

a = tf.constant(0.)
b = 2 * a
g = tf.gradients(a + b, [a, b], stop_gradients=[a, b]) #梯度计算不再追溯a,b之前的变量

输出:

In: sess.run(g)

out:[1.0, 1.0]

如果不设置stop_gradients参数则反向传播梯度计算将追溯到最开始的值a,输出结果为:

In : sess.run(g)

Out: [3.0, 1.0]

1.2 optimizer.compute_gradients

compute_gradients(
    loss,
    var_list=None,
    gate_gradients=GATE_OP,
    aggregation_method=None,
    colocate_gradients_with_ops=False,
    grad_loss=None
)

optimizer.compute_gradients是tf.gradients的封装,作用相同,但是tfgradients只返回梯度,compute_gradients返回梯度和可导的变量;tf.compute_gradients是optimizer.minimize()的第一步,optimizer.compute_gradients返回一个[(gradient, variable),…]的元组列表,其中gradient是tensor。

直观上,optimizer.compute_gradients只比tf.gradients多了一个variable输出。

optimizer = tf.train.GradientDescentOptimizer(learning_rate = 1.0)
self.train_op = optimizer.minimize(self.cost)
sess.run([train_op], feed_dict={x:data, y:labels})

在这个过程中,调用minimize方法的时候,底层进行的工作包括:

(1) 使用tf.optimizer.compute_gradients计算trainable_variables 集合中所有参数的梯度

(2) 用optimizer.apply_gradients来更新计算得到的梯度对应的变量

上面代码等价于下面代码

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
grads_and_vars = optimizer.compute_gradients(loss)
train_op = optimizer.apply_gradients(grads_and_vars)

1.3 tf.stop_gradient

tf.stop_gradient(
    input,
    name=None
)

tf.stop_gradient阻止input的变量参与梯度计算,即在梯度计算的过程中屏蔽input之前的graph。

返回:关于input的梯度

2. 梯度裁剪

如果我们希望对梯度进行截断,那么就要自己计算出梯度,然后进行clip,最后应用到变量上,代码如下所示,接下来我们一一介绍其中的主要步骤

#return a list of trainable variable in you model
params = tf.trainable_variables()

#create an optimizer
opt = tf.train.GradientDescentOptimizer(self.learning_rate)

#compute gradients for params
gradients = tf.gradients(loss, params)

#process gradients
clipped_gradients, norm = tf.clip_by_global_norm(gradients,max_gradient_norm)

train_op = opt.apply_gradients(zip(clipped_gradients, params)))

2.1 tf.clip_by_global_norm介绍

tf.clip_by_global_norm(t_list, clip_norm, use_norm=None, name=None)

 

t_list 表示梯度张量

clip_norm是截取的比率

在应用这个函数之后,t_list[i]的更新公示变为:

global_norm = sqrt(sum(l2norm(t)**2 for t in t_list))
t_list[i] = t_list[i] * clip_norm / max(global_norm, clip_norm)

也就是分为两步:

(1) 计算所有梯度的平方和global_norm

(2) 如果梯度平方和 global_norm 超过我们指定的clip_norm,那么就对梯度进行缩放;否则就按照原本的计算结果

梯度裁剪实例2

loss = w*x*x
optimizer = tf.train.GradientDescentOptimizer(0.1)
grads_and_vars = optimizer.compute_gradients(loss,[w,x])
grads = tf.gradients(loss,[w,x])
# 修正梯度
for i,(gradient,var) in enumerate(grads_and_vars):
    if gradient is not None:
        grads_and_vars[i] = (tf.clip_by_norm(gradient,5),var)
train_op = optimizer.apply_gradients(grads_and_vars)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(grads_and_vars))
     # 梯度修正前[(9.0, 2.0), (12.0, 3.0)];梯度修正后 ,[(5.0, 2.0), (5.0, 3.0)]
    print(sess.run(grads))  #[9.0, 12.0],
    print(train_op)

补充:tensorflow框架中几种计算梯度的方式

1. tf.gradients

tf.gradients(
    ys,
    xs,
    grad_ys=None,
    name='gradients',
    colocate_gradients_with_ops=False,
    gate_gradients=False,
    aggregation_method=None,
    stop_gradients=None,
    unconnected_gradients=tf.UnconnectedGradients.NONE
)

计算ys关于xs的梯度,tf.gradients返回的结果是一个长度为len(xs)的Tensor列表list,每个张量为sum(dy/dx),即ys关于xs的导数。

例子:

tf.gradients(y, [x1, x2, x3]返回[dy/dx1, dy/dx2, dy/dx3]

当y与x无关时,即graph无x到y的路径, 则求y关于x的梯度时返回[None]

参数stop_gradients指定的变量对当前梯度求解而言, 梯度求解将止于这些变量。

实例:

a = tf.constant(0.)
b = 2 * a
g = tf.gradients(a + b, [a, b], stop_gradients=[a, b]) #梯度计算不再追溯a,b之前的变量

输出:

In: sess.run(g)

out:[1.0, 1.0]

如果不设置stop_gradients参数则反向传播梯度计算将追溯到最开始的值a,输出结果为:

In : sess.run(g)

Out: [3.0, 1.0]

2. optimizer.compute_gradients

compute_gradients(
    loss,
    var_list=None,
    gate_gradients=GATE_OP,
    aggregation_method=None,
    colocate_gradients_with_ops=False,
    grad_loss=None
)

optimizer.compute_gradients是tf.gradients的封装1.

是optimizer.minimize()的第一步,返回(gradient, variable)的列表,其中gradient是tensor。

直观上,optimizer.compute_gradients只比tf.gradients多了一个variable输出。

3. tf.stop_gradient

tf.stop_gradient(
    input,
    name=None
)

tf.stop_gradient阻止input的变量参与梯度计算,即在梯度计算的过程中屏蔽input之前的graph。

返回:关于input的梯度

应用:

1、EM算法,其中M步骤不应涉及通过E步骤的输出的反向传播。

2、Boltzmann机器的对比散度训练,在区分能量函数时,训练不得反向传播通过模型生成样本的图形。

3、对抗性训练,通过对抗性示例生成过程不会发生反向训练。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python自动化工具日志查询分析脚本代码实现
Nov 26 Python
Python选择排序、冒泡排序、合并排序代码实例
Apr 10 Python
Python正则替换字符串函数re.sub用法示例
Jan 19 Python
Python及PyCharm下载与安装教程
Nov 18 Python
Python编程实现线性回归和批量梯度下降法代码实例
Jan 04 Python
详解python中递归函数
Apr 16 Python
python实现文件的备份流程详解
Jun 18 Python
Python标准库shutil模块使用方法解析
Mar 10 Python
keras读取训练好的模型参数并把参数赋值给其它模型详解
Jun 15 Python
golang/python实现归并排序实例代码
Aug 30 Python
python中delattr删除对象方法的代码分析
Dec 15 Python
python DataFrame中stack()方法、unstack()方法和pivot()方法浅析
Apr 06 Python
python numpy中multiply与*及matul 的区别说明
May 26 #Python
python文本处理的方案(结巴分词并去除符号)
Django操作cookie的实现
May 26 #Python
pandas中DataFrame检测重复值的实现
python 中的@运算符使用
May 26 #Python
Python 实现定积分与二重定积分的操作
May 26 #Python
python 解决微分方程的操作(数值解法)
You might like
使用php实现下载生成某链接快捷方式的解决方法
2013/05/07 PHP
PHP中的Memcache详解
2014/04/05 PHP
微信支付之JSAPI公众号支付详解
2019/05/15 PHP
Gird组件 Part-3:范例RSSFeed Viewer
2007/03/10 Javascript
在一个浏览器里呈现所有浏览器测试结果的前端测试工具的思路
2010/03/02 Javascript
javascript 得到变量类型的函数
2010/05/19 Javascript
编写自己的jQuery插件简单实现代码
2011/04/19 Javascript
javascript中的变量作用域以及变量提升详细介绍
2013/10/24 Javascript
正则表达式中特殊符号及正则表达式的几种方法总结(replace,test,search)
2013/11/26 Javascript
JavaScript 模块化编程(笔记)
2015/04/08 Javascript
js实现简单排列组合的方法
2016/01/27 Javascript
Javascript复制实例详解
2016/01/28 Javascript
基于socket.io+express实现多房间聊天
2016/03/17 Javascript
Jquery表单验证失败后不提交的解决方法
2016/10/18 Javascript
servlet+jquery实现文件上传进度条示例代码
2017/01/25 Javascript
详解使用vuex进行菜单管理
2017/12/21 Javascript
微信小程序中遇到的iOS兼容性问题小结
2018/11/14 Javascript
nodejs实现用户登录路由功能
2019/05/22 NodeJs
JS扁平化输出数组的2种方法解析
2019/09/17 Javascript
vue 导出文件,携带请求头token操作
2020/09/10 Javascript
python求斐波那契数列示例分享
2014/02/14 Python
Python高级应用实例对比:高效计算大文件中的最长行的长度
2014/06/08 Python
python使用calendar输出指定年份全年日历的方法
2015/04/04 Python
Python处理json字符串转化为字典的简单实现
2016/07/07 Python
Python制作豆瓣图片的爬虫
2017/12/28 Python
Python 进程操作之进程间通过队列共享数据,队列Queue简单示例
2019/10/11 Python
css3简单练习实现遨游浏览器logo的绘制
2013/01/30 HTML / CSS
CSS3实现div从下往上滑入滑出效果示例
2020/04/28 HTML / CSS
分享一个页面平滑滚动小技巧(推荐)
2019/10/23 HTML / CSS
StubHub巴西:购买和出售您的门票
2016/07/22 全球购物
无毒社区工作方案
2014/05/23 职场文书
外出学习心得体会范文
2016/01/18 职场文书
2016年党员创先争优承诺书
2016/03/25 职场文书
python3.9之你应该知道的新特性详解
2021/04/29 Python
Django分页器的用法你都了解吗
2021/05/26 Python
Python实现信息轰炸工具(再也不怕说不过别人了)
2021/06/11 Python