目录
深度学习中图像预处理为什么要减去均值?
最近在看一些keras 代码的时候发现在图像的预处理过程中,总是会有类似于下面的这种操作:
# Subtract mean pixel and multiple by scaling constant
im[:,:,0] = (im[:,:,0] - 103.94) * 0.017
im[:,:,1] = (im[:,:,1] - 116.78) * 0.017
im[:,:,2] = (im[:,:,2] - 123.68) * 0.017
这其中的参数是作者给出的,
Notes
Due to compatibility reasons, several modifications have been made:
BGR mean values [103.94,116.78,123.68] are subtracted
scale: 0.017 is used, instead of the original std values for image preprocessing
ceil_mode: false is used in the first pooling layers ('pool1')
作者的数据集使用的是 ImageNet , 这里的 [103.94,116.78,123.68] 指的是 imagenet 里面所有训练集数据的平均像素值,
三个值 对应图像的 BGR,
那为什么要做这样的一种操作呢?
我在网上看了很多资料, 大体上可以总结为两种 :
1 、去均值是为了对图像进行标准化,可以移除图像的平均亮度值 (intensity)。很多情况下我们对图像的照度并不感兴趣,而更多地关注其内容,比如在对象识别任务中,图像的整体明亮程度并不会影响图像中存在的是什么物体。这时对每个数据点移除像素的均值是有意义的。
https://blog.csdn.net/weixin_37251044/article/details/81157344#fn:2
2、 在每个样本上减去数据的统计平均值可以移除共同的部分,凸显个体差异。
另外,正如该博客作者所说,我们在计算图像均值时,应该只需针对于训练集进行计算,而非使用测试集、验证集和其他以外的数据集进行计算,否则否则就违背了深度学习的原则:即 模型训练过程仅是从数据当中获取有效信息。
去均值的demo如下
import cv2
import numpy as np
shark_img = cv2.imread(r'/home/ldliukuo/图片/shark.jpg')
# shark_img[:, :, 0] = ((shark_img[:, :, 0] - 103.94) * 0.017) # channel B process
subtract_img = np.zeros(shape=(153, 220, 3), dtype=np.float32)
subtract_img[:, :, 0] = ((shark_img[:, :, 0] - 103.94) * 0.017)
subtract_img[:, :, 0] = ((shark_img[:, :, 0] - 116.78) * 0.017)
subtract_img[:, :, 0] = ((shark_img[:, :, 0] - 123.68) * 0.017)
cv2.namedWindow('org_shark', cv2.WINDOW_AUTOSIZE)
cv2.imshow('org_shark', shark_img)
cv2.namedWindow('sub_img', cv2.WINDOW_AUTOSIZE)
cv2.imshow('sub_img', subtract_img)
cv2.waitKey()
cv2.destroyAllWindows()
什么是平均像素值呢?
对于每帧图像来说,均值分为两种:image mean 和 pixel mean。
image mean:
简单的说,读入一张彩色图像,假设是(N*N*3),这时候,求出image mean的话,就也是N*N*3,相当于把所有训练集在同一个空间位置上的像素的对应通道求了均值,也就是caffe里生成的mean.binaryproto文件,(以一个具体的点 ,位于B通道上的(x, y)处为例, image mean 就是训练集上所有图像在该点处的像素值的平均,因为每幅图像都有 B通道, B通道上也都有(x, y)这个点, 所以只需要简单的求个均值就好了 )
pixel mean:
而pixel mean的话,其实是把训练集里面所有图片的所有R通道像素,求了均值,G,B通道类似,也就是不考虑空间位置了。所以求出来就是三个数值(R_mean,G_mean,B_mean),所以其实就是把image mean再求了一次均值。(这个就更好理解了, 训练集都有图像的 R 通道 上 全部的像素点求均值)
一些其他的图像预处理操作
截断标准差
注:待处理的数据 X∈ℝd×N,N 表示样本的个数,d 则是单个样本的维度;
这里比如截断保留 +/- 3 个标准差,并 scale 至 -1/1
xstd = 3*std(X(:));
X = max(min(xstd, X), -xstd)/xstd;
从一个尺度空间,缩放(线性映射)到另一个尺度空间
function theta = initializeParameters(visSize, hidSize):
r = sqrt(6/(visSize+hidSize));
W1 = rand(hidSize, visSize)*2*r-r;
b1 = zeros(hidSize, 1);
theta = [W1(:); b1(:)];
end
参考
https://www.cnblogs.com/Jerry-home/p/10109460.html
https://blog.csdn.net/lanchunhui/article/details/67634274