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与PHP的实现版(推荐)
May 11 Python
Python callable()函数用法实例分析
Mar 17 Python
Python sorted函数详解(高级篇)
Sep 18 Python
python实现石头剪刀布小游戏
Jan 20 Python
Django调用支付宝接口代码实例详解
Apr 04 Python
jupyter notebook实现显示行号
Apr 13 Python
Python实现读取并写入Excel文件过程解析
May 27 Python
pytorch cuda上tensor的定义 以及减少cpu的操作详解
Jun 23 Python
python集合能干吗
Jul 19 Python
Python常用GUI框架原理解析汇总
Dec 07 Python
关于多种方式完美解决Python pip命令下载第三方库的问题
Dec 21 Python
python gui开发——制作抖音无水印视频下载工具(附源码)
Feb 07 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 使用MySQL管理Session的回调函数详解
2013/06/21 PHP
PHP源码分析之变量的存储过程分解
2014/07/03 PHP
完美的php分页类
2017/10/24 PHP
js setattribute批量设置css样式
2009/11/26 Javascript
十个优秀的Ajax/Javascript实例网站收集
2010/03/31 Javascript
IE事件对象(The Internet Explorer Event Object)
2012/06/27 Javascript
js 字符串转换成数字的三种方法
2013/03/23 Javascript
nodejs中转换URL字符串与查询字符串详解
2014/11/26 NodeJs
JavaScript实现的简单拖拽效果
2015/06/01 Javascript
全面解析Bootstrap布局组件应用
2016/02/22 Javascript
VC调用javascript的几种方法(推荐)
2016/08/09 Javascript
原生JS实现-星级评分系统的简单实例
2016/08/21 Javascript
Vue.js如何优雅的进行form validation
2017/04/07 Javascript
javascript填充默认头像方法
2018/02/22 Javascript
Angular父组件调用子组件的方法
2018/04/02 Javascript
jQuery操作元素追加内容示例
2020/01/10 jQuery
js节流防抖应用场景,以及在vue中节流防抖的具体实现操作
2020/09/21 Javascript
使用Python构建Hopfield网络的教程
2015/04/14 Python
利用Python实现Windows定时关机功能
2017/03/21 Python
python 类详解及简单实例
2017/03/24 Python
浅述python中argsort()函数的实例用法
2017/03/30 Python
浅谈Python实现2种文件复制的方法
2018/01/19 Python
Python使用正则表达式获取网页中所需要的信息
2018/01/29 Python
Python中面向对象你应该知道的一下知识
2019/07/10 Python
django 单表操作实例详解
2019/07/30 Python
python使用sessions模拟登录淘宝的方式
2019/08/16 Python
Python3实现将一维数组按标准长度分隔为二维数组
2019/11/29 Python
tensorflow下的图片标准化函数per_image_standardization用法
2020/06/30 Python
python 进程池pool使用详解
2020/10/15 Python
某公司的.net工程师面试题笔试题
2013/11/22 面试题
国贸专业个人求职信范文
2014/01/08 职场文书
英语演讲稿3分钟
2014/04/29 职场文书
防灾减灾活动总结
2014/08/30 职场文书
运动会广播稿300字
2015/08/19 职场文书
CSS3实现的水平标题菜单
2021/04/14 HTML / CSS
Java 使用类型为Object的变量指向任意类型的对象
2022/04/13 Java/Android