從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

機器學習 人工智能 Google 大數據 雷鋒網 2017-03-28

自 2015 年 11 月首次發佈以來,TensorFlow 憑藉谷歌的強力支持,快速的更新和迭代,齊全的文檔和教程,以及上手快且簡單易用等諸多的優點,已經在圖像識別、語音識別、自然語言處理、數據挖掘和預測等 AI 場景中得到了十分廣泛的應用。

在所有這些 AI 應用場景中,或許是源於視覺對人類的直觀性和重要性,圖像識別成為其中發展速度最快的一個。目前,該技術已經逐漸趨於成熟,並在人臉和情緒識別、安防、醫療篩查和汽車壁障等諸多領域都取得了重大成功。

在這種情況下,對於絕大多數的 AI 開發者而言,利用 TensorFlow 自己親手搭建一個圖像識別模塊,就成了一項最順理成章的挑戰。

為了幫助有志於此的開發者實現目標,也為了向那些親手搭建過圖像識別模塊的技術達人提供一個與行業大牛交流、學習的機會,本次公開課雷鋒網 AI 研習社有幸邀請到才雲科技(Caicloud.io)聯合創始人、首席大數據科學家鄭澤宇,他將深入到代碼層為我們詳細講解究竟怎麼用 Tensorflow 自己親手搭建一套圖像識別模塊。

嘉賓介紹

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

鄭澤宇,暢銷書《TensorFlow:實戰 Google 深度學習框架》作者,才雲科技(Caicloud.io)聯合創始人、首席大數據科學家。才雲科技(Caicloud.io)是一家雲計算、人工智能創業公司。最近推出全球首個商用 TensorFlow as a Service (TaaS) 深度學習平臺和行業大數據解決方案,用數據助力企業成長。

鄭澤宇曾在 Google 擔任高級工程師,作為主要技術人員參與並領導了多個大數據項目。提出並主導的產品聚類項目用於銜接谷歌購物和谷歌知識圖譜(Knowledge Graph)數據,使得知識卡片形式的廣告逐步取代傳統的產品列表廣告,開啟了谷歌購物廣告在搜索頁面投遞的新紀元。

鄭澤宇擁有 CMU 計算機碩士學位,在機器學習、人工智能領域有多年研究經驗, 並在 SIGIR、SIGKDD、ACL、ICDM、ICWSM 等頂級國際會議上發表多篇學術論文。

公開課內容

本次公開課的主要內容包括:

1. 深度學習簡介

2. 神經網絡工作原理

3. 用 TensorFlow 實現圖像識別

4. 疑難問題解答及討論

以下為公開課完整視頻:共 55 分鐘。

以下為公開課內容的文字及 PPT 整理。

大家好,今天我想跟大家分享一些深度學習算法在圖像識別上的應用。

主要內容大概可以分為如下三個部分:

● 深度學習介紹;

● 神經網絡工作原理;

● 用 TensorFlow 實現圖像識別。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

深度學習介紹

我們知道深度學習現在是已經是一個非常熱門的技術,那大家第一次聽到這個深度學習的時候呢?很有可能就是因為去年這個時候 AlphaGo 戰勝李世石的這個事情。當時這個事情獲得了全社會的廣泛關注和熱烈討論。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

但其實 AlphaGo 並不是第一個戰勝人類的智能機器人,早在 20 年前就有過 IBM 深藍機器人戰勝人類國際象棋冠軍的記錄。那為什麼 AlphaGo 可以引發這麼大的關注呢?

我認為原因有兩個方面:一是圍棋的複雜度遠超國際象棋;二是因為深度學習技術的發展,它推動了不僅是一個 AlphaGo 這樣的應用程序,它其實也推動了各個方面的人工智能的應用。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

例如谷歌的無人車項目,就是一個距離我們更近的例子。大家都知道,現在無論在國內還是國外,堵車和停車的問題其實都是很嚴重的。但是如果有了無人車這樣一個工具,就能大大提升車主的用戶體驗。

正是因為深度學習技術在 AlphaGo 和無人車等項目背後的巨大推動力,才使得這些項目能夠發展到目前這樣一個比較高的水平。

但其實,深度學習技術並不是一個新技術,它的起源可以追溯到幾十年前,只是這兩年才得到了一個比較快速的發展。如圖中所示的搜索熱度變化圖也能看出,從 2012 年到 2016 年,深度學習這個詞的受關注程度是處於一個指數級增長的狀態。那為什麼會在 2012 年這個時間點出現這樣的一個增長呢?其實是因為 ImageNet 這樣一個圖像識別的比賽。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

ImageNet 是由李飛飛教授發起的一個著名的圖像識別數據集,裡面包括了各種各樣的圖片,然後參賽者需要將物體從圖片中標記出來,做一個分類。這個比賽每年都會舉辦,而且每次的比賽細節都會有所不同。然後在 2012 年的時候,由於深度學習的作用,比賽結果產生了一個巨大突破。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

從下圖可以看出,在 2012 年之前,採用了傳統分類算法的時候,錯誤率大概是 26% 左右。而且我們可以看到這個錯誤率的變化趨勢非常緩慢,也就是說要減低一點錯誤率,就必須付出巨大的努力。但是在引入深度學習算法之後,從 2011 到 2012 年,使得錯誤率從 26% 一下子降低到了 16%,並且從 2012 年開始的這三四年中,錯誤率還在以每年 4% 左右的一個速度在降低。到 2015 年,機器的識別率已經接近了人類的水平,即 5.1% 的錯誤率。2016 年,機器最新的識別正確率已經達到了 97% ,錯誤率達到了 3% 左右,已經比人類好得多。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

如下圖是才雲科技集成 Google 訓練好的一個模型,它可以通過分析用戶上傳的圖片,例如一頭牛,然後分析出這頭牛是某個品種的概率是多少。還有現在大家在 Google 或者百度上傳一張圖片,然後搜索引擎就能比較精確地告訴你這個圖片裡的主體是什麼動物,或者什麼植物,甚至還能提供一段簡單的文字描述等等。其實這些都是基於深度學習的算法來實現的。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

除了圖像識別之外,其實深度學習的早期應用是數字識別。例如圖中所示的這個就是 1998 年的時候 Yann LeCun 教授做的一個手寫體數字識別的項目(如下圖所示),用的就是深度學習技術。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

此外還有 Google 在地圖上的應用,能夠通過圖像識別自動定位門牌號和地理位置等信息。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

其實神經網絡,也就是深度學習技術用在圖像識別的應用還有很多,包括人臉識別、安防領域、火警、群眾事件,還有現在的美顏等等。並且,受到神經網絡思想的啟發,目前包括語音識別、機器翻譯、自然語言處理和大數據分析、預測等行業都得到一個比較大的發展。

神經網絡原理

下面簡單介紹一下神經網絡的情況。

這裡我不會去推導前向傳播或者反向傳播的具體過程。前向傳播的過程比較簡單,這裡會做一個大致的介紹。而反向傳播對數學的要求比較高,並且通過 TensorFlow 可以非常容易地去實現,因此我只會簡單介紹一下基本原理,大家自己有興趣的話可以自己去深挖。這個部分我主要還是做一些流程上的介紹,讓大家知道一個完整的機器學習或者說圖像識別問題,我該怎樣一步一步地去解決它,包括我需要做哪些事,什麼事情可以通過什麼工具來幫助我實現。

首先我們來介紹一下什麼是深度學習。大家可能經常會聽到深度學習和神經網絡這些詞,但它們之間究竟是一個什麼關係呢?其實,深度學習在維基百科上的定義是:多層的非線性變換的一個算法合集。那怎樣實現這個多層非線性變換呢?最好最方便的一種方法就是神經網絡。所以說基本上當前來講的深度學習,就等於是深層神經網絡的一個代名詞。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

神經網絡,大家從這個詞就能看出它多多少少跟人腦的神經網絡有些關聯。如圖所示,左上角就是一個神經元的模型,他包括很多不同的輸入,以及一個軸殼來處理這些輸入,最終得到一個輸出。這個對應到人工神經網絡也是一樣的,它會有多個輸入,然後經過一些變換得到輸出。但人腦的變換函數具體是怎樣的,現在還弄不清楚,我們只能通過這樣一組加權和,加上一個激活函數來模擬人腦。

大家都知道,人腦是通過這種神經網絡的網絡狀結構處理信息的,因此在人工神經網絡結構中也是通過這樣的一種多層結構來實現神經元的連接。如上圖的右下角所示,每一個圓圈都代表一個神經元,多個輸入,一個輸出,上一層的輸出作為下一層的輸入。

下面我簡單介紹一下怎麼用這個網絡結構來處理問題。比如數字識別問題,如圖所示的數字圖像在計算機裡就是一個像素矩陣,然後每個矩陣元素裡面都是各種各樣的一個數字,我們把這些數字作為這個神經網絡的輸入層提供進來,然後通過不同結構的神經網絡處理,從輸入層到隱藏層再到輸出層,就可以得到處理結果。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

比如圖中的這個手寫數字問題,其實就是要識別這個數字到底和 0 到 9 中的哪個數字更像一點。我們可以安排輸出層有 10 個結點,分別代表 0 到 9 的 10 個數字。那麼如果這個圖像是 1 的話,我們就希望代表 1 的這個結點輸出的結果是 1 ,其他的結點是 0 。這樣的話假設我們輸入一張圖像,然後發現代表數字 7 的結點輸出為 1,其他結點為 0 ,那麼我們就等於識別出了這個圖像的內容是 7,也就完成了一個數字識別的任務。

這只是一個最簡單的例子,還有更多更復雜的神經網絡這裡我們就不做具體介紹了,感興趣的朋友可以關注才雲科技開源的一個代碼庫,裡面有各種豐富的樣例代碼。(雷鋒網注:開源地址見下文鏈接)

下面簡單介紹一下深度學習的兩個大的分類:監督學習和非監督學習。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

我通常會把機器學習和人類學習來做一個對比,其實有很多地方都是比較類似的。例如我們小時候去上課,然後考試。其實機器學習也是一個類似的過程,它通過海量的數據,然後學習(總結)出一些對應的規律,並將規律應用在一個測試環境上,就能得到一個諸如正確率這樣的評測指標,最終通過評測指標來評測一個機器學習算法的好壞。

那麼在監督學習的場景中,通過海量的標記過的數據,就相當於人類在學習中通過大量的做題,然後每做一個題都知道對錯,沒有錯的話就加強這個過程,有錯的話就反向改進,這就是監督學習。

而非監督式就不需要人為的標籤數據,它是監督式和強化學習等策略之外的一個選擇。典型的非監督學習有聚類等,它是直接從數據中尋找相似性,即規律。

現在其實機器學習除了監督式和非監督式之外,還有增強學習。它是和監督式及非監督式都有些不同的一種方式。然後,但其實在工業界用得最多的,其實還是監督式學習的方式,非監督式和增強學習現在在工業界的使用還是相對比較少。那其實我們今天也會主要以監督式的這種學習方式作為一個樣例,來告訴大家怎樣去完成一個監督式的學習方法來完成圖像識別工作。

在具體介紹整個模型之前,這裡我先跟大家詳細介紹一下神經網絡的工作原理。

剛剛講到,我們要去做一個圖像分類模塊,就相當於是把這個圖像的原始的像素矩陣傳入輸入層,然後經過一層一層的推導,得到輸出層。那其實神經網絡裡面一個最關鍵的部分,就是說我怎樣通過一層一層的網絡結構來得到從輸入層到輸出層的結果。最簡單的來講,我們先要知道一個單一的神經元的工作方式。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

如圖所示,我們其實可以將每個神經元視為這樣的一個多項式組合,w表示權重,b表示偏移量。那麼訓練時一個最重要的工作就是找到最合適的權重,使得我們的實際輸出與預想輸出一致。那麼輸入的一個加權平均,加一個偏移,最後再通過一個激活函數,最後就能得到輸出。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

這裡我們以一個判斷零件是否合格的例子來講解,注意這裡省略了偏移量和激活函數。比如說我這裡的每一個零件它都會有長度、質量等參數,就相當於收集了很多關於這個零件的數據,其中有一些我們知道是已經合格了的,也就相當於有了一個訓練數據。將這些訓練數據輸入模型,通過結果對比不斷調節隱藏層的權重參數,最終達到一定的正確率之後,也就是完成了模型訓練。接著我們可以測量任意一個零件的參數,把測量數據輸入神經網絡,就能判斷這個零件是否合格。

這樣的一個過程其實就是正向傳播的一個過程。反向傳播相當於是我知道一個零件的長度和質量,也知道它是否合格的時候,再去根據這個目標做一個反向的回饋。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

這裡我列出了一些簡單的激活函數,注意這裡所有的激活函數都是非線性的函數。如果一個模型沒有激活函數的話,就相當於是所有線性過程的疊加,不論模型有多少層,疊加出來還是一個線性過程,也就是模型沒有涉及非線性的因素,也就不會有實際的應用。而激活函數就是一個提供非線性過程的因子,有了激活函數我們才能完成一個非線性變化的過程。

更詳細的內容大家可以參考《TensorFlow:實戰Google深度學習框架》這本書。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

這裡我們介紹兩種常用的激活函數:Softmax 和 Sigmoid。在多分類的問題中,經過層層的推導,其實每個節點的輸出都是不一定的。那麼如果我們想得到一個概率分佈,就需要用到 Softmax 這樣一個層。它相當於對每個輸出節點的大小作為置信度做一個歸一化的操作,然後使得每一個最終輸出節點的值都在 0 到 1 之間,這樣就等於輸出了一個概率分佈。我們可以大概理解為不同的輸出類別的一個概率分佈。在多分類問題中,一般都會用 Softmax 作為最後的處理層,得到一個概率分佈情況。類似的,在二分類中我們通常使用 Sigmoid 函數。

這樣,從輸入層到隱藏層到輸出層再到激活函數,我們等於介紹了全連接神經網絡的一個基本結構。剛剛提到,監督學習就是我們得到一個結果之後,能夠判斷它的好壞。那麼怎麼判斷和評測呢,就需要損失函數。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

通過損失函數,我們可以計算出實際輸出和真實標籤的差別,然後進行優化,縮小這種差別。兩個經典的損失函數一個是交叉熵,另一個是 MSE 最小平方差。他們詳細的用法,包括自定義函數怎麼樣去定義等內容,大家可以參考《TensorFlow:實戰Google深度學習框架》這本書。

定義完損失函數,我們再來講講優化。

首先,優化的是什麼?我們剛剛提到,神經網絡裡的每一個神經元都有參數,我們要優化就是這些參數。那怎樣來優化呢?就是通過我們定義的損失函數,即推導得出的結果要跟真實結果越接近越好。這相當於變成了一個最小化問題。最小化問題確實有比較成熟的數學解法。但對於神經網絡這麼複雜的一個結構,它其實並沒有特別好的數學公式能夠直接求解。

雖然說,優化神經網絡的算法有不少,但主體的思想其實都是基於梯度下降,或者隨機梯度下降。那麼,梯度下降是什麼?用簡單的話來講,它就相當於是把不同參數的取值和損失函數的大小,看成空間中的一個曲面。最簡單的情況下,可看成二維空間上的一條曲線。任意一個參數的取值,就對應了損失函數的取值。這樣子的話,我們就可以通過計算它的梯度來修改參數,使得損失函數會往更小的這樣一個方向去發展。這就是優化神經網絡的最基本的思想。包括反向傳播算法,其實也就是怎麼更快地去計算出每一個參數的梯度,使得計算的時間複雜度減少。優化神經網絡的核心思想其實還是梯度下降。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

梯度下降是在所有的數據集上去算它的梯度。但神經網絡的數據量一般會比較大,一般很難把所有的數據全都用上。這樣的時候,我們一般會採用 minibatch。一次計算部分的梯度來減少計算量。本來我們就知道,梯度下降其實就已經無法達到全局最優值。那使用隨機梯度下降呢,其實就更加難以保證達到最小值,有全部訓練數據集才能有最小值。但我們可以通過調整學習率,使它更加逼近極小值。

這些就是我想給大家講的,神經網絡的大致工作原理。其實這個工作原理講得比較粗淺,也比較 high-level。但大部分人其實對主要的一些部分了解就 OK 了。

用 TensorFlow 實現圖像識別

接下來,我會把這些原理對應到具體的代碼裡面,然後讓大家知道怎麼樣通過 TensorFlow 來實現圖像識別。同時講解怎麼用 TensorFlow 來實現大致的機器學習分類算法。

雖然上面有很多的細節沒有覆蓋,但其實 TensorFlow 也把這樣的一些細節給屏蔽掉了。我的意思是,其實大家只需要理解一些比較 high-level 的東西,就完全能夠通過 TensorFlow 來實現神經網絡的訓練。

我們先談什麼是 TensorFlow,為什麼要選擇 TensorFlow。

TensorFlow 是谷歌在 2015 年底開源的一個深度學習框架。雖然說是深度學習,官方來講,其實 Google 希望把它做成一個計算工具。但這個計算工具的主要任務,就是用來實現深度學習算法。所以說,其他的功能我們暫時也就拋開不談。就深度學習的基本功能來講,TensorFlow 已經得到廣泛的應用。Google自不必提,現在所有 Google 內部的深度學習系統全都是基於TensorFlow。DeepMind 賣了之後,推出的東西也都會基於TensorFlow。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

Google 之外,國內包括華為、京東、小米,其實都在用 TensorFlow。國外像 Twitter、Uber、Snapchat 也在用。使用它的公司其實非常多。現在學術界也好,工業界也好,都偏向使用它。為什麼 TensorFlow 會這麼受歡迎?除了有大公司的背書,社區的貢獻度也是非常重要的一個參考指標。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

在 GitHub,無論是從 star 的數量,fork 的數量,還是從 issues 和 pull request, TensorFlow 都遙遙領先於其他同類深度學習開源框架。對於深度學習來講,它還是一門正在發展中的技術。對於工具來講,我們認為,它是否能夠跟上這門技術的發展,其實是非常重要的一個考核標準。就是說,因為技術的發展是非常快的,如果工具的發展落後於技術的發展,它就會有一個被淘汰的風險。所以說,當它的社區活躍度非常高的時候,這個風險度就會相應的降低。因此我們比較推薦使用 TensorFlow。對於新手來講,我們也比較推薦。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

這裡給出了一個簡單的 TensorFlow 的 Hello World 的程序,實現了一個簡單的向量加法的操作。首先 import 了 TensorFlow ,然後定義了 a、b 兩個向量,包括 name 屬性,接著把它們加起來。這裡 TensorFlow 採用了這樣的一個惰性計算模型,輸出的並不是加法的結果,而是結果的一個引用。另外,要運行整個 result 運算,就必須定義一個 session ,session 會掌握所有 TensorFlow 的運算資源,然後通過 session 運行相關操作。

這裡只是簡單介紹了一個 TensorFlow 的簡單用法,由於時間有限,也無法深入地去詳細介紹。我們關注的是如何用 TensorFlow 實現一個神經網絡的全連接,也就是加權和,加上激活函數的模型。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

加權和可以通過矩陣乘法的方式實現。如上圖代碼所示,這裡通過 placeholder 的方法定義了一個 input ,其中類型是必須的,其他的諸如 shape 等參數則可以等使用的時候再賦值。之後定義了權重 w 和偏移量 b,這裡是通過 Variable 方法定義的,這樣等最後優化的時候,TensorFlow 會針對這些 Variable 展開優化。最後通過乘法和加法操作,也就是通過 output = tf.nn.relu(tf.matmul(x, w) + b) 這一行代碼就實現了神經網絡的基本結構。

這裡是通過基礎的 TensorFlow API 實現的,如果通過 Keras 等更高層的封裝來實現會更加簡單。這裡我們是從基礎的 API 入手來進行講解,如果大家對高層封裝感興趣,可以自己學習。需要指出的是,其實高層封裝和基礎 API 的主要區別是實現上的區別,他們整體上的過程是基本一樣的。

下面我們來看一下如何用 TensorFlow 實現一個具體的圖像識別模塊,即從 MNIST 數據集中識別手寫數字。(完整代碼見下文鏈接)

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

可以看到,TensorFlow 通過 read_data_sets 方法對引用數據進行了一個非常好的封裝,後續可以通過非常簡單的方式讀取這些劃分好的數據集,例如通過 train、validation、test 等關鍵詞就可以讀取訓練和測試數據集等。

如下圖所示,然後是通過 next_batch 來獲取一小批的訓練數據。我們剛剛提到,在利用梯度下降算法時需要在所有的訓練數據上計算梯度,但是計算量太大了,因此這裡通過 next_batch 方法,相當於我們在所有的訓練數據集中篩選一部分,隨機選取一部分訓練數據集,提供到神經網絡的輸入層,然後通過反向迭代方法去優化這個神經網絡。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

這裡 xx 設置等於 100,也就是我們得到了 xs 和 ys 兩個矩陣,xs 代表輸入數組,相當於把一個 28×28 的手寫圖像展開成一個長度為 748 的一維數組。ys 相當於我們的結果,也就是 0-9 這 10 種可能值。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

如上圖,完了之後是一個前向傳播的一個大致過程的程序截圖。這個過程就相當於是定義一層一層的神經網絡結構,這裡 inference 函數中的 input_tensor 相當於輸入矩陣,後面的 reqularizer 就相當於一個正則化的東西。我們可以看到,當輸入來了之後,程序開始進行一層一層的推導,定義一層一層的權重和偏移量,算出每一層的結果,傳入下一層,進入下一層的計算。

其實通過這個前項傳播的定義我們可以看到,無論是全連接層還是卷積神經網絡,甚至是循環神經網絡,它的大致流程都是一樣的,給定輸入,然後通過一層一層的傳遞就可以得到最後的輸出。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

如上圖,下面我們看一下主程序。其實主程序就是調用了 train 的過程,這個 train 的過程其實也是比較簡單的。第一部分是定義輸入,也就是怎樣來提供這個訓練數據的接口,也就是通過 placeholder 的方式導入,輸入這裡是 x ,輸出是 y_ 。然後通過調用 inference 函數來進行一個前向傳播的計算。然後定義了滑動平均和損失函數。

這裡的過程其實是就相當於是:我通過輸入一個訓練數據集,然後得到在當前數據集下的推導結果,然後再通過這個推導結果和正確答案對比,就知道跟正確答案的差別在哪。下一步可以看到我們定義了 loss ,它相當於評估當前模型好壞的一個指標。這裡其實就相當於是評價 cross_entropy 加上正則化,這裡正則化是為了避免過耦合的。

完了之後,下一行是通過 GradientDescentOptimizer 函數優化。TensorFlow 提供了大概 5-7 中不同的優化函數可供選擇,它們針對不同的應用場景,各具特點,大家可以靈活選擇。這裡我認為,對於那些不搞學術研究的同學,其實沒有必要去從數學的角度推導每一個優化函數具體是怎麼優化的,從應用層的角度來看,大部分用戶只需要提供學習率和目標函數,並且瞭解這些優化函數的優劣就可以了,這個相對來說還是比較方便。

在把所有的這些計算方式都定義好了之後,下面就是生成 TensorFlow 的計算圖,以及生成 session。定義好 session 之後,下面訓練的過程就比較簡單了,其實就是寫了一個循環,每次選取一小部分訓練數據,然後去做訓練,隔一段時間再打印一下訓練結果,整個過程就完成了。

所以說整個用 Tensorflow 來實現一個神經網絡的過程,相對還是比較簡單的。需要注意的是,這裡我介紹的只是原生態的 TensorFlow,如果大家要去使用 TFLearn,或者 Keras 這些高級封裝去實現 MNIST 問題的話,可能會更加簡單,大概只需要 2-3 行代碼就可以解決了。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

這裡我們基本上把通過原生態的 Tensorflow 生成神經網絡的過程為大家介紹了一下。其實後面還有個 evaluate 評估的部分(代碼如上圖所示),因為時間關係我就不對著代碼詳細講了,感興趣的同學可以自己下去研究(源碼見下文鏈接)。

下面我再跟大家再介紹一下循環卷積神經網絡。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

剛剛大家看到的這個結構是一個全鏈接的神經網絡,在圖像處理的過程中,使用全連接神經網絡最大的一個問題就是它的參數太多了,這個問題可能會導致模型最終訓練不好。

例如,經常發生的,當你的訓練數據不足的時候,參數又太多,你就可能訓練不出來。一個非常簡單的例子,大家可以想象 N 元的一個方程組,然後我們假設只有 N 個數據,並且這些數據是完全可分的,也就是我們是可以完全求解。但完全求解可能會導致過擬合,因為訓練數據在真實環境下都是有噪音的,也就是沒有辦法做到完全避免隨機因素的影響。在這種情況下如果你過於貼合訓練數據,那麼就有可能沒有辦法去收斂到未知的數據。

所以這就是參數過多可能引發的問題,即過擬合和訓練不出來。那怎樣去解決這兩個問題呢?卷積神經網絡就是一個很好的方法。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

卷積神經網絡就相當於是採用一個內核,即一個規模較小的矩陣,去處理一個比較小的區域,然後去通過移動這個小矩陣,去處理不同的這個塊。這種方式一個直觀的一個意義就是:一般的圖像上相鄰區域的內容是相似的。然後通過這樣的一個潛在的東西,就可以去把一個淺層的表達變成一個更深層的表達。也就是相當於自動從圖像中去提取特徵。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

例如上圖所示,第一層可能可以從圖像中提取一些線條和斑點,第二層提取一些更復雜的性狀。第三層和第四層,層數越多,提取的特徵就會越複雜。然後通過最後提取出來的這樣一些特徵,我們再去做一個全連接的分類,最後這個分類的效果也就會更好。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

然後這裡給出了一個簡單的 LeNet5 的模型,我們可以看到他的大致結構就是從輸入層,經過不斷地卷積池化,再經過 1 到 3 層不等的全連接層,最後得到輸出層。其實現在很多的卷積神經網絡基本上也都保留了這樣的一種結構。

除了這種模型之外,另一種比較特殊的模型是 Google Inception 模型,這裡因為時間關係我也不去做過多的介紹了。

然後我在這裡給出了一個簡單的用 TensorFlow 的程序來實現卷積層。通過代碼其實大家也可以看到,在這個框架裡面,無論是全連接的神經網絡也好,還是卷積神經網絡也好,甚至循環神經網絡也好。它們的訓練過程,以及前面的準備過程其實基本上都是差不多的,你基本上只要去修改,怎麼樣去從輸入得到輸出就可以了。

從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社從原理到代碼:大牛教你如何用 TensorFlow 親手搭建一套圖像識別模塊 | AI 研習社

從代碼也可以看到,開始是定義這個卷積層中的權重和偏移量,完了之後 TensorFlow 會對這個卷積層有一個封裝,然後通過 conv2d 函數得到一個 2D 的卷積層,然後再把偏移量、激活函數加上去。大家可以看到整個的過程還是比較簡單的,同樣的,如果用 Keras 等更高級的封裝來實現的化會更加簡單。

最後我要推薦一下《TensorFlow:實戰Google深度學習框架》這本書,今天講的內容,包括一些略去的內容,基本上全部在這本書裡都有非常詳細的介紹。

另外,前面提到的代碼地址如下:

https://github.com/caicloud/tensorflow-tutorial

代碼庫裡包含了書中所有的樣例代碼,此外還包括了才雲科技提供的 TensorFlow as a Service (TaaS) 深度學習平臺的一些教程和代碼,包括後面我們做的一些圖像分類和圖像識別的樣例代碼,後面也都會陸陸續續添加進去。大家有興趣的化可以關注一下這個代碼庫。

今天的分享就到這裡,謝謝大家!

群友問題解答

問題1:麻煩老師推薦下 Coursera 的機器學習公開課?

答:吳恩達的“機器學習 Machine Learning”非常值得推薦的,那門課我個人至少看了兩到三遍,而且在不同的階段看都會有不同的感受。

網址:https://www.coursera.org/learn/machine-learning

編者按:更多機器學習的精品公開課彙總,詳見雷鋒網相關文章“開發者入門必讀:最值得看的十大機器學習公開課”。

文章鏈接:http://www.leiphone.com/news/201701/0milWCyQO4ZbBvuW.html

問題2:請問 TensorFlow 相比較 Keras 有什麼優勢?

答:Keras 是對於 TensorFlow 一個更高層的封裝,它幾乎可以實現 TensorFlow 的所有功能,TensorFlow 則是更底層更加靈活的一個工具,相對來說 TensorFlow 的功能可能更全。但 Keras 一個最大的問題在於,目前不支持分佈式,我們希望 Keras 在未來的版本更新中能夠加入相關的特性支持。學習的話,可以先從 Keras 入手,因為它和 TensorFlow 沒有本質的區別,它只是 TensorFlow 的一個高層封裝,寫起代碼來會更加方便。

問題3:AI 學習最主要的是算法和建模對不對呀?

答:算法和模型只是一個方面,但其實我還是比較推薦做一些實戰的應用,關鍵還是看你要做什麼事情。如果你是要做學術研究,那就要多看論文,如果你是要做工程或者要找工作的話,建議你多做一些 Kaggle 的比賽。

問題4:TensorFlow 在推薦系統上的運用如何?

答:TensorFlow 官方有一個 Wide & Deep 的教程,是關於谷歌 App 推薦的一些內容,可以關注一下。TensorFlow 是一個兼容的框架,可以被應用在許多問題上,其實更多的是關於深度學習技術的應用,現在學術界有許多相關的研究,大家可以關注一下。

Wide & Deep 鏈接:https://www.tensorflow.org/tutorials/wide_and_deep

問題5:請問 TensorFlow 相比較 Caffe 有什麼不同?

答:TensorFlow 是一個相對更全面的工具,但是在圖像處理上它的表現不如 Caffe 成熟,處理速度也會稍微慢一點。TensorFlow 相比 Caffe 的優點是支持分佈式,而且發展的速度也比 Caffe 更快。

問題6:TensorFlow 實質是通過大量訓練數據(監督學習)和神經網絡算法,實現深度學習過程。未來能不能不需要大量訓練數據,即非監督學習的辦法就可以實現深度學習的過程或工具,Google 等巨頭有這方面的嘗試或計劃嗎?

答:非監督式學習包括增強學習其實也有嘗試,它們其實也都可以通過 TensorFlow 來實現,具體怎麼做大家可以參考官網的教程。TensorFlow 主要還是提供了一個計算框架,可以實現和神經網絡相關的幾乎所有算法。

問題7:TensorFlow 既然支持分佈式,那 TensorFlow On Spark 的意義還大嗎?

答:TensorFlow 支持的分佈式其實只是一個計算框架,TensorFlow On Spark 的意義還是有的,但我覺得沒有 TensorFlow On Kubernetes 的意義大,Spark 主要是做了一個調度和管理的系統,但是性能損失比較大,目前成熟的應用也比較少。大家如果想要了解更多分佈式 TensorFlow 的內容,可以關注才雲科技的平臺。

問題8:我目前在用 Caffe,想著要不要轉 TensorFlow,老師有什麼建議麼?

答:我覺得轉 TensorFlow 還是有意義的,主要還是你具體用 TensorFlow 來做什麼。可能因為我接觸 TensorFlow 比較多,但是我個人認為 Caffe 其實正處在一個慢慢的被淘汰的邊緣。而且目前客觀上講 TensorFlow 的確是一個無論在工業上還是學術上都非常流行的框架。

溫馨提示:需要原版 PPT 和視頻鏈接的朋友可以關注 AI 研習社公眾號(微信號:okweiwu),回覆“鄭澤宇”即可。

相關推薦

推薦中...