2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 计算机视觉之图像增广(翻转 随机裁剪 颜色变化[亮度 对比度 饱和度 色调])

计算机视觉之图像增广(翻转 随机裁剪 颜色变化[亮度 对比度 饱和度 色调])

时间:2022-08-03 06:26:12

相关推荐

计算机视觉之图像增广(翻转 随机裁剪 颜色变化[亮度 对比度 饱和度 色调])

随着深度学习的进步和硬件的更新迭代,计算机视觉技术也得到了更大的提升,在计算机视觉领域,经常要训练深度学习的模型,而训练模型的最终目的是为了更好的应用到实际当中去,那就要解决一个精度问题和泛化能力,对于泛化能力的提升,前面也做了很多的工作,这篇主要是讲解图像的增广,减小对训练数据集的某些属性的依赖,从而测试的时候可以得到更好的泛化能力。

图像增广(image augmentation)技术是通过对训练图像做一系列的改变,产生一些相似但不相同的训练样本,比如随机裁剪,使得目标出现在不同位置,减小模型对其位置的依赖;调整亮度、色彩等因素,减小模型对色彩的敏感度等,这些操作最终都是为了提高泛化能力。

我准备了一张宽500,高400像素的猫的图片,在画布中显示看下效果,注意坐标的表示:

import d2lzh as d2limport mxnet as mxfrom mxnet import autograd,gluon,image,init,ndfrom mxnet.gluon import data as gdata,loss as gloss,utils as gutilsimport sysimport timed2l.set_figsize()img=image.imread('cat.jpg')d2l.plt.imshow(img.asnumpy()) #img.shape:(400,500,3)# 如果使用Jupter Notebook可以不写下面这个show# 将会显示<matplotlib.image.AxesImage at 0x14248272808> 和一张画布图片,注意坐标的起始位置d2l.plt.show()

为了后续便于观察这张猫的图像,做了增广之后的效果,我们在画布上定义一个显示多行多列的图片的函数:

d2l.set_figsize()img=image.imread('cat.jpg')#d2lzh包中已有def show_images(imgs,num_rows,num_cols,scale=2):figsize=(num_cols*scale,num_rows*scale)_,axes=d2l.plt.subplots(num_rows,num_cols,figsize=figsize)for i in range(num_rows):for j in range(num_cols):axes[i][j].imshow(imgs[i*num_cols+j].asnumpy())#隐藏X,Y轴axes[i][j].get_xaxis().set_visible(False)axes[i][j].get_yaxis().set_visible(False)return axes#将每个图片做增广然后显示def apply(img,aug,num_rows=2,num_cols=4,scale=1.5):Y=[aug(img) for _ in range(num_cols*num_rows)]show_images(Y,num_rows,num_cols,scale)

然后分别看下不同随机增广后的效果:

左右翻转

apply(img,gdata.vision.transforms.RandomFlipLeftRight())

上下翻转

apply(img,gdata.vision.transforms.RandomFlipTopBottom())

随机位置裁剪(原面积的10%~100%,高宽比05~2),然后将宽高再缩放到200像素

shape_aug=gdata.vision.transforms.RandomResizedCrop((200,200),scale=(0.1,1),ratio=(0.5,2))apply(img,shape_aug)

亮度变化(1-0.5到1+0.5)

apply(img,gdata.vision.transforms.RandomBrightness(0.5))

色调变化

apply(img,gdata.vision.transforms.RandomHue(0.5))

创建RndomColorJitter实例同时设置亮度、对比度、饱和度、色调的变化

color_aug=gdata.vision.transforms.RandomColorJitter(brightness=0.5,contrast=0.5,saturation=0.5,hue=0.5)apply(img,color_aug)

Compose组合叠加多个图像增广方法

augs=gdata.pose([gdata.vision.transforms.RandomFlipLeftRight(),color_aug,shape_aug])apply(img,augs)d2l.plt.show()

训练CIFAR-10数据集

CIFAR-10也是一个常用的数据集,没有的情况,CIFAR10方法将会自动下载。我们来看下这个数据集的大小,以及显示前面32张图,这个训练数据集是由50000张,高宽是32,通道是3的图像组成,测试集是10000张,里面的类别还是蛮多的,动物、车、船、飞机等

show_images(gdata.vision.CIFAR10(train=True)[0:32][0], 4, 8, scale=0.8)print(gdata.vision.CIFAR10(train=True)._data.shape)#(50000, 32, 32, 3)

一般都是在训练的时候进行图像的增广,而在预测时不应用。

# 训练数据集做增广# ToTensor转换成MXNet需要的格式(批处理大小,通道,高,宽)(N,C,H,W)flip_aug=gdata.pose([gdata.vision.transforms.RandomFlipLeftRight(),gdata.vision.transforms.ToTensor()])# 预测时不做增广no_aug=gdata.pose([gdata.vision.transforms.ToTensor()])# 加载数据集并应用图像增广num_works = 0 if sys.platform.startswith('win32') else 4def load_cifar10(is_train, augs, batch_size):return gdata.DataLoader(gdata.vision.CIFAR10(train=is_train).transform_first(augs), batch_size=batch_size, shuffle=is_train, num_workers=num_works)

使用ResNet-18模型与Adam优化算法来训练

def train_with_data_aug(train_augs, test_augs, lr=0.001):batch_size, ctx, net = 256, d2l.try_all_gpus(), d2l.resnet18(10)net.initialize(ctx=ctx, init=init.Xavier())trainer = gluon.Trainer(net.collect_params(),'adam', {'learning_rate': lr})loss = gloss.SoftmaxCrossEntropyLoss()train_iter = load_cifar10(True, train_augs, batch_size)test_iter = load_cifar10(False, test_augs, batch_size)d2l.train(train_iter, test_iter, net, loss, trainer, ctx, num_epochs=10)train_with_data_aug(flip_aug, no_aug)

本人电脑配置低了,训练时很容易内存溢出:

mxnet.base.MXNetError: [10:20:10] c:\jenkins\workspace\mxnet-tag\mxnet\src\storage\./pooled_storage_manager.h:157: cudaMalloc failed: out of memory

于是将批量大小从256修改成64,然后就可以训练了,也只有一个gpu的情况,效果还是可以的,如下:

training on [gpu(0)]

epoch 1, loss 1.3235, train acc 0.526, test acc 0.659, time 124.6 sec

epoch 2, loss 0.7716, train acc 0.729, test acc 0.738, time 122.7 sec

epoch 3, loss 0.5864, train acc 0.797, test acc 0.801, time 122.8 sec

epoch 4, loss 0.4848, train acc 0.833, test acc 0.782, time 123.5 sec

epoch 5, loss 0.4053, train acc 0.861, test acc 0.808, time 123.7 sec

epoch 6, loss 0.3367, train acc 0.883, test acc 0.820, time 122.7 sec

epoch 7, loss 0.2883, train acc 0.900, test acc 0.828, time 124.3 sec

epoch 8, loss 0.2420, train acc 0.917, test acc 0.850, time 124.3 sec

epoch 9, loss 0.2026, train acc 0.930, test acc 0.840, time 124.9 sec

epoch 10, loss 0.1671, train acc 0.943, test acc 0.846, time 125.1 sec

其实对于组合叠加增广,在前面的WGAN(Wasserstein生成对抗网络)源码的讲解已有使用,如下:

import torchvision.transforms as transformsimport torchvision.datasets as dsetdataset = dset.CIFAR10(root=opt.dataroot, download=True,transform=pose([transforms.Resize(opt.imageSize),transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),]))

可以看出PyTorch框架的写法与MXNet框架的方法差不多,一般也是一些语法细节的区别。PyTorch是来自import torchvision.transforms as transforms这个模块,而MXNet是来自from mxnet.gluon import data as gdata里面的gdata.vision.transforms这个模块。

关于ToTensor()转换形状的函数,做个示例:

transformer = gdata.vision.transforms.ToTensor()imgs = nd.random.uniform(0, 255, (4, 2, 3)).astype(dtype=np.uint8)print(transformer(imgs))#会将(4,2,3)形状转换成(3,4,2)的[0,1)的浮点数

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。