久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

手把手教TensorFlow(附代碼)

 昵稱42427018 2017-10-18


轉(zhuǎn)自數(shù)據(jù)派THU(ID:DatapiTHU)


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是否安裝成功,。


>>>import tensorflow as tf


用tf引用TensorFlow包已成為一種約定,。在本文的所有示例代碼中,均假定已事先執(zhí)行該語(yǔ)句,。


2.2. TensorFlow計(jì)算模型


我們先來(lái)看在TensorFlow中如何計(jì)算c = a b,。這里a = 3,b = 2,。


>>>a = tf.constant (3)

>>>b = tf.constant (2)

>>>c = a b

>>>sess = tf.Session ()

>>>print (sess.run(c))

5


從上面的代碼可以看出,,比起Python中的一句print (3 2),TensorFlow中實(shí)現(xiàn)同樣的功能需要更多的步驟,。首先得把參數(shù)打包,,再交給Session對(duì)象執(zhí)行才能輸出結(jié)果。

現(xiàn)在我們對(duì)代碼稍作修改,,讓程序輸出更多的調(diào)試信息,。


>>>a = tf.constant (3)

>>>b = tf.constant (2)

>>>print (a, b)

Tensor('Const:0', shape=(), dtype=int32) Tensor('Const_1:0', shape=(), dtype=int32)

>>>c = a b

>>>print(c)

Tensor('add:0', shape=(), dtype=int32)

>>>sess = tf.Session ()

>>>sess.run ((a,b))

(3,2)

>>>print(sess.run(c))

5


從上面可以看出,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ú)需再指定。即:


>>>a = tf.constant (3)

>>>b = tf.constant (2)

>>>c = a b

>>>sess = tf.InteractiveSession ()

>>>print (c.eval())

5


另外,,在先前的代碼中,,參數(shù)3和2被固化在代碼中。如果要多次執(zhí)行加法運(yùn)算,,我們可以用tf.placeholder代替tf.constant,,而在執(zhí)行時(shí)再給參數(shù)賦值。如下面的代碼所示:


>>>a = tf.placeholder(tf.int32)

>>>b = tf.placeholder(tf.int32)

>>>c = a b

>>> sess = tf.InteractiveSession()

#下面的語(yǔ)句也可寫成print (sess.run (c, {a:3, b:2}))

>>>print (c.eval ({a:3, b:2}))

5

>>>print (c.eval ({a:[1,2,3], b:[4,5,6]}))

[5 7 9]


另一種存儲(chǔ)參數(shù)的方式是使用變量對(duì)象(tf.Variable),。與tf.constant函數(shù)創(chuàng)建的張量不同,,變量對(duì)象支持參數(shù)的更新,不過這也意味著依賴更多的資源,,與會(huì)話綁定得更緊,。變量對(duì)象必須在會(huì)話對(duì)象中明確地被初始化,通常調(diào)用tf.global_variables_initializer函數(shù)一次性初始化所有變量,。


>>>a = tf.Variable (3)

>>>b = tf.Variable (2)

>>>c = a b

>>>init = tf.global_variables_initializer()

>>>sess = tf.InteractiveSession()

>>>init.run()

>>>print(c.eval())

5

>>>a.load (7)

>>>b.load (8)

>>>print (c.eval())

15


在深度學(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ù)并解壓,。


from tensorflow.examples.tutorials.mnist import input_data

# MNIST_data為隨意指定的存儲(chǔ)數(shù)據(jù)的臨時(shí)目錄

mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)


下載下來(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,。


x = tf.placeholder (tf.float32, [None, 784])

W = tf.Variable (tf.zeros([784, 10]))

b = tf.Variable (tf.zeros([10]))

y = tf.nn.softmax (tf.matmul (x, 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中,,交叉熵表示為下面的代碼:


cross_entropy = -tf.reduce_sum (y_ * tf.log (y))


因?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è)交叉熵,。


y = tf.matmul (x, W) b

cross_entropy = tf.reduce_mean (

        tf.nn.softmax_cross_entropy_with_logits (labels = y_, logits = y))


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)化方法有三種:


  • tf.train.GradientDescentOptimizer

  • tf.train.AdamOptimizer

  • tf.train.MomentumOptimizer


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。


for i in range(1000):

  batch_xs, batch_ys = mnist.train.next_batch(100)

  sess.run (train_step, feed_dict = {x: batch_xs, y_: batch_ys})


該循環(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ì)算正確率,。


import numpy as np

output = sess.run (y, feed_dict = {x: mnist.test.images})

print (np.mean (np.argmax(output,1) == np.argmax(mnist.test.labels,1)))


我們也可以讓TensorFlow來(lái)執(zhí)行比較,,這在很多時(shí)候更為方便和高效。TensorFlow中也有類似的argmax函數(shù),。


correct_prediction = tf.equal (tf.argmax(y,1), tf.argmax(y_,1))

accuracy = tf.reduce_mean (tf.cast(correct_prediction, 'float'))

print (sess.run (accuracy, feed_dict = {x: mnist.test.images, y_: mnist.test.labels}))


這個(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)模型第一層:


x = tf.placeholder (tf.float32, [None, 784])

# 這里使用tf.reshape函數(shù)校正張量的維度,-1表示自適應(yīng)

x_image = tf.reshape (x, [-1, 28, 28, 1])

W_conv1 = tf.Variable (tf.truncated_normal ([5, 5, 1, 32], stddev = 0.1))

b_conv1 = tf.Variable (tf.constant (0.1, shape = [32]))

#執(zhí)行卷積后使用ReLU函數(shù)去線性化

h_conv1 = tf.nn.relu (tf.nn.conv2d(

    x_image, W_conv1, strides = [1, 1, 1, 1], padding = 'SAME') b_conv1)


模型第二層為降采樣層,。采樣窗口尺寸為,,不重疊,因此步長(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è)維度,。


h_pool1 = tf.nn.max_pool (h_conv1, ksize = [1, 2, 2, 1],

                         strides = [1, 2, 2, 1], padding = 'SAME')


模型第三層為卷積層。輸入數(shù)據(jù)尺寸為,,有32個(gè)特征,,過濾器尺寸仍為,需計(jì)算64個(gè)特征,,因此權(quán)重W的類型為,,偏置b為長(zhǎng)度64的向量。


W_conv2 = tf.Variable (tf.truncated_normal ([5, 5, 32, 64], stddev = 0.1))

b_conv2 = tf.Variable (tf.constant(0.1, shape = [64]))

#執(zhí)行卷積后使用ReLU函數(shù)去線性化

h_conv2 = tf.nn.relu (tf.nn.conv2d(

    h_pool1, W_conv2, strides = [1, 1, 1, 1], padding = 'SAME') b_conv2)


模型第四層為降采樣層,,與第二層類似,。圖像尺寸再次縮小一半。


h_pool2 = tf.nn.max_pool (h_conv2, ksize = [1, 2, 2, 1],

                         strides = [1, 2, 2, 1], padding = 'SAME')


模型第五層為全連接層,。輸入數(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)重不被禁用的概率,。


W_fc1 = tf.Variable (tf.truncated_normal ([7 * 7 * 64, 1024], stddev = 0.1))

b_fc1 = tf.Variable (tf.constant (0.1, shape = [1024]))

 

#把4維張量轉(zhuǎn)換為2維

h_pool2_flat = tf.reshape (h_pool2, [-1, 7*7*64])

h_fc1 = tf.nn.relu (tf.matmul (h_pool2_flat, W_fc1) b_fc1)

 

keep_prob = tf.placeholder (tf.float32)

h_fc1_drop = tf.nn.dropout (h_fc1, keep_prob)

模型最后一層為全連接加上Softmax輸出,類似之前介紹的單層模型,。

W_fc2 = tf.Variable (tf.truncated_normal ([1024, 10], stddev = 0.1))

b_fc2 = tf.Variable (tf.constant(0.1, shape = [10]))

 

y_conv = tf.matmul (h_fc1_drop, W_fc2) b_fc2

 

cross_entropy = tf.reduce_mean(

    tf.nn.softmax_cross_entropy_with_logits (labels = y_, logits = y_conv))


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次迭代輸出一次日志,。


train_step = tf.train.AdamOptimizer (1e-4).minimize (cross_entropy)

 

correct_prediction = tf.equal (tf.argmax (y_conv, 1), tf.argmax (y_, 1))

accuracy = tf.reduce_mean (tf.cast (correct_prediction, tf.float32))

 

sess = tf.InteractiveSession()

sess.run (tf.global_variables_initializer())

for i in range(20000):

  batch_xs, batch_ys = mnist.train.next_batch(50)

  if i % 100 == 0:

    train_accuracy = accuracy.eval (feed_dict = {

        x: batch_xs, y_: batch_ys, keep_prob: 1.0})

    print('step %d, training accuracy %g' % (i, train_accuracy))

  train_step.run (feed_dict = {x: batch_xs, y_: batch_ys, keep_prob: 0.5})

 

print ('test accuracy %g' % accuracy.eval (feed_dict = {

    x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))


以上代碼,在最終測(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ì):丁楠雅

編輯:黃繼彥


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多