2017-04-16 43 views
0

由於tensorflow支持變量重用,在前進和後退過程中,計算圖的某些部分可能會出現多次。所以我的問題是,是否有可能在計算圖表中更新關於它們的某些事件的變量?如何在tensorflow中獲取有關某些變量的梯度?

例如,在X_A->Y_B->Y_A->Y_BY_B發生兩次,如何分別更新它們?我的意思是,起初,我們將後一種情況視爲常量,更新前一種情況,然後做相反的事情。

一個更簡單的例子是,說X_AY_BY_A都是標量,然後讓Z = X_A * Y_B * Y_A * Y_B,這裏w.r.t的Y_B兩次出現的的Z梯度X_A * Y_B * Y_A,但實際上的ZY_B梯度2*X_A * Y_B * Y_A。在這個例子中,分別計算梯度似乎是不必要的,但並不總是那些計算可交換的。

在第一個示例中,通過調用X_A->Y_B上的tf.stop_gradient可計算到後一次出現的梯度。但我想不出一種方法來取回前一個。有沒有辦法在tensorflow的python API中做到這一點?

編輯:

@Seven提供了關於如何處理它的時候再使用一個變量的例子。然而,通常它是一個可重用的變量作用域,其中包含許多管理它們的變量和函數。據我所知,他們沒有辦法重用變量作用域,將tf.stop_gradient應用到它包含的所有變量。

回答

1

我的理解是,當您使用A = tf.stop_gradient(A)時,A將被視爲常量。我在這裏有一個例子,也許它可以幫助你。

import tensorflow as tf 

wa = tf.get_variable('a', shape=(), dtype=tf.float32, 
        initializer=tf.constant_initializer(1.5)) 
b = tf.get_variable('b', shape=(), dtype=tf.float32, 
        initializer=tf.constant_initializer(7)) 

x = tf.placeholder(tf.float32, shape=()) 
l = tf.stop_gradient(wa*x) * (wa*x+b) 
op_gradient = tf.gradients(l, x) 


sess = tf.Session() 
sess.run(tf.global_variables_initializer()) 


print sess.run([op_gradient], feed_dict={x:11}) 
+0

嗨,謝謝你的例子! 'tf.stop_gradient'確實解決了這個問題的某些部分,正如我在我描述的最後一段中提到的那樣。但是,它只能阻止漸變,直到重用部分的最後一次出現爲止,但在其他情況下無法工作。 – Zardinality

+0

對不起,我誤解了你的問題。也許你可以計算兩個函數,一個停止第一個事件的梯度,第二個停止第二個。我想你想平均兩個漸變來更新權重? – Seven

+0

對不起,我沒有說清楚。這是事情,因爲大部分時間都是被重用的變量作用域,所以我想不出一種方法來阻止變量作用域的漸變,並保護它在下次出現時可以被訓練。設計兩個功能是可行的,但只有在您手動管理這些變量時纔是可行的。此外,我只想得到梯度與某些事件,因爲平均所有梯度類型獲得直接獲取梯度(它們的總和)的結果。 – Zardinality

0

我有一個解決這個問題的解決方法。爲涉及的變量作用域定義一個自定義getter,該變量作用域默認爲tf.stop_gradient。這可以將在此範圍內返回的所有變量設置爲張量不貢獻梯度,但有時事情會變得複雜,因爲它返回張量而不是變量,例如使用tf.nn.batch_norm時。