目标检测学习笔记——数据增强

目标检测的数据增强一般在写dataset自定义类时使用
pytorch一般在定义完模型后就转存到GPU上
在运用对tensor进行的方法前要把数据转化成张量

1.输入到模型前必须转化成tensor,所以可以在数据增强时利用torch.from_numpy(images).type(torch.FloatTensor).cuda()
这里数据在dataset和dataloader里都是ndarray,在传入模型前才转化成tensor

def fit_one_epoch(model_train, model, yolo_loss, loss_history, optimizer, epoch, epoch_step, epoch_step_val, gen, gen_val, Epoch, cuda):
    loss        = 0
    val_loss    = 0

    model_train.train()
    print('Start Train')
    with tqdm(total=epoch_step,desc=f'Epoch {epoch + 1}/{Epoch}',postfix=dict,mininterval=0.3) as pbar:
        for iteration, batch in enumerate(gen):
            if iteration >= epoch_step:
                break

            images, targets = batch[0], batch[1]
            with torch.no_grad():
                if cuda:
                    images  = torch.from_numpy(images).type(torch.FloatTensor).cuda()
                    targets = [torch.from_numpy(ann).type(torch.FloatTensor).cuda() for ann in targets]
                else:
                    images  = torch.from_numpy(images).type(torch.FloatTensor)
                    targets = [torch.from_numpy(ann).type(torch.FloatTensor) for ann in targets]
            #----------------------#
            #   清零梯度
            #----------------------#
            optimizer.zero_grad()
            #----------------------#
            #   前向传播
            #----------------------#
            outputs         = model_train(images)
             #----------------------#
            #   计算损失
            #----------------------#
            loss_value = yolo_loss(outputs, targets)

            #----------------------#
            #   反向传播
            #----------------------#
            loss_value.backward()
            optimizer.step()

            loss += loss_value.item()
            
            pbar.set_postfix(**{'loss'  : loss / (iteration + 1), 
                                'lr'    : get_lr(optimizer)})
            pbar.update(1)

  1. 在transforms时就转化成tensor
data_transforms = transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])

上述对data_transforms进行了四种变换,前两个是对PILImage进行的,分别对其进行随机大小和随机宽高比的裁剪,之后resize到指定大小224,以及对原始图像进行随机的水平翻转;

第三个transforms.ToTensor() 将PILImage转变为torch.FloatTensor的数据形式;

而最后一个Normalize则是对tensor进行的。

多种组合变换有一定的先后顺序,处理PILImage的变换方法(大多数方法)都需要放在ToTensor方法之前,而处理tensor的方法(比如Normalize方法)就要放在ToTensor方法之后。

一、torchvision.transforms

torchvision.transforms的数据增强方式竟然用Compose组合在一起使用,使用时只要直接调用即可,

tranform = torchvision.transforms.Compose([...])
img = transform(img)

添加链接描述PyTorch 学习笔记:transforms的二十二个方法(transforms用法非常详细)
pytorch中的torchvision.transforms模块详解
添加链接描述torchvision.transforms包的使用

transform1 = transforms.Compose([
    transforms.ToTensor(),# 先将PILimage或者ndarray转化成tensor
    transforms.Normalize(mean = [0.5, 0.5, 0.5], std = [0.5, 0.5, 0.5])
    # 再对每个通道的数据进行正则化,将(0,1)之间的数据转化成(-1,1)之间,这样更利于模型学习
    ]
)

transform3 = transforms.Compose([
        transforms.ToTensor(), 
        transforms.ToPILImage(),
        transforms.RandomCrop((100,100)),# RandomCrop是对PILImage进行,所以需要先用ToPILImage()
        ]
    )
img6 = transform3(img3)
print(img6.size)  # 100 * 100
img3.show()
img6.show()

(一) 裁剪(Crop)—— 中心裁剪:transforms.CenterCrop 随机裁剪:transforms.RandomCrop 随机长宽比裁剪:transforms.RandomResizedCrop 上下左右中心裁剪:transforms.FiveCrop 上下左右中心裁剪后翻转,transforms.TenCrop

(二) 翻转和旋转(Flip and Rotation) ——依概率p水平翻转:transforms.RandomHorizontalFlip(p=0.5) 依概率p垂直翻转:transforms.RandomVerticalFlip(p=0.5) 随机旋转:transforms.RandomRotation

(三) 图像变换(resize) ——transforms.Resize 标准化:transforms.Normalize 转为tensor,并归一化至[0-1]:transforms.ToTensor 填充:transforms.Pad 修改亮度、对比度和饱和度:transforms.ColorJitter 转灰度图:transforms.Grayscale 线性变换:
transforms.LinearTransformation() 仿射变换:transforms.RandomAffine 依概率p转为灰度图:transforms.RandomGrayscale 将数据转换为PILImage:transforms.ToPILImage transforms.Lambda:Apply a user-defined lambda as a transform.

(四) 对transforms操作,使数据增强更灵活 transforms.RandomChoice(transforms), 从给定的一系列transforms中选一个进行操作 transforms.RandomApply(transforms, p=0.5),给一个transform加上概率,依概率进行操作 transforms.RandomOrder,将transforms中的操作随机打乱

二、albumentations

albumentations使用时要用关键词参数image = img并且返回值不直接是增强后的图片,而是字典要用
transforms(image=img)[‘image’]访问。

def get_train_transforms():
    return Compose([
            RandomResizedCrop(CFG['img_size'], CFG['img_size']),
            Transpose(p=0.5),
            HorizontalFlip(p=0.5),
            #VerticalFlip(p=0.5),
            ShiftScaleRotate(p=0.5),
            HueSaturationValue(hue_shift_limit=0.2, sat_shift_limit=0.2, val_shift_limit=0.2, p=0.5),
            RandomBrightnessContrast(brightness_limit=(-0.1,0.1), contrast_limit=(-0.1, 0.1), p=0.5),
            Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], max_pixel_value=255.0, p=1.0),
            #CoarseDropout(p=0.5),
            #Cutout(p=0.5),
            ToTensorV2(p=1.0),
        ], p=1.)
  
        
def get_valid_transforms():
    return Compose([
            CenterCrop(CFG['img_size'], CFG['img_size'], p=1.),
            Resize(CFG['img_size'], CFG['img_size']),
            Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], max_pixel_value=255.0, p=1.0),
            ToTensorV2(p=1.0),
        ], p=1.)
self.transforms = transforms
if self.transforms:
	img = self.transforms(image=img)['image']

你可能感兴趣的:(目标检测学习笔记,pytorch,深度学习,机器学习)