bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

基于TensorFlow中如何自定義梯度-創新互聯

這篇文章主要為大家展示了“基于TensorFlow中如何自定義梯度”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“基于TensorFlow中如何自定義梯度”這篇文章吧。

創新互聯建站專注于沂水網站建設服務及定制,我們擁有豐富的企業做網站經驗。 熱誠為您提供沂水營銷型網站建設,沂水網站制作、沂水網頁設計、沂水網站官網定制、微信小程序開發服務,打造沂水網絡公司原創品牌,更為您提供沂水網站排名全網營銷落地服務。

前言

在深度學習中,有時候我們需要對某些節點的梯度進行一些定制,特別是該節點操作不可導(比如階梯除法如 基于TensorFlow中如何自定義梯度 ),如果實在需要對這個節點進行操作,而且希望其可以反向傳播,那么就需要對其進行自定義反向傳播時的梯度。在有些場景,如[2]中介紹到的梯度反轉(gradient inverse)中,就必須在某層節點對反向傳播的梯度進行反轉,也就是需要更改正常的梯度傳播過程,如下圖的 基于TensorFlow中如何自定義梯度 所示。

基于TensorFlow中如何自定義梯度

在tensorflow中有若干可以實現定制梯度的方法,這里介紹兩種。

1. 重寫梯度法

重寫梯度法指的是通過tensorflow自帶的機制,將某個節點的梯度重寫(override),這種方法的適用性最廣。我們這里舉個例子[3].

符號函數的前向傳播采用的是階躍函數y=sign(x) y = \rm{sign}(x)y=sign(x),如下圖所示,我們知道階躍函數不是連續可導的,因此我們在反向傳播時,將其替代為一個可以連續求導的函數y=Htanh(x) y = \rm{Htanh(x)}y=Htanh(x),于是梯度就是大于1和小于-1時為0,在-1和1之間時是1。

基于TensorFlow中如何自定義梯度

使用重寫梯度的方法如下,主要是涉及到tf.RegisterGradient()和tf.get_default_graph().gradient_override_map(),前者注冊新的梯度,后者重寫圖中具有名字name='Sign'的操作節點的梯度,用在新注冊的QuantizeGrad替代。

#使用修飾器,建立梯度反向傳播函數。其中op.input包含輸入值、輸出值,grad包含上層傳來的梯度
@tf.RegisterGradient("QuantizeGrad")
def sign_grad(op, grad):
 input = op.inputs[0] # 取出當前的輸入
 cond = (input>=-1)&(input<=1) # 大于1或者小于-1的值的位置
 zeros = tf.zeros_like(grad) # 定義出0矩陣用于掩膜
 return tf.where(cond, grad, zeros) 
 # 將大于1或者小于-1的上一層的梯度置為0
 
#使用with上下文管理器覆蓋原始的sign梯度函數
def binary(input):
 x = input
 with tf.get_default_graph().gradient_override_map({"Sign":'QuantizeGrad'}):
 #重寫梯度
  x = tf.sign(x)
 return x
 
#使用
x = binary(x)

其中的def sign_grad(op, grad):是注冊新的梯度的套路,其中的op是當前操作的輸入值/張量等,而grad指的是從反向而言的上一層的梯度。

通常來說,在tensorflow中自定義梯度,函數tf.identity()是很重要的,其API手冊如下:

tf.identity(
 input,
 name=None
)

其會返回一個形狀和內容都和輸入完全一樣的輸出,但是你可以自定義其反向傳播時的梯度,因此在梯度反轉等操作中特別有用。

這里再舉個反向梯度[2]的例子,也就是梯度為 基于TensorFlow中如何自定義梯度 而不是 基于TensorFlow中如何自定義梯度

import tensorflow as tf
x1 = tf.Variable(1)
x2 = tf.Variable(3)
x3 = tf.Variable(6)
@tf.RegisterGradient('CustomGrad')
def CustomGrad(op, grad):
#  tf.Print(grad)
 return -grad
 
g = tf.get_default_graph()
oo = x1+x2
with g.gradient_override_map({"Identity": "CustomGrad"}):
 output = tf.identity(oo)
grad_1 = tf.gradients(output, oo)
with tf.Session() as sess:
 sess.run(tf.global_variables_initializer())
 print(sess.run(grad_1))

因為-grad,所以這里的梯度輸出是[-1]而不是[1]。有一個我們需要注意的是,在自定義函數def CustomGrad()中,返回的值得是一個張量,而不能返回一個參數,比如return 0,這樣會報錯,如:

AttributeError: 'int' object has no attribute 'name'

顯然,這是因為tensorflow的內部操作需要取返回值的名字而int類型沒有名字。

PS:def CustomGrad()這個函數簽名是隨便你取的。

2. stop_gradient法

對于自定義梯度,還有一種比較簡潔的操作,就是利用tf.stop_gradient()函數,我們看下例子[1]:

t = g(x)
y = t + tf.stop_gradient(f(x) - t)

這里,我們本來的前向傳遞函數是f(x),但是想要在反向時傳遞的函數是g(x),因為在前向過程中,tf.stop_gradient()不起作用,因此+t和-t抵消掉了,只剩下f(x)前向傳遞;而在反向過程中,因為tf.stop_gradient()的作用,使得f(x)-t的梯度變為了0,從而只剩下g(x)在反向傳遞。

我們看下完整的例子:

import tensorflow as tf

x1 = tf.Variable(1)
x2 = tf.Variable(3)
x3 = tf.Variable(6)

f = x1+x2*x3
t = -f

y1 = t + tf.stop_gradient(f-t)
y2 = f

grad_1 = tf.gradients(y1, x1)
grad_2 = tf.gradients(y2, x1)
with tf.Session(config=config) as sess:
 sess.run(tf.global_variables_initializer())

 print(sess.run(grad_1))
 print(sess.run(grad_2))

第一個輸出為[-1],第二個輸出為[1],顯然也實現了梯度的反轉。

以上是“基于TensorFlow中如何自定義梯度”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注創新互聯成都網站設計公司行業資訊頻道!

另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

文章標題:基于TensorFlow中如何自定義梯度-創新互聯
本文鏈接:http://vcdvsql.cn/article32/dsddpc.html

成都網站建設公司_創新互聯,為您提供搜索引擎優化域名注冊動態網站面包屑導航建站公司網站策劃

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都網頁設計公司