I optimizer.minimize(loss, var_list)

我们都知道,TensorFlow为我们提供了丰富的优化函数,例如GradientDescentOptimizer。这个方法会自动根据loss计算对应variable的导数。示例如下:

loss = ...
opt = tf.tf.train.GradientDescentOptimizer(learning_rate=0.1)
train_op = opt.minimize(loss)
init = tf.initialize_all_variables() with tf.Seesion() as sess:
sess.run(init)
for step in range(10):
session.run(train_op)

首先我们看一下minimize()的源代码(为方便说明,部分参数已删除):

def minimize(self, loss, global_step=None, var_list=None, name=None):

    grads_and_vars = self.compute_gradients(loss, var_list=var_list)

    vars_with_grad = [v for g, v in grads_and_vars if g is not None]
if not vars_with_grad:
raise ValueError(
"No gradients provided for any variable, check your graph for ops"
" that do not support gradients, between variables %s and loss %s." %
([str(v) for _, v in grads_and_vars], loss)) return self.apply_gradients(grads_and_vars, global_step=global_step,
name=name)

由源代码可以知道minimize()实际上包含了两个步骤,即compute_gradientsapply_gradients,前者用于计算梯度,后者用于使用计算得到的梯度来更新对应的variable。下面对这两个函数做具体介绍。

II computer_gradients(loss, val_list)

参数含义:

  • loss: 需要被优化的Tensor
  • val_list: Optional list or tuple of tf.Variable to update to minimize loss. Defaults to the list of variables collected in the graph under the key GraphKeys.TRAINABLE_VARIABLES.

简单说该函数就是用于计算loss对于指定val_list的导数的,最终返回的是元组列表,即[(gradient, variable),...]。

看下面的示例

x = tf.Variable(initial_value=50., dtype='float32')
w = tf.Variable(initial_value=10., dtype='float32')
y = w*x opt = tf.train.GradientDescentOptimizer(0.1)
grad = opt.compute_gradients(y, [w,x])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(grad))

返回值如下:

>>> [(50.0, 10.0), (10.0, 50.0)]

可以看到返回了一个list,list中的元素是元组。第一个元组第一个元素是50,表示\(\frac{\partial{y}}{\partial{w}}\)的计算结果,第二个元素表示\(w\)。第二个元组同理不做赘述。

其中tf.gradients(loss, tf.variables)的作用和这个函数类似,但是它只会返回计算得到的梯度,而不会返回对应的variable。

with tf.Graph().as_default():
x = tf.Variable(initial_value=3., dtype='float32')
w = tf.Variable(initial_value=4., dtype='float32')
y = w*x grads = tf.gradients(y, [w])
print(grads) opt = tf.train.GradientDescentOptimizer(0.1)
grads_vals = opt.compute_gradients(y, [w])
print(grad_vals) >>>
[<tf.Tensor 'gradients/mul_grad/Mul:0' shape=() dtype=float32>]
[(<tf.Tensor 'gradients_1/mul_grad/tuple/control_dependency:0' shape=() dtype=float32>, <tf.Variable 'Variable_1:0' shape=() dtype=float32_ref>)]

III apply_gradients(grads_and_vars, global_step=None, name=None)

该函数的作用是将compute_gradients()返回的值作为输入参数对variable进行更新。

那为什么minimize()会分开两个步骤呢?原因是因为在某些情况下我们需要对梯度做一定的修正,例如为了防止梯度消失(gradient vanishing)或者梯度爆炸(gradient explosion),我们需要事先干预一下以免程序出现Nan的尴尬情况;有的时候也许我们需要给计算得到的梯度乘以一个权重或者其他乱七八糟的原因,所以才分开了两个步骤。

IV Example

下面给出一个使用tf.clip_by_norm来修正梯度的例子:

with tf.Graph().as_default():
x = tf.Variable(initial_value=3., dtype='float32')
w = tf.Variable(initial_value=4., dtype='float32')
y = w*x opt = tf.train.GradientDescentOptimizer(0.1)
grads_vals = opt.compute_gradients(y, [w])
for i, (g, v) in enumerate(grads_vals):
if g is not None:
grads_vals[i] = (tf.clip_by_norm(g, 5), v) # clip gradients
train_op = opt.apply_gradients(grads_vals)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(grads_vals))
print(sess.run([x,w,y])) >>>
[(3.0, 4.0)]
[3.0, 4.0, 12.0]

其他的tf.clip_by_*方法可参看TensorFlow学习笔记之--[tf.clip_by_global_norm,tf.clip_by_value,tf.clip_by_norm等的区别]

微信公众号:AutoML机器学习

MARSGGBO♥原创

如有意合作或学术讨论欢迎私戳联系~
邮箱:marsggbo@foxmail.com


2018-12-2

TensorFlow学习笔记之--[compute_gradients和apply_gradients原理浅析]的更多相关文章

  1. tensorflow学习笔记——使用TensorFlow操作MNIST数据(1)

    续集请点击我:tensorflow学习笔记——使用TensorFlow操作MNIST数据(2) 本节开始学习使用tensorflow教程,当然从最简单的MNIST开始.这怎么说呢,就好比编程入门有He ...

  2. tensorflow学习笔记——自编码器及多层感知器

    1,自编码器简介 传统机器学习任务很大程度上依赖于好的特征工程,比如对数值型,日期时间型,种类型等特征的提取.特征工程往往是非常耗时耗力的,在图像,语音和视频中提取到有效的特征就更难了,工程师必须在这 ...

  3. Tensorflow学习笔记No.4.1

    使用CNN卷积神经网络(1) 简单介绍CNN卷积神经网络的概念和原理. 已经了解的小伙伴可以跳转到Tensorflow学习笔记No.4.2学习如和用Tensorflow实现简单的卷积神经网络. 1.C ...

  4. Tensorflow学习笔记No.7

    tf.data与自定义训练综合实例 使用tf.data自定义猫狗数据集,并使用自定义训练实现猫狗数据集的分类. 1.使用tf.data创建自定义数据集 我们使用kaggle上的猫狗数据以及tf.dat ...

  5. Tensorflow学习笔记No.8

    使用VGG16网络进行迁移学习 使用在ImageNet数据上预训练的VGG16网络模型对猫狗数据集进行分类识别. 1.预训练网络 预训练网络是一个保存好的,已经在大型数据集上训练好的卷积神经网络. 如 ...

  6. Tensorflow学习笔记2:About Session, Graph, Operation and Tensor

    简介 上一篇笔记:Tensorflow学习笔记1:Get Started 我们谈到Tensorflow是基于图(Graph)的计算系统.而图的节点则是由操作(Operation)来构成的,而图的各个节 ...

  7. Tensorflow学习笔记2019.01.22

    tensorflow学习笔记2 edit by Strangewx 2019.01.04 4.1 机器学习基础 4.1.1 一般结构: 初始化模型参数:通常随机赋值,简单模型赋值0 训练数据:一般打乱 ...

  8. Tensorflow学习笔记2019.01.03

    tensorflow学习笔记: 3.2 Tensorflow中定义数据流图 张量知识矩阵的一个超集. 超集:如果一个集合S2中的每一个元素都在集合S1中,且集合S1中可能包含S2中没有的元素,则集合S ...

  9. 深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识

    深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识 在tf第一个例子的时候需要很多预备知识. tf基本知识 香农熵 交叉熵代价函数cross-entropy 卷积神经网络 s ...

随机推荐

  1. (逆序对 分治法)P1908 逆序对 洛谷

    题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定 ...

  2. Linux truncate的使用方法介绍

    Linux truncate的使用方法介绍 参考资料:https://www.fengbohello.top/archives/linux-truncate 本命令缩减或扩充指定文件的大小为指定值.参 ...

  3. 如何修改Tomcat的默认项目发布路径

    tomcat默认的项目发布目录是/webapp/ROOT,如果想自定义发布目录,应该怎么办呢? 修改配置文件 首先,修改$tomcat/conf/server.xml文件. 在server.xml文件 ...

  4. Event Recommendation Engine Challenge分步解析第七步

    一.请知晓 本文是基于: Event Recommendation Engine Challenge分步解析第一步 Event Recommendation Engine Challenge分步解析第 ...

  5. MyBatis-Select 流程

    mybatis 版本:3.5.1 测试代码: public interface MyUserMapperAnnotation { @Select("select * from myuser ...

  6. js异步下载文件请求

    注意 :通常下载文件是用get请求 window.location.href=url; 但是 我们需要下载完成监听,所以必须要异步执行.用常规的ajax是不可以的.我们要用blob对象来实现1.原生的 ...

  7. python js(JavaScript)初识

    ####################总结############## 引入: 可以在body标签中放入<script type=”text/javascript”></scrip ...

  8. python 进程锁 生产者消费者模型 队列 (进程其他方法,守护进程,数据共享,进程隔离验证)

    #######################总结######### 主要理解 锁      生产者消费者模型 解耦用的   队列 共享资源的时候 是不安全的 所以用到后面的锁 守护进程:p.daem ...

  9. weblogic的基本概念

    1.Domain,Administration Server, Managed Server 域包含一个或多个 WebLogic Server 实例. Domain 中包含一个特殊的 WebLogic ...

  10. 新SQL temp

    select a.createtime, -- 日期 dept.name as deptName, -- 科室 (select t.docname from ( SELECT u.clinic_id ...