1. 前言 深度學(xué)習(xí)算法的成功使人工智能的研究和應(yīng)用取得了突破性進(jìn)展,并極大地改變了我們的生活,。越來(lái)越多的開發(fā)人員都在學(xué)習(xí)深度學(xué)習(xí)方面的開發(fā)技術(shù),。Google推出的TensorFlow是目前最為流行的開源深度學(xué)習(xí)框架,在圖形分類,、音頻處理,、推薦系統(tǒng)和自然語(yǔ)言處理等場(chǎng)景下都有豐富的應(yīng)用。盡管功能強(qiáng)大,,該框架學(xué)習(xí)門檻并不高,只要掌握Python安裝和使用,,并對(duì)機(jī)器學(xué)習(xí)和神經(jīng)網(wǎng)絡(luò)方面的知識(shí)有所了解就可以上手,。本文就帶你來(lái)一趟TensorFlow的啟蒙之旅。
2. 初識(shí)TensorFlow 2.1. TensorFlow安裝說(shuō)明 我們先來(lái)安裝TensorFlow,。TensorFlow對(duì)環(huán)境不算挑剔,,在Python 2.7和Python3下面均可運(yùn)行,操作系統(tǒng)Linux,、MAC,、Windows均可(注意新版本剛出來(lái)時(shí)可能只支持部分操作系統(tǒng)),,只要是64位。安裝TensorFlow主要不同之處是TensorFlow安裝包分支持GPU和不支持GPU兩種版本,,名稱分別為tensorflow-gpu和tensorflow,。實(shí)際生產(chǎn)環(huán)境最好安裝支持GPU的版本,以利于GPU強(qiáng)大的計(jì)算能力,,不過這需要先安裝相應(yīng)的CUDA ToolKit和CuDNN,。相比之下,安裝不支持GPU的TensorFlow包容易些,,順利的話執(zhí)行一句pip install tensorflow就OK,。如果讀者在安裝中遇到問題,可根據(jù)錯(cuò)誤提示在網(wǎng)上搜索解決辦法,。 安裝后,,可在命令行下啟動(dòng)Python或打開Jupyter Notebook,執(zhí)行下面的語(yǔ)句驗(yàn)證TensorFlow是否安裝成功,。
用tf引用TensorFlow包已成為一種約定,。在本文的所有示例代碼中,均假定已事先執(zhí)行該語(yǔ)句,。 2.2. TensorFlow計(jì)算模型 我們先來(lái)看在TensorFlow中如何計(jì)算c = a b,。這里a = 3,b = 2,。
從上面的代碼可以看出,,比起Python中的一句print (3 2),TensorFlow中實(shí)現(xiàn)同樣的功能需要更多的步驟,。首先得把參數(shù)打包,,再交給Session對(duì)象執(zhí)行才能輸出結(jié)果。 現(xiàn)在我們對(duì)代碼稍作修改,,讓程序輸出更多的調(diào)試信息,。
從上面可以看出,a,、b,、c都是張量(Tensor)而不是數(shù)字。張量的數(shù)學(xué)含義是多維數(shù)組,。我們把1維數(shù)組稱為向量,,2維數(shù)組稱為矩陣。而不管1維,、2維,、3維、4維,都可以稱作張量,,甚至標(biāo)量(數(shù)字)也可以看作是0維的張量,。在深度學(xué)習(xí)中,幾乎所有數(shù)據(jù)都可以看作張量,,如神經(jīng)網(wǎng)絡(luò)的權(quán)重,、偏置等。一張黑白圖片可以用2維張量表示,,其中的每個(gè)元素表示圖片上一個(gè)像素的灰度值,。一張彩色圖片則需要用3維張量表示,其中兩個(gè)維度為寬和高,,另一個(gè)維度為顏色通道,。TensorFlow的名字中就含有張量(Tensor)這個(gè)詞。另一個(gè)詞Flow的意思是“流”,,表示通過張量的流動(dòng)來(lái)表達(dá)計(jì)算,。TensorFlow是一個(gè)通過圖(Graph)的形式來(lái)表述計(jì)算的編程系統(tǒng),圖中每個(gè)節(jié)點(diǎn)為一種操作(Operation),,包括計(jì)算,、初始化、賦值等,。張量則為操作的輸入和輸出,。如上面的c = a b為張量的加法操作,等效于c = tf.add (a, b),,a和b是加法操作的輸入,,c是加法操作的輸出。 把張量提交給會(huì)話對(duì)象(Session)執(zhí)行,,就可以得到具體的數(shù)值,。即在TensorFlow中包含兩個(gè)階段,先以計(jì)算圖的方式定義計(jì)算過程,,再提交給會(huì)話對(duì)象,,執(zhí)行計(jì)算并返回計(jì)算結(jié)果。這是由于,,TensorFlow的核心不是用Python語(yǔ)言實(shí)現(xiàn)的,,每一步調(diào)用都需要函數(shù)庫(kù)與Python之間的切換,存在很大開銷,。而且TensorFlow通常在GPU上執(zhí)行,,如果每一步都自動(dòng)執(zhí)行的話,則GPU把大量資源浪費(fèi)在多次接收和返回?cái)?shù)據(jù)上,,遠(yuǎn)不如一次性接收返回?cái)?shù)據(jù)高效。我們可以把TensorFlow的計(jì)算過程設(shè)想為叫外賣。如果我們到館子里用餐,,可以邊吃邊上菜,。如果叫外賣的話,就得先一次性點(diǎn)好菜譜,,再讓對(duì)方把飯菜做好后打包送來(lái),,讓送餐的多次跑路不太合適。 與sess.run (c)的等效的語(yǔ)句是c.eval (session = sess),。作為對(duì)象和參數(shù),,張量和會(huì)話剛好調(diào)了個(gè)位置。如果上下文中只用到一個(gè)會(huì)話,,則可用tf.InteractiveSession()創(chuàng)建默認(rèn)的會(huì)話對(duì)象,,后面執(zhí)行計(jì)算時(shí)無(wú)需再指定。即:
另外,,在先前的代碼中,,參數(shù)3和2被固化在代碼中。如果要多次執(zhí)行加法運(yùn)算,,我們可以用tf.placeholder代替tf.constant,,而在執(zhí)行時(shí)再給參數(shù)賦值。如下面的代碼所示:
另一種存儲(chǔ)參數(shù)的方式是使用變量對(duì)象(tf.Variable),。與tf.constant函數(shù)創(chuàng)建的張量不同,,變量對(duì)象支持參數(shù)的更新,不過這也意味著依賴更多的資源,,與會(huì)話綁定得更緊,。變量對(duì)象必須在會(huì)話對(duì)象中明確地被初始化,通常調(diào)用tf.global_variables_initializer函數(shù)一次性初始化所有變量,。
在深度學(xué)習(xí)中,,變量對(duì)象通常用于表示待優(yōu)化的模型參數(shù)如權(quán)重、偏置等,,其數(shù)值在訓(xùn)練過程中自動(dòng)調(diào)整,。這在本文后面的例子中可以看到。
3. TensorFlow機(jī)器學(xué)習(xí)入門 3.1. 導(dǎo)入數(shù)據(jù) MNIST是一個(gè)非常有名的手寫體數(shù)字識(shí)別數(shù)據(jù)集,,常常被用作機(jī)器學(xué)習(xí)的入門樣例,。TensorFlow的封裝讓使用MNIST更加方便。現(xiàn)在我們就以MINIST數(shù)字識(shí)別問題為例探討如何使用TensorFlow進(jìn)行機(jī)器學(xué)習(xí),。 MNIST是一個(gè)圖片集,,包含70000張手寫數(shù)字圖片:
它也包含每一張圖片對(duì)應(yīng)的標(biāo)簽,告訴我們這個(gè)是數(shù)字幾,。比如,,上面這四張圖片的標(biāo)簽分別是5,,0,4,,1,。 在下面的代碼中,input_data.read_data_sets()函數(shù)下載數(shù)據(jù)并解壓,。
下載下來(lái)的數(shù)據(jù)集被分成3部分:55000張訓(xùn)練數(shù)據(jù)(minist.train),;5000張驗(yàn)證數(shù)據(jù)(mnist.validation);10000張測(cè)試數(shù)據(jù)(mnist.test),。切分的目的是確保模型設(shè)計(jì)時(shí)有一個(gè)單獨(dú)的測(cè)試數(shù)據(jù)集不用于訓(xùn)練而是用來(lái)評(píng)估這個(gè)模型的性能,,從而更加容易把設(shè)計(jì)的模型推廣到其他數(shù)據(jù)集上。 每一張圖片包含個(gè)像素點(diǎn),。我們可以用一個(gè)數(shù)字?jǐn)?shù)組來(lái)表示一張圖片: 數(shù)組展開為長(zhǎng)度是的向量,,則訓(xùn)練數(shù)據(jù)集mnist.train.images 是一個(gè)形狀為 [60000, 784] 的張量。在此張量里的每一個(gè)元素,,都表示某張圖片里的某個(gè)像素的灰度,,其值介于0和1之間。 MNIST數(shù)據(jù)集的標(biāo)簽是長(zhǎng)度為10的one-hot向量(因?yàn)榍懊婕虞d數(shù)據(jù)時(shí)指定了one_hot為True),。 一個(gè)one-hot向量除了某一位的數(shù)字是1以外其余各維度數(shù)字都是0,。比如,標(biāo)簽3將表示成([0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0]),。因此,, mnist.train.labels 是一個(gè) [55000, 10] 的數(shù)字矩陣。 3.2. 設(shè)計(jì)模型 現(xiàn)在我們通過訓(xùn)練一個(gè)叫做Softmax的機(jī)器學(xué)習(xí)模型來(lái)預(yù)測(cè)圖片里的數(shù)字,?;仡櫼幌拢诸惡突貧w(數(shù)值預(yù)測(cè))是最基本的機(jī)器學(xué)習(xí)問題,。線性回歸是針對(duì)回歸問題最基本的機(jī)器學(xué)習(xí)模型,,其基本思想是為各個(gè)影響因素分配合適的權(quán)重,預(yù)測(cè)的結(jié)果是各影響因素的加權(quán)和,。邏輯(Logistic)回歸則常用來(lái)處理分類問題,,它在線性回歸的基礎(chǔ)上,通過Logistic函數(shù)(也稱Sigmoid函數(shù))把低于和高于參照值的結(jié)果分別轉(zhuǎn)換為接近0和1的數(shù)值,。不過邏輯回歸只能處理二分問題,。Softmax回歸則是邏輯回歸在多分類問題上的推廣。整個(gè)模型如下圖所示:
或者用線性代數(shù)公式表示為: 其中,,x為輸入數(shù)據(jù)的特征向量,,向量的長(zhǎng)度為圖片的像素(),向量中的每個(gè)元素為圖片上各點(diǎn)的灰度值,,W為的權(quán)重矩陣,,其中784對(duì)應(yīng)于圖片的像素,,10對(duì)應(yīng)于0 - 9這10個(gè)數(shù)字,b為長(zhǎng)度為10的向量,,向量中的每個(gè)元素為0 - 9各個(gè)數(shù)字的偏置,,得到各個(gè)數(shù)字的權(quán)重,,最后softmax函數(shù)把權(quán)重轉(zhuǎn)換為概率分布,。通常我們最后只保留概率最高的那個(gè)數(shù)字,不過有時(shí)也關(guān)注概率較高的其他數(shù)字,。 下面是TensorFlow中實(shí)現(xiàn)該公式的代碼,,核心代碼為最后一句,其中tf.matmul函數(shù)表示Tensor中的矩陣乘法,。注意與公式中略有不同的是,,這里把x聲明為2維的張量,其中第1維為任意長(zhǎng)度,,這樣我們就可以批量輸入圖片進(jìn)行處理,。另外,為了簡(jiǎn)單起見,,我們用0填充W和b,。
除了模型外,我們還需要定義一個(gè)指標(biāo)來(lái)指示如何優(yōu)化模型中的參數(shù),。我們通常定義指標(biāo)來(lái)表示一個(gè)模型不盡人意的程度,,然后盡量最小化這個(gè)指標(biāo)。這個(gè)指標(biāo)稱為成本函數(shù),。成本函數(shù)與模型是密切相關(guān)的,。回歸問題一般用均方誤差作成本函數(shù),,而對(duì)于分類問題,,常用的成本函數(shù)是交叉熵(cross-entropy),定義為 其中y是我們預(yù)測(cè)的概率分布,,y’是實(shí)際的分布,。對(duì)交叉熵的理解涉及信息論方面的知識(shí),這里我們可以把它看作反映預(yù)測(cè)不匹配的指標(biāo),,或者說(shuō)該指標(biāo)反映實(shí)際情況出乎預(yù)料的程度,。注意交叉熵是非對(duì)稱的。在TensorFlow中,,交叉熵表示為下面的代碼:
因?yàn)榻徊骒匾话銜?huì)與Softmax回歸一起使用,,所以TensorFlow對(duì)這兩個(gè)功能進(jìn)行了統(tǒng)一封裝,并提供了tf.nn.softmax_cross_entropy_with_logits函數(shù),??梢灾苯油ㄟ^下面的代碼來(lái)實(shí)現(xiàn)使用了Softmax回歸之后的交叉熵函數(shù),。注意與公式中的y不同,代碼中的y是Softmax函數(shù)調(diào)用前的值,。最后調(diào)用tf.reduce_mean函數(shù)取平均值,,因?yàn)閳D片是批量傳入的,針對(duì)每張圖片會(huì)計(jì)算出一個(gè)交叉熵,。
3.3. 設(shè)計(jì)優(yōu)化算法 現(xiàn)在我們需要考慮如何調(diào)整參數(shù)使成本函數(shù)最小,,這在機(jī)器學(xué)習(xí)中稱為優(yōu)化算法的設(shè)計(jì)問題。筆者這里對(duì)TensorFlow實(shí)現(xiàn)優(yōu)化的過程作一個(gè)簡(jiǎn)要的介紹,,要知道優(yōu)化算法從某種意義上講比模型更重要,。 TensorFlow是一個(gè)基于神經(jīng)網(wǎng)絡(luò)的深度學(xué)習(xí)框架。對(duì)于Softmax這樣的模型,,被當(dāng)作是不含隱藏層的全連接神經(jīng)網(wǎng)絡(luò),。通過調(diào)整神經(jīng)網(wǎng)絡(luò)中的參數(shù)對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行擬合,可以使得模型對(duì)未知的樣本提供預(yù)測(cè)的能力,,表現(xiàn)為前向傳播和反向傳播(Backpropagation)的迭代過程,。在每次迭代的開始,首先需要選取全部或部分訓(xùn)練數(shù)據(jù),,通過前向傳播算法得到神經(jīng)網(wǎng)絡(luò)模型的預(yù)測(cè)結(jié)果,。 因?yàn)橛?xùn)練數(shù)據(jù)都是有正確答案標(biāo)注的,所以可以計(jì)算出當(dāng)前神經(jīng)網(wǎng)絡(luò)模型的預(yù)測(cè)答案與正確答案之間的差距,。最后,,基于預(yù)測(cè)值和真實(shí)值之間的差距,反向傳播算法會(huì)相應(yīng)更新神經(jīng)網(wǎng)絡(luò)參數(shù)的取值,,使得在這批數(shù)據(jù)上神經(jīng)網(wǎng)絡(luò)模型的預(yù)測(cè)結(jié)果和真實(shí)答案更加接近,。如下圖所示: TensorFlow支持多種不同的優(yōu)化器,讀者可以根據(jù)具體的應(yīng)用選擇不同的優(yōu)化算法,。比較常用的優(yōu)化方法有三種:
train_step = tf.train.GradientDescentOptimizer (0.01).minimize (cross_entropy) 在這里,,我們要求TensorFlow用梯度下降算法(Gradient Descent)以0.01的學(xué)習(xí)速率最小化交叉熵。梯度下降算法是一個(gè)簡(jiǎn)單的學(xué)習(xí)過程,,TensorFlow只需將每個(gè)變量一點(diǎn)點(diǎn)地往使成本不斷降低的方向移動(dòng),。語(yǔ)句返回的train_step表示執(zhí)行優(yōu)化的操作(Operation),可以提交給會(huì)話對(duì)象運(yùn)行,。 3.4. 訓(xùn)練模型 現(xiàn)在我們開始訓(xùn)練模型,,迭代1000次。注意會(huì)話對(duì)象執(zhí)行的不是W,、b也不是y,,而是train_step。
該循環(huán)的每個(gè)步驟中,,我們都會(huì)隨機(jī)抓取訓(xùn)練數(shù)據(jù)中的100個(gè)批處理數(shù)據(jù)點(diǎn),,然后我們用這些數(shù)據(jù)點(diǎn)作為參數(shù)替換之前的占位符來(lái)運(yùn)行train_step操作,。 使用一小部分的隨機(jī)數(shù)據(jù)來(lái)進(jìn)行訓(xùn)練被稱為隨機(jī)訓(xùn)練(stochastic training)- 在這里更確切的說(shuō)是隨機(jī)梯度下降訓(xùn)練。在理想情況下,,我們希望用我們所有的數(shù)據(jù)來(lái)進(jìn)行每一步的訓(xùn)練,,因?yàn)檫@能給我們更好的訓(xùn)練結(jié)果,但顯然這需要很大的計(jì)算開銷,。所以,,每一次訓(xùn)練我們可以使用不同的數(shù)據(jù)子集,這樣做既可以減少計(jì)算開銷,,又可以最大化地學(xué)習(xí)到數(shù)據(jù)集的總體特性,。 3.5. 評(píng)估模型 到驗(yàn)證我們的模型是否有效的時(shí)候了。我們可以基于訓(xùn)練好的W和b,,用測(cè)試圖片計(jì)算出y,并取預(yù)測(cè)的數(shù)字與測(cè)試圖片的實(shí)際標(biāo)簽進(jìn)行對(duì)比,。在Numpy中有個(gè)非常有用的函數(shù)argmax,,它能給出數(shù)組中最大元素所在的索引值。由于標(biāo)簽向量是由0, 1組成,,因此最大值1所在的索引位置就是類別標(biāo)簽,。對(duì)y而言,最大權(quán)重的索引位置就是預(yù)測(cè)的數(shù)字,,因?yàn)閟oftmax函數(shù)是單調(diào)遞增的,。下面代碼比較各個(gè)測(cè)試圖片的預(yù)測(cè)與實(shí)際是否匹配,并通過均值函數(shù)計(jì)算正確率,。
我們也可以讓TensorFlow來(lái)執(zhí)行比較,,這在很多時(shí)候更為方便和高效。TensorFlow中也有類似的argmax函數(shù),。
這個(gè)最終結(jié)果值應(yīng)該大約是91%,。完整的代碼請(qǐng)參考https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist_softmax.py,有少量修改,。
4. TensorFlow深度學(xué)習(xí)入門 4.1. 卷積神經(jīng)網(wǎng)絡(luò)介紹 前面我們使用了單層神經(jīng)網(wǎng)絡(luò),。如果增加神經(jīng)網(wǎng)絡(luò)的層數(shù),可以進(jìn)一步提高正確率,。不過,,增加層數(shù)會(huì)使需要訓(xùn)練的參數(shù)增多,這除了導(dǎo)致計(jì)算速度減慢,,還很容易引發(fā)過擬合問題,。所以需要一個(gè)更合理的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)來(lái)有效地減少神經(jīng)網(wǎng)絡(luò)中參數(shù)個(gè)數(shù)。對(duì)于圖像識(shí)別這類問題,,卷積神經(jīng)網(wǎng)絡(luò)(CNN)是目前最為有效的結(jié)構(gòu),。 卷積神經(jīng)網(wǎng)絡(luò)是一個(gè)層級(jí)遞增的結(jié)構(gòu),,其基本思想是從對(duì)像素、邊緣的認(rèn)識(shí)開始,,再到局部形狀,,最后才是整體感知。在傳統(tǒng)方法中,,我們需要在分類前對(duì)圖像進(jìn)行預(yù)處理,,如平滑、去噪,、光照歸一化等,,從中提取角點(diǎn)、梯度等特征,,而卷積神經(jīng)網(wǎng)絡(luò)把這一過程自動(dòng)化,。當(dāng)然,神經(jīng)網(wǎng)絡(luò)是一個(gè)黑盒子,,沒有前面所提到的這些概念,,它所提取的都是抽象意義上的特征,與人類理解的語(yǔ)意特征無(wú)法對(duì)應(yīng),。況且經(jīng)過多層變換,,圖片早已面目全非。另外卷積神經(jīng)網(wǎng)絡(luò)也可以用于圖像識(shí)別以外的領(lǐng)域,。不過為了淺顯易懂,,下文中仍然使用像素、顏色之類的日常用語(yǔ),。 卷積神經(jīng)網(wǎng)絡(luò)中特征識(shí)別的基本手段是卷積(Convolution),。我們可以理解為把圖片進(jìn)行特效處理,新圖片的每個(gè)位置的像素值是原圖片對(duì)應(yīng)位置及相鄰位置像素值的某種方式的疊加或取反,,類似于Photoshop中的濾鏡如模糊,、銳化、馬賽克什么的,,TensorFlow中稱為過濾器(Filter),。卷積的計(jì)算方式是相鄰區(qū)域內(nèi)像素的加權(quán)求和,用公式表示的話,,仍是,,不過計(jì)算限定在很小的矩形區(qū)域內(nèi)。 由于卷積只針對(duì)圖片的相鄰位置,,可保證訓(xùn)練后能夠?qū)τ诰植康妮斎胩卣饔凶顝?qiáng)的響應(yīng),。另外,不論在圖像的什么位置,都使用同一組權(quán)重,,相當(dāng)于把過濾器當(dāng)作手電筒在圖片上來(lái)回掃描,,這使圖像內(nèi)容在圖片中的位置不影響判斷結(jié)果。卷積網(wǎng)絡(luò)的這些特點(diǎn)使它顯著減少參數(shù)數(shù)量的同時(shí),,又能夠更好的利用圖像的結(jié)構(gòu)信息,,提取出圖像從低級(jí)到復(fù)雜的特征,甚至可以超過人類的表現(xiàn),。 神經(jīng)網(wǎng)絡(luò)需要使用激活函數(shù)去除線性化,,否則即便增加網(wǎng)絡(luò)的深度也依舊還是線性映射,起不到多層的效果,。與Softmax模型所使用的Sigmoid函數(shù)不同,,卷積神經(jīng)網(wǎng)絡(luò)鐘愛激活函數(shù)的是ReLU,它有利于反向傳播階段的計(jì)算,,也能緩解過擬合,。ReLU函數(shù)很簡(jiǎn)單,就是忽略小于0的輸出,,可以理解為像折紙那樣對(duì)數(shù)據(jù)進(jìn)行區(qū)分,。注意在使用ReLU函數(shù)時(shí),比較好的做法是用一個(gè)較小的正數(shù)來(lái)初始化偏置項(xiàng),,以避免神經(jīng)元節(jié)點(diǎn)輸出恒為0的問題。下圖是Sigmoid和ReLU函數(shù)的對(duì)比,。 除了卷積外,,卷積神經(jīng)網(wǎng)絡(luò)通常還會(huì)用到降采樣(downsampling或subsampling)。我們可以理解為把圖片適當(dāng)縮小,,由此在一定程度上控制過擬合并減少圖像旋轉(zhuǎn),、扭曲對(duì)特征提取的影響,因?yàn)榻挡蓸舆^程中模糊了方向信息,。卷積神經(jīng)網(wǎng)絡(luò)正是通過卷積和降采樣,,成功將數(shù)據(jù)量龐大的圖像識(shí)別問題不斷降維,最終使其能夠被訓(xùn)練,。降采樣在卷積神經(jīng)網(wǎng)絡(luò)中通常被稱為池化(Pooling),,包括最大池化、平均池化等,。其中最常見的是最大池化,,它將輸入數(shù)據(jù)分成不重疊的矩形框區(qū)域,對(duì)于每個(gè)矩形框的數(shù)值取最大值作為輸出,。如下圖所示,。 4.2. 構(gòu)建LeNet-5網(wǎng)絡(luò) 對(duì)卷積神經(jīng)網(wǎng)絡(luò)有了基本了解后,,我們現(xiàn)在開始使用這種網(wǎng)絡(luò)來(lái)處理MNIST數(shù)字識(shí)別問題。這里參照最經(jīng)典的LeNet-5模型,,介紹如何使用TensorFlow進(jìn)行深度學(xué)習(xí),。LeNet-5的結(jié)構(gòu)如下圖所示??梢钥闯?,LeNet-5中包含兩次的卷積和降采樣,再經(jīng)過兩次全連接并使用Softmax分類作為輸出,。 模型第一層是卷積層,。輸入是原始圖片,尺寸為,,顏色用灰度表示,,因此數(shù)據(jù)類型為,考慮到批量輸入,,數(shù)據(jù)應(yīng)有4個(gè)維度,。過濾器尺寸為,計(jì)算32個(gè)特征,,因此權(quán)重W為的張量,,偏置b為長(zhǎng)度32的向量。另外,,為確保輸出的圖片仍為大小,,在對(duì)圖片邊緣的像素進(jìn)行卷積時(shí),我們用0補(bǔ)齊周邊,。 TensorFlow中,,tf.nn.conv2d函數(shù)實(shí)現(xiàn)卷積層前向傳播的算法。這個(gè)函數(shù)的前兩個(gè)參數(shù)分別表示輸入數(shù)據(jù)x和權(quán)重W,,均為4個(gè)維度的張量,,如前所述。權(quán)重在初始化時(shí)應(yīng)該加入少量的噪聲來(lái)打破對(duì)稱性以及避免0梯度,,這里我們用tf.truncated_normal函數(shù)生成的隨機(jī)量填充,。函數(shù)的隨后兩個(gè)參數(shù)定義卷積的方式,包括過濾器在圖像上滑動(dòng)時(shí)移動(dòng)的步長(zhǎng)及填充方式,。步長(zhǎng)用長(zhǎng)度為4的數(shù)組表示,,對(duì)應(yīng)輸入數(shù)據(jù)的4個(gè)維度,實(shí)際上只需要調(diào)整中間兩個(gè)數(shù)字,,這里我們?cè)O(shè)置為[1, 1, 1, 1],,表示一個(gè)像素一個(gè)像素地移動(dòng)。填充方式有“SAME”或“VALID”兩種選擇,,其中“SAME”表示添加全0填充,,“VALID”表示不添加。 下面的代碼實(shí)現(xiàn)模型第一層:
模型第二層為降采樣層,。采樣窗口尺寸為,,不重疊,因此步長(zhǎng)也是,,采用最大池化,,采樣后圖像的尺寸縮小為原來(lái)的一半。實(shí)現(xiàn)圖片最大池化的函數(shù)是tf.nn.max_pool,。它的參數(shù)與tf.nn.conv2d類似,,只不過第二個(gè)參數(shù)設(shè)置的不是權(quán)重而是采樣窗口的大小,用長(zhǎng)度為4的數(shù)組表示,,對(duì)應(yīng)輸入數(shù)據(jù)的4個(gè)維度,。
模型第三層為卷積層。輸入數(shù)據(jù)尺寸為,,有32個(gè)特征,,過濾器尺寸仍為,需計(jì)算64個(gè)特征,,因此權(quán)重W的類型為,,偏置b為長(zhǎng)度64的向量。
模型第四層為降采樣層,,與第二層類似,。圖像尺寸再次縮小一半。
模型第五層為全連接層,。輸入數(shù)據(jù)尺寸為,,有64個(gè)特征,輸出1024個(gè)神經(jīng)元,。由于是全連接,輸入數(shù)據(jù)x和權(quán)重W都應(yīng)為2維的張量,。全連接參數(shù)較多,,這里引入Dropout避免過擬合。Dropout在每次訓(xùn)練時(shí)隨機(jī)禁用部分權(quán)重,,相當(dāng)于多個(gè)訓(xùn)練實(shí)例上取平均結(jié)果,,同時(shí)也減少了各個(gè)權(quán)重之間的耦合。TensorFlow中實(shí)現(xiàn)Dropout的函數(shù)為tf.nn.dropout,。該函數(shù)第二個(gè)參數(shù)表示每個(gè)權(quán)重不被禁用的概率,。
4.3. 訓(xùn)練和評(píng)估模型 為了進(jìn)行訓(xùn)練和評(píng)估,,我們使用與之前簡(jiǎn)單的單層Softmax模型幾乎相同的一套代碼,只是我們會(huì)用更加復(fù)雜的ADAM優(yōu)化器來(lái)縮短收斂時(shí)間,另外在feed_dict中加入額外的參數(shù)keep_prob來(lái)控制Dropout比例,。然后每100次迭代輸出一次日志,。
以上代碼,在最終測(cè)試集上的準(zhǔn)確率大概是99.2%,。完整的代碼請(qǐng)參考https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist_deep.py,,局部有修改。
5. 總結(jié) 在本文中,,我們介紹了TensorFlow的基本用法,,并以MNIST數(shù)據(jù)為例,基于Softmax模型和卷積神經(jīng)網(wǎng)絡(luò)分別講解如何使用TensorFlow進(jìn)行機(jī)器學(xué)習(xí)和深度學(xué)習(xí),。 TensorFlow對(duì)深度學(xué)習(xí)提供了強(qiáng)大的支持,,包含豐富的訓(xùn)練模型,還提供了TensorBoard,、TensorFlow游樂場(chǎng),、TensorFlow Debugger等可視化和調(diào)試等手段方便。限于篇幅,,這里不一一介紹,,詳見TensorFlow的官方文檔。深度學(xué)習(xí)是一個(gè)較新的技術(shù),,理論和實(shí)踐中都有不少坑,。不過只要多學(xué)多上手,相信能讓TensorFlow成為您手中的利器,。
參考資料: 《TensorFlow:實(shí)戰(zhàn)Google深度學(xué)習(xí)框架》 才云科技,、鄭澤宇、顧思宇著 《面向機(jī)器智能的TensorFlow實(shí)踐》 Sam Abrahams等著,,段菲,、陳澎譯 《你好,TensorFlow》 http://mp.weixin.qq.com/s/0qJmicqIxwS7ChTvIcuJ-g 《TensorFlow白皮書》(譯文) http://www.jianshu.com/p/65dc64e4c81f 《卷積神經(jīng)網(wǎng)絡(luò)》 http://blog.csdn.net/celerychen2009/article/details/8973218 《卷積神經(jīng)網(wǎng)絡(luò)入門學(xué)習(xí)》 http://blog.csdn.net/hjimce/article/details/51761865 校對(duì):丁楠雅 編輯:黃繼彥 |
|
來(lái)自: 昵稱42427018 > 《算法與培訓(xùn)》