上周在实验室开荒某个代码,看到中间这么一段,对Tensorflow中的stop_gradient()还不熟悉,特此周末进行重新并总结。
y = xx + K.stop_gradient(rounded - xx)
这代码最终调用位置在tensoflow.python.ops.gen_array_ops.stop_gradient(input, name=None),关于这段代码为什么这样写的意义在文末给出。
【stop_gradient()意义】
用stop_gradient生成损失函数w.r.t.的梯度。
【tf.gradients()理解】
tf中我们只需要设计我们自己的函数,tf提供提供强大的自动计算函数梯度方法,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 )
gradients() adds ops to the graph to output the derivatives of ys with respect to xs. It returns a list of Tensor of length len(xs) where each tensor is the sum(dy/dx) for y in ys.
1、tf.gradients()实现ys对xs的求导
2、ys和xs可以是Tensor或者list包含的Tensor
3、求导返回值是一个list,list的长度等于len(xs)
eg.假设返回值是[grad1, grad2, grad3],ys=[y1, y2],xs=[x1, x2, x3]。则计算过程为:
import numpy as np import tensorflow as tf #构造数据集 x_pure = np.random.randint(-10, 100, 32) x_train = x_pure + np.random.randn(32) / 32 y_train = 3 * x_pure + 2 + np.random.randn(32) / 32 x_input = tf.placeholder(tf.float32, name='x_input') y_input = tf.placeholder(tf.float32, name='y_input') w = tf.Variable(2.0, name='weight') b = tf.Variable(1.0, name='biases') y = tf.add(tf.multiply(x_input, w), b) loss_op = tf.reduce_sum(tf.pow(y_input - y, 2)) / (2 * 32) train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss_op) gradients_node = tf.gradients(loss_op, w) sess = tf.Session() init = tf.global_variables_initializer() sess.run(init) for i in range(20): _, gradients, loss = sess.run([train_op, gradients_node, loss_op], feed_dict={x_input: x_train[i], y_input: y_train[i]}) print("epoch: {} \t loss: {} \t gradients: {}".format(i, loss, gradients)) sess.close()
自定义梯度和更新函数
import numpy as np import tensorflow as tf #构造数据集 x_pure = np.random.randint(-10, 100, 32) x_train = x_pure + np.random.randn(32) / 32 y_train = 3 * x_pure + 2 + np.random.randn(32) / 32 x_input = tf.placeholder(tf.float32, name='x_input') y_input = tf.placeholder(tf.float32, name='y_input') w = tf.Variable(2.0, name='weight') b = tf.Variable(1.0, name='biases') y = tf.add(tf.multiply(x_input, w), b) loss_op = tf.reduce_sum(tf.pow(y_input - y, 2)) / (2 * 32) # train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss_op) #自定义权重更新 grad_w, grad_b = tf.gradients(loss_op, [w, b]) new_w = w.assign(w - 0.01 * grad_w) new_b = b.assign(b - 0.01 * grad_b) init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) for i in range(20): _, gradients, loss = sess.run([new_w, new_b, loss_op], feed_dict={x_input: x_train[i], y_input: y_train[i]}) print("epoch: {} \t loss: {} \t gradients: {}".format(i, loss, gradients)) sess.close()
【tf.stop_gradient()理解】
在tf.gradients()参数中存在stop_gradients,这是一个List,list中的元素是tensorflow graph中的op,一旦进入这个list,将不会被计算梯度,更重要的是,在该op之后的BP计算都不会运行。
import numpy as np import tensorflow as tf a = tf.constant(0.) b = 2 * a c = a + b g = tf.gradients(c, [a, b]) with tf.Session() as sess: tf.global_variables_initializer().run() print(sess.run(g)) #输出[3.0, 1.0]
在用一个stop_gradient()的例子
import tensorflow as tf #实验一 w1 = tf.Variable(2.0) w2 = tf.Variable(2.0) a = tf.multiply(w1, 3.0) a_stoped = tf.stop_gradient(a) # b=w1*3.0*w2 b = tf.multiply(a_stoped, w2) gradients = tf.gradients(b, xs=[w1, w2]) print(gradients) #输出[None, <tf.Tensor 'gradients/Mul_1_grad/Reshape_1:0' shape=() dtype=float32>] #实验二 a = tf.Variable(1.0) b = tf.Variable(1.0) c = tf.add(a, b) c_stoped = tf.stop_gradient(c) d = tf.add(a, b) e = tf.add(c_stoped, d) gradients = tf.gradients(e, xs=[a, b]) with tf.Session() as sess: tf.global_variables_initializer().run() print(sess.run(gradients)) #因为梯度从另外地方传回,所以输出 [1.0, 1.0]
【答案】
开始提出的问题,为什么存在那段代码:
t = g(x)
y = t + tf.stop_gradient(f(x) - t)
这里,我们本来的前向传递函数是XX,但是想要在反向时传递的函数是g(x),因为在前向过程中,tf.stop_gradient()不起作用,因此+t和-t抵消掉了,只剩下f(x)前向传递;而在反向过程中,因为tf.stop_gradient()的作用,使得f(x)-t的梯度变为了0,从而只剩下g(x)在反向传递。
以上这篇Tensorflow中k.gradients()和tf.stop_gradient()用法说明就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]