布匹缺陷检测 - Baseline学习及改进(4天)

比赛链接:https://tianchi.aliyun.com/competition/entrance/531864/introduction?spm=5176.12281976.0.0.506441a6dTFHF3

关于Baseline代码,地址为:https://github.com/datawhalechina/team-learning-cv/tree/master/DefectDetection

在这里插入图片描述

  1. 开源框架选择
    任务分析
    此次任务是布匹瑕疵检测,首先考虑的应该是目标检测框架。当前目标检测主要分为one-stage和two-stage两种类型,以YOLO,SSD等框架为代表的one-stage速度快,以Faster-RCNN为代表的two-stage框架精度高。基于本次任务时间有限制在1小时内,因此采用单阶段YOLOV5的方案
    环境配置

pip install -U -r requirements.txt

#Output:
Cython
numpy1.17
opencv-python
torch>=1.4
matplotlib
pillow
tensorboard
PyYAML>=5.3
torchvision
scipy
tqdm
训练设置
$ python train.py --data coco.yaml --cfg yolov5s.yaml --weights ‘’ --batch-size 64
yolov5m 40
yolov5l 24
yolov5x 16
测试设置
$ python detcet.py --source ./inference/images/ --weights yolov5s.pt --conf 0.4
2. 数据预处理
数据格式转换
代码详见convertTrainLabel.py ,部分代码及分析如下
#读取比赛数据标签文件
josn_path = “./train_data/guangdong1_round2_train2_20191004_Annotations/Annotations/anno_train.json”
image_path = “./train_data/guangdong1_round2_train2_20191004_images/defect/”
with open(josn_path, ‘r’) as f:
temps = tqdm(json.loads(f.read()))
for temp in temps:
name = temp[“name”].split(’.’)[0]
path = os.path.join(image_path, name, temp[“name”])
im = cv2.imread(path)
sp = im.shape
image_h, image_w = sp[0], sp[1]
x_l, y_l, x_r, y_r = temp[“bbox”]
#获取标签对应的类别一共15种
if temp[“defect_name”]
“沾污”:
defect_name = ‘0’
elif temp[“defect_name”]==“错花”:
defect_name = ‘1’

#标注格式转换 江都区并存入列表
x_center = (x_l + x_r)/(2image_w)
y_center = (y_l + y_r)/(2
image_h)
w = (x_r - x_l)/(image_w)
h = (y_r - y_l)/(image_h)
name_list.append(temp[“name”])
c_list.append(defect_name)
image_h_list.append(image_w)
image_w_list.append(image_h)
x_center_list.append(x_center)
y_center_list.append(y_center)
w_list.append(w)
h_list.append(h)

#读取列表 list 数据,并划分训练集和验证集
index = list(set(name_list))
print(len(index))
for fold in [0]:
val_index = index[len(index) * fold // 5:len(index) * (fold + 1) // 5]
print(len(val_index))
for num, name in enumerate(name_list):
print(c_list[num], x_center_list[num], y_center_list[num], w_list[num], h_list[num])
row = [c_list[num], x_center_list[num], y_center_list[num], w_list[num], h_list[num]]
if name in val_index:
path2save = ‘val/’
else:
path2save = ‘train/’

    #数据写入 yolov5文件格式
    if not os.path.exists('convertor/fold{}/labels/'.format(fold) + path2save):
        os.makedirs('convertor/fold{}/labels/'.format(fold) + path2save)
    with open('convertor/fold{}/labels/'.format(fold) + path2save + name.split('.')[0] + ".txt", 'a+') as f:
        for data in row:
            f.write('{} '.format(data))
        f.write('\n')
        if not os.path.exists('convertor/fold{}/images/{}'.format(fold, path2save)):
            os.makedirs('convertor/fold{}/images/{}'.format(fold, path2save))
        sh.copy(os.path.join(image_path, name.split('.')[0], name),
                'convertor/fold{}/images/{}/{}'.format(fold, path2save, name))
  1. 模型训练
    数据路径设置:编辑一个数据路径文件夹yaml文件
    例如:data/coco128.yaml

train and val datasets (image directory or *.txt file with image paths)

train: ./process_data/images/train/
val: ./process_data/images/val/

number of classes

nc: 15

class names

names: [‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘10’, ‘11’, ‘12’,‘13’, ‘14’, ‘15’]
模型文件选择:yolov5x.yaml, yolov5m.yaml, yolov5l.yaml yolov5s.yaml文件
可以选择合适的模型文件,从左到右精度下降,但是速率增大
nc: 15 # number of classes
depth_multiple: 1.33 # model depth multiple
width_multiple: 1.25 # layer channel multiple
anchors:

  • [116,90, 156,198, 373,326] # P5/32
  • [30,61, 62,45, 59,119] # P4/16
  • [10,13, 16,30, 33,23] # P3/8
    backbone:

[from, number, module, args]

[[-1, 1, Focus, [64, 3]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, BottleneckCSP, [128]],

模型训练
$ python train.py --data coco.yaml --cfg yolov5s.yaml --weights ‘’ --batch-size 64
yolov5m 40
yolov5l 24
yolov5x 16
4. 测试模型并生成结果
将detect.py的输出结果的格式修改成提交结果的格式
#将输出结果的格式变成比赛需要提交的格式,并存入list,方便后面写入result.json文件中
if save_json:
name = os.path.split(txt_path)[-1]
print(name)
x1, y1, x2, y2 = float(xyxy[0]), float(xyxy[1]), float(xyxy[2]), float(xyxy[3])
bbox = [x1, y1, x2, y2]
img_name = name
conf = float(conf)
#add solution remove other
result.append(
{‘name’: img_name+’.jpg’, ‘category’: int(cls+1), ‘bbox’: bbox,
‘score’: conf})
print("result: ", {‘name’: img_name+’.jpg’, ‘category’: int(cls+1), ‘bbox’: bbox,‘score’: conf})
#写入result.json文件中
if save_json:
if not os.path.exists(save_dir):
os.makedirs(save_dir)
with open(os.path.join(save_dir, “result.json”), ‘w’) as fp:
json.dump(result, fp, indent=4, ensure_ascii=False)
最后就是docker生成镜像,并提交镜像,至此就实现了比赛的Baseline了
四、改进思路

在实现比赛的Baseline后,可以说是完成了第一步,后面如果想要获取好的成绩就需要我们根据比赛的任务,比赛的难点。进行调整方案,修改网络,修改策略。
前面我们提到该布匹缺陷检测任务的难点主要有:
数据种类分布不均匀
缺陷具有极端的长宽比
小目标问题

  1. 数据种类分布不均匀
    解决思路:
    过采样种类较少的样本
    数据扩增:在训练方面,除了常规的数据增强之外,我们观察到原始的标注存在不准确的情况,为了使网络适应这种不确定性,我们在训练时随机对原始的标注框进行了抖动,是网络能够学习这种不确定性
  2. 缺陷具有极端的长宽比
    解决思路:
    anchor 设置:考虑到样本的长宽比差异较大,通过聚类分析可以发现,原始的anchor并不能满足当前任务的需要,通过增加anchor数目,提高检测性能。
    可变形卷积:增强特征提取能力,提高检测性能 方法:在 backbone结构的最后一个block采用可变形卷积核 优点:可变形卷积能够计算每个点的偏移,从最合适的地方取特征进行卷积
  3. 小目标问题
    解决思路:
    针对小目标的扩增方式:Copy-Pasted 也就是将小目标贴到图像中的任意位置并生成新的标注,并且粘贴的小目标可以进行随机变换(缩放,翻折,旋转等),这种方式通过增加每个图像中小目标的数量,匹配的 anchor 的数量也会随之增加,这进而提升了小目标在训练阶段对 loss 计算的贡献。
    多尺度训练:多尺度训练(Multi Scale Training, MST)通常是指设置几种不同的图片输入尺度,训练时从多个尺度中随机选取一种尺度,将输入图片缩放到该尺度并送入网络中
    FPN 增加融合因子 Effective Fusion Factor in FPN for Tiny Object Detection
    4.涨分Tricks
    在实现对网络的改进后,我们可以使用一些比赛的涨分技巧
    半监督学习
    利用训练集训练好的模型预测测试集,将预测结果作为伪标签加入训练
    测试增强
    对检测图片进行翻折、旋转、色彩增强,然后分别对这些扩增图片进行预测,将多个预测结果进行融合
    模型集成
    多种模型进行预测,将一张图片的多个结果进行融合
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值