官术网_书友最值得收藏!

3.2 優化器和計算圖

3.2.1 梯度和優化器

前面已經說過,TF的實質是一個自動求微分的工具。根據BP算法(見算法2-2),我們已經知道了在計算偏導數的過程中如何避免重復計算。TF中的優化器(tf.train.Optimizer)及其子孫類就是用來自動求微分的。Optimizer.minimize()函數是用來求張量的最小值的。請注意,與tf.assign()函數一樣,上述minimize()函數返回的也是一個張量。所以執行這個函數并不能馬上求解tensor的極小值,就像執行tf.assign()并不能馬上給一個變量賦值一樣。必須在一個會話的范圍內,通過該會話的run()方法運行minimize()返回的張量,才能求得一個目標函數極小值的解。

tf.train.Optimizer有很多子類,最簡單的就是基于GD法的梯度下降優化器:tr.train.GradientDescentOptimizer。它的原理是根據BP算法計算目標函數針對每個可訓練變量的偏導數,然后利用GD法的式(2-2)計算每個可訓練變量的誤差,最后再把誤差加到對應的變量上(見算法2-1)。除了梯度下降優化器外,TF還有很多其他優化器,例如MomentumOptimier、AdamOptimier等。它們都是為了克服梯度下降優化器的不足而提出的,我們在后面的章節中會加以說明。下面通過例子來說明優化器的使用方法。

3.2.2 求解平方根

根據前面的討論,我們已經知道,用GD法求正數a的平方根等價于求解函數y=(x2-a2的最小值。所以代碼應該是這樣的:

請注意:

1)初始化器Initializer用來為變量賦初值。常用的初始化器有tf.initializer包里的ones、zeros、random_normal、random_uniform等,分別表示給變量的每一個元素賦初值1、0、正態分布隨機數和均勻分布隨機數。注意,變量的真正初始化要到運行Session.run(tf.global_variables_initializer())時才執行。

2)在對模型進行訓練前,應該執行Session.run(tf.global_variables_initializer()),給所有可訓練張量賦初值。如果沒有定義變量,這一句可不運行。變量只需賦初值一次,因此這一句應該在while循環前執行。

Session每運行一次ts.train_op張量,就會按照BP算法自動計算目標函數針對每個相關可訓練變量[5]的偏導數(即梯度),然后按照Optimizer對象的規定計算每個變量的誤差,最后根據誤差自動調整每個變量的值。

3)Session.run()函數一次可運行一個張量或者多個張量。當運行多個張量時,請把它們組成一個列表(list)或者元組(tupple)。一般來說,張量之間的次序不重要。如果只求一個張量的值,run()的返回值就是這個張量的值;如果同時求多個張量的值,則返回一個依次包含每個張量的值的列表。tf.train.Optimizer張量的值是None。

上面程序運行的結果是:

sqrt(2)=1.4141785

sqrt(3)=1.7320222

sqrt(4)=1.9999753

sqrt(5)=2.2360463

sqrt(6)=2.4494696

sqrt(7)=2.6457334

sqrt(8)=2.8284097

sqrt(9)=2.9999843

sqrt(10)=3.1622627

3.2.3 計算圖

前文已經說過,計算圖的實質是依賴關系圖。依賴關系圖不僅定義了運算之間的依賴關系,還避免了重復運算。但是,在上一節計算平方根時,并沒有涉及計算圖tf.Graph。這是怎么回事呢?

第一,我們實際上已經使用了計算圖。在TF里,如果用戶不顯示地使用一個計算圖,系統就會建一個缺省計算圖。用戶可以通過tf.get_default_graph()函數,或者Session.graph屬性獲取這個計算圖。

第二,由于沒有顯示地使用計算圖,所以代碼3-9存在一個缺陷,即如果我們在其他的.py文件中定義了一個新的模型,則它跟當前計算平方根的模型都存在于系統的缺省計算圖上。這不但會導致變量名字沖突,當模型不再被使用時,還會為清除模型帶來不便。一般地,我們應該讓計算圖與模型之間一一對應,最好不要在同一個計算圖上定義兩個獨立的模型。

使用計算圖的方法是先構建一個tf.Graph對象,然后調用as_default()方法,并在其下創建所有張量。下面是使用計算圖求平方根的程序:

運行結果與上一節代碼的結果相同。

主站蜘蛛池模板: 广平县| 德令哈市| 炉霍县| 峡江县| 罗定市| 正安县| 左贡县| 山丹县| 白水县| 南部县| 天门市| 宣汉县| 青州市| 定襄县| 文化| 中西区| 酉阳| 达尔| 确山县| 吴江市| 关岭| 昌宁县| 洛隆县| 安化县| 准格尔旗| 迁安市| 湖州市| 合肥市| 鸡东县| 苍山县| 平江县| 麟游县| 新巴尔虎左旗| 镇宁| 瑞安市| 湘潭县| 东丰县| 汝州市| 军事| 章丘市| 三门峡市|