TensorFlow系列专题(十四): 手把手带你搭建卷积神经网络实现冰山图像分类
目錄:
冰山圖片識別背景
數(shù)據(jù)介紹
數(shù)據(jù)預(yù)處理
模型搭建
結(jié)果分析
總結(jié)
一、冰山圖片識別背景
這里我們要解決的任務(wù)是來自于Kaggle上的一道賽題(https://www.kaggle.com/c/statoil-iceberg-classifier-challenge),簡單介紹一下賽題的背景:在加拿大的東海岸經(jīng)常會有漂流的冰山,這對航行在該海域的船舶造成了很大的威脅。挪威國家石油公司(Statoil)是一家在全球運(yùn)營的國際能源公司,該公司曾與C-CORE等公司合作,C-CORE基于其衛(wèi)星數(shù)據(jù)和計算機(jī)視覺技術(shù)建立了一個監(jiān)控系統(tǒng)。Statoil發(fā)布該賽題的目的是希望利用機(jī)器學(xué)習(xí)的技術(shù),更準(zhǔn)確的及早發(fā)現(xiàn)和識別出威脅船舶航行的冰山。
二、數(shù)據(jù)介紹
賽題提供了兩個數(shù)據(jù)文件“train.json”和“test.json”,其中“test.json”是比賽中用來對模型驚醒評分的,沒有類標(biāo),這里我們只需要使用“train.json”文件。該數(shù)據(jù)集中有1604個打標(biāo)過的訓(xùn)練數(shù)據(jù),單個樣本的數(shù)據(jù)格式如下:
|
字段名 |
字段說明 |
|
id |
圖像的id。 |
|
band_1,band_2 |
衛(wèi)星圖像數(shù)據(jù),band_1和band_2是以特定入射角下不同極化方式產(chǎn)生的雷達(dá)后向散射為特征的信號,分別對應(yīng)HH(水平發(fā)射/水平接收)和HV(水平發(fā)射/垂直接收)兩種極化方式的數(shù)據(jù),其大小均為。 |
|
inc_angle |
獲得該數(shù)據(jù)時的入射角度。該字段部分缺少數(shù)據(jù),標(biāo)記為“na”。 |
|
is_iceberg |
類標(biāo),0:船只,1:冰山。 |
我們將數(shù)據(jù)可視化后進(jìn)行觀察,如圖1所示。圖像上方是冰山圖像的可視化效果,三幅圖分別對應(yīng)“HH”計劃方式、“HV”計劃方式以及兩者結(jié)合后的數(shù)據(jù)。圖像下方是船只圖像的可視化效果。
圖1訓(xùn)練數(shù)據(jù)可視化效果
圖1中的冰山和船只,通過觀察可以較為容易的區(qū)分出來,但是還有很多如圖2所示的數(shù)據(jù),即使仔細(xì)觀察也很難區(qū)分開來。
圖2 訓(xùn)練數(shù)據(jù)可視化效果
三、數(shù)據(jù)預(yù)處理
首先我們導(dǎo)入需要的包:
接下來我們定義一個數(shù)據(jù)預(yù)處理的函數(shù):
“data_preprocess”函數(shù)接受兩個參數(shù),“path”為訓(xùn)練數(shù)據(jù)“train.json”的文件路徑,“more_data”為布爾類型,當(dāng)其為“true”時,會調(diào)用函數(shù)“create_more_data”進(jìn)行訓(xùn)練數(shù)據(jù)的擴(kuò)充(即數(shù)據(jù)增強(qiáng))。
第11行到第17行代碼中,我們對樣本數(shù)據(jù)進(jìn)行了處理,除了原有的“band_1”和“band_2”,我們增加了“band_3”,band_3=band_1+band_2。最后我們使用numpy的“dstack”將三種數(shù)據(jù)進(jìn)行堆疊,因此我們單個樣本的數(shù)據(jù)維度為75x75x3。
第20行代碼是調(diào)用“create_more_data”函數(shù)對訓(xùn)練數(shù)據(jù)進(jìn)行擴(kuò)充,第26行代碼是對訓(xùn)練集的類標(biāo)數(shù)據(jù)進(jìn)行擴(kuò)充,因為“create_more_data”函數(shù)將訓(xùn)練數(shù)據(jù)擴(kuò)充為了原來的6倍,因此這里對應(yīng)的也要將類標(biāo)擴(kuò)充為原來的6倍。
“create_more_data”函數(shù)的實現(xiàn)如下:
在“create_more_data”函數(shù)中我們通過對圖像進(jìn)行旋轉(zhuǎn)和翻轉(zhuǎn)來擴(kuò)充數(shù)據(jù)集,雖然旋轉(zhuǎn)前后的圖像是同一張,但是由于特征的位置發(fā)生了變化,因此對于模型來說就是不同的數(shù)據(jù),旋轉(zhuǎn)或翻轉(zhuǎn)操作是擴(kuò)充圖像數(shù)據(jù)集的一個簡單有效的方法。在31至35行代碼中,我們定義了5個列表,用來保存擴(kuò)充的數(shù)據(jù)集,對應(yīng)的操作分別是逆時針旋轉(zhuǎn)90度、逆時針旋轉(zhuǎn)180度、逆時針旋轉(zhuǎn)270度、左右翻轉(zhuǎn)和上下翻轉(zhuǎn)。具體實現(xiàn)如下:
上面的代碼中,我們使用numpy的“rot90”和“flip”函數(shù)對圖像進(jìn)行旋轉(zhuǎn)和翻轉(zhuǎn)操作。“flip”函數(shù)的第二個參數(shù)控制翻轉(zhuǎn)的方式,“0”為左右翻轉(zhuǎn),“1”為上下翻轉(zhuǎn)。第78行代碼中,使用numpy的“concatenate”函數(shù)將擴(kuò)充的數(shù)據(jù)預(yù)原數(shù)據(jù)進(jìn)行拼接。
四、模型搭建
接下來我們實現(xiàn)模型部分,這里我們使用TensorFlow的高級API來搭建網(wǎng)絡(luò)。
在84行代碼中,我們使用“tf.keras.Sequential()”創(chuàng)建一個序貫?zāi)P停蜇災(zāi)P褪嵌鄠€網(wǎng)絡(luò)層的線性堆疊,我們使用“tf.keras.Sequential().add()”方法逐層添加網(wǎng)絡(luò)結(jié)構(gòu)。第87到90行代碼是第一個卷積塊,這里的卷積層我們使用了128個大小為3x3的卷積核,使用了relu激活函數(shù)。在卷積層后面是一個池化層,采用最大池化,池化窗口的大小為3x3,橫向和縱向的步長都為2。在池化層的后面我們使用了Dropout,丟棄了20%的神經(jīng)元,防止參數(shù)過多導(dǎo)致過擬合。接下來是三個類似的卷積塊。
在第109行代碼中,我們使用“Flatten()”將前一層網(wǎng)絡(luò)的輸出轉(zhuǎn)換為了一維的數(shù)據(jù),這是為了接下來的全連接操作。第112行代碼是第一個全連接層,有256個神經(jīng)元,全連接層后面接relu激活函數(shù),同樣使用了Dropout。第117至119是類似的一個全連接部分。
由于是二分類問題,在122行代碼中我們使用了一個只有一個神經(jīng)元的全連接層,并使用了Sigmoid激活函數(shù),得到最終的輸出。
第126至128行使用“compile”編譯模型,其中“l(fā)oss='binary_crossentropy'”指明使用的是對數(shù)損失函數(shù),通過“optimizer”參數(shù)設(shè)置使用Adam優(yōu)化器,學(xué)習(xí)率設(shè)置為0.0001。“metrics” 列表包含評估模型在訓(xùn)練和測試時的性能的指標(biāo),我們設(shè)置了“metrics=['accuracy']”,則在訓(xùn)練的過程中,訓(xùn)練集和驗證集上的準(zhǔn)確率都會打印出來。
第130行使用了“summary()”函數(shù),訓(xùn)練開始后終端會打印出模型的概況信息,如圖3所示,其中包含了網(wǎng)絡(luò)的結(jié)構(gòu),以及每層的參數(shù)數(shù)量等信息。其中最后一行顯示我們總的訓(xùn)練數(shù)據(jù)為7699條,驗證集的數(shù)據(jù)量為1925條。
圖3 模型的概況信息
五、結(jié)果分析
接下來我們讀取數(shù)據(jù),并訓(xùn)練模型:
第134行代碼中我們調(diào)用“data_preprocess”函數(shù)獲取預(yù)處理后的訓(xùn)練數(shù)據(jù),設(shè)置“more_data”為“true”進(jìn)行數(shù)據(jù)擴(kuò)充。第140行代碼中,我們調(diào)用“fit”方法開始模型的訓(xùn)練,通過“batch_size”設(shè)置每個批次訓(xùn)練25條數(shù)據(jù),通過“epochs”設(shè)置訓(xùn)練的總回合數(shù)為“100”。通過設(shè)置“verbose”為1,在終端上顯示訓(xùn)練的進(jìn)度。通過設(shè)置“validation_split”為0.2,將訓(xùn)練集一分為二,其中80%作為訓(xùn)練集,20%作為驗證集。
模型的訓(xùn)練過程和結(jié)果如圖4所示:
圖4 模型的訓(xùn)練過程和結(jié)果
六、總結(jié)
在前面幾節(jié)內(nèi)容里我們介紹了卷積神經(jīng)網(wǎng)絡(luò)的基本結(jié)構(gòu)和原理,在這一節(jié)里我們使用TensorFlow搭建了一個簡單的卷積神經(jīng)網(wǎng)絡(luò),實現(xiàn)圖像分類的任務(wù)。
通過前幾章的學(xué)習(xí),我們深入理解了CNN中卷積,池化等典型結(jié)構(gòu)的原理,以及CNN實際相關(guān)的圖片識別比賽。相信大家對于CNN會有更深層次的認(rèn)識。后邊會接著這里開始介紹運(yùn)用CNN技術(shù)來預(yù)測的典型3個項目。
歡迎關(guān)注磐創(chuàng)博客資源匯總站:
http://docs.panchuang.net/
歡迎關(guān)注PyTorch官方中文教程站:
http://pytorch.panchuang.net/
總結(jié)
以上是生活随笔為你收集整理的TensorFlow系列专题(十四): 手把手带你搭建卷积神经网络实现冰山图像分类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络虚拟化基础协议·Genev
- 下一篇: Update 语句