贈書|人工智慧識萬物:卷積神經網絡的前世今生

2020-12-23 AI科技大本營

來源 |《Python人工智慧開發從入門到精通》

作者 | 楊柳、郭坦、魯銀芝

責編 | 晉兆雨

深度學習在技術與應用上的突破引發了第三次人工智慧浪潮,獲得了空前成功。在前述章節的基礎上,本章將主要介紹訓練卷積神經網絡和深度神經網絡的重要方法與技巧,深度神經網絡的遷移學習策略,以及如何訓練深度神經網絡以解決實際問題等內容。作為人工智慧的核心研究內容,以卷積神經網絡(ConvolutionalNeural Networks, CNNs)為代表的深度學習技術已在計算機視覺應用,如智能監控、智慧醫療及機器人自動駕駛等領域取得突破性進展,而這些應用的成功落地很大程度上依賴於視覺識別模塊。

結合前文內容,本章將詳細介紹如何構建並利用CNNs 這一功能強大的深度學習模型解決實際的圖像識別問題。

*文末有贈書福利

受20世紀中期興起的神經科學及腦科學研究的啟發,通過模擬生物神經元接收和處理信息的基本特性,研究人員提出並設計了人工神經元。作為計算機科學、生物學和數學的交叉融合,卷積神經網絡已經發展成為計算機視覺領域中最具影響力和有效的基礎技術。

早在20 世紀60 年代,生物學家Hubel 和Wiesel 通過研究貓的視覺皮層,發現每個視覺神經元都只對一個小區域範圍內的視覺圖像產生響應,即感受野(Receptive Field)。初級視覺皮層中的神經元能夠響應視覺環境中特定的簡單特徵,除此之外,Hubel 和Wiesel 通過研究發現了簡單和複雜兩種不同類型的細胞,其中簡單細胞只在特定的空間位置對它們偏好的方向產生最強烈響應,而複雜細胞具有更大的空間不變性。

根據這些實驗和分析,他們得出結論:複雜細胞通過在來自多個簡單細胞(每個都有一個不同的偏好位置)的輸入進行池化而實現這種不變性,這兩個特性,即對特定特徵的選擇性和通過前饋連接增大空間不變性,構成了CNN人工視覺系統的生物及神經學基礎。

發展至80年代,日本科學家Kunihiko Fukushima 通過研究並融合有關生物視覺的相關領域知識,提出了Neocognitron 神經認知機的概念,該神經認知機由S 細胞和C 細胞構成,可通過無監督的方式學習識別簡單的圖像。20 世紀90 年代,Yann LeCun 等人發表論文,確立了CNN 影響至今的經典網絡結構,後來經過對網絡結構的不斷完善與改進,得到一種多層的人工神經網絡,命名為LeNet-5,在手寫數字識別任務上取得良好效果。和其他神經網絡一樣,LeNet-5能夠使用反向傳播算法(Back Propagation)訓練。

LeNet-5 網絡雖然較小,但它含有諸多神經網絡學習的關鍵模塊,具體包括卷積層、池化層及全連接層,這些基本模塊構成當前深度神經網絡模型的基礎,下文將對LeNet-5 的結構及工作原理進行深入分析。同時,藉助實例加深讀者對卷積神經網絡各個模塊功能的理解。

卷積神經網絡與LeNet-5

LeNet-5 出自Yann LeCun 教授於1998 發表的論文Gradient-Based Learning Applied to DocumentRecognition 中,LeNet-5 模型共有7 層,如圖11-1 所示為LeNet-5 的基本網絡架構。

LeNet-5 的基本網絡架構

該模型除了輸入層之外,每層都包含可訓練參數,每個網絡層產生多個特徵圖,每個特徵圖可通過一種卷積濾波器提取輸入數據一種類型的特徵。各個網絡層的功能與參數情況介紹如下。

1. 輸入層

首先是輸入數據網絡層,上例中輸入圖像尺寸統一歸一化為32×32×1,其中1 表示輸入圖像為單通道的灰度圖,一般不將該層作為LeNet-5 網絡的基本構成,即不將輸入層視為網絡層次結構之一。

2. C1 層

C 取自Convolutional 的首字母,指卷積。讀者可能對卷積的概念並不陌生,對數字圖像做卷積運算,本質上是通過卷積核(卷積模板)在圖像上滑動,將圖像上的像素灰度值與對應卷積核上的數值相乘,然後將所有相乘後的值相加作為卷積核中間像素對應像素的灰度值,以此方式遍歷完成對整張圖像像素的卷積計算。如圖11-2顯示了圖像卷積計算過程中一次相乘後相加的運算過程,該卷積核大小為3×3,卷積核內共有9 個數值,數值個數即為圖像像素值與卷積核上數值相乘次數,運算結果-4 代替了原圖像中對應位置處的值。按此方式,沿著圖片以步長為1 滑動,每次滑動1個像素都進行一次相乘再相加的操作,即可得到最終的輸出結果。

卷積計算過程

圖像卷積計算中,卷積核的設計十分重要,一般需遵循如下基本規則。

卷積核大小一般是奇數,奇數大小的卷積核使得卷積核關於中間像素點中心對稱,因此卷積核尺寸一般是3×3、5×5或7×7。卷積核有中心,相應地就有半徑的概念,如7×7 大小的卷積核,其半徑為3。卷積核所有的元素之和一般應等於1,這是為了保持圖像卷積計算過程中像素能量(亮度)的守恆。若濾波器矩陣所有元素之和大於1,那麼濾波後的圖像就會比原圖像更亮;反之,若小於1,那麼得到的圖像將會變暗。濾波後可能會出現負數或大於255 的數值。對這種情況,通常將它們直接截斷到0~255之間即可。而對於負數,也可以取絕對值。經卷積計算所得輸出通常被稱為「響應」,如果是邊緣檢測算子,那麼響應為圖像邊緣,能夠檢測到特定的圖像邊緣。在LeNet-5網絡中得到的響應是特徵圖(Feature Map),計算結果為輸入圖像的特徵表達,卷積核的參數權重可以通過優化算法在監督信息的指導下自適應地學習得到。LeNet-5 網絡中C1 層輸入圖像尺寸為32×32×1,卷積核大小為5×5,一共包括6 種大小為5×5 的卷積核,卷積核滑動一行之後,得到的結果的邊長變為32-5+1,提取的特徵映射大小是28×28,即(32-5+1)=28。6種不同的卷積核,可以從不同的角度提取圖像不同特性的特徵。

神經元數量為28×28×6,則可訓練參數為(5×5+1)×6,即每個濾波器含5×5=25個單元權值參數和1個偏置參數,一共6 個濾波器,因此總的連接數為(5×5+1)×6×28×28=122 304。針對122 304 個連接,通過權值共享策略,只需學習156 個參數。

3. S2 層

S 指的是Subsamples,該網絡層完成下採樣操作,得到對應的特徵圖。下採樣的原則是在減少數據量的同時儘可能保留有用的信息。與普通插值下採樣的方式不同,該層實際採用的是一種被稱為池化(Pooling)的方法。具體是將一幅圖像分割成若干塊,每個圖像塊的輸出是該圖像塊原有像素的統計結果。

圖像下採樣池化方法有很多,如Mean-pooling( 均值採樣)、Max-pooling( 最大值採樣)、Overlapping ( 重疊採樣)、L2-pooling( 均方採樣)、Local Contrast Normalization( 局部對比歸一化)、Stochastic-pooling( 隨機採樣) 和Def-pooling( 形變約束採樣) 等,其中最經典的是最大池化,也是最常用的,下面簡要介紹最大池化的實現原理。

為直觀起見,假設有如圖11-3(a)中大小為4×4 的圖像,圖像中每個像素點的值是上面各個格子中的數值。現在對這張4×4 大小的圖像進行池化操作,池化的大小為(2,2),步長為2。採用最大池化操作,首先對圖像進行分塊,每個圖像塊大小為2×2,然後按照圖11-3(b)中方式統計每個圖像塊的最大值,作為下採樣後圖像的像素值,得到圖11-3(c)中結果,該過程即為最大池化。

除此之外,還有其他池化方法,如均值池化,具體是對每個塊求取平均值作為下採樣的新像素值。上述例子未涉及重疊採樣,即每個圖像塊之間沒有相互重疊的部分,而步長為2 時,圖像分塊不重疊。

最大池化操作示意圖

LeNet-5 網絡中的S2 層的輸入是上一層的輸出,共有6 個特徵映射,每個特徵映射的尺寸為28×28,使用2×2 大小的核進行池化操作,得到S2,即6 個14×14 大小的特徵映射(28/2=14)。換言之,S2 中的池化層是對C1 中的2×2 區域內的像素求和乘以一個權值係數再加上一個偏置,然後將這個結果再做一次映射。與卷積層連接數的計算方法一樣,連接數=參數個數×特徵映射大小,即(2×2+1)×6×14×14=5880。

4. C3 層

C3 層同樣是卷積層,輸入為S2 中所有6 個或若干個特徵圖的組合。具體地,該層卷積核大小為5×5,一共有6種卷積核,輸出特徵圖大小為10×10,即(14-5+1)=10。需要注意的是,C3 中每個特徵圖是連接到S2 中的所有6 個或若干個特徵圖的,即該層的特徵圖是上一層提取到的特徵圖的不同組合。如圖11-4 所示,LeCun 在原論文中給出的一種組合連接方式。

LeNet-5 網絡C3 層特徵映射組合方式

圖11-4 中共有6 行16 列,橫軸代表C3 特徵映射索引,縱軸代表S2 特徵圖索引。每列的X表示C3 中的每個特徵映射與S2 中的特徵圖的連接情況,可以看到C3 的前6 個特徵圖,對應上圖第1 個紅框的6 列,以S2 中3 個相鄰的特徵圖子集為輸入,緊接著6 個特徵圖(對應上圖第2 個紅框的6 列)以S2 中4 個相鄰特徵圖子集為輸入。

然後,接下來的3 個特徵圖(對應上圖第3 個紅框的3 列)以S2 中不相鄰的4 個特徵圖子集為輸入,C3 中的最後一個特徵圖對應上圖第4 個紅框的1 列將S2 中所有特徵圖為輸入。這裡得到的每一個特徵圖為多核多通道卷積,將每一列稱為一個卷積核,它由若干個卷積模板構成,因為是多個卷積核模板卷積的結果得到一個特徵圖,仍然認為是一個卷積核,所以每列只有一個偏置參數。之所以採取這種組合方式,LeCun 主要是基於以下兩點考慮:減少參數;採用不對稱的組合連接方式有利於提取多種組合特徵。

5. S4 層

S4 層為下採樣層,即池化層,窗口大小為2×2,包括16 個特徵圖,C3 層的16 個10×10 的特徵圖分別進行以2×2 為單位的池化得到16 個5×5 的特徵圖,步長為2,即本網絡層的輸出張量大小為5×5×16,一共有5×5×5×16=2000 個連接,連接的方式與S2 層類似。

6. C5 層

C5 層是一個卷積層,輸入為S4 層的全部16 個特徵圖,該層卷積原理與普通卷積層一致,只是因為恰巧卷積核大小與輸入特徵圖尺寸一樣,因此得到一維,即1×1(5-5+1)的輸出,卷積核種類為120,得到120 維的卷積結果,每個都與上一層的16 個特徵圖相連,因此一共有(5×5×16+1)×120=48 120 個可訓練參數。

7. F6 層

F6 層是全連接層,採用全連接的方式與C5 層連接,由對C5 層的輸入乘以權重加上偏置,結果通過激活Sigmoid 函數輸出。F6 層有84 個節點,對應於一個7×12 的比特圖,-1 表示白色,1 表示黑色,這樣每個符號的比特圖的黑白色對應一個編碼,F6 層的訓練參數/ 連接數為(120+1)×84=10 164。

8. Output 輸出層

Output 輸出層同樣是全連接層,共有10 個節點,分別代表數字0~9,且如果節點i 的值為0,則網絡識別的結果是數字i。採用的是徑向基函數(RBF)的網絡連接方式。假設x 是上一層的輸入,y 是RBF 的輸出,則RBF 輸出的計算方式如式(11-1)所示。

式中wij 的值由i 的比特圖編碼確定,i 取值為0~9,j 取值為0~(7*12-1)。RBF 輸出的值越接近於0,表示當前網絡的輸入越接近於i,即越接近於i 的ASCII 編碼,該層一共包含84×10=840 個可學習參數。卷積神經網絡在本質上是在不需要獲取輸入和輸出之間精確的數學表達的情況下,學習從輸入數據到目標輸出的複雜映射,卷積神經網絡的優勢在於能夠很好地利用圖像的二維結構信息,LeNet-5 在銀行支票手寫體字符識別問題上得到成功應用。

不考慮輸入層,LeNet-5 是一個7 層的網絡,卷積層的參數較少,這得益於卷積層的若干重要特性,即局部連接和共享權重。現在常用的LeNet-5 結構和Yann LeCun 教授在1998 年論文中提出的結構在某些細節上存在一定的區別,如激活函數的使用,現在一般使用ReLU 作為激活函數,而輸出層一般選用Softmax。CNN 能夠提取原始圖像的有效表徵,這賦予CNN 經過較少的預處理,即可從原始像素中學習和識別視覺規律的能力。然而,由於LeNet-5 提出伊始,缺乏大規模的訓練數據,計算機的計算能力也難以滿足要求,CNN 的網絡架構在不同文獻中的描述略有差異。

不過,CNN 的基本組成單元和模塊相對一致,可以像搭積木一樣將不同功能的網絡層組合起來,從而實現規模更大、深度更深的網絡。因此,從某種意義上說,CNN 或深度學習中的網絡層本質上是能夠進行信息處理的積木單元。LeNet-5 對於更複雜問題的處理效果並不理想,但通過對LeNet-5 的網絡結構的分析與研究,可以直觀地了解卷積神經網絡的構建方法,能夠為分析和構建更複雜、更深層的卷積神經網絡打下堅實的基礎。

總結卷積神經網絡的成功經驗,主要在於局部連接(LocalConnection)、權值共享(Weight Sharing)和池化層(Pooling)中的降採樣(Down-Sampling)。

(1)卷積層(Convolutions Layer)。卷積層由很多的卷積核(Convolutional Kernel)組成,卷積核用來計算不同的特徵圖,卷積層是卷積神經網絡的核心。在圖像識別裡用到的卷積是二維卷積,具體是二維濾波器滑動到二維圖像上所有位置,並在每個位置上與該像素點及其領域像素點做內積。卷積操作被廣泛應用於圖像處理領域,不同類型的卷積核可以提取圖像不同類型的特徵,例如,邊緣、角點等特徵。在深層卷積神經網絡中,通過卷積操作可以提取出圖像低級簡單到抽象複雜的特徵,學習輸入數據具有較強普適性的特徵表達。除此之外,激活函數能夠為CNN 卷積神經網絡引入非線性,增強網絡的複雜建模能力,常用的非線性激活函數有Sigmoid、Tanh 和ReLu 等,前兩者常見於全連接層,後者ReLu 則多用於卷積層。

(2)池化層(Pooling Layer)。池化是非線性下採樣的一種形式,主要作用是通過減少網絡的參數來減小計算量,同時池化層能降低卷積層輸出的特徵向量,通常在卷積層的後面會加上一個池化層,通過卷積層與池化層交替使用可以獲得更複雜的高層抽象特徵,並且能夠在一定程度上避免和緩解過擬合現象。常用的池化操作包括最大池化、平均池化等,其中最大池化是用不重疊的矩形框將輸入層分成不同的區域,對於每個矩形框內的數值取最大值作為統計輸出。

(3)全連接層(Full Connected Layer)。如果說卷積層、池化層和激活函數映射等操作是將原始數據映射到隱層特徵空間的話,那麼全連接層則起到將學到的「分布式特徵表示」映射到樣本標記空間的作用,將多層的特徵表達拉直成一個一維的向量,實現神經網絡的高層抽象推理能力,在整個卷積神經網絡中起到「分類器」的作用。

(4)局部連接(Local Connection)。局部連接指的是每個神經元僅與輸入神經元的一塊區域相連,該局部區域也被稱為感受野(Receptive Field)。局部連接的思想可追溯至生物學裡面的視覺系統結構,即視覺皮層的神經元實質上是局部接收信息的。在圖像卷積操作中,神經元在空間維度上是局部連接的,但在深度上是全部連接的。對於二維圖像本身而言,局部像素關聯較強,這種局部連接保證了學習後的過濾器能夠對於局部的輸入特徵有最強的響應。

(5)權重共享(Weight Sharing)。實際中,圖像的底層邊緣特徵與特徵在圖中的具體位置無關,即特徵可能出現在圖像的任意位置,權重共享正是利用這一特點,具體是指卷積核內權重參數被整張圖共享,而不會因圖像內位置的不同而改變,可在圖像中的不同位置學習到同樣的特徵,權重共享可以在很大程度上減少參數數量。

LeNet-5 的TensorFlow 實現

前文介紹了LeNet-5 的基本網絡結構,以及各個網絡功能層的特點與作用,本節將利用TensorFlow 具體實現這一網絡。首先需要說明以下幾點。

(1)LeNet-5 主要採用Tanh 和Sigmoid 作為非線性激活函數,但相對這兩者採用ReLu 激活函數的卷積神經網絡更加有效。

(2)LeNet-5 採用平均池化作為下採樣操作,但是目前最大池化操作應用更為廣泛。

(3)LeNet-5 網絡最後一層採用Gaussian 連接層,用於輸出0~9 這10 個類別中的一類,但是目前分類器操作已經被Softmax 層取代。

第1 步:建立config.py 文件,可以將超參數設置在config.py 中,方便後期對模型進行調整。代碼實現與說明如程序清單11-1 所示。

程序清單11-1 config.py 文件建立及超參數設置

1. """2. 設置模型的超參數3.4.5. KEEP_PROB: 網絡隨機失活的概率6. LEARNING_RATE: 學習的速率,即梯度下降的速率7. BATCH_SIZE: 一次訓練所選取的樣本數8. PARAMETER_FILE: 模型參數保存的路徑9. MAX_ITER: 最大迭代次數10. """11.12. KEEP_PROB = 0.513. LEARNING_RATE = 1e-514. BATCH_SIZE =5015. PARAMETER_FILE = "checkpoint/variable.ckpt"16. MAX_ITER = 50000第2 步:構建LeNet 模型的LeNet.py 文件,建立一個名為Lenet 的類,類中實現模型的初始化與構建,代碼實現與說明如程序清單11-2 所示。

程序清單11-2 構建LeNet 模型與LeNet.py 文件

1. import tensorflow as tf2. import tensorflow.contrib.slim as slim3. import config as cfg4.5. class Lenet:6. def __init__(self):7. """8. 初始化LeNet 網絡9. """10. # 設置網絡輸入的圖片為二維張量,數據的類型為float32,行數不固定,列固定為78411. self.raw_input_image = tf.placeholder(tf.float32, [None, 784])12.13. # 改變網絡輸入張量的形狀為四維,-1 表示數值不固定14. self.input_images = tf.reshape(self.raw_input_image, [-1, 28, 28, 1])15.16. # 設置網絡輸入標籤為二維張量,數據類型為float,行數不固定,列固定為1017. self.raw_input_label = tf.placeholder("float", [None, 10])18.19. # 改變標籤的數據類型為int3220. self.input_labels = tf.cast(self.raw_input_label,tf.int32)21.22. # 設置網絡的隨機失活概率23. self.dropout = cfg.KEEP_PROB24.25. # 構建兩個網絡26. # train_digits 為訓練網絡,開啟dropout27. # pred_digits 為預測網絡,關閉dropout28. with tf.variable_scope("Lenet") as scope:29. self.train_digits = self.construct_net(True)30. scope.reuse_variables31. self.pred_digits = self.construct_net(False)32.33. # 獲取網絡的預測數值34. self.prediction = tf.argmax(self.pred_digits, 1)35.36. # 獲取網絡的預測數值與標籤的匹配程度37. self.correct_prediction = tf.equal(tf.argmax(self.pred_digits, 1), tf.argmax(self.input_labels, 1))38.39. # 將匹配程度轉換為float 類型,表示為精度40. self.train_accuracy = tf.reduce_mean(tf.cast(self.correct_prediction, "float"))41.42. # 計算train_digits 與labels 之間的係數softmax 交叉熵,定義為loss43. self.loss = slim.losses.softmax_cross_entropy(self.train_digits, self.input_labels)44.45. # 設置學習速率46. self.lr = cfg.LEARNING_RATE47. self.train_op = tf.train.AdamOptimizer(self.lr).minimize(self.loss)48.49.50. defconstruct_net(self,is_trained = True):51. """52. 接收is_trained 參數判斷是否開啟dropout53. 用slim 構建LeNet 模型54. 第一、三、五層為卷積層、第二、四層為池化層55. 接下來對第五層扁平化,再接入全連接56. 接著進行隨機失活防止過擬合,再次接入全連接層57. 最後返回構建的網絡58. """59. with slim.arg_scope([slim.conv2d], padding='VALID',60. weights_initializer=tf.truncated_normal_initializer(stddev=0.01),61. weights_regularizer=slim.l2_regularizer(0.0005)):62. net = slim.conv2d(self.input_images,6,[5,5],1,padding='SAME',scope='conv1')63. net = slim.max_pool2d(net, [2, 2], scope='pool2')64. net = slim.conv2d(net,16,[5,5],1,scope='conv3')65. net = slim.max_pool2d(net, [2, 2], scope='pool4')66. net = slim.conv2d(net,120,[5,5],1,scope='conv5')67. net = slim.flatten(net, scope='flat6')68. net = slim.fully_connected(net, 84, scope='fc7')69. net = slim.dropout(net, self.dropout,is_training=is_trained, scope='dropout8')70. digits = slim.fully_connected(net, 10, scope='fc9')71. return digits本模型是對著名的手寫字體MNIST數據集進行訓練,可以在網站http://yann.lecun.com/exdb/mnist/ 上很方便地直接下載數據,得到如圖11-5 的MNIST 數據集。

MNIST 數據集列表

第3 步:建立模型訓練文件Train.py,主要實現數據讀取、模型訓練等功能,代碼實現與說明如程序清單11-3 所示。

程序清單11-3 模型訓練文件Train.py 的建立

1. import tensorflow.examples.tutorials.mnist.input_data as input_data2. import tensorflow as tf3. import config as cfg4. import os5. import lenet6. from lenet import Lenet7.8.9. def main:10. # 從指定路徑加載訓練數據11. mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)12.13. # 開啟TensorFlow 會話14. sess = tf.Session15.16. # 設置超參數17. batch_size = cfg.BATCH_SIZE18. parameter_path = cfg.PARAMETER_FILE19. lenet = Lenet20. max_iter = cfg.MAX_ITER21.22. # 加載已保存的模型參數文件,如果不存在則調用初始化函數生成初始網絡23. saver = tf.train.Saver24. if os.path.exists(parameter_path):25. saver.restore(parameter_path)26. else:27. sess.run(tf.initialize_all_variables)28.29. # 迭代訓練max_iter 次,每次抽取50 個樣本進行訓練30. # 每100 次列印出當前數據的精度31. # 訓練完成後保存模型參數32. for i in range(max_iter):33. batch = mnist.train.next_batch(50)34. if i % 100 == 0:35. train_accuracy = sess.run(lenet.train_accuracy,feed_dict={36. lenet.raw_input_image: batch[0],lenet.raw_input_label: batch[1]37. })38. print("step %d, training accuracy %g" % (i, train_accuracy))39. sess.run(lenet.train_op,feed_dict={lenet.raw_input_image: batch[0],lenet.raw_input_label: batch[1]})40. save_path = saver.save(sess, parameter_path)41.42. if __name__ == '__main__':43. main(第4 步:在上述完成步驟的基礎上,運行Train.py。如圖11-6 所示,可以看到隨著不斷迭代優化,模型精度在逐步提高。

模型迭代優化過程

第5 步:建立測試文件Inference.py。具體地,建立一個Inference 類完成對圖片的識別,成員函數predict 接收圖片作為參數,返回預測值,代碼實現與說明如程序清單11-4 所示。

程序清單11-4 測試文件Inference.py 的建立

1. import tensorflow as tf2. from PIL import Image,ImageOps3. import numpy as np4. from lenet import Lenet5. import config as cfg6.7. class inference:8. def __init__(self):9. """10. 構建Lenet 網絡,設置模型參數文件路徑,開啟TensorFlow 會話11. """12. self.lenet = Lenet13. self.sess = tf.Session14. self.parameter_path = cfg.PARAMETER_FILE15. self.saver = tf.train.Saver16.17. def predict(self,image):18. """19. 接收要測試的圖片作為參數,返回預測值20. """21. # 將圖片轉換為合適的大小進行輸入22. img = image.convert('L')23. img = img.resize([28, 28], Image.ANTIALIAS)24. image_input = np.array(img, dtype="float32") / 25525. image_input = np.reshape(image_input, [-1, 784])26.27. # 讀取模型參數並對圖片進行預測,返回預測值28. self.saver.restore(self.sess,self.parameter_path)29. predition = self.sess.run(self.lenet.prediction, feed_dict={self.lenet.raw_input_image: image_input})30. return predition第6 步:為了方便地實現對手寫數字的識別,可以使用python 的tkinter方便地繪製一個UI 進行識別,具體實現代碼如程序清單11-5 所示。

程序清單11-5 利用tkinter 建立UI

1. import tkinter2. from PIL import Image,ImageDraw3. from Inference import inference4.5. class MyCanvas:6. """7. 設置一個256*256 大小的容器進行手寫界面的繪製8. 背景色設置為黑色,繪製軌跡設置為白色9. """10. def __init__(self,root):11. self.root=root12. self.canvas=tkinter.Canvas(root,width=256,height=256,bg='black')13. self.canvas.pack14. self.image1 = Image.new("RGB", (256, 256), "black")15. self.draw = ImageDraw.Draw(self.image1)16. self.canvas.bind('<B1-Motion>',self.Draw)17.18. # 繪製軌跡19. def Draw(self,event):20. self.canvas.create_oval(event.x,event.y,event.x,event.y,outline="white",width = 20)21. self.draw.ellipse((event.x-10,event.y-10,event.x+10,event.y+10),fill=(255,255,255))22.23.24. def main:25. # 建立一個tkinter 對象, 設置大小為380*30026. root = tkinter.Tk27. root.geometry('380x300')28. # 創建一個256*256 的框架容納手寫的容器,位於tkinter 對象的左邊,填充y 方向29. frame = tkinter.Frame(root, width=256, height=256)30. frame.pack_propagate(0)31. frame.pack(side="left", fill='y')32. # 將frame 導入canvas 容器33. canvas1 = MyCanvas(frame)34. # 創建一個圖像識別的實例35. infer = inference36.37. # 定義識別按鈕觸發函數38. # 按下的時候將cavas 導出為圖片,放入infer 中進行圖像識別,並將結果顯示在label2 中39. def inference_click:40. img = canvas1.image141. result = infer.predict(img)42. result = int(result)43. label2["text"] = str(result)44.45. # 定義清除按鈕的觸發函數46. # 按下的時候將canvas 情況並重新繪製背景,並將label 設置為空47. def clear_click:48. canvas1.canvas.delete("all")49. canvas1.image1 = Image.new("RGB", (256, 256), "black")50. canvas1.draw = ImageDraw.Draw(canvas1.image1)51. label2["text"] = ""52.53. # 定義識別按鈕的樣式54. botton_Inference = tkinter.Button(root,55. text=" 檢測",56. width=14,57. height=2,58. command=inference_click59. )60. # 定義清除按鈕的樣式61. botton_Clear = tkinter.Button(root,62. text=" 清屏",63. width=14,64. height=2,65. command=clear_click66. )67. # 綁定識別按鈕到tkinter 中,設置位置為頂層68. botton_Inference.pack(side="top")69.70. # 綁定清除按鈕到tkinter 中71. botton_Clear.pack(side="top")72.73. # 定義label174. label1 = tkinter.Label(root, justify="center", text=" 檢測結果為:")75. label1.pack(side="top")76.77. # 定義label278. label2 = tkinter.Label(root, justify="center")79.80. # 設置字體樣式與大小81. label2["font"] = ("Arial, 48")82. label2.pack(side="top")83. root.mainloop84.85. if __name__ == '__main__':86. main第7 步:運行代碼並進行如下的幾組測試,測試結果如圖11-7 所示。

手寫數字測試示例

#歡迎留言在評論區和我們討論#

看完本文,對於人工智慧、卷積神經網絡你有什麼想說的?

歡迎在評論區留言

我們將在 8 月 2日精選出 3 條優質留言

贈送《Python人工智慧開發從入門到精通》紙質書籍一本哦

相關焦點

  • 圖神經網絡的「前世今生」
    作者 | 俞壹齡編輯 | 李仲深GNN的前世今生 Humility簡介GNN的分類經典圖網絡實現參考文獻代碼實現GNN的前世今生簡介從圖像分類, 視頻處理到語音識別,為處理圖數據之上的任務, 圖神經網絡就應運而生了.
  • 人工智慧晶片的前世與今生
    人工智慧的今天來之不易,將來也有很長的路要走。最近人工智慧(AI)的話題非常火爆。科學家們對基於人類大腦功能的計算做了很多研究,看它們是否能解決真實世界中的問題,從而創造了「神經網絡」的概念。1970年,Marvin Minsky告訴《Life》雜誌,「只需三到八年的時間,我們就能創造出擁有普通人類智能的機器」。到了二十世紀八十年代,AI走出實驗室進入商業領域,創造了一段投資的神話。
  • 人工智慧之卷積神經網絡(CNN)
    ^_^本文引用地址:http://www.eepw.com.cn/article/201806/381807.htm  20世紀60年代,Hubel和Wiesel在研究貓腦皮層中用於局部敏感和方向選擇的神經元時發現其獨特的網絡結構可以有效地降低反饋神經網絡的複雜性,繼而提出了卷積神經網絡CNN(Convolutional Neural Networks)。
  • 清華制人工神經網絡晶片,能效比GPU高兩個數量級
    近日,清華大學微電子所、未來晶片技術高精尖創新中心錢鶴、吳華強團隊與合作者在頂尖學術期刊、英國《自然》雜誌(Nature)在線發表論文,報導了基於憶阻器陣列晶片卷積網絡的完整硬體實現。人工神經網絡近年來大放異彩,如果用憶阻器連接成陣列,作為人工神經網絡的硬體,會有什麼效果?憶阻器陣列儘管國內外許多企業、研究機構給予關注,但據清華大學新聞頁面報導,當前國際上的憶阻器研究還停留在簡單網絡結構的驗證,或者基於少量器件數據進行的仿真。基於憶阻器陣列的完整硬體實現仍然有很多挑戰。
  • 光學卷積神經網絡加速器:通過光學實現更強大的人工智慧!
    導讀據美國喬治·華盛頓大學官網近日報導,該校和加州大學洛杉磯分校的研究人員與深度科技創業公司 Optelligence LLC 共同開發出一種光學卷積神經網絡加速器,每秒能夠處理拍字節創新近日,美國喬治·華盛頓大學和加州大學洛杉磯分校(UCLA)的研究人員與深度科技創業公司 Optelligence LLC 共同開發出一種光學卷積神經網絡加速器,每秒能夠處理拍字節(1拍字節=2^50位元組)級的大量信息
  • 從圖(Graph)到圖卷積(Graph Convolution):漫談圖神經網絡 (二)
    在從圖(Graph)到圖卷積(Graph Convolution): 漫談圖神經網絡 (一)中,我們簡單介紹了基於循環圖神經網絡的兩種重要模型,在本篇中,我們將著大量筆墨介紹圖卷積神經網絡中的卷積操作。
  • 什麼是人工神經網絡(ANN)?
    每天使用神經網絡的應用程式有很多,例如Google的翻譯服務,Apple的Face ID iPhone鎖和Amazon的Alexa AI驅動的助手。神經網絡也在其他領域的一些重要人工智慧突破背後,例如診斷皮膚和乳腺癌,讓目光投向自動駕駛汽車。人工神經網絡背後的概念和科學已經存在了數十年。
  • 清華用憶阻器制人工神經網絡晶片,能效比GPU高兩個數量級
    近日,清華大學微電子所、未來晶片技術高精尖創新中心錢鶴、吳華強團隊與合作者在頂尖學術期刊、英國《自然》雜誌(Nature)在線發表論文,報導了基於憶阻器陣列晶片卷積網絡的完整硬體實現。人工神經網絡近年來大放異彩,如果用憶阻器連接成陣列,作為人工神經網絡的硬體,會有什麼效果?憶阻器陣列儘管國內外許多企業、研究機構給予關注,但據清華大學新聞頁面報導,當前國際上的憶阻器研究還停留在簡單網絡結構的驗證,或者基於少量器件數據進行的仿真。基於憶阻器陣列的完整硬體實現仍然有很多挑戰。
  • 從特徵檢測器到視覺轉換器:卷積神經網絡的時代到此結束了嗎?
    圖源:unsplash近十年來,卷積神經網絡一直在全球計算機視覺研究領域發揮著主導作用。但研究者們正在提出一種新方法,想要利用轉換器的功能賦予圖像更深層的意義。轉換器最初是為自然語言處理任務而設計的,主攻神經網絡機器翻譯。後來,谷歌研究院的阿列克謝·多索維斯基(Alexey Dosovitskiy)、盧卡斯·拜爾(Lucas Beyer)等人撰寫了一篇題目為《一幅圖像值得16x16個字符:大規模用於圖像識別的轉換器》的論文,提出了一種名為視覺轉換器(ViT)的架構,該架構可通過轉換器處理圖像數據。
  • 【專利解密】深鑑科技結合神經網絡處理器與通用處理器的AI晶片
    【嘉德點評】深鑑科技發明的人工智慧晶片,結合了神經網絡專用處理器和通用處理器的晶片結構,不僅可以提供一個靈活的系統,並且可以適用於複雜的神經網絡。 深鑑科技的AI晶片基於FPGA設計,其設計的亞里斯多德架構是針對卷積神經網絡而設計的,其設計的笛卡爾架構是專為處理DNN/RNN網絡而設計的,可對經過結構壓縮後的稀疏神經網絡進行極致高效的硬體加速。 在人工智慧領域,卷積神經網絡尤其在圖像處理領域有著非常廣泛的應用,其具有訓練方法簡單、計算結構統一的特點。
  • 卷積神經網絡的卷積到底是什麼
    打開APP 卷積神經網絡的卷積到底是什麼 人工智慧遇見磐創 發表於 2020-05-05 08:40:00 卷積神經網絡是一種特殊的神經網絡結構,是自動駕駛汽車、人臉識別系統等計算機視覺應用的基礎,其中基本的矩陣乘法運算被卷積運算取代。
  • AI的人工神經網絡
    人工神經網絡是模擬人和動物的神經網絡的某種結構和功能的模擬,所以要了解神經網絡的工作原理,所以我們首先要了解生物神經元。其結構如下圖所示: 從上圖可看出生物神經元它包括,細胞體:由細胞核、細胞質與細胞膜組成;軸突:是從細胞體向外伸出的細長部分,也就是神經纖維。
  • 科學家開發卷積神經網絡預測三維基因組
    科學家開發卷積神經網絡預測三維基因組 作者:小柯機器人 發布時間:2020/10/15 15:45:23 格萊斯頓研究所的數據科學和生物技術Katherine S.
  • 機器學習之神經網絡(1)
    其實神經網絡技術的靈感來自人體內的神經結構。,我們可以自己人工創建一個「神經元」——感知器。(可以細細體會一下~)由此,神經網絡的理論開始大放異彩,再加上如今硬體設備的發達以及網絡結構的不斷簡化,神經網絡得到了很好的發展。
  • NeurIPS 2020線上分享 | 華為諾亞方舟:超越CNN的加法神經網絡
    目前出現了多種獲得高計算能效深度神經網絡的算法,如從準確度損失極少的預訓練神經網絡中刪除不重要參數或濾波器的權重剪枝方法,以及通過模仿教師模型輸出分布來直接學習學生模型的知識蒸餾方法。另一個獲得高效神經網絡的研究途徑是減少權重和激活值的位寬以降低內存使用和功耗。這類方法有很多,也可以大幅度降低計算複雜度,但生成網絡的性能依然低於 CNN 方法。
  • 人工智慧學習之什麼是人工神經網絡?
    許多人工智慧計算機系統的核心技術是人工神經網絡(ANN),而這種網絡的靈感來源於人類大腦中的生物結構。通過使用連接的「神經元」結構,這些網絡可以通過「學習」並在沒有人類參與的情況下處理和評估某些數據。這樣的實際實例之一是使用人工神經網絡(ANN)識別圖像中的對象。
  • GCN圖卷積網絡入門詳解
    字幕組雙語原文:【GCN】圖卷積網絡(GCN)入門詳解英語原文:Graph Convolutional Networks (GCN)翻譯:聽風1996、大表哥在這篇文章中,我們將仔細研究一個名為GCN的著名圖神經網絡。
  • 今天的卷積網絡,Yann LeCun在93年就已經玩得很溜了
    手寫數字識別是很多人入門神經網絡時用來練手的一個項目,但就是這麼簡單的一個項目,最近在 reddit 上又火了一把,因為在 MIT 計算機科學和人工智慧實驗室,有人挖到了一個「祖師爺」級別的視頻……從這段視頻中我們可以看到,LeCun 在 90 年代初創造的文本識別系統已經達到了驚人的速度和準確率,這在當時的條件下是非常難能可貴的。
  • 德克薩斯A&M大學在讀博士遊宇寧:自監督學習在圖卷積網絡中的研究...
    當前自監督學習已經被廣泛用於訓練卷積神經網絡(CNNs),有效地提高了圖像表示學習可傳遞性、泛化能力和魯棒性,並且已在語義分割、目標檢測、圖像分類、人體動作識別等實戰場景中展現出卓越效果。現在更多無需人工標註的前置任務訓練也被提出,如前景對象分割、圖像修補、圖像著色等。然而,自監督如何應用於處理圖數據結構的圖卷積網絡(GCNs)的問題卻很少被探索。
  • 神經網絡計算效率如何來提高
    閃億半導體的該項專利,在計算神經網絡時,呈陣列排布的多個存儲單元中,任意N條第一信號線和任意M條第二信號線限定的區域均可以作為一個存儲陣列,從而大大增加存算一體化電路中的存儲陣列數量以及各存儲陣列大小的靈活性,進而增加所能計算的神經網絡的神經元層數目範圍以及每個神經元層內的節點數目範圍。