地表建筑物识别-异常数据的清洗
文件结构
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轮,(加载之前训练时损失几乎下降的模型权重)模型损失一下就下降了不少。
问题数据还是很多,但是相比些数据来说,还算不是太过分,勉强凑合着用,如果真要筛选,那就要手工了,要花费大量时间,并且不一定提升明显。