数据规范-Normalization是深度学习中咱们很容易忽视,也很容易出错的问题。咱们训练的全部数据在输入到模型中的时候都要进行一些规范化。例如在pytorch中,有些模型是经过规范化后的数据进行训练的,因此咱们在使用这些预训练好的模型的时候,要注意在将本身的数据投入模型中以前要首先对数据进行规范化。python
在pytorch附带的模型中咱们能够选择预训练模型:git
import torchvision.models as models
resnet18 = models.resnet18(pretrained=True)
alexnet = models.alexnet(pretrained=True)
squeezenet = models.squeezenet1_0(pretrained=True)
vgg16 = models.vgg16(pretrained=True)
densenet = models.densenet161(pretrained=True)
inception = models.inception_v3(pretrained=True)复制代码
预训练模型即模型中的权重参数都被训练好了,在构造模型后读取模型权重便可。github
可是有些东西须要注意:网络
也就是说,模型设计的正确只是第一步,咱们输入的图像数据的格式的正确性也是特别重要的,咱们日常输入的图像大部分都是三通道RGB彩色图像,数据范围大部分都是[0-255],也就是一般意义上的24-bit图(RGB三通道各8位)。在pytorch中有专门的一些模块:transforms
模块来对图像进行一些预处理操做:dom
transform = transforms.Compose([
transforms.RandomResizedCrop(100),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])复制代码
并且在pytorch的官方介绍中也提到了,pytorch使用的预训练模型搭配的数据必须是:学习
也就是3通道RGB图像(3 x H x W),并且高和宽最好不低于224(由于拿来作预训练的模型大小就是224 x 224),而且图像数据大小的范围为[0-1],使用mean和std去Normalize。spa
为何这样说官方也说了,由于全部的预训练模型是使用通过normal后的数据获得的,因此咱们输入的数据也必须通过格式化,不然很容易出现损失爆炸。设计
为何咱们要进行格式化呢?3d
咱们选取一组人脸图片来举个例子,这组人脸图像的格式是这样的:code
这里从Labeled faces in the Wild数据集中取出100我的脸图像,这个数据集中每张图像对应着一个名字,并且每张图像的脸都差很少被定位到了中间。
咱们有了这一组数据后,接下来要作的通常是这几个步骤:
在图像输入到神经网络以前要注意,每张图都要保证同样的尺寸和大小。大部分的模型要求输入的图像的形状是正方形,通常都是256 x 25六、128 x 128 、 64 x 64或者其余的形状,这种方形是最好进行训练的。固然其余形状也是能够的,好比长方形,但若是是长方形的话就要注意设计卷积层通道的时候要稍微注意一下。总之,咱们都是先对图像极性crop,crop成正方形,通常取图像的中心位置。
好比下面这张人脸图(256 x 256)就很舒服,呃,由于不用修剪了。
比例也是比较重要的,图像形状肯定了,可是有些时候咱们在训练时随着卷积层愈来愈深,特征图愈来愈小,为了实现一些功能,咱们所须要的图像的比例也要稍微改变一下。不管是放大仍是缩小,假如缩小到100像素,咱们就让上面的图像乘以0.39(100/256)。可是放大和缩小时都要考虑四舍五入,是floor仍是ceil就各有见地了。
一组图像集的均值和方差能够很好地归纳这组图像的信息和特征。均值就是一组数据的平均水平,而方差表明的是数据的离散程度。下图是以前展现的100张人脸图的均值图和方差图,能够看到左面的均值图中,明显看到一个模糊的人脸。而且能够看出100张人脸图中,人的脸是分布在中心的,而右边的方差图能够看到中心颜色偏暗(小于100),四周偏亮(大于100),也就是说明100张图中,图像四周的分布明显变化比较剧烈。
在这样Normalize以后,神经网络在训练的过程当中,梯度对每一张图片的做用都是平均的,也就是不存在比例不匹配的状况。而在normalize以前每张图片的特征分布都是不同的,有的陡峭有的平缓,若是不进行预处理,那么在梯度降低的时候有些图片的特征值比较大而有些则比较小,这样梯度运算没法顾及到不一样特征不一样维度不一样层次的降低趋势,这样很难进行训练,loss会不停的震荡。
说到重点了,咱们在文章最开始说的格式化,其实即便在一组图中,每一个图像的像素点首先减去全部图像均值的像素点,而后再除以方差。这样能够保证全部的图像分布都类似,也就是在训练的时候更容易收敛,也就是训练的更快更好了。另外,不一样图像像素点范围的mean和std是不同的,通常咱们输入的都是[0-1]或者[0-255]的图像数据,在pytorch的模型中,输入的是[0-1],而在caffe的模型中,咱们输入的是[0-255]。
下面这个图就是在格式化后的100张人脸图。
显然,格式化就是使数据中心对齐,如cs231n中的示例图,左边是原始数据,中间是减去mean的数据分布,右边是除以std方差的数据分布,固然cs231n中说除以std其实能够不去执行,由于只要数据都遵循必定范围的时候(好比图像都是[0-255])就没有必要这样作了。
有时候须要输入不是彩色图,这时候可能须要对数据进行降维操做,也就是RGB->GRAY,固然还有颜色通道和色彩通道的改变,例如RGB->BGR,或者RGB->YUV。颜色通道的改变是为了实现不一样的任务和功能,这就要视状况来决定。
在pytorch的transforms模块中有不少的变化,均可以用来作数据加强,好比图像翻转,旋转,极坐标变换,均可以获得不一样的“原始图”从而加大训练变量达到很好的训练效果。这里很少说,这个须要单独说明。
文章来源于OLDPAN博客,欢迎来访:Oldpan博客
欢迎关注Oldpan博客公众号,持续酝酿深度学习质量文: