深度学习(4)数据预处理-均值减法


当样本类别差异较大,减少样本差异,对样本数据进行预处理,这也是提高模型泛华能力的一种。
典型的预处理方法有三种: 均值减法、均一化、白化。先简单总结下均值减法。

均值减法

大规模的物体识别经常会使用均值减法对数据进行预处理。如图所示计算所有训练样本的均值图像时,可使用如下公式:
在这里插入图片描述
训练样本和均值文件相减可得到差分图像,然后将其作为样本数据输入网络;

这样各数据的平均值就会变位零,图像整体的亮度变化就能得到抑制

1、什么是均值?

对于每帧图像来说,均值分为两种:image mean 和 pixel mean。

  • image mean:
    简单的说,读入一张彩色图像,假设是(N * N * 3),这时候求出image mean的话,也是N* N* 3,相当于把所有训练集在同一个空间位置上的像素的对应通道求了均值,也就是caffe里生成的mean.binaryproto文件

  • pixel mean:
    pixel mean是把训练集里面所有图片的所有R通道像素,求了均值,G、B通道类似,也就是不考虑空间位置了。所以求出来就是三个数值(R_mean,G_mean,B_mean),所以其实就是把image mean再求了一次均值。

  • 去均值选择两者区别:
    在用DIGITS的时候,遇到了减去均值是用image mean还是pixel mean,并且这个区别会导致最后用训练好的网络模型来测试之前训练的时候用到的验证集却达不到训练时候测试的准确率,(用pixel mean就能获得和训练时候的一样的准确率),一直很疑惑两者的区别,好好研究了一下发现是这样的。
    .
    发现去均值是为了对图像进行标准化,可以移除图像的平均亮度值 (intensity)。很多情况下我们对图像的亮度并不感兴趣,而更多地关注其内容,比如在对象识别任务中,图像的整体明亮程度并不会影响图像中存在的是什么物体。这时对每个数据点移除像素的均值是有意义的。而另一个资料显示在每个样本上减去数据的统计平均值可以移除共同的部分,凸显个体差异。其效果如下所示:
    在这里插入图片描述
    可以看到天空的纹理被移除了,凸显了汽车和高楼等主要特征。
    .
    我们在计算图像均值时,应该只需针对于训练集进行计算,而非使用测试集,验证集和其他以外的数据集进行计算,否则否则就违背了深度学习的原则:模型训练过程仅能从训练模型中获取信息。所以imagenet的均值我们不应该使用。但是只要对比实验中使用同样的方式处理,也是可以的。

详细可参考https://github.com/NVIDIA/DIGITS/issues/1551

2、为什么要去均值?

1)从主成分分析(PCA)入手解释

  • 就是数据特征标准化

特征标准化指的是(独立地)使得数据的每一个维度具有零均值和单位方差。这是归一化中最常见的方法并被广泛地使用(例如,在使用支持向量机(SVM)时,特征标准化常被建议用作预处理的一部分)。在实际应用中,特征标准化的具体做法是:首先计算每一个维度上数据的均值(使用全体数据计算),之后在每一个维度上都减去该均值。下一步便是在数据的每一维度上除以该维度上数据的标准差。

对于自然图像,更多的是做图像零均值化,并不需要估计样本的方差。这是因为在自然图像上进行训练时,对每一个像素单独估计均值和方差意义不大,因为(理论上)图像任一部分的统计性质都应该和其它部分相同,图像的这种特性被称作平稳性(stationarity)。

对于图像,这种归一化可以移除图像的平均亮度值 (intensity)。很多情况下我们对图像的照度并不感兴趣,而更多地关注其内容,比如在对象识别任务中,图像的整体明亮程度并不会影响图像中存在的是什么物体。这时对每个数据点移除像素的均值是有意义的。

2)从深度学习反向传播计算入手

了解到基本在deep learning中只要你是使用gradient descent来训练模型的话都要在数据预处理步骤进行数据归一化。当然这也是有一定原因的。

根据公式

在这里插入图片描述
如果输入层 x 很大,在反向传播时候传递到输入层的梯度就会变得很大。梯度大,学习率就得非常小,否则会越过最优。在这种情况下,学习率的选择需要参考输入层数值大小,而直接将数据归一化操作,能很方便的选择学习率。而且受 x 和 w 的影响,各个梯度的数量级不相同,因此,它们需要的学习率数量级也就不相同。对 w1 适合的学习率,可能相对于 w2 来说会太小,如果仍使用适合 w1 的学习率,会导致在 w2 方向上走的非常慢,会消耗非常多的时间,而使用适合 w2 的学习率,对 w1 来说又太大,搜索不到适合 w1 的解。

3、代码

1)图像去均值(image mean)

# Normalize the data: subtract the mean image
X_train = sum_img
print ("减去均值之前,X_train的第一幅图像的RGB通道的第一个通道的图像数值32*32:")
print (X_train[0][0])
mean_image = np.mean(X_train, axis=0)    
#shape=(3,32, 32) 这里axis=0表示按照列算均值,在这里是将所有图像的R图上的每个像素点的数值取平均,G,B通道同理,这里是image mean。
X_train_m = X_train - mean_image

print ("-----------------------------------------------")
print ("mean_image的形状以及数值")
print (mean_image.shape)
print (mean_image[0])
print ("-----------------------------------------------")
print ("减去均值之后,X_train的第一幅图像的RGB通道的第一个通道的图像数值32*32:")
print (X_train_m[0][0])

输出:

减去均值之前,X_train的第一幅图像的RGB通道的第一个通道的图像数值32*32:
[[ 62  61  60 ...,  64  82  62]
 [ 62  63  61 ...,  77 114  64]
 [ 67  78 115 ..., 100 119  63]
 ..., 
 [161 159 159 ..., 152 157 156]
 [163 161 162 ..., 162 161 161]
 [169 167 167 ..., 167 167 167]]
-----------------------------------------------
mean_image的形状以及数值
(3, 32, 32)
[[ 121.33333333  114.66666667  113.83333333 ...,  134.          135.5
   130.66666667]
 [ 112.33333333  111.5         110.33333333 ...,  134.16666667
   136.16666667  125.16666667]
 [ 113.33333333  112.66666667  119.83333333 ...,  134.16666667  137.5
   123.66666667]
 ..., 
 [ 135.66666667  131.66666667  129.66666667 ...,   99.33333333   84.           86.        ]
 [ 129.16666667  125.5         128.5        ...,  112.16666667
    99.66666667  101.        ]
 [ 129.83333333  125.66666667  127.66666667 ...,  122.16666667
   112.33333333  109.66666667]]
-----------------------------------------------
减去均值之后,X_train的第一幅图像的RGB通道的第一个通道的图像数值32*32:
[[-59.33333333 -53.66666667 -53.83333333 ..., -70.         -53.5
  -68.66666667]
 [-50.33333333 -48.5        -49.33333333 ..., -57.16666667 -22.16666667
  -61.16666667]
 [-46.33333333 -34.66666667  -4.83333333 ..., -34.16666667 -18.5
  -60.66666667]
 ..., 
 [ 25.33333333  27.33333333  29.33333333 ...,  52.66666667  73.          70.        ]
 [ 33.83333333  35.5         33.5        ...,  49.83333333  61.33333333
   60.        ]
 [ 39.16666667  41.33333333  39.33333333 ...,  44.83333333  54.66666667
   57.33333333]]

2)像素均值(pixel mean)

import os
import cv2
from numpy import *

img_dir='.\img'
img_list=os.listdir(img_dir)
img_size=224
sum_r=0
sum_g=0
sum_b=0
count=0

for img_name in img_list:
    img_path=os.path.join(img_dir,img_name)
    img=cv2.imread(img_path)
    img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    img=cv2.resize(img,(img_size,img_size))
    sum_r=sum_r+img[:,:,0].mean()
    sum_g=sum_g+img[:,:,1].mean()
    sum_b=sum_b+img[:,:,2].mean()
    count=count+1

sum_r=sum_r/count
sum_g=sum_g/count
sum_b=sum_b/count
img_mean=[sum_r,sum_g,sum_b]
print (img_mean)

输出:

[122.30835127019559, 115.90339671024662, 99.094251567814624]

代码请访问github:csdn/Image-mean-data/

caffe中则有计算图像均值(image mean)和计算像素均值(pixel mean)工具代码。

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值