Caffe学习系列——工具篇:计算数据集的图像均值

本系列文章介绍深度学习框架Caffe及其实践,本文主要介绍Caffe的实用工具—— compute_image_mean 计算图像均值.

1. 图像预处理——零均值化

   数据预处理在深度学习中非常重要,数据预处理中,标准的第一步是数据归一化。特征归一化常用的方法包含如下几种:

  • 简单缩放
  • 逐样本均值消减(也称为移除直流分量)
  • 特征标准化(使数据集中所有特征都具有零均值和单位方差)

  特征标准化指的是(独立地)使得数据的每一个维度具有零均值和单位方差。这是归一化中最常见的方法并被广泛地使用(例如,在使用支持向量机(SVM)时,特征标准化常被建议用作预处理的一部分)。在实际应用中,特征标准化的具体做法是:首先计算每一个维度上数据的均值(使用全体数据计算),之后在每一个维度上都减去该均值。下一步便是在数据的每一维度上除以该维度上数据的标准差。
  对于自然图像,更多的是做图像零均值化,并不需要估计样本的方差。这是因为在自然图像上进行训练时,对每一个像素单独估计均值和方差意义不大,因为(理论上)图像任一部分的统计性质都应该和其它部分相同,图像的这种特性被称作平稳性(stationarity)

【 注:】所谓“自然图像”,不严格的说,是指人或动物在他们一生中所见的那种图像。通常我们选取含草木等内容的户外场景图片,然后从中随机截取小图像块(如16x16像素)来训练算法。在实践中我们发现,大多数特征学习算法对训练图片的确切类型并不敏感,所以大多数用普通照相机拍摄的图片,只要不是特别的模糊或带有非常奇怪的人工痕迹,都可以使用。

  对于自然图片,即使不进行方差归一化操作,不同特征的方差值彼此相似,故而我们不再进行任何方差归一化操作。既然我们不做方差归一化,唯一还需进行的规整化操作就是均值规整化,其目的是保证所有特征的均值都在0附近。根据应用,在大多数情况下,我们并不关注所输入图像的整体明亮程度。比如在对象识别任务中,图像的整体明亮程度并不会影响图像中存在的是什么物体。更为正式地说,我们对图像块的平均亮度值不感兴趣,所以可以减去这个值来进行均值规整化[1]。
  如果你处理的图像并非自然图像(比如,手写文字,或者白背景正中摆放单独物体),其他规整化操作就值得考虑了,而哪种做法最合适也取决于具体应用场合。但对自然图像而言,对每幅图像进行上述的零均值规整化,是默认而合理的处理。

【注:】如果你的数据是平稳的(即数据每一个维度的统计都服从相同分布),那么你可以考虑在每个样本上减去数据的统计平均值(逐样本计算)。对于图像,这种归一化可以移除图像的平均亮度值 (intensity)。很多情况下我们对图像的照度并不感兴趣,而更多地关注其内容,这时对每个数据点移除像素的均值是有意义的。注意:虽然该方法广泛地应用于图像,但在处理彩色图像时需要格外小心,具体来说,是因为不同色彩通道中的像素并不都存在平稳特性[2]。 

2. Caffe计算图像均值工具——compute_image_mean 

2.1 二进制格式的均值计算

  caffe中使用的均值数据格式是binaryproto, 作者为我们提供了一个计算均值的文件compute_image_mean.cpp,放在caffe根目录下的tools文件夹里面。编译后的可执行体放在 build/tools/ 下面,我们直接调用就可以了

# sudo build/tools/compute_image_mean examples/mnist/mnist_train_lmdb examples/mnist/mean.binaryproto

带两个参数:
第一个参数:examples/mnist/mnist_train_lmdb, 表示需要计算均值的数据,格式为lmdb的训练数据。
第二个参数:examples/mnist/mean.binaryproto, 计算出来的结果保存文件。

2.2 Caffe均值文件mean.binaryproto转mean.npy

  使用Caffe的C++接口进行操作时,需要的图像均值文件是pb格式,例如常见的均值文件名为mean.binaryproto;但在使用Python接口进行操作时,需要的图像均值文件是numpy格式,例如mean.npy。所以在跨语言进行操作时,需要将mean.binaryproto转换成mean.npy,转换代码如下:

#!/usr/bin/env python
import caffe
import numpy as np

MEAN_PROTO_PATH = 'mean.binaryproto'               # 待转换的pb格式图像均值文件路径
MEAN_NPY_PATH = 'mean.npy'                         # 转换后的numpy格式图像均值文件路径

blob = caffe.proto.caffe_pb2.BlobProto()           # 创建protobuf blob
data = open(MEAN_PROTO_PATH, 'rb' ).read()         # 读入mean.binaryproto文件内容
blob.ParseFromString(data)                         # 解析文件内容到blob
# 将blob中的均值转换成numpy格式,array的shape (mean_number,channel, hight, width)
array = np.array(caffe.io.blobproto_to_array(blob))
mean_npy = array[0]             # 一个array中可以有多组均值存在,故需要通过下标选择其中一组均值
np.save(MEAN_NPY_PATH ,mean_npy)

  出现的一个问题: 我在使用这种方法时,发现打印出的array[0]是一个空的列表:
    Caffe学习系列——工具篇:计算数据集的图像均值_第1张图片
    目前还没有找出原因,欢迎大家指教 :D

Reference

[1] UFLDL.主成分分析.
http://ufldl.stanford.edu/wiki/index.php/%E4%B8%BB%E6%88%90%E5%88%86%E5%88%86%E6%9E%90
[2] dcxhun3的博客. 深度学习—–数据预处理
http://blog.csdn.net/dcxhun3/article/details/47999281

你可能感兴趣的:(计算机视觉CV,Caffe,深度学习,深度学习,Caffe,数据预处理,特征标准化)