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