通用数据增强方法(Data Argumentation)

 

argumentation

通用数据增强方法(Data argumentation

1、前言

机器学习尤其是深度学习中,为了防止模型过拟合,数据增强也是一种非常有效的方法,好多牛逼的模型除了网络结构精妙意外,在数据(比较吃数据的有监督深度学习)上也做了不可忽视工作,才有state of the art的效果。来看一张图

C10和C100是没有经过数据增强的训练效果,C10+和C100+则是经过数据增强的效果,提升非常明显……,这个是分类的错误率。在目标检测领域,好的算法都采用了精妙的数据增强,如YOLOv2&v3、SSD、faster-RCNN和MASK-RCNN等。

2、数据增强

2.1 随机裁切(random crop)

  随机裁切几乎是所有深度学习框架训练都具有的数据增强方法,在很多有名的深度学习网络(VGG,AlexNet,GoogleNet,ResNet……)的训练中,对输入256*256的图像,通常会以224或227的窗口随机获得子图像作为训练,而在测试时则是以图像中心的子块(Patch)。最终使用则直接将图像resize到训练时用的crop size大小。实现也是比较简单,在红色区域内随机取点作为滑窗左上角顶点。

Python实现:

 import numpy.random as npr  def randomCrop(img,size_h,size_w):      rows,cols=img.shape[:2]      left_h=npr.randint(0,rows-size_h)      left_w=npr.randint(0,cols-size_w)      crop_img=img[left_h:left_h+size_h,left_w:left_w+size_w]      return crop_img

2.2 翻转(左右上下)

  左右翻转也叫做水平翻转或镜像(mirror),将图像的左右部分以图像垂直中轴线为中心进行镜像对换。假设原图像高度为h,宽度为w,原图像某一像素点P(x0,y0), 经过水平镜像变换后为P(w-1-x0,y0),矩阵表示:

Python代码(左右镜像):

 #水平翻转 def  horizontalFlip(img):     size = img.shape  # 获得图像的形状     iLR = img.copy()  # 获得一个和原始图像相同的图像,注意这里要使用深度复制     h = size[0]     w = size[1]     for i in range(h):  # 元素循环         for j in range(w):             iLR[i, w - 1 - j] = img[i, j]     return iLR  #垂直翻转 def verticalFlip(img):     size = img.shape  # 获得图像的形状     iLR = img.copy()  # 获得一个和原始图像相同的图像,注意这里要使用深度复制     h = size[0]     w = size[1]     for i in range(h):  # 元素循环         for j in range(w):             iLR[ h- 1 - i,j] = img[i, j]     return iLR 

2.3 颜色抖动(color jitter)

颜色抖动是指对图像的曝光度(exposure)、饱和度(saturation)和色调(hue)进行随机变化形成不同光照及颜色下的图片,达到数据增强的目的,尽可能使得模型能够使用不同光照条件小的情形,提高模型泛化能力。

YOLOv2-v3的目标检测就用到了这一数据增强方法,YOLO在训练的每一BATch中对训练数据进行在线数据增强(包括颜色抖动) ,实现上首先将图像变换到HSV颜色空间,然后对图像在HSV颜色空间中随机的改变图像的曝光度、饱和度和色调,然后再将变换后的图像转到RGB空间。具体实现代码可以参考YOLO源码(image.c),

 void random_distort_image(image im, float hue, float saturation, float exposure)  {      float dhue = rand_uniform_strong(-hue, hue);      float dsat = rand_scale(saturation);      float dexp = rand_scale(exposure);      distort_image(im, dhue, dsat, dexp);  }  void distort_image(image im, float hue, float sat, float val)  {      rgb_to_hsv(im);      scale_image_channel(im, 1, sat);//改变S通道,该通道的像素值乘上随机sat值      scale_image_channel(im, 2, val);//改变V通道,该通道的像素值乘上随机val值      int i;      for(i = 0; i < im.w*im.h; ++i){          im.data[i] = im.data[i] + hue;//改变H通道,该通道像素值加随机hue值          if (im.data[i] > 1) im.data[i] -= 1;          if (im.data[i] < 0) im.data[i] += 1;      }      hsv_to_rgb(im);      constrain_image(im);  }

对于部分任务也可以借鉴该方法,对样本进行离线或者在线的数据增强。

2.4 噪声(高斯噪声)

一般对图像加入高斯噪声可以使得图像变得模糊,从而模拟模糊情况。Python实现

 from skimage import util def gaussNoise(img):      noise_img=util.random_noise(img,mode='gaussian')      result=util.img_as_ubyte(noise_img)      return result

2.5 旋转

图像旋转一般是以图像中心为旋转中心进行随机旋转(一般有一个正负角度约束),而。Python实现

 from skimage.transform import rotate def img_rotate(img,angle):      return rotate(img,angle)
 rotate_limit=(-30, 30)  theta = np.pi / 180 * np.random.uniform(rotate_limit[0], rotate_limit[1]) #逆  img_rot = img_rotate(img, theta)
 #OpenCV实现
 def cv_rotate(img,center,angle,scale):      rows,cols=img.shape[:2]      M = cv2.getRotationMatrix2D(center, angle, scale)      dst = cv2.warpAffine(img, M, (cols, rows))      return dst

2.6 平移

  1)图像沿着X轴或Y轴的平移有以下四种情况:

 def move_right(img,dis):      size = img.shape  # 获得图像的形状      iLR = img.copy()  # 获得一个和原始图像相同的图像,注意这里要使用深度复制      h = size[0]      w = size[1]      for i in range(h):          for j in range(w):              if j-dis>0:                  iLR[i,j]=img[i,j-dis]              else:                  iLR[i, j] =0      return iLR    def move_left(img,dis):      size = img.shape  # 获得图像的形状      iLR = img.copy()  # 获得一个和原始图像相同的图像,注意这里要使用深度复制      h = size[0]      w = size[1]      for i in range(h):          for j in range(w):              if j+dis0:                  iLR[i,j]=img[i-dis,j]              else:                  iLR[i, j] =0      return iLR

2)图像沿着任意向量平移

参考:https://blog.csdn.net/sty945/article/details/79387054

 def translate(image, x, y): #3      M = np.float32([[1, 0, x], [0, 1, y]]) #4  //X轴移动x, Y中移动y      shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0])) #5      return shifted #6

2.7 缩放

  全卷积网络对于尺度没有严格要求,如目标检测算法yolov2-v3在训练过程中会对样本进行随机尺度变换(每隔10步变换一次),实现多尺度训练,进而跨尺度特征融合。同时也使得模型对于不同尺度的图像有更强的适应性。

 from skimage.transform import rescale def image_resize(img,scale):      result=rescale(img,scale)      return result

2.8 PCA jitter

PCA jitter是实际上对RGB颜色空间添加扰动,从而达到对RGB颜色添加噪声的目的,具体为对RGB空间做PCA,然后对主成分做一个(0, 0.1)的高斯扰动。最早使用是在2012年的AlexNet,从论文实验中可以看出,PCA jitter对于分类的性能提升比较显著。

 def PCA_Jittering (img):      img = np.asanyarray(img, dtype='float32')      img = img / 255.0      img_size = img.size // 3  # 转换为单通道      img1 = img.reshape(img_size, 3)      img1 = np.transpose(img1)  # 转置      img_cov = np.cov([img1[0], img1[1], img1[2]])  # 协方差矩阵      lAMDa, p = np.linalg.eig(img_cov)  # 得到上述协方差矩阵的特征向量和特征值       # p是协方差矩阵的特征向量      p = np.transpose(p)  # 转置回去        # 生成高斯随机数********可以修改      alpha1 = random.gauss(0, 1)      alpha2 = random.gauss(0, 1)      alpha3 = random.gauss(0, 1)       # lamda是协方差矩阵的特征值      v = np.transpose((alpha1 * lamda[0], alpha2 * lamda[1], alpha3 * lamda[2]))  # 转置       # 得到主成分      add_num = np.dot(p, v)       # 在原图像的基础上加上主成分      img2 = np.array([img[:, :, 0] + add_num[0], img[:, :, 1] + add_num[1], img[:, :, 2] + add_num[2]])       # 现在是BGR,要转成RBG再进行保存      img2 = np.swapaxes(img2, 0, 2)      img2 = np.swapaxes(img2, 0, 1)      return img2

相关阅读

如何增强网站吸引力

 如何增强网站吸引力?有些网站虽然设计效果很炫酷,看起来比较高端有品位,但是如果用户不认可,网站也难以带来预期的效果。毕竟网站的

怎么让网站的数据更有利用价值

 网站数据分析是通过观察、调查、实验、测量等结果,通过数据的显示形式把网站各方面情况反映出来,使运营者更加了解网站的运营情况

数据库学习的一些基础知识及常用命令

数据库 “数据库”是以一定方式储存在一起、能够多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合。 【基本

数据结构之二叉排序树(C语言实现)

一、基本概念 1.二叉排序树 二叉排序树(Binary sort tree,BST),又称为二叉查找树,或者是一棵空树;或者是具有下列性质的二叉树: (1)若

数据仓库

操作型数据(如:某超市昨天卖了一箱啤酒,收银员实际收到100,找零20元)。 特点:细节化,分散化。 决策型数据(如:该超市上个月一共卖了多少瓶

发表评论