如何用Python和深度神經(jīng)網(wǎng)絡(luò)識(shí)別圖像?
我看見的時(shí)候自然會(huì)知道
只需要10幾行Python代碼,你就能構(gòu)建自己的機(jī)器視覺(jué)模型,快速準(zhǔn)確識(shí)別海量圖片??靵?lái)試試吧!
0、視覺(jué)
進(jìn)化的作用,讓人類對(duì)圖像的處理非常高效。
這里,我給你展示一張照片。
如果我這樣問(wèn)你:
你能否分辨出圖片中哪個(gè)是貓,哪個(gè)是狗?
你可能立即會(huì)覺(jué)得自己遭受到了莫大的侮辱。并且大聲質(zhì)問(wèn)我:你覺(jué)得我智商有問(wèn)題嗎?!
息怒。
換一個(gè)問(wèn)法:
你能否把自己分辨貓狗圖片的方法,描述成嚴(yán)格的規(guī)則,教給計(jì)算機(jī),以便讓它替我們?nèi)祟惙直娉汕先f(wàn)張圖片呢?
對(duì)大多數(shù)人來(lái)說(shuō),此時(shí)感受到的,就不是羞辱,而是壓力了。
如果你是個(gè)有毅力的人,可能會(huì)嘗試各種判別標(biāo)準(zhǔn):圖片某個(gè)位置的像素顏色、某個(gè)局部的邊緣形狀、某個(gè)水平位置的連續(xù)顏色長(zhǎng)度……
你把這些描述告訴計(jì)算機(jī),它果然就可以判斷出左邊的貓和右邊的狗了。
問(wèn)題是,計(jì)算機(jī)真的會(huì)分辨貓狗圖片了嗎?
我又拿出一張照片給你。
你會(huì)發(fā)現(xiàn),幾乎所有的規(guī)則定義,都需要改寫。
當(dāng)機(jī)器好不容易可以用近似投機(jī)取巧的方法正確分辨了這兩張圖片里面的動(dòng)物時(shí),我又拿出來(lái)一張新圖片……
幾個(gè)小時(shí)以后,你決定放棄。
別氣餒。
你遭遇到的,并不是新問(wèn)題。就連大法官,也有過(guò)同樣的煩惱。
1964年,美國(guó)***法院的大法官Potter Stewart在“Jacobellis v. Ohio”一案中,曾經(jīng)就某部電影中出現(xiàn)的某種具體圖像分類問(wèn)題,說(shuō)過(guò)一句名言“我不準(zhǔn)備就其概念給出簡(jiǎn)短而明確的定義……但是,我看見的時(shí)候自然會(huì)知道”(I know it when I see it)。
原文如下:
I shall not today attempt further to define the kinds of material I understand to be embraced within that shorthand description (“hard-core pornography”), and perhaps I could never succeed in intelligibly doing so. But I know it when I see it, and the motion picture involved in this case is not that.
考慮到精神文明建設(shè)的需要,這一段就不翻譯了。
人類沒(méi)法把圖片分辨的規(guī)則詳細(xì)、具體而準(zhǔn)確地描述給計(jì)算機(jī),是不是意味著計(jì)算機(jī)不能辨識(shí)圖片呢?
當(dāng)然不是。
2017年12月份的《科學(xué)美國(guó)人》雜志,就把“視覺(jué)人工智能”(AI that sees like humans)定義為2017年新興技術(shù)之一。
你早已聽說(shuō)過(guò)自動(dòng)駕駛汽車的神奇吧?沒(méi)有機(jī)器對(duì)圖像的辨識(shí),能做到嗎?
你的好友可能(不止一次)給你演示如何用新買的iPhone X做面部識(shí)別解鎖了吧?沒(méi)有機(jī)器對(duì)圖像的辨識(shí),能做到嗎?
醫(yī)學(xué)領(lǐng)域里,計(jì)算機(jī)對(duì)于科學(xué)影像(如X光片)的分析能力,已經(jīng)超過(guò)有多年從業(yè)經(jīng)驗(yàn)的醫(yī)生了。沒(méi)有機(jī)器對(duì)圖像的辨識(shí),能做到嗎?
你可能一下子覺(jué)得有些迷茫了——這難道是奇跡?
不是。
計(jì)算機(jī)所做的,是學(xué)習(xí)。
通過(guò)學(xué)習(xí)足夠數(shù)量的樣本,機(jī)器可以從數(shù)據(jù)中自己構(gòu)建模型。其中,可能涉及大量的判斷準(zhǔn)則。但是,人類不需要告訴機(jī)器任何一條。它是完全自己領(lǐng)悟和掌握的。
你可能會(huì)覺(jué)得很興奮。
那么,下面我來(lái)告訴你一個(gè)更令你興奮的消息——你自己也能很輕易地構(gòu)建圖片分類系統(tǒng)!
不信?請(qǐng)跟著我下面的介紹,來(lái)試試看。
1、數(shù)據(jù)
咱們就不辨識(shí)貓和狗了,這個(gè)問(wèn)題有點(diǎn)不夠新鮮。
咱們來(lái)分辨機(jī)器貓,好不好?
對(duì),我說(shuō)的就是哆啦a夢(mèng)。
把它和誰(shuí)進(jìn)行區(qū)分呢?
一開始我想找霸王龍,后來(lái)覺(jué)得這樣簡(jiǎn)直是作弊,因?yàn)樗麄z長(zhǎng)得實(shí)在差別太大。
既然哆啦a夢(mèng)是機(jī)器人,咱們就另外找個(gè)機(jī)器人來(lái)區(qū)分吧。
一提到機(jī)器人,我立刻就想起來(lái)了它。
對(duì),機(jī)器人瓦力(WALLE)。
我給你準(zhǔn)備好了119張哆啦a夢(mèng)的照片,和80張瓦力的照片。圖片已經(jīng)上傳到了這個(gè)Github項(xiàng)目(https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fwshuyi%2Fdemo-python-image-classification)。
請(qǐng)點(diǎn)擊這個(gè)鏈接(https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fwshuyi%2Fdemo-python-image-classification%2Farchive%2Fmaster.zip),下載壓縮包。然后在本地解壓。作為咱們的演示目錄。
解壓后,你會(huì)看到目錄下有個(gè)image文件夾,其中包含兩個(gè)子目錄,分別是doraemon和walle。
打開其中doraemon的目錄,我們看看都有哪些圖片。
可以看到,哆啦a夢(mèng)的圖片真是五花八門。各種場(chǎng)景、背景顏色、表情、動(dòng)作、角度……不一而足。
這些圖片,大小不一,長(zhǎng)寬比例也各不相同。
我們?cè)賮?lái)看看瓦力,也是類似的狀況。
數(shù)據(jù)已經(jīng)有了,下面我們來(lái)準(zhǔn)備一下環(huán)境配置。
2、環(huán)境
我們使用Python集成運(yùn)行環(huán)境Anaconda。
請(qǐng)到這個(gè)網(wǎng)址(https://link.jianshu.com/?t=https%3A%2F%2Fwww.continuum.io%2Fdownloads) 下載***版的Anaconda。
下拉頁(yè)面,找到下載位置。根據(jù)你目前使用的系統(tǒng),網(wǎng)站會(huì)自動(dòng)推薦給你適合的版本下載。我使用的是macOS,下載文件格式為pkg。
下載頁(yè)面區(qū)左側(cè)是Python 3.6版,右側(cè)是2.7版。請(qǐng)選擇2.7版本。
雙擊下載后的pkg文件,根據(jù)中文提示一步步安裝即可。
安裝好Anaconda后,我們需要安裝TuriCreate。
請(qǐng)到你的“終端”(Linux, macOS)或者“命令提示符”(Windows)下面,進(jìn)入咱們剛剛下載解壓后的樣例目錄。
執(zhí)行以下命令,我們來(lái)創(chuàng)建一個(gè)Anaconda虛擬環(huán)境,名字叫做turi。
然后,我們激活turi虛擬環(huán)境。
在這個(gè)環(huán)境中,我們安裝***版的TuriCreate。
安裝完畢后,執(zhí)行:
這樣就進(jìn)入到了Jupyter筆記本環(huán)境。我們新建一個(gè)Python 2筆記本。
這樣就出現(xiàn)了一個(gè)空白筆記本。
點(diǎn)擊左上角筆記本名稱,修改為有意義的筆記本名“demo-python-image-classification”。
準(zhǔn)備工作完畢,下面我們就可以開始編寫程序了。
3、代碼
首先,我們讀入TuriCreate軟件包。它是蘋果并購(gòu)來(lái)的機(jī)器學(xué)習(xí)框架,為開發(fā)者提供非常簡(jiǎn)便的數(shù)據(jù)分析與人工智能接口。
- import turicreate as tc
 
我們指定圖像所在的文件夾image。
- img_folder = 'image'
 
前面介紹了,image下,有哆啦a夢(mèng)和瓦力這兩個(gè)文件夾。注意如果將來(lái)你需要辨別其他的圖片(例如貓和狗),請(qǐng)把不同類別的圖片也在image中分別存入不同的文件夾,這些文件夾的名稱就是圖片的類別名(cat和dog)。
然后,我們讓TuriCreate讀取所有的圖像文件,并且存儲(chǔ)到data數(shù)據(jù)框。
- data = tc.image_analysis.load_images(img_folder, with_path=True)
 
這里可能會(huì)有錯(cuò)誤信息。
- Unsupported image format. Supported formats are JPEG and PNG file: /Users/wsy/Dropbox/var/wsywork/learn/demo-workshops/demo-python-image-classification/image/walle/.DS_Store
 
本例中提示,有幾個(gè).DS_Store文件,TuriCreate不認(rèn)識(shí),無(wú)法當(dāng)作圖片來(lái)讀取。
這些.DS_Store文件,是蘋果macOS系統(tǒng)創(chuàng)建的隱藏文件,用來(lái)保存目錄的自定義屬性,例如圖標(biāo)位置或背景顏色。
我們忽略這些信息即可。
下面,我們來(lái)看看,data數(shù)據(jù)框里面都有什么。
- data
 
可以看到,data包含兩列信息,***列是圖片的地址,第二列是圖片的長(zhǎng)寬描述。
因?yàn)槲覀兪褂昧?19張哆啦a夢(mèng)圖片,80張瓦力圖片,所以總共的數(shù)據(jù)量是199條。數(shù)據(jù)讀取完整性驗(yàn)證通過(guò)。
下面,我們需要讓TuriCreate了解不同圖片的標(biāo)記(label)信息。也就是,一張圖片到底是哆啦a夢(mèng),還是瓦力呢?
這就是為什么一開始,你就得把不同的圖片分類保存到不同的文件夾下面。
此時(shí),我們利用文件夾名稱,來(lái)給圖片打標(biāo)記。
- data['label'] = data['path'].apply(lambda path: 'doraemon' if 'doraemon' in path else 'walle')
 
這條語(yǔ)句,把doraemon目錄下的圖片,在data數(shù)據(jù)框里打標(biāo)記為doraemon。反之就都視為瓦力(walle)。
我們來(lái)看看標(biāo)記之后的data數(shù)據(jù)框。
- data
 
可以看到,數(shù)據(jù)的條目數(shù)量(行數(shù))是一致的,只是多出來(lái)了一個(gè)標(biāo)記列(label),說(shuō)明圖片的類別。
我們把數(shù)據(jù)存儲(chǔ)一下。
- data.save('doraemon-walle.sframe')
 
這個(gè)存儲(chǔ)動(dòng)作,讓我們保存到目前的數(shù)據(jù)處理結(jié)果。之后的分析,只需要讀入這個(gè)sframe文件就可以了,不需要從頭去跟文件夾打交道了。
從這個(gè)例子里,你可能看不出什么優(yōu)勢(shì)。但是想象一下,如果你的圖片有好幾個(gè)G,甚至幾個(gè)T,每次做分析處理,都從頭讀取文件和打標(biāo)記,就會(huì)非常耗時(shí)。
我們深入探索一下數(shù)據(jù)框。
TuriCreate提供了非常方便的explore()函數(shù),幫助我們直觀探索數(shù)據(jù)框信息。
- data.explore()
 
這時(shí)候,TuriCreate會(huì)彈出一個(gè)頁(yè)面,給我們展示數(shù)據(jù)框里面的內(nèi)容。
原先打印data數(shù)據(jù)框,我們只能看到圖片的尺寸,此時(shí)卻可以瀏覽圖片的內(nèi)容。
如果你覺(jué)得圖片太小,沒(méi)關(guān)系。把鼠標(biāo)懸停在某張縮略圖上面,就可以看到大圖。
數(shù)據(jù)框探索完畢。我們回到notebook下面,繼續(xù)寫代碼。
這里我們讓TuriCreate把data數(shù)據(jù)框分為訓(xùn)練集合和測(cè)試集合。
- train_data, test_data = data.random_split(0.8, seed=2)
 
訓(xùn)練集合是用來(lái)讓機(jī)器進(jìn)行觀察學(xué)習(xí)的。電腦會(huì)利用訓(xùn)練集合的數(shù)據(jù)自己建立模型。但是模型的效果(例如分類的準(zhǔn)確程度)如何?我們需要用測(cè)試集來(lái)進(jìn)行驗(yàn)證測(cè)試。
這就如同老師不應(yīng)該把考試題目都拿來(lái)給學(xué)生做作業(yè)和練習(xí)一樣。只有考學(xué)生沒(méi)見過(guò)的題,才能區(qū)分學(xué)生是掌握了正確的解題方法,還是死記硬背了作業(yè)答案。
我們讓TuriCreate把80%的數(shù)據(jù)分給了訓(xùn)練集,把剩余20%的數(shù)據(jù)拿到一邊,等待測(cè)試。這里我設(shè)定了隨機(jī)種子取值為2,這是為了保證數(shù)據(jù)拆分的一致性。以便重復(fù)驗(yàn)證我們的結(jié)果。
好了,下面我們讓機(jī)器開始觀察學(xué)習(xí)訓(xùn)練集中的每一個(gè)數(shù)據(jù),并且嘗試自己建立模型。
下面代碼***次執(zhí)行的時(shí)候,需要等候一段時(shí)間。因?yàn)門uriCreate需要從蘋果開發(fā)者官網(wǎng)上下載一些數(shù)據(jù)。這些數(shù)據(jù)大概100M左右。
需要的時(shí)長(zhǎng),依你和蘋果服務(wù)器的連接速度而異。反正在我這兒,下載挺慢的。
好在只有***次需要下載。之后的重復(fù)執(zhí)行,會(huì)跳過(guò)下載步驟。
- model = tc.image_classifier.create(train_data, target='label')
 
下載完畢后,你會(huì)看到TuriCreate的訓(xùn)練信息。
- Resizing images...
 - Performing feature extraction on resized images...
 - Completed 168/168
 - PROGRESS: Creating a validation set from 5 percent of training data. This may take a while.
 - You can set ``validation_set=None`` to disable validation tracking.
 
你會(huì)發(fā)現(xiàn),TuriCreateh會(huì)幫助你把圖片進(jìn)行尺寸變換,并且自動(dòng)抓取圖片的特征。然后它會(huì)從訓(xùn)練集里面抽取5%的數(shù)據(jù)作為驗(yàn)證集,不斷迭代尋找***的參數(shù)配置,達(dá)到***模型。
這里可能會(huì)有一些警告信息,忽略就可以了。
當(dāng)你看到下列信息的時(shí)候,意味著訓(xùn)練工作已經(jīng)順利完成了。
可以看到,幾個(gè)輪次下來(lái),不論是訓(xùn)練的準(zhǔn)確度,還是驗(yàn)證的準(zhǔn)確度,都已經(jīng)非常高了。
下面,我們用獲得的圖片分類模型,來(lái)對(duì)測(cè)試集做預(yù)測(cè)。
- predictions = model.predict(test_data)
 
我們把預(yù)測(cè)的結(jié)果(一系列圖片對(duì)應(yīng)的標(biāo)記序列)存入了predictions變量。
然后,我們讓TuriCreate告訴我們,在測(cè)試集上,我們的模型表現(xiàn)如何。
先別急著往下看,猜猜結(jié)果正確率大概是多少?從0到1之間,猜測(cè)一個(gè)數(shù)字。
猜完后,請(qǐng)繼續(xù)。
- metrics = model.evaluate(test_data)
 - print(metrics['accuracy'])
 
這就是正確率的結(jié)果:
- 0.967741935484
 
我***次看見的時(shí)候,震驚不已。
我們只用了100多個(gè)數(shù)據(jù)做了訓(xùn)練,居然就能在測(cè)試集(機(jī)器沒(méi)有見過(guò)的圖片數(shù)據(jù))上,獲得如此高的辨識(shí)準(zhǔn)確度。
為了驗(yàn)證這不是準(zhǔn)確率計(jì)算部分代碼的失誤,我們來(lái)實(shí)際看看預(yù)測(cè)結(jié)果。
- predictions
 
這是打印出的預(yù)測(cè)標(biāo)記序列:
- dtype: str
 - Rows: 31
 - ['doraemon', 'doraemon', 'doraemon', 'doraemon', 'walle', 'doraemon', 'walle', 'doraemon', 'walle', 'walle', 'doraemon', 'doraemon', 'doraemon', 'doraemon', 'doraemon', 'walle', 'doraemon', 'doraemon', 'walle', 'walle', 'doraemon', 'doraemon', 'walle', 'walle', 'walle', 'doraemon', 'doraemon', 'walle', 'walle', 'doraemon', 'walle']
 
再看看實(shí)際的標(biāo)簽。
- test_data['label']
 
這是實(shí)際標(biāo)記序列:
- dtype: str
 - Rows: 31
 - ['doraemon', 'doraemon', 'doraemon', 'doraemon', 'walle', 'doraemon', 'walle', 'walle', 'walle', 'walle', 'doraemon', 'doraemon', 'doraemon', 'doraemon', 'doraemon', 'walle', 'doraemon', 'doraemon', 'walle', 'walle', 'doraemon', 'doraemon', 'walle', 'walle', 'walle', 'doraemon', 'doraemon', 'walle', 'walle', 'doraemon', 'walle']
 
我們查找一下,到底哪些圖片預(yù)測(cè)失誤了。
你當(dāng)然可以一個(gè)個(gè)對(duì)比著檢查。但是如果你的測(cè)試集有成千上萬(wàn)的數(shù)據(jù),這樣做效率就會(huì)很低。
我們分析的方法,是首先找出預(yù)測(cè)標(biāo)記序列(predictions)和原始標(biāo)記序列(test_data['label'])之間有哪些不一致,然后在測(cè)試數(shù)據(jù)集里展示這些不一致的位置。
- test_data[test_data['label'] != predictions]
 
我們發(fā)現(xiàn),在31個(gè)測(cè)試數(shù)據(jù)中,只有1處標(biāo)記預(yù)測(cè)發(fā)生了失誤。原始的標(biāo)記是瓦力,我們的模型預(yù)測(cè)結(jié)果是哆啦a夢(mèng)。
我們獲得這個(gè)數(shù)據(jù)點(diǎn)對(duì)應(yīng)的原始文件路徑。
- wrong_pred_img_path = test_data[predictions != test_data['label']][0]['path']
 
然后,我們把圖像讀取到img變量。
- img = tc.Image(wrong_pred_img_path)
 
用TuriCreate提供的show()函數(shù),我們查看一下這張圖片的內(nèi)容。
- img.show()
 
因?yàn)樯疃葘W(xué)習(xí)的一個(gè)問(wèn)題在于模型過(guò)于復(fù)雜,所以我們無(wú)法精確判別機(jī)器是怎么錯(cuò)誤辨識(shí)這張圖的。但是我們不難發(fā)現(xiàn)這張圖片有些特征——除了瓦力以外,還有另外一個(gè)機(jī)器人。
如果你看過(guò)這部電影,應(yīng)該知道兩個(gè)機(jī)器人之間的關(guān)系。這里我們按下不表。問(wèn)題在于,這個(gè)右上方的機(jī)器人圓頭圓腦,看上去與棱角分明的瓦力差別很大。但是,別忘了,哆啦a夢(mèng)也是圓頭圓腦的。
4、原理
按照上面一節(jié)的代碼執(zhí)行后,你應(yīng)該已經(jīng)了解如何構(gòu)建自己的圖片分類系統(tǒng)了。在沒(méi)有任何原理知識(shí)的情況下,你研制的這個(gè)模型已經(jīng)做得非常棒了。不是嗎?
如果你對(duì)原理不感興趣,請(qǐng)?zhí)^(guò)這一部分,看“小結(jié)”。
如果你對(duì)知識(shí)喜歡刨根問(wèn)底,那咱們來(lái)講講原理。
雖然不過(guò)寫了10幾行代碼,但是你構(gòu)建的模型卻足夠復(fù)雜和高大上。它就是傳說(shuō)中的卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network, CNN)。
它是深度機(jī)器學(xué)習(xí)模型的一種。最為簡(jiǎn)單的卷積神經(jīng)網(wǎng)絡(luò)大概長(zhǎng)這個(gè)樣子:
最左邊的,是輸入層。也就是咱們輸入的圖片。本例中,是哆啦a夢(mèng)和瓦力。
在計(jì)算機(jī)里,圖片是按照不同顏色(RGB,即Red, Green, Blue)分層存儲(chǔ)的。就像下面這個(gè)例子。
根據(jù)分辨率不同,電腦會(huì)把每一層的圖片存成某種大小的矩陣。對(duì)應(yīng)某個(gè)行列位置,存的就是個(gè)數(shù)字而已。
這就是為什么,在運(yùn)行代碼的時(shí)候,你會(huì)發(fā)現(xiàn)TuriCreate首先做的,就是重新設(shè)置圖片的大小。因?yàn)槿绻斎雸D片大小各異的話,下面步驟無(wú)法進(jìn)行。
有了輸入數(shù)據(jù),就順序進(jìn)入下一層,也就是卷積層(Convolutional Layer)。
卷積層聽起來(lái)似乎很神秘和復(fù)雜。但是原理非常簡(jiǎn)單。它是由若干個(gè)過(guò)濾器組成的。每個(gè)過(guò)濾器就是一個(gè)小矩陣。
使用的時(shí)候,在輸入數(shù)據(jù)上,移動(dòng)這個(gè)小矩陣,跟原先與矩陣重疊的位置上的數(shù)字做乘法后加在一起。這樣原先的一個(gè)矩陣,就變成了“卷積”之后的一個(gè)數(shù)字。
下面這張動(dòng)圖,很形象地為你解釋了這一過(guò)程。
這個(gè)過(guò)程,就是不斷從一個(gè)矩陣上去尋找某種特征。這種特征可能是某個(gè)邊緣的形狀之類。
再下一層,叫做“池化層”(Pooling Layer)。這個(gè)翻譯簡(jiǎn)直讓人無(wú)語(yǔ)。我覺(jué)得翻譯成“匯總層”或者“采樣層”都要好許多。下文中,我們稱其為“采樣層”。
采樣的目的,是避免讓機(jī)器認(rèn)為“必須在左上角的方格位置,有一個(gè)尖尖的邊緣”。實(shí)際上,在一張圖片里,我們要識(shí)別的對(duì)象可能發(fā)生位移。因此我們需要用匯總采樣的方式模糊某個(gè)特征的位置,將其從“某個(gè)具體的點(diǎn)”,擴(kuò)展成“某個(gè)區(qū)域”。
如果這樣說(shuō),讓你覺(jué)得不夠直觀,請(qǐng)參考下面這張動(dòng)圖。
這里使用的是“***值采樣”(Max-Pooling)。以原先的2x2范圍作為一個(gè)分塊,從中找到***值,記錄在新的結(jié)果矩陣?yán)铩?/p>
一個(gè)有用的規(guī)律是,隨著層數(shù)不斷向右推進(jìn),一般結(jié)果圖像(其實(shí)正規(guī)地說(shuō),應(yīng)該叫做矩陣)會(huì)變得越來(lái)越小,但是層數(shù)會(huì)變得越來(lái)越多。
只有這樣,我們才能把圖片中的規(guī)律信息抽取出來(lái),并且盡量掌握足夠多的模式。
如果你還是覺(jué)得不過(guò)癮,請(qǐng)?jiān)L問(wèn)這個(gè)網(wǎng)站(https://link.jianshu.com/?t=http%3A%2F%2Fscs.ryerson.ca%2F%7Eaharley%2Fvis%2Fconv%2Fflat.html)。
它為你生動(dòng)解析了卷積神經(jīng)網(wǎng)絡(luò)中,各個(gè)層次上到底發(fā)生了什么。
左上角是用戶輸入位置。請(qǐng)利用鼠標(biāo),手寫一個(gè)數(shù)字(0-9)。寫得難看一些也沒(méi)有關(guān)系。
我輸入了一個(gè)7。
觀察輸出結(jié)果,模型正確判斷***選擇為7,第二可能性為3?;卮鹫_。
讓我們觀察模型建構(gòu)的細(xì)節(jié)。
我們把鼠標(biāo)挪到***個(gè)卷積層。停在任意一個(gè)像素上。電腦就告訴我們這個(gè)點(diǎn)是從上一層圖形中哪幾個(gè)像素,經(jīng)過(guò)特征檢測(cè)(feature detection)得來(lái)的。
同理,在***個(gè)Max pooling層上懸停,電腦也可以可視化展示給我們,該像素是從哪幾個(gè)像素區(qū)塊里抽樣獲得的。
這個(gè)網(wǎng)站,值得你花時(shí)間多玩兒一會(huì)兒。它可以幫助你理解卷積神經(jīng)網(wǎng)絡(luò)的內(nèi)涵。
回顧我們的示例圖:
下一層叫做全連接層(Fully Connected Layer),它其實(shí)就是把上一層輸出的若干個(gè)矩陣全部壓縮到一維,變成一個(gè)長(zhǎng)長(zhǎng)的輸出結(jié)果。
之后是輸出層,對(duì)應(yīng)的結(jié)果就是我們需要讓機(jī)器掌握的分類。
如果只看***兩層,你會(huì)很容易把它跟之前學(xué)過(guò)的深度神經(jīng)網(wǎng)絡(luò)(Deep Neural Network, DNN)聯(lián)系起來(lái)。
既然我們已經(jīng)有了深度神經(jīng)網(wǎng)絡(luò),為什么還要如此費(fèi)力去使用卷積層和采樣層,導(dǎo)致模型如此復(fù)雜呢?
這里出于兩個(gè)考慮:
首先是計(jì)算量。圖片數(shù)據(jù)的輸入量一般比較大,如果我們直接用若干深度神經(jīng)層將其連接到輸出層,則每一層的輸入輸出數(shù)量都很龐大,總計(jì)算量是難以想像的。
其次是模式特征的抓取。即便是使用非常龐大的計(jì)算量,深度神經(jīng)網(wǎng)絡(luò)對(duì)于圖片模式的識(shí)別效果也未必盡如人意。因?yàn)樗鼘W(xué)習(xí)了太多噪聲。而卷積層和采樣層的引入,可以有效過(guò)濾掉噪聲,突出圖片中的模式對(duì)訓(xùn)練結(jié)果的影響。
你可能會(huì)想,咱們只編寫了10幾行代碼而已,使用的卷積神經(jīng)網(wǎng)絡(luò)一定跟上圖差不多,只有4、5層的樣子吧?
不是這樣的,你用的層數(shù),有足足50層呢!
它的學(xué)名,叫做Resnet-50,是微軟的研發(fā)成果,曾經(jīng)在2015年,贏得過(guò)ILSRVC比賽。在ImageNet數(shù)據(jù)集上,它的分類辨識(shí)效果,已經(jīng)超越人類。
我把對(duì)應(yīng)論文的地址附在這里(https://link.jianshu.com/?t=https%3A%2F%2Farxiv.org%2Fabs%2F1512.03385),如果你有興趣,可以參考。
請(qǐng)看上圖中最下面的那一個(gè),就是它的大略樣子。
足夠深度,足夠復(fù)雜吧。
如果你之前對(duì)深度神經(jīng)網(wǎng)絡(luò)有一些了解,一定會(huì)更加覺(jué)得不可思議。這么多層,這么少的訓(xùn)練數(shù)據(jù)量,怎么能獲得如此好的測(cè)試結(jié)果呢?而如果要獲得好的訓(xùn)練效果,大量圖片的訓(xùn)練過(guò)程,豈不是應(yīng)該花很長(zhǎng)時(shí)間嗎?
沒(méi)錯(cuò),如果你自己從頭搭建一個(gè)Resnet-50,并且在ImageNet數(shù)據(jù)集上做訓(xùn)練,那么即便你有很好的硬件設(shè)備(GPU),也需要很長(zhǎng)時(shí)間。
如果你在自己的筆記本上訓(xùn)練……算了吧。
那么,TuriCreate難道真的是個(gè)奇跡?既不需要花費(fèi)長(zhǎng)時(shí)間訓(xùn)練,又只需要小樣本,就能獲得高水平的分類效果?
不,數(shù)據(jù)科學(xué)里沒(méi)有什么奇跡。
到底是什么原因?qū)е逻@種看似神奇的效果呢?這個(gè)問(wèn)題留作思考題,請(qǐng)善用搜索引擎和問(wèn)答網(wǎng)站,來(lái)幫助自己尋找答案。
5、小結(jié)
通過(guò)本文,你已掌握了以下內(nèi)容:
如何在Anaconda虛擬環(huán)境下,安裝蘋果公司的機(jī)器學(xué)習(xí)框架TuriCreate。
如何在TuriCreate中讀入文件夾中的圖片數(shù)據(jù)。并且利用文件夾的名稱,給圖片打上標(biāo)記。
如何在TuriCreate中訓(xùn)練深度神經(jīng)網(wǎng)絡(luò),以分辨圖片。
如何利用測(cè)試數(shù)據(jù)集,檢驗(yàn)圖片分類的效果。并且找出分類錯(cuò)誤的圖片。
卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network, CNN)的基本構(gòu)成和工作原理。
但是由于篇幅所限,我們沒(méi)有提及或深入解釋以下問(wèn)題:
如何批量獲取訓(xùn)練與測(cè)試圖片數(shù)據(jù)。
如何利用預(yù)處理功能,轉(zhuǎn)換TuriCreate不能識(shí)別的圖片格式。
如何從頭搭建一個(gè)卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network, CNN),對(duì)于模型的層次和參數(shù)做到完全掌控。
如何既不需要花費(fèi)長(zhǎng)時(shí)間訓(xùn)練,又只需要小樣本,就能獲得高水平的分類效果(提示關(guān)鍵詞:遷移學(xué)習(xí),transfer learning)。
請(qǐng)你在實(shí)踐中,思考上述問(wèn)題。歡迎留言和發(fā)送郵件,與我交流你的思考所得。
原文鏈接:https://www.jianshu.com/u/7618ab4a30e4










































 
 
 














 
 
 
 