Tensorflow中k.gradients()和tf.stop_gradient()用法說(shuō)明
上周在實(shí)驗(yàn)室開(kāi)荒某個(gè)代碼,看到中間這么一段,對(duì)Tensorflow中的stop_gradient()還不熟悉,特此周末進(jìn)行重新并總結(jié)。
y = xx + K.stop_gradient(rounded - xx)
這代碼最終調(diào)用位置在tensoflow.python.ops.gen_array_ops.stop_gradient(input, name=None),關(guān)于這段代碼為什么這樣寫(xiě)的意義在文末給出。
【stop_gradient()意義】
用stop_gradient生成損失函數(shù)w.r.t.的梯度。
【tf.gradients()理解】
tf中我們只需要設(shè)計(jì)我們自己的函數(shù),tf提供提供強(qiáng)大的自動(dòng)計(jì)算函數(shù)梯度方法,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()實(shí)現(xiàn)ys對(duì)xs的求導(dǎo)
2、ys和xs可以是Tensor或者list包含的Tensor
3、求導(dǎo)返回值是一個(gè)list,list的長(zhǎng)度等于len(xs)
eg.假設(shè)返回值是[grad1, grad2, grad3],ys=[y1, y2],xs=[x1, x2, x3]。則計(jì)算過(guò)程為:
import numpy as np import tensorflow as tf #構(gòu)造數(shù)據(jù)集 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()
自定義梯度和更新函數(shù)
import numpy as np import tensorflow as tf #構(gòu)造數(shù)據(jù)集 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) #自定義權(quán)重更新 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()參數(shù)中存在stop_gradients,這是一個(gè)List,list中的元素是tensorflow graph中的op,一旦進(jìn)入這個(gè)list,將不會(huì)被計(jì)算梯度,更重要的是,在該op之后的BP計(jì)算都不會(huì)運(yùn)行。
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]
在用一個(gè)stop_gradient()的例子
import tensorflow as tf #實(shí)驗(yàn)一 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>] #實(shí)驗(yàn)二 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)) #因?yàn)樘荻葟牧硗獾胤絺骰?,所以輸?[1.0, 1.0]
【答案】
開(kāi)始提出的問(wèn)題,為什么存在那段代碼:
t = g(x)
y = t + tf.stop_gradient(f(x) - t)
這里,我們本來(lái)的前向傳遞函數(shù)是XX,但是想要在反向時(shí)傳遞的函數(shù)是g(x),因?yàn)樵谇跋蜻^(guò)程中,tf.stop_gradient()不起作用,因此+t和-t抵消掉了,只剩下f(x)前向傳遞;而在反向過(guò)程中,因?yàn)閠f.stop_gradient()的作用,使得f(x)-t的梯度變?yōu)榱?,從而只剩下g(x)在反向傳遞。
以上這篇Tensorflow中k.gradients()和tf.stop_gradient()用法說(shuō)明就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python光學(xué)仿真通過(guò)菲涅耳公式實(shí)現(xiàn)波動(dòng)模型
這篇文章主要介紹了python光學(xué)仿真通過(guò)菲涅耳公式實(shí)現(xiàn)波動(dòng)模型的示例解析原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-10-10淺談numpy數(shù)組中冒號(hào)和負(fù)號(hào)的含義
下面小編就為大家分享一篇淺談numpy數(shù)組中冒號(hào)和負(fù)號(hào)的含義,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04Python中線程threading.Thread的使用詳解
python的thread模塊是比較底層的模塊,python的threading模塊是對(duì)thread做了一些包裝的,可以更加方便的被使用。本文將為大家詳細(xì)介紹一下python中的線程threading.Thread()的使用,需要的可以參考一下2022-07-07使用coverage統(tǒng)計(jì)python web項(xiàng)目代碼覆蓋率的方法詳解
這篇文章主要介紹了使用coverage統(tǒng)計(jì)python web項(xiàng)目代碼覆蓋率的方法,詳細(xì)分析了coverage的安裝以及coverage命令統(tǒng)計(jì)py文件相關(guān)操作技巧,需要的朋友可以參考下2019-08-08python實(shí)現(xiàn)一次創(chuàng)建多級(jí)目錄的方法
這篇文章主要介紹了python實(shí)現(xiàn)一次創(chuàng)建多級(jí)目錄的方法,涉及Python中os模塊makedirs方法的使用技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-05-05