3.11 TensorFlow-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
| 3.10 深度學習框架 | 回到目錄 | 3.12 總結 |
TensorFlow
歡迎來到這周的最后一個視頻,有很多很棒的深度學習編程框架,其中一個是TensorFlow,我很期待幫助你開始學習使用TensorFlow,我想在這個視頻中向你展示TensorFlow程序的基本結構,然后讓你自己練習,學習更多細節,并運用到本周的編程練習中,這周的編程練習需要花些時間來做,所以請務必留出一些空余時間。
先提一個啟發性的問題,假設你有一個損失函數 JJJ 需要最小化,在本例中,我將使用這個高度簡化的損失函數, J(w)=w2?10w+25J(w)=w^2-10w+25J(w)=w2?10w+25 ,這就是損失函數,也許你已經注意到該函數其實就是 (w?5)2(w-5)^2(w?5)2 ,如果你把這個二次方式子展開就得到了上面的表達式,所以使它最小的 www 值是5,但假設我們不知道這點,你只有這個函數,我們來看一下怎樣用TensorFlow將其最小化,因為一個非常類似的程序結構可以用來訓練神經網絡。其中可以有一些復雜的損失函數 J(w,b)J(w,b)J(w,b) 取決于你的神經網絡的所有參數,然后類似的,你就能用TensorFlow自動找到使損失函數最小的 www 和 bbb 的值。但讓我們先從左邊這個更簡單的例子入手。
我在我的Jupyter notebook中運行Python,
xxxxxxxxxx import numpy as np import tensorflow as tf #導入TensorFlow ? w = tf.Variable(0,dtype = tf.float32) #接下來,讓我們定義參數w,在TensorFlow中,你要用tf.Variable()來定義參數 ? #然后我們定義損失函數: ? cost = tf.add(tf.add(w**2,tf.multiply(- 10.,w)),25) #然后我們定義損失函數J 然后我們再寫: ? train = tf.train.GradientDescentOptimizer(0.01).minimize(cost) #(讓我們用0.01的學習率,目標是最小化損失)。 ? #最后下面的幾行是慣用表達式: ? init = tf.global_variables_initializer() ? session = tf.Session()#這樣就開啟了一個TensorFlow session。 ? session.run(init)#來初始化全局變量。 ? #然后讓TensorFlow評估一個變量,我們要用到: ? session.run(w) ? #上面的這一行將w初始化為0,并定義損失函數,我們定義train為學習算法,它用梯度下降法優化器使損失函數最小化,但實際上我們還沒有運行學習算法,所以#上面的這一行將w初始化為0,并定義損失函數,我們定義train為學習算法,它用梯度下降法優化器使損失函數最小化,但實際上我們還沒有運行學習算法,所以session.run(w)評估了w,讓我:: ? print(session.run(w))所以如果我們運行這個,它評估 www 等于0,因為我們什么都還沒運行。
xxxxxxxxxx #現在讓我們輸入: ? $session.run(train),它所做的就是運行一步梯度下降法。 #接下來在運行了一步梯度下降法后,讓我們評估一下w的值,再print: ? print(session.run(w)) #在一步梯度下降法之后,w現在是0.1。現在我們運行梯度下降1000次迭代:
這是運行了梯度下降的1000次迭代,最后 www 變成了4.99999,記不記得我們說 (w?5)2(w-5)^2(w?5)2 最小化,因此 www 的最優值是5,這個結果已經很接近了。
希望這個讓你對TensorFlow程序的大致結構有了了解,當你做編程練習,使用更多TensorFlow代碼時,我這里用到的一些函數你會熟悉起來,這里有個地方要注意, www 是我們想要優化的參數,因此將它稱為變量,注意我們需要做的就是定義一個損失函數,使用這些add和multiply之類的函數。TensorFlow知道如何對add和mutiply,還有其它函數求導,這就是為什么你只需基本實現前向傳播,它能弄明白如何做反向傳播和梯度計算,因為它已經內置在add,multiply和平方函數中。
對了,要是覺得這種寫法不好看的話,TensorFlow其實還重載了一般的加減運算等等,因此你也可以把 costcostcost 寫成更好看的形式,把之前的cost標成注釋,重新運行,得到了同樣的結果。
一旦 www 被稱為TensorFlow變量,平方,乘法和加減運算都重載了,因此你不必使用上面這種不好看的句法。
TensorFlow還有一個特點,我想告訴你,那就是這個例子將 www 的一個固定函數最小化了。如果你想要最小化的函數是訓練集函數又如何呢?不管你有什么訓練數據 xxx ,當你訓練神經網絡時,訓練數據 xxx 會改變,那么如何把訓練數據加入TensorFlow程序呢?
我會定義 xxx ,把它想做扮演訓練數據的角色,事實上訓練數據有 xxx 和 yyy ,但這個例子中只有 xxx ,把 xxx 定義為:x = tf.placeholder(tf.float32,[3,1]),讓它成為 [3,1][3,1][3,1] 數組,我要做的就是,因為 costcostcost 這個二次方程的三項前有固定的系數,它是 w2?10w+25w^2-10w+25w2?10w+25 ,我們可以把這些數字1,-10和25變成數據,我要做的就是把 costcostcost 替換成:cost = x[0][0]*w**2 +x[1][0]*w + x[2][0],現在 xxx 變成了控制這個二次函數系數的數據,這個placeholder函數告訴TensorFlow,你稍后會為 xxx 提供數值。
讓我們再定義一個數組,coefficient = np.array([[1.],[-10.],[25.]]),這就是我們要接入 xxx 的數據。最后我們需要用某種方式把這個系數數組接入變量 xxx ,做到這一點的句法是,在訓練這一步中,要提供給 xxx 的數值,我在這里設置:
feed_dict = {x:coefficients}
好了,希望沒有語法錯誤,我們重新運行它,希望得到和之前一樣的結果。
現在如果你想改變這個二次函數的系數,假設你把:
coefficient = np.array([[1.],[-10.],[25.]])
改為:coefficient = np.array([[1.],[-20.],[100.]])
現在這個函數就變成了 (w?10)2(w-10)^2(w?10)2 ,如果我重新運行,希望我得到的使 (w?10)2(w-10)^2(w?10)2 最小化的 www 值為10,讓我們看一下,很好,在梯度下降1000次迭代之后,我們得到接近10的 www 。
在你做編程練習時,見到更多的是,TensorFlow中的placeholder是一個你之后會賦值的變量,這種方式便于把訓練數據加入損失方程,把數據加入損失方程用的是這個句法,當你運行訓練迭代,用feed_dict來讓x=coefficients。如果你在做mini-batch梯度下降,在每次迭代時,你需要插入不同的mini-batch,那么每次迭代,你就用feed_dict來喂入訓練集的不同子集,把不同的mini-batch喂入損失函數需要數據的地方。
希望這讓你了解了TensorFlow能做什么,讓它如此強大的是,你只需說明如何計算損失函數,它就能求導,而且用一兩行代碼就能運用梯度優化器,Adam優化器或者其他優化器。
這還是剛才的代碼,我稍微整理了一下,盡管這些函數或變量看上去有點神秘,但你在做編程練習時多練習幾次就會熟悉起來了。
還有最后一點我想提一下,這三行(藍色大括號部分)在TensorFlow里是符合表達習慣的,有些程序員會用這種形式來替代,作用基本上是一樣的。
但這個with結構也會在很多TensorFlow程序中用到,它的意思基本上和左邊的相同,但是Python中的with命令更方便清理,以防在執行這個內循環時出現錯誤或例外。所以你也會在編程練習中看到這種寫法。那么這個代碼到底做了什么呢?讓我們看這個等式:
cost =x[0][0]*w**2 +x[1][0]*w + x[2][0]#(w-5)**2
TensorFlow程序的核心是計算損失函數,然后TensorFlow自動計算出導數,以及如何最小化損失,因此這個等式或者這行代碼所做的就是讓TensorFlow建立計算圖,計算圖所做的就是取 x[0][0]x[0][0]x[0][0] ,取 www ,然后將它平方,然后 x[0][0]x[0][0]x[0][0] 和 w2w^2w2 相乘,你就得到了 x[0][0]?w2x[0][0]*w^2x[0][0]?w2 ,以此類推,最終整個建立起來計算 cost=x[0][0]?w??2+x[1][0]?w+x[2][0]cost=x[0][0]*w**2+x[1][0]*w+x[2][0]cost=x[0][0]?w??2+x[1][0]?w+x[2][0] ,最后你得到了損失函數。
TensorFlow的優點在于,通過用這個計算損失,計算圖基本實現前向傳播,TensorFlow已經內置了所有必要的反向函數,回憶一下訓練深度神經網絡時的一組前向函數和一組反向函數,而像TensorFlow之類的編程框架已經內置了必要的反向函數,這也是為什么通過內置函數來計算前向函數,它也能自動用反向函數來實現反向傳播,即便函數非常復雜,再幫你計算導數,這就是為什么你不需要明確實現反向傳播,這是編程框架能幫你變得高效的原因之一。
如果你看TensorFlow的使用說明,我只是指出TensorFlow的說明用了一套和我不太一樣的符號來畫計算圖,它用了 x[0][0]x[0][0]x[0][0] , www ,然后它不是寫出值,想這里的 w2w^2w2 ,TensorFlow使用說明傾向于只寫運算符,所以這里就是平方運算,而這兩者一起指向乘法運算,以此類推,然后在最后的節點,我猜應該是一個將 x[2][0]x[2][0]x[2][0] 加上去得到最終值的加法運算。
為本課程起見,我認為計算圖用第一種方式會更容易理解,但是如果你去看TensorFlow的使用說明,如果你看到說明里的計算圖,你會看到另一種表示方式,節點都用運算來標記而不是值,但這兩種呈現方式表達的是同樣的計算圖。
在編程框架中你可以用一行代碼做很多事情,例如,你不想用梯度下降法,而是想用Adam優化器,你只要改變這行代碼,就能很快換掉它,換成更好的優化算法。所有現代深度學習編程框架都支持這樣的功能,讓你很容易就能編寫復雜的神經網絡。
我希望我幫助你了解了TensorFlow程序典型的結構,概括一下這周的內容,你學習了如何系統化地組織超參數搜索過程,我們還講了Batch歸一化,以及如何用它來加速神經網絡的訓練,最后我們講了深度學習的編程框架,有很多很棒的編程框架,這最后一個視頻我們重點講了TensorFlow。有了它,我希望你享受這周的編程練習,幫助你更熟悉這些概念。
課程PPT
| 3.10 深度學習框架 | 回到目錄 | 3.12 總結 |
總結
以上是生活随笔為你收集整理的3.11 TensorFlow-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3.10 深度学习框架-深度学习第二课《
- 下一篇: 3.12 总结-深度学习第二课《改善深层