從0梳理1場(chǎng)CV大賽(Top 3%)!
摘要:數(shù)據(jù)競(jìng)賽對(duì)于大家理論實(shí)踐和增加履歷幫助比較大,但許多讀者反饋不知道如何入門,本文以全國(guó)數(shù)字生態(tài)大賽為背景,梳理了cv數(shù)據(jù)競(jìng)賽的整個(gè)流程和改進(jìn)思路。
0.賽事背景
大賽名稱:全國(guó)數(shù)字生態(tài)創(chuàng)新大賽-智能算法賽
大賽地址:
https://tianchi.aliyun.com/s/92ccdd364891b9e559a10e1df10079de(或文末閱讀原文)
大賽類型:計(jì)算機(jī)視覺(jué)、語(yǔ)義分割
1. 賽題分析
賽題基于不同地形地貌的高分辨率遙感影像資料,要求參賽隊(duì)伍利用遙感影像智能解譯技術(shù)識(shí)別提取土地覆蓋和利用類型,實(shí)現(xiàn)生態(tài)資產(chǎn)盤點(diǎn)、土地利用動(dòng)態(tài)監(jiān)測(cè)、水環(huán)境監(jiān)測(cè)與評(píng)估、耕地?cái)?shù)量與監(jiān)測(cè)等應(yīng)用。
地表類型(初賽)包括:
{
??1:?"耕地",
??2:?"林地",
??3:?"草地",
??4:?"道路",
??5:?"城鎮(zhèn)建設(shè)用地",
??6:?"農(nóng)村建設(shè)用地",
??7:?"工業(yè)用地",
??8:?"構(gòu)筑物"
??9:?"水域"
??10:?"裸地"
?}
2.?賽題數(shù)據(jù)
賽題設(shè)置
初賽:利用算法對(duì)遙感影像進(jìn)行10大類地物要素分類,主要考察算法地物分類的準(zhǔn)確性;復(fù)賽:利用AI算法對(duì)遙感影像進(jìn)行10大類地物要素地物分類。同時(shí)考察算法地物分類的準(zhǔn)確性及模型推理效率。
數(shù)據(jù)介紹
數(shù)據(jù)簡(jiǎn)介:數(shù)據(jù)為覆蓋0.8m-2m分辨率的高分系列遙感多光譜影像,成像波段包括R、G、B、Nir波段,數(shù)據(jù)覆蓋地貌包括:山地、丘陵地區(qū)、河湖(水庫(kù))、平原、城鎮(zhèn)等等。感謝浙江大學(xué)環(huán)境與資源學(xué)院為本賽題提供數(shù)據(jù)支持。 數(shù)據(jù)規(guī)格:4萬(wàn)+張遙感影像及對(duì)應(yīng)地物分類標(biāo)記樣本,影像大小為256*256像素。 初賽:16017張高分遙感影像和標(biāo)注文件訓(xùn)練集,A榜測(cè)試集3000張測(cè)試數(shù)據(jù),B榜測(cè)試集4366張測(cè)試數(shù)據(jù)。復(fù)賽:15904張高分遙感影像和標(biāo)注文件,6000張測(cè)試數(shù)據(jù)。
訓(xùn)練測(cè)試數(shù)據(jù)說(shuō)明:影像保存格式為tif文件,包括R、G、B、Nir四個(gè)波段,訓(xùn)練測(cè)試集影像尺寸均為256 * 256像素。標(biāo)簽數(shù)據(jù)格式為單通道的png。
評(píng)價(jià)標(biāo)準(zhǔn)
初賽指標(biāo)
使用通用指標(biāo)平均交并比mIoU,計(jì)算每個(gè)類別的交并比的平均值,僅對(duì)算法效果進(jìn)行評(píng)價(jià),具體計(jì)算公式為:
其中,是目標(biāo)類別數(shù),是真值類別為i的像素被分為第j類的個(gè)數(shù)。
復(fù)賽指標(biāo)
在初賽指標(biāo)基礎(chǔ)上,綜合考慮算法效果、模型推理效率。具體如下:在mIoU的技術(shù)上引入模型效率評(píng)價(jià)指標(biāo),模型效率得分Fe,衡量模型推理時(shí)間得分,F(xiàn)e的計(jì)算方式待復(fù)賽階段公布。
最終成績(jī)計(jì)算公式為:
3.?建模方法
首先可以對(duì)賽題的數(shù)據(jù)進(jìn)行分析,下圖所示左邊為對(duì)應(yīng)的標(biāo)注,右邊為原圖。
從中大致看出,原始圖片是比較模糊的,也表明賽題難度比較大。

根據(jù)對(duì)賽題任務(wù)的理解,可以將賽題任務(wù)視為語(yǔ)義分割任務(wù),則可以使用語(yǔ)義分割的流程來(lái)完成。
輸入四通道圖片,完成10通道輸出。

具體的流程可以分為:
構(gòu)建賽題數(shù)據(jù)集,數(shù)據(jù)&標(biāo)簽讀??; 構(gòu)建分割模型; 完成模型訓(xùn)練并提交;
賽題數(shù)據(jù)讀取
首先完成賽題讀取,這里我們先只用到TIF默認(rèn)三通道,然后對(duì)應(yīng)的標(biāo)注映射到0-9范圍內(nèi)。
class?TianChiDataset(D.Dataset):
????def?__init__(self,?paths,?transform,?test_mode=False):
????????self.paths?=?paths
????????self.transform?=?transform
????????self.test_mode?=?test_mode
????????
????????self.len?=?len(paths)
????????self.as_tensor?=?T.Compose([
????????????T.ToPILImage(),
????????????T.Resize(IMAGE_SIZE),
????????????T.ToTensor(),
????????????T.Normalize([0.625,?0.448,?0.688],?????????????????????????[0.131,?0.177,?0.101]),
????????])
????????
????#?get?data?operation
????def?__getitem__(self,?index):
????????img?=?cv2.imread(self.paths[index])
????????img?=?cv2.cvtColor(img,?cv2.COLOR_BGR2RGB)
????????if?not?self.test_mode:
????????????mask?=?cv2.imread(self.paths[index].replace('.tif',?'.png'))?-?1
????????????mask?=?cv2.resize(mask,?(IMAGE_SIZE,?IMAGE_SIZE))
????????????augments?=?self.transform(image=img,?mask=mask)
????????????return?self.as_tensor(augments['image']),?augments['mask'][:,?:,?0].astype(np.int64)
????????else:
????????????return?self.as_tensor(img),?''????????
????
????def?__len__(self):
????????return?self.len模型構(gòu)建
使用FCN或者Unet都是可以的:
#?Unet
import?segmentation_models_pytorch?as?smp
model?=?smp.Unet(
????????encoder_name="resnet50",????????#?choose?encoder,?e.g.?mobilenet_v2?or?efficientnet-b7
????????encoder_weights="imagenet",?????#?use?`imagenet`?pretreined?weights?for?encoder?initialization
????????in_channels=3,??????????????????#?model?input?channels?(1?for?grayscale?images,?3?for?RGB,?etc.)
????????classes=10,??????????????????????#?model?output?channels?(number?of?classes?in?your?dataset)
)
#?FCN
model?=?torchvision.models.segmentation.fcn_resnet50(True)
model.classifier[4]?=?nn.Conv2d(512,?10,?kernel_size=(1,?1),?stride=(1,?1))損失函數(shù)&訓(xùn)練
這里由于圖片像素有可能屬于多個(gè)類別,因此我們直接選用CrossEntropy對(duì)像素類別進(jìn)行分類即可。
需注意,這里我們本質(zhì)是對(duì)256*256尺寸每個(gè)像素進(jìn)行類別劃分,所以此時(shí)的類別10體現(xiàn)在具體的通道上。
optimizer?=?torch.optim.AdamW(model.parameters(),?lr=1e-4,?weight_decay=1e-3)
loss_fn?=?nn.CrossEntropyLoss().to(DEVICE);
best_iou?=?0
for?epoch?in?range(1,?EPOCHES+1):
????losses?=?[]
????start_time?=?time.time()
????model.train()
????model.to(DEVICE);
????for?image,?target?in?tqdm_notebook(loader):
????????optimizer.zero_grad()
????????output?=?model(image)
????????loss?=?loss_fn(output,?target)
????????loss.backward()
????????optimizer.step()預(yù)測(cè)提交
model.eval()
for?idx,?name?in?enumerate(tqdm_notebook(glob.glob('./suichang_round1_test_partA_210120/*.tif')[:])):
????image?=?cv2.imread(name)
????image?=?trfm(image)
????with?torch.no_grad():
????????image?=?image.to(DEVICE)[None]
????????score1?=?model(image).cpu().numpy().argmax(0)?+?1
????????cv2.imwrite('results/'?+?name.split('/')[-1].replace('.tif',?'.png'),?score_sigmoid)使用單折模型完成訓(xùn)練,可以到線上34.5的分?jǐn)?shù),在排行榜100名以內(nèi)。

4. 改進(jìn)思路
類別不均衡的情況
由于賽題使用mIOU進(jìn)行評(píng)價(jià),而賽題中不同類別存在不均衡的情況。
可以從損失函數(shù)進(jìn)行嘗試,如Lovasz-Softmax Loss、 Focal Loss等; 可以在數(shù)據(jù)采樣角度考慮,對(duì)像素占比少的類別進(jìn)行上采樣;

多折模型
可以對(duì)賽題數(shù)據(jù)進(jìn)行多折劃分,然后訓(xùn)練多個(gè)模型,然后集成多個(gè)模型的結(jié)果。
數(shù)據(jù)通道
將R、G、B、Nir四個(gè)波段加入訓(xùn)練,帶來(lái)的精度肯定會(huì)比三通道高。這部分操作可能需要修改分割模型輸入層的通道個(gè)數(shù)。
分類損失&分類模型
賽題類別存在不均衡的情況,因此也可以考慮在分割的同時(shí)加加入類別損失。
完整代碼的notebook可在后臺(tái)回復(fù)阿水下載
希望能幫助你完整實(shí)踐一場(chǎng)cv賽事。
