本文為 AI 研習社編譯的技術博客,原標題 :

How a team of deep learning newbies came 3rd place in a kaggle contest作者 | Mercy Markus翻譯 | linlh、Jenny_0420

校對 | 醬番梨 審核 | 約翰遜·李加薪 整理 | 立魚王

原文鏈接:towardsdatascience.com/

照片由Alexander Naglestad拍攝於Unsplash

The Women in Data Science組織與她們的合作夥伴共同發起了 WiDS Datathon 的活動。這個活動的挑戰在於,你需要建立一個預測衛星圖像中油棕種植園存在的模型。Planet and Figure Eight慷慨地提供了地球衛星最近拍攝的衛星圖像的注釋數據集。數據集圖像具有3米的空間解析度,每個圖像都基於圖像中存在的油棕種植園進行標記(0表示無種植園,1表示有種植園)。任務是訓練一個模型,該模型將衛星圖像作為輸入,並輸出包含油棕種植園的圖像可能性預測。標號訓練和測試數據集由競賽創建者提供用於模型開發。點此瞭解更多。

我和我的隊友(Abdishakur、Halimah和Ifeoma Okoh)在這個挑戰中使用了Fast.AI框架。多虧了Thomas Capelle在Kaggle上的入門內核,它為如何解決這個問題提供了很多洞見,同時也為Fast.ai團隊創建了一個令人驚嘆的深度學習課程,簡化了許多困難的深度學習概念。現在,初學者深入學習,就可以贏得 kaggle 比賽。

讓我們開始:一個簡單易學的深度學習教程

現在不要擔心什麼都懂,這需要大量的練習。本教程旨在向您展示,對於初學者來說,fast.ai 到底有多厲害。我假設你懂一點點Python,而且你也接觸過一些機器學習。如果你滿足了上述那些條件,萬事俱備,咱們開始吧!

這裡顯示的所有代碼都可以在谷歌協作實驗室上使用;這是一個免費的Jupyter筆記本環境,不需要設置,完全在雲中運行。通過協作,您可以編寫和執行代碼,保存和共享您的分析,以及訪問強大的計算資源,所有這些都是免費的。單擊此處訪問我們將使用的代碼。

導入 fast.ai 和其他需要用到的庫:

導入庫

獲取比賽的數據

為了讓獲取數據更加簡單直接,Abdishakur 把比賽的數據文件上傳到了dropbox.com。你可以在比賽的頁面中找到。你需要同意比賽的規則纔能夠獲取這些數據。

# Get the data from dropbox link
!wget https://www.dropbox.com/s/6kltw0kqynlijxv/widsdatathon2019.zip

# The downloaded competition data is zipped, let us unzip it
!unzip widsdatathon2019.zip
# The training and testing data have already been seperated, Unzip them as well
!unzip train_images.zip
!unzip leaderboard_holdout_data.zip
!unzip leaderboard_test_data.zip

查看數據

當我們面臨一個問題第一件需要做的事情就是看下手上的數據。在找到解決的方法之前,我們需要理解這個問題並且看下數據長什麼樣。看數據意味著理解數據是如何構成的,數據的標記(label)是怎樣的,以及示例圖片張是怎樣的。

使用pandas庫來讀取數據:

用於訓練模型的數據標記

在處理圖像分類數據集和表格式數據集最大的差別在於標籤的存儲方式。標籤在這裡指的就是圖像中的內容。在這個比賽的數據集中,標籤是存儲在CSV文件中的。

要了解表格中score這一列是如何計算得到的,請查看原文。

使用seaborn庫的countplot函數來繪製訓練數據的分佈。從圖形中,我們可以看到14,300張圖片中沒有包含油棕人工林(oil palm plantations),而942張圖片中是有的。這個就是稱之為不平衡的數據,這屬於深度學習的問題,在這裡不展開。

兩個類別的統計
訓練數據集的分佈

準備數據

測試數據提供在兩個分開的目錄中,the leaderboard holdout data 和 leaderboard test data。我們要將這兩個結合起來,因為這是比賽的要求,提交對兩個數據集的預測結果。總的共有6534張圖像。

整合 leaderboard holdout data 數據 leaderboard test data

在這裡我們使用 fast.ai 的DataBlock API來結構化數據,這是一個非常方便的方式來將數據餵給我們的模型。

一個ImageList來存放數據
  • 使用ImageList來保存訓練數據,和使用from_df方式。這樣做的原因是因為存儲測試集信息的數據格式叫做df。告訴程序該去哪裡找到訓練圖片:path,和保存圖片的文件夾:train_images。
  • 接下來,隨機分配訓練集。保留20%的數據在訓練過程中衡量模型的性能。選定一個種子保證當我們重來的時候結果相同。我們需要確保知道哪些有效而哪些沒有。
  • 告訴ImageList哪裡找到數據的標籤,以及我們剛剛整合的測試數據。
  • 最後,在數據上執行變換。設置 flip_vert = True 來翻轉圖片,這樣可以使得不管圖片旋轉了某個方向模型都可以識別。使用 imagenet_stats來標準化圖片。(註:這個是遷移學習的技巧)

預覽圖片

下面是帶有和不帶有油棕人工林的衛星圖片:

展示兩批圖片

有油棕人工林的標籤為1,沒有的為0

訓練模型

現在開始訓練模型。使用卷積神經網路作為主幹和resnet模型中預訓練好的權重,resnet模型是被訓練好用於大量圖片分類的模型。不用擔心這具體的意思是什麼。現在,我們構建一個模型能夠輸入衛星圖像,並且能輸出屬於兩個類別的概率。

卷積神經網路

找到最優模型學習率

接下來,使用 lr_find() 來找到最理想的學習率,使用recorder.plot()可視化這個過程。

找到最優的模型學習率

在這個圖像中選擇最接近曲線斜率最陡峭的地方:1e-2,作為我們的學習率。

用學習率 = 1e-2訓練模型循環5次

這裡我們會使用 fit_one_cycle 函數訓練模型5輪( 在所有的data上循環5次)

訓練和驗證的損失

有注意到上圖矩陣表格中training_loss和valid_loss在逐漸消失嗎?使用這些來監測模型性能的改善隨著時間的變化。

最好的模型在第4輪訓練完得到。

訓練模型的輸出; 訓練和驗證損失的變化

當運行訓練和驗證數據集時,fast.ai 內部會選擇和保存最優的模型。

評估模型

比賽提交是基於在預測可能性和觀察到目標, has_oilpalm之間的接收器工作特性曲線下的面積( the Area under the Receiver Operating Characteristic curve )。想要學習更多關於AUC曲線的知識可以看這個開發者速成課程,這個視頻,或者是Kaggle學習論壇的帖子。Fast.ai默認沒有提供這個方法,這裡我們使用 scikit-learn 庫。

列印出驗證矩陣

使用預訓練的模型和fast.ai的美在於你可以獲得一個非常好的預測準確率,在這個例子中沒有花費太多力氣就達到了99.4%。

第一階段訓練的矩陣信息

保存模型並繪製關於預測的混淆矩陣

learn.save(resnet50-stg1)

使用混淆矩陣查看結果

繪製混淆矩陣

混淆矩陣是以圖形化的方式來查看模型對於圖片確和不正確的預測結果。

第一階段訓練的混淆矩陣

對於這個圖形,我們看到模型正確預測了2,863張沒有油棕人工林的圖像,168張圖像有油棕人工林是正確分類的。10張圖片含有油棕人工林但是被分為沒有油棕人工林,7張圖片是沒有包含油棕人工林但是被分類為有油棕人工林。

對於一個簡單的模型這個效果還不錯。

接下來,我們為訓練迭代找一個理想的學習率。

找一個理想的學習率

選擇介於1e-6到1e-4之間的學習率

使用最大化的介於1e-6到1e-4之間的學習率餵給模型,並訓練7輪。

訓練7輪模型,學習率不超出1e-6到1e-4的範圍。

訓練和驗證的損失

圖形化的方式觀察矩陣參數來監視模型在每輪訓練後的性能。

訓練模型的輸出;訓練和驗證損失的變化

保存第二階段訓練的模型。

learn.save(resnet50-stg2)

準確率, 錯誤率和AUC分數

列印出模型的準確率,錯誤率,曲線下面積的度量。

第二階段訓練的指標信息

正如你所看到的準確率從99.44%提升到了99.48%。錯誤率從0.0056降低到了0.0052。AUC也同樣有進步,從99.82%變到了99.87%。

繪製混淆矩陣

經過和上次繪製的混淆矩陣的對比,你會發現這個模型能夠得到更好的預測結果。

第二階段訓練的混淆矩陣

相比前面來說,錯誤分類了7張沒有包含油棕人工林的圖片,現在降到了3張,這是一種進步了。

你會發現,在訓練的過程中,我們遵循著一個模式:訓練過程中調整少量的參數。這個過程就稱之為微調。大部分的深度學習實驗都遵循一個相似的迭代模式。

圖像變換

在數據上做更多的圖像變換,這樣能夠幫助改善我們的模型。關於每一種轉換可以在fast.ai的文檔中找到描述。

在圖像上應用不同的轉換來改善模型

  • max_lighting: 如果設置為None,由max_lighting控制的隨機亮度和對比度,按照p_lighting的概率應用
  • max_zoom : 如果不是1或者比1小的值,隨機選擇1到max_zoom的值按照概率p_affine的值應用
  • max_warp : 如果設置為None,在-max_warp到max_warp之間隨機確定對稱扭曲的程度,按照概率p_affine應用

重新找到一個最優的學習率。

找到一個理想的學習率

選擇1e-6的學習率

訓練模型5輪

訓練5輪

訓練和驗證的損失

對於訓練的參數和之前的參數,我們的模型稍微在迭代0.0169對比0.0163更差了。不要感到失望。

模型訓練的輸出,最好的模型是在第3輪訓練

保存第三階段的訓練模型,並列印出指標信息。可以看到現在模型的準確率是99.38%,上個階段是99.48%。AUC分數從99.87%提升到88.91%,這個是比賽進行評判的指標。

learn.save(resnet50-stg3)

準確率,錯誤率和AUC分數

第三階段訓練的指標

最後的訓練階段

不知道你有沒有注意到我們一開始的圖像設置size=164,然後我們慢慢的增加到了size=256,就像下面這樣的做法。這樣做是為了運用fast.ai在分類中逐步改變圖片的大小。比如說訓練開始的時候使用比較小的圖片,然後隨著訓練的進行慢慢提升圖片的大小。這種方式在開始時模型會非常不準確,但是在看了大量圖片之後會突然變化,並取得巨大的進步,在後面的訓練中,模型能夠識別更大的圖片來學習圖片中細微粒的差別。想要了解更多,點擊這裡。

應用不同的變換來提升模型,圖片大小增加到256

再次尋找最優的學習率。

找一個理想的學習率

找一個理想的學習率

用學習率為1e-4訓練5輪模型

訓練5輪模型,學習率設置為1e-4

訓練和驗證損失

可以看到訓練指標和之前的對比,我們的模型有了小小的提升,從0.0169變成0.0168。

模型訓練的輸出; 最好的模型在第2輪訓練

保存最後階段的模型,並列印出指標信息。

learn.save(resnet50-stg4)

準確率,錯誤率和AUC分數

你會注意到模型的準確度現在是99.44%,上一次訓練階段的改進率為99.38%。

第四階段訓練的指標

準備比賽的提交文件

現在可以看到我們的模型能夠對數據做出多好的預測了。

準備一個CSV提交文件

提交到WiDS Datathon

現在還可以進入WiDS比賽中,並提交你的結果。直接去到比賽的頁面中,點擊加入比賽,然後接受比賽的規則。之後就可以提交的預測結果了,看看你參加了這個比賽的成績排在怎樣的位置吧。

模型預測的結果得到私有測試集和公開測試集的分數

免責聲明:這個教程不會使得你和我們一樣排在第三名,我想把這些按照最簡單的語言表達出來。如果想要知道更詳細的,查看 Abdishakur的帖子。

想要學習更多的內容嗎?瞭解下Jeremy Howard和fast.ai團隊製作的非常棒的課程當中的第七部分吧。

AI研習社友情提示:學習道路千萬條,不看原文就一條。

想要繼續查看該篇文章相關鏈接和參考文獻?

點擊作為一個深度學習新手團隊,如何拿到kaggle比賽第三名的?即可訪問:

https://ai.yanxishe.com/page/TextTranslation/1660?

ai.yanxishe.com

AI入門、大數據、機器學習免費教程

35本世界頂級原本教程限時開放,這類書單由知名數據科學網站 KDnuggets 的副主編,同時也是資深的數據科學家、深度學習技術愛好者的Matthew Mayo推薦,他在機器學習和數據科學領域具有豐富的科研和從業經驗。

點擊鏈接即可獲取:https://ai.yanxishe.com/page/resourceDetail/417


推薦閱讀:
相關文章