『TensorFlow』梯度優化相關


tf.trainable_variables可以得到整個模型中所有trainable=True的Variable,也是自由處理梯度的基礎

基礎梯度操作方法:

tf.gradients 
用來計算導數。該函數的定義如下所示

def gradients(ys,
              xs,
              grad_ys=None,
              name="gradients",
              colocate_gradients_with_ops=False,
              gate_gradients=False,
              aggregation_method=None):

雖然可選參數很多,但是最常使用的還是ys和xs。根據說明得知,ys和xs都可以是一個tensor或者tensor列表。而計算完成以后,該函數會返回一個長為len(xs)的tensor列表,列表中的每個tensor是ys中每個值對xs[i]求導之和。如果用數學公式表示的話,那么 g = tf.gradients(y,x)可以表示成 ,

『cs231n』通過代碼理解風格遷移

tf.gradients(loss, model.input_tensor)  # 計算梯度,並非使用optimizer類實現

 

tf.clip_by_global_norm 

修正梯度值,用於控制梯度爆炸的問題。梯度爆炸和梯度彌散的原因一樣,都是因為鏈式法則求導的關系,導致梯度的指數級衰減。為了避免梯度爆炸,需要對梯度進行修剪。 
先來看這個函數的定義:

def clip_by_global_norm(t_list, clip_norm, use_norm=None, name=None):

輸入參數中:t_list為待修剪的張量, clip_norm 表示修剪比例(clipping ratio).

函數返回2個參數: list_clipped,修剪后的張量,以及global_norm,一個中間計算量。當然如果你之前已經計算出了global_norm值,你可以在use_norm選項直接指定global_norm的值。

那么具體如何計算呢?根據源碼中的說明,可以得到 

list_clipped[i]=t_list[i] * clip_norm / max(global_norm, clip_norm),

其中 global_norm = sqrt(sum([l2norm(t)**2 for t in t_list]))

可以寫作 

其中, 
LicLig代表t_list[i]和list_clipped[i], 
NcNg代表clip_norm 和 global_norm的值。 
其實也可以看到其實Ng就是t_list的L2模。上式也可以進一步寫作 

也就是說,當t_list的L2模大於指定的Nc時,就會對t_list做等比例縮放。

 這里講解一下具體應用於優化器的方法,

self._lr = tf.Variable(0.0, trainable=False)  # lr 指的是 learning_rate
tvars = tf.trainable_variables()

grads, _ = tf.clip_by_global_norm(tf.gradients(cost, tvars),
                                    config.max_grad_norm)

# 梯度下降優化,指定學習速率
optimizer = tf.train.GradientDescentOptimizer(self._lr)
# optimizer = tf.train.AdamOptimizer()
# optimizer = tf.train.GradientDescentOptimizer(0.5)
self._train_op = optimizer.apply_gradients(zip(grads, tvars))  # 將梯度應用於變量
# self._train_op = optimizer.minimize(grads)

 

優化器類處理法:

『TensorFlow』網絡操作API_下

提取梯度,使用梯度優化變量,效果和上面的例子相同,

# 創建一個optimizer.
opt = GradientDescentOptimizer(learning_rate=0.1)

# 計算<list of variables>相關的梯度
grads_and_vars = opt.compute_gradients(loss, <list of variables>)

# grads_and_vars為tuples (gradient, variable)組成的列表。
#對梯度進行想要的處理,比如cap處理
capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars]

# 令optimizer運用capped的梯度(gradients)
opt.apply_gradients(capped_grads_and_vars)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM