地表建筑物识别-异常数据的清洗

地表建筑物识别-异常数据的清洗

文件结构

utils.py
eval.py
model.py
dataset.py
数据集
   |----test_a(文件夹)
   |----train(文件夹)
   |----test_a_samplesubmit.csv
   |----train_mask.csv
   |----ratio_ls

train_mask.csv文件,的列有"name",“mask”

1.将建筑物占比ratio加入到train_mask.csv中

现在再补充一列"ratio",ratio是建筑物像素占整张图的比例大小

import pandas as pd
import numpy as np
from PIL import Image
from tqdm import tqdm
import matplotlib.pyplot as plt
from file1 import rle_decode

train_mask = pd.read_csv("数据集/train_mask.csv",sep="\t",names=["name","mask"])
train_mask["mask"]=train_mask["mask"].fillna("")
l = len(train_mask)
ratio_ls = []
for i in tqdm(range(l)):
    if train_mask["mask"].iloc[i]!="":
        ls = list(map(int,train_mask["mask"].iloc[i].split(" ")))
        number = sum(ls[1::2])
        pic_path = "数据集/"+"train/"+train_mask["name"].iloc[i]
        img = np.array(Image.open(pic_path))
        ratio = number/(img.shape[0]*img.shape[1])
    else:
        ratio = 0

    ratio_ls.append(ratio)
train_mask["ratio"] = np.array(ratio_ls)
print(train_mask)
train_mask.to_csv("数据集/ratio_ls",header=False,index=False)

得到了ratio_ls文件,有"name",“mask”,"ratio"三列

2.统计ratio在特定区间的图片数量

res2为建筑物占比大于0.6的
res4为建筑物占比在0到0.002之间的,但不包含0
(至于我为什么要用copy(),因为pandas给了warning)

res1 = ratio[ratio["ratio"]>0.6]
res2 = res1.copy()
res2['name'] = res2['name'].apply(lambda x: '数据集/train/' + x)
print("ratio大于阈值的图片数量:",len(res1),len(res1)/len(ratio))

res3 = ratio[(ratio["ratio"]<0.002)&ratio["ratio"]>0]
res4 = res3.copy()
res4['name'] = res4['name'].apply(lambda x: '数据集/train/' + x)
print("ratio小于阈值的图片数量:",len(res4),len(res4)/len(ratio))

得到结果

ratio大于阈值的图片数量: 259 0.008633333333333333
ratio小于阈值的图片数量: 801 0.0267

相比于整个数据集3W张还是要小很多

3.可视化异常数据

num = 0
img_path = res2["name"].iloc[num]
img_mask = res2["mask"].iloc[num]
img_mask = rle_decode(img_mask)
img = np.array(Image.open(img_path))
plt.subplot(1,2,1)
plt.imshow(img)
plt.subplot(1,2,2)
plt.imshow(img_mask,cmap="gray")
plt.show()

数据集内存在很多屋顶,给训练带来严重的影响

比如:
地表建筑物识别-异常数据的清洗
地表建筑物识别-异常数据的清洗
右下侧,停车厂变成了建筑,一言难尽…
地表建筑物识别-异常数据的清洗
同样是屋顶
地表建筑物识别-异常数据的清洗
地表建筑物识别-异常数据的清洗
屋顶又+1,后面就不继续看了。

然而测试集中,翻了将近几百张,仅有1~3张屋顶,是半张图屋顶。训练集中,全屋顶的图就显的影响很大了。

把上述可视化的代码中的res2改成res4,查看阈值小的建筑。
可以看到,它仅仅把屋顶上的一个箱子当作了建筑
地表建筑物识别-异常数据的清洗
再有是,这些边边角角的数据
地表建筑物识别-异常数据的清洗
也许没人知道这个点是什么
地表建筑物识别-异常数据的清洗
可见小ratio的图,会给训练带来一些麻烦。

4.读取筛选完的数据

已经完成了分析,也完成了ratio_ls的生成

在训练前,要加载数据集,把trai_mask.csv,替换成加载ratio,设定阈值,将这些异常数据删除掉。

train_mask = pd.read_csv('数据集/ratio_ls', sep=',', names=['name', 'mask',"ratio"])
train_mask['name'] = train_mask['name'].apply(lambda x: '数据集/train/' + x)
train_mask = train_mask[((train_mask["ratio"]<0.6)&(train_mask["ratio"]>0.002))|(train_mask["ratio"]==0)]

再后面便是,定义数据集了,划分数据集等…

dataset = TianChiDataset(
        train_mask['name'].values,
        train_mask['mask'].fillna('').values,
        trfm, False
    )

5.总结

经过筛选后,训练1轮,(加载之前训练时损失几乎下降的模型权重)模型损失一下就下降了不少。

问题数据还是很多,但是相比些数据来说,还算不是太过分,勉强凑合着用,如果真要筛选,那就要手工了,要花费大量时间,并且不一定提升明显。

上一篇:如何在vue项目里面展示 pdf文件


下一篇:Spring Boot JPA中java 8 的应用