全球人工智能技术创新大赛【热身赛一】--笔记二--数据增强

baseline的情况

baseline的数据情况

baseline使用的数据其实只是一部分,仅用了guangdong1_round2_train2_20191004_images\defect下的1264份有缺陷的数据。normal数据和其他3个文件夹的数据都是没有用到的。

baseline使用的参数:

模型:yolov5x.pt(用了预训练权重)
划分后的训练集数量:1025(如果我没记错)
batchsize:8
image_size:640*640
epoch:200
训练时长:10个小时+

baseline的训练报告:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过上面的图片可以发现,数据分布极其不均匀,从而导致部分缺陷的类别识别效果差、对应类别的AP值低,从而大大的影响了map。从排行榜的得分情况可以看出,map分值低是非常突出的情况,同时map得分的权重占80%。

baseline的得分

在这里插入图片描述

更多数据

除了我上面baseline用到的文件外,还有另外三个文件夹:在这里插入图片描述
这三个文件其实是一份数据,猜测官方是为了方便我们下载(因为解压需要文件的双倍内存,就是20G文件的解压,需要40G的内存空间才能成功)。这些文件的结构其实也是这样的:
|-- defect Images #存放有瑕疵的图像数据
|-- normal Images #存放无疵点的图像数据,jpeg编码图像文件
|-- Annotations #存放属性标签标注数据
|-- README.md #对数据的详细介绍

这样子我们就可以和baseline所用到的文件进行一个合并,对应文件夹复制过去就好了,json文件只要一个,就要打开文件内容进行复制了。这里有地方需要注意,如下图:(可能表达不太好,结合自己观察应该不难理解)
在这里插入图片描述

数据合并后的情况

数据合并后,defect共有4372份数据,normal有895份数据。
数据是多了,但也不一定全是好事,合并后数据大小为21Gb+.
单单对defect的数据进行划分train和val就要30min:
在这里插入图片描述
谨慎合并啊…

对合并后的数据进一步分析

①从下图可以看出数据合并后,数据不均匀依旧是十分严重的问题。
在这里插入图片描述
②通过对图片数据的观察可以发现,图片的命名的前缀其实和图片的类型有关:
例如名字开头为:0818A1_ 的都是这类布匹:
在这里插入图片描述
经过统计可以发现共有存在缺陷的共有68类布匹。
如下图,进一步统计可以观察到布匹类型也是存在着不均匀的。
在这里插入图片描述
③每种布匹的缺陷种类个数情况:(图片太大了,放大看要加载好久,可以考虑下载到桌面)
通过下图可以发现不同布匹他们的缺陷种类分布区别比较大,由此可以有一个思路,就是专门对某一种布匹进行数据增强,这样子既可能对缺陷的种类进行增强,也可以对布匹种类不平衡做出调整。
在这里插入图片描述

使用整合后的defect数据进行进一步训练

对baseline得到的权重,进一步使用整合后的defect数据进行训练,epoch=70,训练时间=10h+
得分:在这里插入图片描述

数据增强

通过分析,进行数据增强可能存在的问题:不是一张图片对应一个label,有可能某张图片对应很多种缺陷,如果想争对某类缺陷进行增强,那必须要同时对存在这种缺陷的图片的其他缺陷一块增强,增加了难度。

增强方式

由于时间关系,我最终还是以某一类缺陷为对象进行数据增强。例如:选取对存在"破洞"这种缺陷的图片,对这些图片进行数据增强,包括这些图片的其他缺陷。
增强方式有:缩放并且进行长和宽的扭曲、添加灰边、翻转、色域扭曲;这4个操作共同构成一张图片的增强。

增强效果的观察

原图:

在这里插入图片描述

增强后:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

增强参数设置

对"沾污"不做数据增强
对[“错花”, “水印”]增强1倍
对[“花毛”, “缝头”, “缝头印”, “虫粘”, “破洞”, “褶子”, “织疵”, “漏印”, “蜡斑”, “色差”, “网折”, “其他”]增强4倍

增强后的数据统计

数据增强后,存在缺陷的图片数量共有:18174,是原来的4倍有多的数据量。
对数据增强后,对所有缺陷进行统计,如下图所示。数量的确得到了提升,但是由于沾污也会随着图片的增强而被动增加,各种缺陷类别的比例还是相差较大。
在这里插入图片描述

小总结

数据成功增强了,但是样本不均匀还是没有解决,一个原因是因为时间不够无法对增强的数量进行调整尝试,也有部分原因是数据使然。
比较遗憾的是没时间尝试以布匹种类为对象进行数据增强,有可能可以解决样本不均衡和布匹种类不均衡的问题。

更多的改进:除了数据增强外,我还添加了normal(无缺陷)的数据进行训练。

进行了调整之后,再次进行训练,这次的训练数据:15254 ,测试数据:3813 ,batchsize:30 ,epoch:90 ,一轮的训练时间:大约30min ,估计的总训练时间:大约45h(现在训练直接要训练到3月1日10点,真好家伙,哈哈哈)
冲一把,希望最终有个好成绩

代码

自己肝的代码,可能不太整洁和轻便,数据量也很大,这个数据增强也运行了挺长时间的。

from PIL import Image, ImageDraw
import numpy as np
from matplotlib.colors import rgb_to_hsv, hsv_to_rgb
import json
import os

def rand(a=0, b=1):
    return np.random.rand()*(b-a) + a

def get_random_data(annotation_name, box_data,input_shape, random=True, max_boxes=20, jitter=.5, hue=.1, sat=1.5, val=1.5, proc_img=True):
    '''random preprocessing for real-time data augmentation'''
#     line = annotation_line.split()
    image = Image.open(annotation_name)
    iw, ih = image.size
    w,h= input_shape
    box = np.array(box_data)

    # 对图像进行缩放并且进行长和宽的扭曲
    new_ar = w/h * rand(1-jitter,1+jitter)/rand(1-jitter,1+jitter)
    scale = rand(.5,1.5)
    if new_ar < 1:
        nh = int(scale*h)
        nw = int(nh*new_ar)
    else:
        nw = int(scale*w)
        nh = int(nw/new_ar)
    image = image.resize((nw,nh), Image.BICUBIC)

    # 将图像多余的部分加上灰条
    dx = int(rand(0, w-nw))
    dy = int(rand(0, h-nh))
    new_image = Image.new('RGB', (w,h), (128,128,128))
    new_image.paste(image, (dx, dy))
    image = new_image

    # 翻转图像
    flip = rand()<.5
    if flip: image = image.transpose(Image.FLIP_LEFT_RIGHT)

    # 色域扭曲
    hue = rand(-hue, hue)
    sat = rand(1, sat) if rand()<.5 else 1/rand(1, sat)
    val = rand(1, val) if rand()<.5 else 1/rand(1, val)
    x = rgb_to_hsv(np.array(image)/255.)
    x[..., 0] += hue
    x[..., 0][x[..., 0]>1] -= 1
    x[..., 0][x[..., 0]<0] += 1
    x[..., 1] *= sat
    x[..., 2] *= val
    x[x>1] = 1
    x[x<0] = 0
    image_data = hsv_to_rgb(x) # numpy array, 0 to 1

    # 将box进行调整
    box_data = np.zeros((max_boxes,5))
    if len(box)>0:
        np.random.shuffle(box)
        box[:, [0,2]] = box[:, [0,2]]*nw/iw + dx
        box[:, [1,3]] = box[:, [1,3]]*nh/ih + dy
        if flip: box[:, [0,2]] = w - box[:, [2,0]]
        box[:, 0:2][box[:, 0:2]<0] = 0
        box[:, 2][box[:, 2]>w] = w
        box[:, 3][box[:, 3]>h] = h
        box_w = box[:, 2] - box[:, 0]
        box_h = box[:, 3] - box[:, 1]
        box = box[np.logical_and(box_w>1, box_h>1)] # discard invalid box
        if len(box)>max_boxes: box = box[:max_boxes]
        box_data[:len(box)] = box
    
    return image_data, box_data


def get_defect_name(i):
    if temps[i]["defect_name"]=="沾污":
        defect_name = 1
    elif temps[i]["defect_name"]=="错花":
        defect_name = 2
    elif temps[i]["defect_name"] == "水印":
        defect_name = 3
    elif temps[i]["defect_name"] == "花毛":
        defect_name = 4
    elif temps[i]["defect_name"] == "缝头":
        defect_name = 5
    elif temps[i]["defect_name"] == "缝头印":
        defect_name = 6
    elif temps[i]["defect_name"] == "虫粘":
        defect_name = 7
    elif temps[i]["defect_name"] == "破洞":
        defect_name = 8
    elif temps[i]["defect_name"] == "褶子":
        defect_name = 9
    elif temps[i]["defect_name"] == "织疵":
        defect_name = 10
    elif temps[i]["defect_name"] == "漏印":
        defect_name = 11
    elif temps[i]["defect_name"] == "蜡斑":
        defect_name = 12
    elif temps[i]["defect_name"] == "色差":
        defect_name = 13
    elif temps[i]["defect_name"] == "网折":
        defect_name = 14
    elif temps[i]["defect_name"] == "其他":
        defect_name = 15
        
    return defect_name

def reduce_defect_name(i):
    name = ["沾污", "错花", "水印", "花毛", "缝头", "缝头印", "虫粘", "破洞", "褶子", "织疵", "漏印", "蜡斑", "色差", "网折", "其他"]
    return name[i-1]



if __name__ == "__main__":
    josn_path = "./data/all_defect/Annotations/anno_train.json"
    with open(josn_path, 'r') as f:
        temps = json.loads(f.read())
    new = temps#记录json变化
    
    #选择数据增强哪些label
    label = ["错花", "水印", "花毛", "缝头", "缝头印", "虫粘", "破洞", "褶子", "织疵", "漏印", "蜡斑", "色差", "网折", "其他"]
    passed = []
    for i in range(len(temps)):
        if (temps[i]['name'] in passed):#确保一张图片只增强一次
            continue
        if (temps[i]['defect_name'] not in label):
            continue
        
        raw_box = []
        
        x_l, y_l, x_r, y_r = temps[i]["bbox"]
        defect_name = get_defect_name(i)
        
        raw_box.append([x_l, y_l, x_r, y_r, defect_name])
        
        #往上找该图片是否有box跳过了
        i_ = i
        while temps[i_-1]['name'] == temps[i]['name']:
            x_l, y_l, x_r, y_r = temps[i_-1]["bbox"]
            defect_name = get_defect_name(i_-1)
            i_-=1
        #往下找把该图片的所有box都添加上
        i_ = i
        while i_+1 < len(temps) and temps[i_+1]['name'] == temps[i]['name']:
            x_l, y_l, x_r, y_r = temps[i_+1]["bbox"]
            defect_name = get_defect_name(i_+1)
            i_+=1

            raw_box.append([x_l, y_l, x_r, y_r, defect_name])
        
        passed.append(temps[i]['name'])
        
        img_name = temps[i]['name']
        img_path = './data/all_defect/detect/' + img_name.split('.')[0]+'/'+temps[i]['name']
        
        if (temps[i]['defect_name'] in ["花毛", "缝头", "缝头印", "虫粘", "破洞", "褶子", "织疵", "漏印", "蜡斑", "色差", "网折", "其他"]):
            num = 4
        else:
            num = 1
        for t in range(num):
    #         print(raw_box)
            image_data, box_data = get_random_data(img_path,raw_box,[1024,1024],max_boxes=len(raw_box))
            os.makedirs('./data/all_defect/detect/'+img_name.split('.')[0] + '_'+ str(t)) 
            img = Image.fromarray((image_data*255).astype(np.uint8))
            img.save('./data/all_defect/detect/' +img_name.split('.')[0] + '_'+ str(t)+'/'+img_name.split('.')[0] + '_'+ str(t) + '.jpg')
            
            for k in box_data:
                tmp_k = list(k)
#                 print(type(k))
                append  = dict(name=img_name.split('.')[0] + '_'+ str(t) + '.jpg',defect_name=reduce_defect_name(int(tmp_k[4])),
                               bbox=[round(tmp_k[0],2),round(tmp_k[1],2),round(tmp_k[2],2),round(tmp_k[3],2)])
                new.append(append)
            
    with open("./data/all_defect/Annotations/new.json", 'w') as f:
        json.dump(new,f,indent=4)  

参考

深度学习小技巧-目标检测当中的数据增强(Bubbliiiing 深度学习 教程):
https://www.bilibili.com/video/BV1ZA411b7L8

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值