pytorch源码解析系列-yolov4最核心技巧代码详解(3)- 数据处理以及图像增强

输入是啥?

现在 我们知道了yolo的模型,知道了模型获取的推理输出,在进入训练代码之前,我们需要了解到yolo数据的处理方式,以及用了何种图像增强方法。(不然连输入是啥都不知道,你怎么看的懂训练过程呢)

数据载入

其实数据载入这块没有必要单独拿出来说的,但是学会如何写collate function是很重要的
我们先看下数据源

## 如果你多进程报错 num_workers要改成1 大部分CPU训练机器都会出这个问题
## batchsize = batch // subdivisions 所以你就知道超参数这块实际上最终的batchsize是由这两个数据决定的
train_loader = DataLoader(train_dataset, batch_size=config.batch // config.subdivisions, shuffle=True,
                              num_workers=8, pin_memory=True, drop_last=True, collate_fn=collate)

只需要在collate_fn指定自己写的方法就行了,自己写可以把很多数据预处理都搞定在这个方法里

def collate(batch):
    images = []
    bboxes = []
    for img, box in batch:
        images.append([img])
        bboxes.append([box])
    #拿torch和numpy写都行,反正都要最后转成torch的
    #这边就是数据的标准预处理了,把格式处理成[B,C,H,W] 再除以255
    images = np.concatenate(images, axis=0)
    images = images.transpose(0, 3, 1, 2)
    images = torch.from_numpy(images).div(255.0)
    bboxes = np.concatenate(bboxes, axis=0)
    bboxes = torch.from_numpy(bboxes)
    return images, bboxes

Mosaic图像增强

小目标的AP一般比中目标和大目标低很多,而且小目标的分布并不均匀,所以作者用Mosaic处理这种问题
CutMix数据增强:两张图片进行拼接
然后给他变形一下↓
Mosaic数据增强:4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接。
好处就是,一次把4个图片拧一块,batch直接4倍了,岂不美哉?
看看代码如何实现的:(注:代码实现较老,没有用torchvision)

#yolo的Dataset写法不会的建议先学下基础 这里的代码实际上没必要,
#dataset的label文件是指定一个txt的 你如果跑过yolo4的训练就知道要自己制作train.txt
class Yolo_dataset(Dataset):
    def __init__(self, lable_path, cfg, train=True):
        super(Yolo_dataset, self).__init__()
    #这边参数的意思是 mixup=4是用 mosaic+cutmix, 2是只用mixup,3是mosaic 。
        if cfg.mixup == 2:
            print("cutmix=1 - isn't supported for Detector")
            raise
        elif cfg.mixup == 2 and cfg.letter_box:
            print("Combination: letter_box=1 & mosaic=1 - isn't supported, use only 1 of these parameters")
            raise

        self.cfg = cfg
        self.train = train
		# label载入 每张图片的里面分类都载进字典
        truth = {
   }
        f = open(lable_path, 'r', encoding='utf-8')
        for line in f.readlines():
            data = line.split(" ")
            truth[data[0]] = []
            for i in data[1:]:
                truth[data[0]].append([int(float(j)) for j in i.split(',')])

        self.truth = truth
        self.imgs = list(self.truth.keys())

重点在下面mosiac的实现:

	# 每次从dataset拿数据的时候,都会随机抽4张图片做mosiac
    def __getitem__(self, index):
        if not self.train:
            return self._get_val_item(index)
        img_path = self.imgs[index]
        #从label里拿到类别bboxes
        bboxes = np.array(self.truth.get(img_path), dtype=np.float)
        img_path = os.path.join(self.cfg.dataset_dir, img_path)
        use_mixup = self.cfg.mixup
        # 一半概率不用增强
        if random.randint(0, 1):
            use_mixup = 0
		# mixup==3是使用mosaic 
        if use_mixup == 3:
            min_offset = 0.2 #指定剪切率之后 随机从宽高剪切一个区域
            cut_x = random.randint(int(self.cfg.w * min_offset), int(self.cfg.w * (1 - min_offset)))
            cut_y = random.randint(int(self.cfg.h * min_offset), int(self.cfg.h * (1 - min_offset)))

        r1, r2, r3, r4, r_scale = 0, 0, 0, 0, 0
        dhue, dsat, dexp, flip, blur = 0, 0, 0, 0, 0
        gaussian_noise = 0

        out_img = np.zeros([self.cfg.h, self.cfg.w, 3])
        out_bboxes = []
		#这边就知道 use_mixup里数字的意思了,0就是不用 只循环1次,3是mosiac,循环4次
        for i in range(use_mixup + 1):
            if i != 0:
            	#不是第一张图片 就从图片库里随便抽一张做拼接
                img_path = random.choice(list(self.truth.keys()))
                bboxes = np.array(self.truth
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值