Resnet-152的图像预处理

152层的 Resnet的图片输入尺寸为224*224,那对于大多数情况,图片的分辨率都是大于这个数值,那么该如何把图片的尺寸裁剪到这样一个尺寸,又如何进行数据增强呢?

第一,调整尺寸(Rescaling)
先将图片较短的那条边,随机缩放到[256,480]这样一个范围内。注意,此时的图片是等比例缩放的。举个例子,原始图片的尺寸为[1000,800,3],假设图片短边缩放到256,那么此时图片的尺寸即为[320,256,3],即图片的长宽比例是不变的。

第二,裁剪(Cropping)
将图片进行水平翻转,然后从原图片和翻转后的图片中,随机裁剪出224*224的图片。那到底裁几张呢?Resnet没有明说。。。我觉得还是看自己计算机的配置。因为从理论上来说,假设裁剪过后的图片尺寸为[256,256,3],如果按照步长为1,最多可以裁剪出(256-224)*(256-224) = 1024张,再加上水平翻转的图片,还要乘以个2,也就是2048张图片。一张图片扩展了2048倍,肯定是非常夸张了,那所以,我的做法是随机裁剪个10张,就差不多了。

第三,归一化(Normalizing)
具体做法就是对于整个训练集图片,每个通道分别减去训练集该通道平均值。

第四,颜色抖动(color shifting)
这里resnet 引用的是Alexnet 2012年提出的做法,对于每张图片,每个通道的数据先由二维转成一维(例如256*256*3,转成65536*3),再对该图片(65536*3)三个通道求出协方差矩阵(3*3),再求出协方差矩阵的特征向量p和特征值λ,最后按照下图这样一个公式进行转换进行变换, 这里α是一个服从均值为0,方差为0.1的随机变量(简单来说就是一个很小的随机数),[p1,p2,p3]是一个3*3的矩阵,[λ1,λ2,λ3]的转置是一个3*1的矩阵,最后矩阵相乘的结果也是个3*1的矩阵,刚好可以和原图片3个通道相加,这里执行的是python中的广播机制,即图片每个通道65536个像素点都加上同一个数。


这样就完成了颜色的随机抖动,不过我一直想不明白特征值乘以特征向量有着什么样的数学解释,如果您知道,请联系我(QQ380922457,知乎ID:梁航铭)

第五,测试方法
先抽取测试集图像的四个角以及中间的224×224部分,还包括镜像共有10个部分(Patch)结果,再对这10个输入的测试结果做平均作为我们对该测试集图片的最终测试结果。

代码如下

from random import normalvariate
import numpy as np
import os
from PIL import Image
from random import randint
IMAGE_PATH ="/Users/lianghangming/Desktop/"


# 等比例地把图片较短的一边缩放到区间[256,480]
def rescale(image):
  w = image.size[0]
  h = image.size[1]
  sizeMax =480
  sizeMin =256
  random_size = randint(sizeMin,sizeMax)
  if w < h:
    return image.resize((random_size,round(h/w * random_size)))
  else:
    return image.resize((round(w/h * random_size),random_size))


# 随机裁剪图片
def random_crop(image):
  w = image.size[0]
  h = image.size[1]
  size =224
  new_left = randint(0,w - size)
  new_upper = randint(0,h - size)
  return image.crop((new_left,new_upper,size+new_left,size+new_upper))


# 水平翻转图片
def horizontal_flip(image):
  returnimage.transpose(Image.FLIP_LEFT_RIGHT)


# 图片均值归一化
def nomalizing(image,mean_value,add_num):
  image = np.array(image)
  # image = image.astype(float)
  for i in range(3):
    add_num = add_num.astype(int)
    image[:,:,i] = (image[:,:,i] - mean_value[i] + add_num[i])#/std[i]
  return image


# 求整个训练集图片的均值
def mean(image_dir):
  for file in os.listdir(image_dir):
    iffile.endswith("jpg"):
    file = os.path.join(image_dir,file)
    image = np.array(Image.open(file))
    image = np.reshape(image,[-1,3])
    try:
      image_array = np.concatenate((image_array,image),0)# 第一张图片不存在image_array
    except:
      image_array = image
      mean_value = image_array.mean(0)
      # std_value = image_array.std(0)
  return mean_value


# 求整个训练集图片的PCA
def pca(image_dir,mean_value):
  for file in os.listdir(image_dir):
    iffile.endswith("jpg"):
    file = os.path.join(image_dir,file)
    image = np.array(Image.open(file))
    image = np.reshape(image,[-1,3])
    image = image.astype(float)
    image -= mean_value# 零均值化
    # image = image/255.0
    try:
      image_array = np.concatenate((image_array,image),0)# 第一张图片不存在image_array
    except:
      image_array = image
# 求协方差矩阵
   image_cov = np.cov([image_array[:,0],image_array[:,1],image_array[:,2]])
   lambd,p = np.linalg.eig(image_cov)
   alpha0 = normalvariate(0,0.1)
   alpha1 = normalvariate(0,0.1)    alpha2 = normalvariate(0,0.1)
   v = np.transpose((alpha0*lambd[0],alpha1*lambd[1],alpha2*lambd[2]))
   add_num = np.dot(v,np.transpose(p))
   return add_num

如有错误,欢迎指正

你可能感兴趣的:(Resnet-152的图像预处理)