基於DeepLab v3的遙感圖像語義分割教程
前言
前兩個月做過一次基於Unet的遙感圖像語義分割教程,效果較差。這次選用一個稍微新一點的模型,再跑一次相同的數據集,加上遷移學習的技巧,看看效果怎么樣。
教程准備
-
開源的圖像語義分割DeepLabv3代碼(二分類)
-
DeepLabv3+基本原理(借鑒)
核心代碼
-
dataloader
數據讀取部分,最值得注意的就是images和labels的數據格式,文件讀取的方法倒是次要的,千篇一律。這里我們讀取的圖像依舊是上次的數據集,images是(3 X 256 X 256)的RGB圖像,labels是0、1、2、3...7的單通道灰度圖(256 X 256),記得讀取的時候用GRAY_SCALE模式。
數據的預處理部分,將images數據集做歸一化處理(也可再加上標准差處理),轉化成0~1的tensor;將labels轉化成long型,這里設置long是因為后面的損失函數CrossEntropyLoss需要標簽是Long的格式,如果用MSELoss的損失函數,那么用float格式,數據大小范圍不做調整,轉換成tensor即可。

-
model(transfer learning)
model用的是DeepLab v3模型,backbone是Resnet101模型。在此基礎上進行遷移學習,可以得到更好的效果。下面給出了DeepLab v3+模型的源碼,與v3大同小異,網絡結構本人不做解釋。加載完Resnet101模型的參數后,替換最后一層為新的outputchannels。
常用遷移學習代碼:



-
Training
這里的重點主要是看模型輸出的數據維度。可以看到outputs['out']是沒有經過概率化的數組,數組的維度是(batchsize X category X height X width),而label的維度是(batchsize X height X width)。在損失函數為nn.CrossEntropyLoss()的情況下,label的維度中不需要category的1維,如果有的話進行sequeeze;損失函數為nn.MSELoss的情況下,label的維度是(batchsize X 1 X height X width)。每次epoch結束,保存該過程中最好的模型參數。

這里有點疑問:nn.CrossEntropyLoss對樣本做了概率化處理再計算損失;那么nn.MSELoss呢?這個是不是二分類、多分類都可以用,是不是也對樣本做了概率化處理呢?
-
choose cost func/optimizer
除了前述的損失函數之外,這里還需要定義優化器。此外還有兩個計算指標,f1_score和accuracy_score,其中accuracy_score用來計算多類別預測中成功的百分比,roc_auc_score是二分類中使用的指標,這些方法源於sklearn.metrics。

結果
10個epoch下的結果...用的訓練集,還是不咋地。

指標變化圖

預測類型分布

結果對比
后記
-
nn.MSELoss需要了解了解,弄清楚這些損失函數做的計算處理和要求輸入的數組維度。
-
這里用了f1_score和auccracy_score兩個指標。只看了后者的,前者沒關心。
-
click庫輸入參數的方法看起來比
argparse.ArgumentParser()還簡單。 -
一般來說,還需要調整epochs/batchsize/lr/gamma來調參。
-
6G顯存不夠啊,想換新顯卡了。
-
有空介紹一下時間序列分析(RNN、LSTM)相關的模型,ConvLSTM這類圖像時序模型看起來挺有意思的,看看能不能找到源碼吧。
