這是一個為沒有人工智能背景的程式員提供的機器學習上手指南。使用神經網絡不需要博士學位,你也不需要成為實作人工智能下一個突破的人,你隻需要使用現有的技術就行了——畢竟我們現在已經實作的東西已經很突破了,而且還非常有用。我認為我們越來越多的人将會和機器學習打交道就像我們之前越來越多地使用開源技術一樣——而不再僅僅将其看作是一個研究主題。在這份指南中,我們的目标是編寫一個可以進行高準确度預測的程式——僅使用圖像本身來分辨 data/untrained-samples 中程式未見過的樣本圖像中是海豚還是海馬。下面是兩張圖像樣本:

為了實作我們的目标,我們将訓練和應用一個卷積神經網絡(cnn)。我們将從實踐的角度來接近我們的目标,而不是闡釋其基本原理。目前人們對人工智能有很大的熱情,但其中很多都更像是讓實體學教授來教你自行車技巧,而不是讓公園裡你的朋友來教你。
為此,我(github 使用者 humphd/david humphrey)決定在 github 上寫下我的指南,而不是直接發在部落格上,因為我知道我下面的寫的一切可能會有些誤導、天真或錯誤。我目前仍在自學,我發現現在還很缺乏可靠的初學者文檔。如果你覺得文章有錯誤或缺失了某些重要的細節,請發送一個 pull 請求。下面就讓我教你「自行車的技巧」吧!
指南位址:https://github.com/humphd
概述
我們将在這裡探索以下内容:
設定和使用已有的、開源的機器學習技術,尤其是 caffe 和 didits
建立一個圖像資料集
從頭開始訓練一個神經網絡
在我們的神經網絡從未見過的圖像上對其進行測試
通過微調已有的神經網絡(alexnet 和 googlenet)來提升我們的神經網絡的準确度
部署和使用我們的神經網絡
問:我知道你說過我們不會談論神經網絡理論,但我覺得在我們開始動手之前至少應該來一點總體概述。我們應該從哪裡開始?
對于神經網絡的理論問題,你能在網上找到海量的介紹文章——從短文章到長篇論述到線上課程。根據你喜歡的學習形式,這裡推薦了三個比較好的起點選擇:
j alammar 的部落格《a visual and interactive guide to the basics of neural networks》非常贊,使用直覺的案例介紹了神經網絡的概念:https://jalammar.github.io/visual-interactive-guide-basics-neural-networks/
brandon rohrer 的這個視訊是非常好的卷積神經網絡介紹:https://www.youtube.com/watch?v=fmpdiaimiea
如果你想了解更多理論上的知識,我推薦 michael nielsen 的線上書籍《neural networks and deep learning》:http://neuralnetworksanddeeplearning.com/index.html
設定
安裝 caffe
caffe 位址:http://caffe.berkeleyvision.org/
首先,我們要使用來自伯克利視覺和學習中心(berkely vision and learning center)的 caffe 深度學習架構(bsd 授權)。
問:稍等一下,為什麼選擇 caffe?為什麼不選現在人人都在談論的 tensorflow?
沒錯,我們有很多選擇,你也應該了解一下所有的選項。tensorflow 确實很棒,你也應該試一試。但是這裡選擇 caffe 是基于以下原因:
這是為計算機視覺問題定制的
支援 c++ 和 python(即将支援 node.js:https://github.com/silklabs/node-caffe)(https://github.com/silklabs/node-caffe%ef%bc%89)
快速且穩定
但是我選擇 caffe 的頭号原因是不需要寫任何代碼就能使用它。你可以聲明性地完成所有工作(caffe 使用結構化的文本檔案來定義網絡架構),并且也可以使用指令行工具。另外,你也可以為 caffe 使用一些漂亮的前端,這能讓你的訓練和驗證過程簡單很多。基于同樣的原因,下面我們會選擇 nvidia 的 digits。
caffe 的安裝有點麻煩。這裡有不同平台的安裝說明,包括一些預建構的 docker 或 aws 配置:http://caffe.berkeleyvision.org/installation.html
注:當我在進行練習的時候,我使用了來自 github 的尚未釋出的 caffe 版本:https://github.com/bvlc/caffe/commit/5a201dd960840c319cefd9fa9e2a40d2c76ddd73
在 mac 要配置成功則難得多,這個版本有一些版本問題會在不同的步驟終止你的進度。我用了好幾天時間來試錯,我看了十幾個指南,每一個都有一些不同的問題。最後發現這個最為接近:https://gist.github.com/doctorpangloss/f8463bddce2a91b949639522ea1dcbe4。另外我還推薦:https://eddiesmo.wordpress.com/2016/12/20/how-to-set-up-caffe-environment-and-pycaffe-on-os-x-10-12-sierra/,這篇文章比較新而且連結了許多類似的讨論。
到目前為止,安裝 caffe 就是我們做的最難的事情,這相當不錯,因為你可能原來還以為人工智能方面會更難呢!
如果安裝遇到問題請不要放棄,痛苦是值得的。如果我會再來一次,我可能會使用一個 ubuntu 虛拟機,而不是直接在 mac 上安裝。如果你有問題要問,可以到 caffe 使用者讨論組:https://groups.google.com/forum/#!forum/caffe-users
問:我需要一個強大的硬體來訓練神經網絡嗎?要是我沒法擷取一個強大的 gpu 怎麼辦?
是的,深度神經網絡确實需要大量的算力和能量……但那是在從頭開始訓練并且使用了巨型資料集的情況。我們不需要那麼做。我們可以使用一個預訓練好的網絡(其它人已經為其投入了數百小時的計算和訓練),然後根據你的特定資料進行微調即可。我們後面會介紹如何實作這一目标,但首先我要向你說明:後面的一切工作都是在一台沒有強大 gpu 的一年前的 macbook 上完成的。
另外說明一點,因為我有一塊內建英特爾顯示卡,而不是英偉達的 gpu,是以我決定使用 opencl caffe 分支:https://github.com/bvlc/caffe/tree/opencl,它在我的筆記本電腦上效果良好!
當你安裝完 caffe 之後,你應該有或能夠做下列事情:
一個包含了你建構的 caffe 的目錄。如果你是按标準方式做的,應該會有一個 build/ 目錄包含了運作 caffe 所需的一切、捆綁的 python 等等,build/ 的父目錄将是你的 caffe_root(後面我們會用到它)
運作 make test && make runtest,應該會通過
安裝了所有的 python 依賴包之後(在 python/ 中執行 for req in $(cat requirements.txt); do pip install $req; done;運作 make pycaffe && make pytest 應該會通過
你也應該運作 make distribute 以在 distribute/ 中建立一個帶有所有必要的頭檔案、二進制檔案等的可分發的 caffe 版本
在我的機器上,caffe 完全建構後,我的 caffe_root 目錄有以下基本布局:
caffe/ build/ python/ lib/ tools/ caffe ← this is our main binary distribute/ include/ bin/ proto/
到現在,我們有了訓練、測試和程式設計神經網絡所需的一切。下一節我們會為 caffe 增加一個使用者友好的基于網頁的前端 digits,這能讓我們對網絡的訓練和測試變得更加簡單。
安裝 digits
digits 位址:https://github.com/nvidia/digits
英偉達的深度學習 gpu 訓練系統(deep learning gpu training system/digits)是一個用于訓練神經網絡的 bsd 授權的 python 網頁應用。盡管我們可以在 caffe 中用指令行或代碼做到 digits 所能做到的一切,但使用 digits 能讓我們的工作變得更加簡單。而且因為 digits 有很好的可視化、實時圖表等圖形功能,我覺得使用它也能更有樂趣。因為你正在嘗試和探索學習,是以我強烈推薦你從 digits 開始。
在 https://github.com/nvidia/digits/tree/master/docs 有一些非常好的文檔,包括一些安裝、配置和啟動的頁面。我強烈建議你在繼續之前通讀一下。我并不是一個使用 digits 的專家,如果有問題可以在公開的 digits 使用者組查詢或詢問:https://groups.google.com/forum/#!forum/digits-users
安裝 digits 的方式有很多種,從 docker 到 linux 上的 pre-baked package,或者你也可以從源代碼建構。我用的 mac,是以我就是從源代碼建構的。
注:在我的實踐中,我使用了 github 上未釋出的 digits 版本:https://github.com/nvidia/digits/commit/81be5131821ade454eb47352477015d7c09753d9
因為 digits 隻是一些 python 腳本,是以讓它們工作起來很簡單。在啟動伺服器之前你要做的事情是設定一個環境變量,告訴 digits 你的 caffe_root 的位置在哪裡:
export caffe_root=/path/to/caffe ./digits-devserver
注:在 mac 上,這些伺服器腳本出現了一些問題,可能是因為我的 python 二進制檔案叫做 python2,其中我隻有 python2.7。
你可以在 /usr/bin 中 symlink 它或在你的系統上修改 digits 啟動腳本以使用合适的二進制檔案。
一旦伺服器啟動,你可以在你的浏覽器中通過 http://localhost:5000 來完成一切後續工作。
訓練一個神經網絡
訓練神經網絡涉及到幾個步驟:
1. 準備一個帶有分類圖像的資料集
2. 定義網絡架構
3. 使用準備好的資料集訓練和驗證這個網絡
下面我們會做這三個步驟,以展現從頭開始和使用預訓練的網絡之間的差異,同時也展示如何使用 caffe 和 digits 上最常用的兩個預訓練的網絡 alexnet、 googlenet。
對于我們的訓練,我們将使用一個海豚(dolphins)和海馬(seahorses)圖像的小資料集。這些圖像放置在 data/dolphins-and-seahorses。你至少需要兩個類别,可以更多(有些我們将使用的網絡在 1000 多個類别上進行了訓練)。我們的目标是:給我們的網絡展示一張圖像,它能告訴我們圖像中的是海豚還是海馬。
準備資料集
dolphins-and-seahorses/ dolphin/ image_0001.jpg image_0002.jpg image_0003.jpg ... seahorse/
最簡單的開始方式就是将你的圖檔按不同類别建立目錄:
在上圖中的每一個目錄都是按将要分類的類别建立的,所建檔案夾目錄下是将以用于訓練和驗證的圖檔。
問:所有待分類和驗證的圖檔必須是同樣大小嗎?檔案夾的命名有影響嗎?
回答都是「否」。圖檔的大小會在圖檔輸入神經網絡之前進行規範化處理,我們最終需要的圖檔大小為 256×256 像素的彩色圖檔,但是 digits 可以很快地自動裁切或縮放(我們采用縮放)我們的圖像。檔案夾的命名沒有任何影響——重要的是其所包含的圖檔種類。
問:我能對這些類别做更精細的區分嗎?
當然可以。詳見 https://github.com/nvidia/digits/blob/digits-4.0/docs/imagefolderformat.md。
我們要用這些圖檔來建立一個新的資料集,準确的說是一個分類資料集(classification dataset)。
我們會使用 digits 的預設設定,并把我們的訓練圖檔檔案路徑設定到 data/dolphins-and-seahorses 檔案夾。如此一來,digits 将會使用這些标簽(dolphin 和 seahorse)來建立一個圖像縮放過的資料集——圖檔的大小将會是 256×256,其中 75% 的為訓練圖檔,25% 的為測試圖檔。
給你的資料集起一個名字,如 dolphins-and-seahorses,然後滑鼠點選建立(create)。
通過上面的步驟我們已經建立了一個資料集了,在我的筆記本上隻需要 4 秒就可以完成。最終在所建的資料集裡有 2 個類别的 92 張訓練圖檔(其中 49 張 dolphin,43 張 seahorse),另外還有 30 張驗證圖檔(16 張 dolphin 和 14 張 seahorse)。不得不說這的确是一個非常小的資料集,但是對我們的示範試驗和 digits 操作學習來說已經足夠了,因為這樣網絡的訓練和驗證就不會用掉太長的時間了。
你可以在這個資料庫檔案夾裡檢視壓縮之後的圖檔。
訓練嘗試 1:從頭開始
回到 digits 的首頁,我們需要建立一個新的分類模型(classification model):
我們将開始用上一步所建立的 dolphins-and-seahorses 資料集來訓練模型,仍然使用 digits 的預設設定。對于第一個神經網絡模型,我們可以從提供的神經網絡架構中選取一個既有的标準模型,即 alexnet。alexnet 的網絡結構在 2012 年的計算機視覺競賽 imagenet 中獲勝過(imagenet 為計算機視覺頂級比賽)。在 imagenet 競賽裡需要完成 120 萬張圖檔中 1000 多類圖檔的分類。
caffe 使用結構化文本檔案(structured text files)來定義網絡架構,其所使用的文本檔案是基于谷歌的 protocol buffer。你可以閱讀 caffe 采用的方案:https://github.com/bvlc/caffe/blob/master/src/caffe/proto/caffe.proto。其中大部分内容在這一部分的神經網絡訓練的時候都不會用到,但是了解這些構架對于使用者還是很有用的,因為在後面的步驟裡我們将會對它們進行調整。alexnet 的 prototxt 檔案是這樣的,一個執行個體: https://github.com/bvlc/caffe/blob/master/models/bvlc_alexnet/train_val.prototxt。
我們将會對這個神經網絡進行 30 次 epochs,這意味着網絡将會進行學習(運用我們的訓練圖檔)并自行測試(運用我們的測試圖檔),然後根據訓練的結果調整網絡中各項參數的權重值,如此重複 30 次。每一次 epoch 都會輸出一個分類準确值(accuracy,介于 0% 到 100% 之間,當然值越大越好)和一個損失度(loss,所有錯誤分類的比率,值越小越好)。理想的情況是我們希望所訓練的網絡能夠有較高的準确率(accuracy)和較小的損失度(loss)。
初始訓練的時候,所訓練網絡的準确率低于 50%。這是情理之中的,因為第一次 epoch,網絡隻是在随意猜測圖檔的類别然後任意設定權重值。經過多次 epochs 之後,最後能夠有 87.5% 的準确率,和 0.37 的損失度。完成 30 次的 epochs 隻需不到 6 分鐘的時間。
我們可以上傳一張圖檔或者用一個 url 位址的圖檔來測試訓練完的網絡。我們來測試一些出現在我們訓練和測試資料集中的圖檔:
網絡的分類結果非常完美,當我們測試一些不屬于我們訓練和測試資料集的其他圖檔時:
分類的準确率直接掉下來了,誤把 seahorse 分類為 dolphin,更糟糕的是網絡對這樣的錯誤分類有很高的置信度。
事實是我們的資料集太小了,根本無法用來訓練一個足夠好的神經網絡。我們需要數萬乃至數百萬張圖檔才能訓練一個有用的神經網絡,用這麼多的圖檔也意味着需要很強勁的計算能力來完成所有的計算過程。
訓練嘗試 2:微調 alexnet
怎麼微調網絡
從頭設計一個神經網絡,收集足量的用以訓練這個網絡的資料(如,海量的圖檔),并在 gpu 上運作數周來完成網絡的訓練,這些條件遠非我們大多數人可以擁有。能夠以更加實際——用較小一些的資料集來進行訓練,我們運用一個稱為遷移學習(transfer learning)或者說微調(fine tuning)的技術。fine tuning 借助深度學習網絡的輸出,運用已訓練好的神經網絡來完成最初的目辨別别。
試想使用神經網絡的過程就好比使用一個雙目望遠鏡看遠處的景物。那麼當你第一次把雙目望遠鏡放到眼前的時候,你看到的是一片模糊。當你開始調焦的時候,你慢慢可以看出顔色、線、形狀,然後最終你可以分辨出鳥的外形,在此之上你進一步調試進而可以識别出鳥的種類。
在一個多層網絡中,最開始的幾層是用于特征提取的(如,邊線),之後的網絡層通過這些提取的特征來識别外形「shape」(如,一個輪子,一隻眼睛),然後這些輸出将會輸入到最後的分類層,分類層将會根據之前所有層的特征積累來确定待分類目标的種類(如,判斷為貓還是狗)。一個神經網絡從像素、線形、眼睛、兩隻眼睛的确定位置,這樣的步驟來一步步确立分類目标的種類(這裡是貓)。
我們在這裡所做的就是給新的分類圖檔指定一個已訓練好的網絡用于初始化網絡的權重值,而不是用新建構網絡自己的初始權重。因為已訓練好的網絡已經具備「看」圖檔特征的功能的,我們所需要的是這個已訓練的網絡能「看」我們所建圖檔資料集——這一具體任務中特定類型的圖檔。我們不需要從頭開始訓練大部分的網絡層——我們隻需要将已訓練網絡中已經學習的層轉接到我們建立的分類任務上來。不同于我們的上一次的實驗,在上次實驗中網絡的初始權重值是随機賦予的,這次實驗中我們直接使用已經訓練網絡的最終權重值作為我們建立網絡的初始權重值。但是,必須去除已經訓練好的網絡的最後分類層并用我們自己的圖檔資料集再次訓練這個網絡,即在我們自己的圖檔類上微調已訓練的網絡。
對于這次實驗,我們需要一個與經由與我們訓練資料足夠相似的資料集所訓練的網絡,隻有這樣已訓練網絡的權重值才對我們有用。幸運的是,我們下面所使用的網絡是在海量資料集(自然圖檔集 imagenet)上訓練得到的,這樣的已訓練網絡能滿足大部分分類任務的需要。
這種技術已經被用來做一些很有意思的任務如醫學圖像的眼疾篩查,從海裡收集到的顯微圖像中識别浮遊生物物種,給 flickr 上的圖檔進行藝術風格分類。
完美的完成這些任務,就像所有的機器學習一樣,你需要很好的了解資料以及神經網絡結構——你必須對資料的過拟合格外小心,你或許需要調整一些層的設定,也很有可能需要插入一些新的網絡層,等等類似的調整。但是,我們的經驗表明大部分時候還是可以完成任務的「just work」,而且用我們這麼原始的方法去簡單嘗試一下看看結果如何是很值得的。
上傳預訓練網絡
在我們的第一次嘗試中,我們使用了 alexnet 的架構,但是網絡各層的權重是随機分布的。我們需要做的就是需要下載下傳使用一個已經經過大量資料集訓練的 alexnet。
alexnet 的快照(snapshots)如下,可供下載下傳:https://github.com/bvlc/caffe/tree/master/models/bvlc_alexnet。我們需要一個二進制檔案 .caffemodel,含有訓練好的權重,可供下載下傳 http://dl.caffe.berkeleyvision.org/bvlc_alexnet.caffemodel。在你下載下傳這些與訓練模型的時候,讓我們來趁機多學點東西。2014 年的 imagenet 大賽中,谷歌利用其開源的 googlenet (https://research.google.com/pubs/pub43022.html)(一個 22 層的神經網絡)赢得了比賽。googlenet 的快照如下,可供下載下傳: https://github.com/bvlc/caffe/tree/master/models/bvlc_googlenet。在具備了所有的預訓練權重之後,我們還需要.caffemodel 檔案,可供下載下傳:http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel.
有了 .caffemodel 檔案之後,我們既可以将它們上傳到 digits 當中。在 digits 的首頁當中找到預訓練模型(pretrained models)的标簽,選擇上傳預訓練模型(upload pretrained model):
對于這些預訓練的模型,我們可以使用 digits 的預設值(例如,大小為 256×256 像素的彩色圖檔)。我們隻需要提供 weights (.caffemodel) 和 model definition (original.prototxt)。點選這些按鈕來選擇檔案。
模型的定義,googlenet 我們可以使用 https://github.com/bvlc/caffe/blob/master/models/bvlc_googlenet/train_val.prototxt,alexnet 可以使用 https://github.com/bvlc/caffe/blob/master/models/bvlc_alexnet/train_val.prototxt。我們不打算使用這些網絡的分類标簽,是以我們可以直接添加一個 labels.txt 檔案:
在 alexnet 和 googlenet 都重複這一過程,因為我們在之後的步驟當中兩者我們都會用到。
問題:有其他的神經網絡能作為微調的基礎嗎?
回答:caffe model zoo 有許多其他預訓練神經網絡可供使用,詳情請檢視 https://github.com/bvlc/caffe/wiki/model-zoo
使用預訓練 caffe 模型進行人工神經網絡訓練就類似于從頭開始實作,雖然我們隻需要做一些調整。首先我們需要将學習速率由 0.01 調整到 0.001,因為我們下降步長不需要這麼大(我們會進行微調)。我們還将使用預訓練網絡(pretrained network)并根據實際修改它。
在預訓練模型的定義(如原文本)中,我們需要對最終完全連接配接層(輸出結果分類的地方)的所有 references 重命名。我們這樣做是因為我們希望模型能從現在的資料集重新學習新的分類,而不是使用以前最原始的訓練資料(我們想将目前最後一層丢棄)。我們必須将最後的全連接配接層由「fc8」重命名為一些其他的(如 fc9)。最後我們還需要将分類類别從 1000 調整為 2,這裡需要調整 num_output 為 2。
下面是我們需要做的一些調整代碼:
我已經将所有的改進檔案放在 src/alexnet-customized.prototxt 裡面。
這一次,我們的準确率由 60% 多先是上升到 87.5%,然後到 96% 一路到 100%,同時損失度也穩步下降。五分鐘後,我們的準确率到達了 100%,損失也隻有 0.0009。
測試海馬圖像時以前的網絡會出錯,現在我們看到完全相反的結果,即使是小孩畫的海馬,系統也 100% 确定是海馬,海豚的情況也一樣。
即使你認為可能很困難的圖像,如多個海豚擠在一起,并且它們的身體大部分在水下,系統還是能識别。
訓練嘗試 3:微調 googlenet
像前面我們微調 alexnet 模型那樣,同樣我們也能用 googlenet。修改這個網絡會有點棘手,因為你已經定義了三層全連接配接層而不是隻有一層。
在這個案例中微調 googlenet,我們需要再次建立一個新的分類模型:我們需要重命名三個全連接配接分類層的所有 references,即 loss1/classifier、loss2/classifier 和 loss3/classifier,并重新定義結果類别數(num_output: 2)。下面是我們需要将三個分類層重新命名和從 1000 改變輸出類别數為 2 的一些代碼實作。
我己經将完整的檔案放在 src/googlenet-customized.prototxt 裡面。
問題:這些神經網絡的原文本(prototext)定義需要做什麼修改嗎?我們修改了全連接配接層名和輸出結果分類類别數,那麼在什麼情況下其它參數也能或也需要修改的?
回答:問得好,這也是我有一些疑惑的地方。例如,我知道我們能「固定」确切的神經網絡層級,并保證層級之間的權重不改變。但是要做其它的一些改變就涉及到了解我們的神經網絡層級是如何起作用的,這已經超出了這份入門向導的範圍,同樣也超出了這份向導作者現有的能力。
就像我們對 alexnet 進行微調,将下降的學習速率由 0.01 減少十倍到 0.001 一樣。
問:還有什麼修改是對這些網絡微調有意義的?周遊所有資料的次數(numbers of epochs)不同怎麼樣,改變批量梯度下降的大小(batch sizes)怎麼樣,求解器的類型(adam、 adadelta 和 adagrad 等)呢?還有下降學習速率、政策(exponential decay、inverse decay 和 sigmoid decay 等)、步長和 gamma 值呢?
問得好,這也是我有所疑惑的。我對這些隻有一個模糊的了解,如果你知道在訓練中如何修改這些值,那麼我們很可能做出些改進,并且這需要更好的文檔。
因為 googlenet 比 alexnet 有更複雜的網絡構架,是以微調需要更多的時間。在我的筆記本電腦上,用我們的資料集重新訓練 googlenet 需要 10 分鐘,這樣才能實作 100% 的準确率,同時損失函數值隻有 0.0070。
正如我們看到的 alexnet 微調版本,我們修改過的 googlenet 表現得十分驚人,是我們目前最好的。
使用我們的模型
我們的網絡在訓練和檢測之後,就可以下載下傳并且使用了。我們利用 digits 訓練的每一個模型都有了一下載下傳模型(download model)鍵,這也是我們在訓練過程中選擇不同 snapshots 的一種方法(例如 epoch #30):
在點選 download model 之後,你就會下載下傳一個 tar.gz 的文檔,裡面包含以下檔案:
在 caffe 文檔中對我們所建立的模型使用有一段非常好的描述。如下:
一個網絡是由其設計,也就是設計(prototxt)和權重(.caffemodel)決定。在網絡被訓練的過程中,網絡權重的目前狀态被存儲在一個.caffemodel 中。這些東西我們可以從訓練/檢測階段移到生産階段。在它的目前狀态中,網絡的設計并不是為了部署的目的。在我們可以将我們的網絡作為産品釋出之前,我們通常需要通過幾種方法對它進行修改: 1. 移除用來訓練的資料層,因為在分類時,我們已經不再為資料提供标簽了。 2. 移除所有依賴于資料标簽的層。 3. 設定接收資料的網絡。 4. 讓網絡輸出結果。
digits 已經為我們做了這些工作,它已經将我們 prototxt 檔案中所有不同的版本都分離了出來。這些文檔我們在使用網絡時會用到:
deploy.prototxt -是關于網絡的定義,準備接收圖像輸入資料
mean.binaryproto - 我們的模型需要我們減去它處理的每張圖像的圖像均值,所産生的就是平均圖像(mean image)。
labels.txt - 标簽清單 (dolphin, seahorse),以防我們想要把它們列印出來,否則隻有類别編号。
snapshot_iter_90.caffemodel -這些是我們網絡的訓練權重。
利用這些檔案,我們可以通過多種方式對新的圖像進行分類。例如,在 caffe_root 中,我們可以使用 build/examples/cpp_classification/classification.bin 來對一個圖像進行分類:
$ cd $caffe_root/build/examples/cpp_classification $ ./classification.bin deploy.prototxt snapshot_iter_90.caffemodel mean.binaryproto labels.txt dolphin1.jpg
這會産生很多的調試文本,後面會跟着對這兩種分類的預測結果:
0.9997 -「dolphin」 0.0003 -「seahorse」
你可以在這個 caffe 案例中檢視完整的 c++ 源碼:https://github.com/bvlc/caffe/tree/master/examples
使用 python 界面和 digits 進行分類的案例:https://github.com/nvidia/digits/tree/master/examples/classification
最後,caffe 的案例中還有一個非常好的 python 示範:https://github.com/bvlc/caffe/blob/master/examples/00-classification.ipynb
我希望可以有更多更好的代碼案例、api 和預先建立的模型等呈現給大家。老實說,我找到的大多數代碼案例都非常的簡短,并且文檔介紹很少——caffe 的文檔雖然有很多,但也有好有壞。對我來說,這似乎意味着會有人為初學者建立比 caffe 更進階的工具。如果說在進階語言中出現了更加簡單的模型,我可以用我們的模型「做正确的事情」;應該有人将這樣的設想付諸行動,讓使用 caffe 模型變得像使用 digits 訓練它們一樣簡單。當然我們不需要對這個模型或是 caffe 的内部了解那麼多。雖然目前我還沒有使用過 deepdetect,但是它看起來非常的有趣,另外仍然還有其他我不知道的工具。
結果
文章開頭提到,我們的目标是編寫一個使用神經網絡對 data/untrained-samples 中所有的圖像進行高準确度預測的程式。這些海豚和海馬的圖像是在訓練資料或是驗證資料時候從未使用過的。
未被訓練過的海豚圖像

未被訓練過的海馬圖像
接下來,讓我們一起來看看在這一挑戰當中存在的三次嘗試的結果:
模型嘗試 1: 從零開始建構 alexnet(第 3 位)
image
dolphin
seahorse
result
<a>dolphin1.jpg</a>
71.11%
28.89%
<a>dolphin2.jpg</a>
99.2%
0.8%
<a>dolphin3.jpg</a>
63.3%
36.7%
<a>seahorse1.jpg</a>
95.04%
4.96%
<a>seahorse2.jpg</a>
56.64%
43.36
<a>seahorse3.jpg</a>
7.06%
92.94%
模型嘗試 2:微調 alexnet(第 2 位)
99.1%
0.09%
99.5%
0.05%
91.48%
8.52%
0%
100%
模型嘗試 3:微調 googlenet(第 1 位)
99.86%
0.14%
0.5%
0.02%
99.98%
結論
我們的模型運作非常好,這可能是通過調整一個預訓練的網絡完成的。很顯然,海豚 vs. 海馬的例子有一些牽強,資料集也非常的有限——如果我們想擁有一個強大的網絡,那我們确實需要更多、更好的資料。但因為我們的目标是去檢測神經網絡的工具和工作流程,是以這其實是一種很理想的情況,尤其是它不需要昂貴的裝置或是花費大量的時間。
綜上所述,我希望這些經驗能夠讓那些一直對機器學習望而卻步的人擺脫對開始學習的恐懼。在你看到它的作用之後,再決定是否要在學習積極學習和神經網絡理論中投入時間要簡單很多。現在你已經對它的設定和工作方法都已經有所了解,之後你便可以嘗試去做一些分類。你也可以利用 caffe 和 digits 去做一些其他的事情,例如,在圖像中尋找物體,或是進行圖像分割。
原文連結:https://github.com/humphd/have-fun-with-machine-learning/blob/master/readme.md
本文來源于"中國人工智能學會",原文發表時間" 2017-01-03 "