有哪些優秀的Kaggle競賽解決方案,可以分享嗎?機器之心Pro2018-10-25 22:06:04

地球上一些儲藏了大量石油和天然氣的區域,其地表下還有大量的沉積鹽。但要準確找出哪些地方有大量沉積鹽並非易事。專業的地震成像仍然需要對鹽礦體進行專業的人工判斷。這導致了非常主觀、高度可變的渲染過程。此外,這對石油和天然氣開採也造成了潛在的隱患。為了建立最準確的地震成像(seismic image)和 3D 渲染,TGS(世界領先的地理資料公司)希望 Kaggle 的機器學習社群能構建一種可以自動、準確識別一塊次表層是不是鹽體的演算法。

這正是我們今天要介紹的 Kaggle 競賽:TGS 鹽體識別挑戰賽,挑戰者需要開發出能準確分割地表以下沉積鹽分佈的演算法。簡言之,這就是一個影象語義分割任務。本文介紹了獲得該競賽第一名的方案。

本項競賽獎金豐厚,前四名總共可獲得 10 萬美元的獎勵,而第一名將獲得 5 萬美元。

目前該競賽的提交日期已經截止,該賽事共有 3291 個隊伍參賽。以下是前十名的成績排行:

有哪些優秀的Kaggle競賽解決方案,可以分享嗎?

賽題背景

地震資料是透過地震反射(reflection seismology)收集的,這種方法要求能量的受控震源(如壓縮氣體或地震振動器),以及記錄來自地下岩石介面反射的感測器。之後處理記錄的資料,建立地球內部的 3D 檢視。地震反射類似於 X 光、聲波定位儀和回波定位。

地震成像是透過將來自岩石邊界的反射成像來生成的。地震成像展示了不同岩石型別之間的邊界。理論上,反射的力量與岩石介面兩側的物理特性的差別成正比。地震成像展示了岩石邊界,但它們並不能顯示岩石的屬性,一些岩石容易辨認,一些則很難。

世界上一些地區地下存在大量的鹽。地震成像的一大挑戰就是識別哪些地表下面有鹽。鹽很容易識別,也很難識別。鹽的密度通常是 2。14 g/cc,比周圍的岩石密度低。鹽的地震波速是 4。5 km/sec,通常比周圍的岩石速度快。這種區別就使得在鹽巖-沉積層介面處反射的變化比較大。通常鹽是非晶質岩石,沒有太多內部結構。這意味著鹽內部通常不會有太多反射,除非其中有沉積物。這種情況下鹽的地震波速較高,使得地震成像出現問題。

資料

使用的資料是在次表層底部多個地點選取的一系列圖片。影象的解析度為 101 x 101,每個畫素被分類為鹽或沉積物。除了地震成像之外,還為每個影象提供成像位置的深度。比賽的目標是分割含鹽區域。

有哪些優秀的Kaggle競賽解決方案,可以分享嗎?

訓練資料集示例

評估

比賽根據 IoU 閾值上不同交叉點的平均精度來計算比分。提交的目標畫素預測值和真實目標畫素之間的 IoU 分數計算方式如下:

有哪些優秀的Kaggle競賽解決方案,可以分享嗎?

將一系列 IoU 閾值代入該公式,在每個點計算一個平均精度值。閾值的範圍在 0。5 到 0。95 之間,步長為 0。05:(0。5, 0。55, 0。6, 0。65, 0。7, 0。75, 0。8, 0。85, 0。9, 0。95)。換句話說,在閾值為 0。5 時,如果預測目標與真實目標的交集大於 0。5,則該預測物件被視為「命中」。

在每個閾值 t 處,基於預測目標與所有真實目標對比所產生的真正類(TP)、假負類(FN)和假正類(FP)的數量來計算精度值:

有哪些優秀的Kaggle競賽解決方案,可以分享嗎?

當單個預測目標與真實目標匹配並且 IoU 高於閾值時,記為真正類。假正類表示預測目標沒有與之關聯的真實物件,假負類表示真實目標沒有與之關聯的預測目標。然後,將上述每個 IoU 閾值上精度值的平均值作為單個影象的平均精度值:

有哪些優秀的Kaggle競賽解決方案,可以分享嗎?

最後,競賽的評估度量返回的分數是測試資料集中每個影象平均精度的平均值。

第一名方案

首先,我要祝賀並感謝我的隊友 phalanx,他為此付出了很大的努力!這是我在影象分割領域處理的第一個問題,三個月前我對分割還一無所知。所以,這項第一是對我們所獲知識和經驗的巨大獎勵。我想,這對新手來說也是一個很好的示例:只要你肯努力,即使沒什麼背景知識也能獲得不錯的成績。

區域性驗證

我們建立了 5 個按深度分層的常見 fold。區域性驗證的分數與 LB 有很強的相關性。

第一階段訓練

我們每個人都基於訓練資料開發了一個模型:

我的模型

輸入:101→resize to 192→pad to 224

編碼器:在 ImageNet 上預訓練的 ResNeXt50

解碼器:conv3x3+BN,上取樣,scSE

訓練概覽:

最佳化器:RMSprop,批大小:24

損失:BCE+Dice。從 0。0001 開始降低高原上的 LR

損失:Lovasz。從 0。0005 開始降低高原上的 LR

損失:Lovasz。4 個帶有餘弦退火 LR 的 snapshot,每個 snapshot 需要 80 個 epoch,LR 從 0。0001 開始

phalanx 的模型

編碼器為 ResNet34(架構與下面描述的 resnet_34_pad_128 相似)

輸入:101→ resize to 202→pad to 256

5-fold ResNeXt50 有 0。864Public LB(0。878 Private LB)

5-fold ResNet34 有 0。863Public LB(0。880 Private)

它們的整合分數為 0。867Public LB(0。885 Private)

第二階段訓練

基於第一階段得到的整合分數,我們創造了一套置信假標籤。置信度為置信畫素預測的百分比(probability < 0。2 or probability> 0。8)

我們有兩個模型:

我的 ResNeXt50 在置信假標籤上進行預訓練;在它們上面訓練了 5folds。0。871(0。890 Private)

phalanx 在每個 fold 中添加了 1580 個假標籤,並從頭開始訓練模型。0。861(0。883 Private)

它們的整合得分為 0。870(0。891 Private)

第三階段訓練

從第二階段得到所有的假標籤,phalanx 訓練了 2 個模型:

resnet_34_pad_128

輸入:101 -> pad to 128

編碼器:ResNet34 + scSE (conv7x7 -> conv3x3,移除第一個最大池化)

中心模組:特徵金字塔注意力模組 (移除 7x7)

解碼器: conv3x3,轉置卷積,scSE + hyper columns

損失:Lovasz

resnet_34_resize_128

輸入: 101 -> resize to 128

編碼器:ResNet34 + scSE(移除第一個最大池化)

中心模組:conv3x3, 全域性卷積網路

解碼器:全域性注意力上取樣(實施 like senet -> like scSE, conv3x3 -> GCN) + 深度監督

損失: 用於分類的 BCE 以及用於分割的 Lovasz

訓練概覽

最佳化器:SGD,批大小:32

在假標籤上進行預訓練。3 個帶有餘弦退火 LR 的 snapshot,每個 snapshot 有 50 個 epoch,LR 0。01 → 0。001

在訓練資料上進行微調。5 folds、4 個帶有餘弦退火 LR 的 snapshot,每個 snapshot 有 50 個 epoch,LR 0。01 → 0。001

resnet_34_pad_128 had 0。874 (0。895 Private)

resnet_34_resize_128 had 0。872 (0。892 Private)

最終模型

最終模型是 ResNeXt50(來自第二階段)和 resnet_34_pad_128(來自第三階段)與水平翻轉 TTA: 0。876Public LB(0。896 Private LB)的混合。

資料增強

我們用了非常相似的資料增強列表。我的資料增強基於強大的 albumentations 庫:

水平翻轉(p=0。5)

隨機亮度(p=0。2,limit=0。2)

隨機對比(p=0。1,limit=0。2)

平移 縮放 旋轉(shift_limit=0。1625, scale_limit=0。6, rotate_limit=0, p=0。7)

後處理

我們開發了基於拼圖鑲嵌的後處理。理念如下:

在訓練資料中找到所有的垂直或半垂直(影象的下半部分是垂直的)影象;

鑲嵌中上述影象下方的所有測試影象都得到相同的掩碼;

它們上方只有一個測試影象獲得相同的掩碼,並且只有當其鑲嵌深度> = 3 時。

GPU 資源

我只有一個 1080 的 GPU。

phalanx 有一個 1080Ti,在上週的比賽中又拿到一個。

框架

我用的是 Keras。非常感謝 qubvel 在 Keras 中關於分割 zoo 的絕佳 repo。

phalanx 用的是 PyTorch。