深度学习中数据预处理方法

深度学习中数据预处理方法

数据预处理在众多深度学习算法中都起着重要作用,通常预处理包括数据归一化和白化。

数据归一化(Normalization)

数据归一化(Data Normalization)是数据预处理的第一步,有很多方法,如常见的高斯归一化、最大最小值归一化等,而在深度学习中常用的是以下几种:

简单缩放(Simple Rescaling)

简单缩放,对数据的每一个维度的值重新调节(这些维度可能是相互独立的),使得最终的数据向量落在 [0,1]或[ − 1,1] 的区间内(根据数据情况而定),以满足应用需求。

例如,在sparse auto-encoder中,由于网络的输出和输入是近似相等的,而隐含层和输出层神经元通常采用的是sigmoid函数作为激活函数,该函数值域为[0,1],因此为了保证输出等于输入,通常需要将输入缩放至[0,1]这个范围,然后再进行训练。在处理自然图像时,我们获得的像素值在 [0,255] 区间中,常用的处理是将这些像素值除以 255,使它们缩放到 [0,1] 中。

使用Tensorflow可以进行如下处理:

image = tf.cast(image, tf.float32) * (1. / 255) - 0.5
# image 参数表示一个三维的张量(tensor) 分别对应图像高、宽、通道数目(height, width, channels)

逐样本均值消减(Per-example mean subtraction)

逐样本均值消减,也称为移除直流分量(remove DC),当数据平稳(stationary),即数据每一个维度的统计都服从相同分布,可以考虑在每个样本上减去数据的统计平均值(逐样本计算,即分别计算各样本的均值,然后各样本减去其对应的均值)。

自然图像具有平稳的性质,所以这种归一化方法也是比较常用的。这种归一化可以移除图像的平均亮度值 (intensity)。很多情况下我们对图像的照度并不感兴趣,而更多地关注其内容,这时对每个数据点移除像素的均值是有意义的。若图像是自然灰度图像,由于灰度图像具有平稳特性,通常可选择这种方法,即移除直流分量(逐样本移除直流分量后还可以继续逐样本除以各样本的标准差,不过这一步通常不做,因为其平稳特性)。

注意:虽然该方法广泛地应用于图像,但在处理彩色图像时需要格外小心,具体来说,是因为不同色彩通道中的像素并不都存在平稳特性

对自然图像应用PCA算法时候,通常也会这样处理。在深度学习图像预处理时,可以使用如下代码: 使用Tensorflow框架

tf.image.per_image_standardization(image)
# image 参数表示一个三维的张量(tensor) 分别对应图像高、宽、通道数目(height, width, channels)

使用opencv:

import os
import cv2
from numpy import *

img_dir='/image/path'
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

特征标准化(Feature Standardization)

特征标准化的目的是使数据集中所有特征都具有零均值和单位方差,即数据的每一个维度具有零均值和单位方差,这也是比较常见的一种归一化方法,比如使用SVM时候也要进行类似处理。在实际应用中,特征标准化的具体做法是:首先计算每一个维度上数据的均值(使用全体数据计算),之后在每一个维度上都减去该均值。下一步便是在数据的每一维度上除以该维度上数据的标准差。

例如\(X\)是一个训练样本集,包含m个训练样本且每个训练样本的维数是n。应用特征标准化时先计算各行数据的均值,然后样本集\(X\)减去该均值得到零均值化后的样本集\(X^{'}\)。之后\(X^{'}\)的各行除以该行数据的标准差就会得到特征标准化后的样本。

若输入是自然彩色图像,由于色彩通道间并不存在平稳特性,因此通常对数据进行特征缩放(使像素值位于 [0,1] 区间)。然后再进行PCA/ZCA白化等操作,在白化前需进行特征分量均值归零(即使特征的每一个维度具有零均值,通常不需要除以各维度数据的标准差,因为各维度标准差很接近)。在UFLDL教程的练习中(linear decoder)采用的是这种方法,而在有些论文中,也会采用第二种方法(逐样本去均值和除以标准差),如论文“An Analysis of Single-Layer Networks in Unsupervised Feature Learning”,这样在后续白化处理时是不是还需要再对各维度进行零均值化(因为计算协方差矩阵时需要这一步)。

PCA/ZCA白化

在做完简单的归一化后,白化通常会被用来作为接下来的预处理步骤,它会使我们的算法工作得更好。实际上许多深度学习算法都依赖于白化来获得好的特征。

在进行 PCA/ZCA 白化时,首先使特征零均值化是很有必要的,这保证了$ _i x^{(i)} = 0$。特别地,这一步需要在计算协方差矩阵前完成。(唯一例外的情况是已经进行了逐样本均值消减,并且数据在各维度上或像素上是平稳的。)接下来在 PCA/ZCA 白化中我们需要选择合适的 epsilon(回忆一下,这是规则化项,对数据有低通滤波作用)。 选取合适的 epsilon 值对特征学习起着很大作用,下面讨论在两种不同场合下如何选取 epsilon

基于重构的模型

在基于重构的模型中(包括自编码器,稀疏编码,受限 Boltzman 机(RBM),k-均值(K-Means)),经常倾向于选取合适的 epsilon 以使得白化达到低通滤波的效果。(注:通常认为数据中的高频分量是噪声,低通滤波的作用就是尽可能抑制这些噪声,同时保留有用的信息。在 PCA 等方法中,假设数据的信息主要分布在方差较高的方向,方差较低的方向是噪声(即高频分量),因此后文中 epsilon 的选择与特征值有关)。一种检验 epsilon 是否合适的方法是用该值对数据进行 ZCA 白化,然后对白化前后的数据可视化。如果 epsilon 值过低,白化后的数据会显得噪声很大;相反,如果 epsilon 值过高,白化后的数据与原始数据相比就过于模糊。一种直观上得到 epsilon 大小的方法是以图形方式画出数据的特征值,选取的 epsilon 应大于大多数较小的、反映数据中噪声的特征值。

在基于重构的模型中,损失函数有一项是用于惩罚那些与原始输入数据差异较大的重构结果(注:以自动编码机为例,要求输入数据经过编码和解码之后还能尽可能的还原输入数据)。如果 epsilon 太小,白化后的数据中就会包含很多噪声,而模型要拟合这些噪声,以达到很好的重构结果。因此,对于基于重构的模型来说,对原始数据进行低通滤波就显得非常重要。

  • 如果数据已被缩放到合理范围(如[0,1]),可以从epsilon = 0.01epsilon = 0.1开始调节epsilon

基于正交化ICA的模型

对基于正交化ICA的模型来说,保证输入数据尽可能地白化(即协方差矩阵为单位矩阵)非常重要。这是因为:这类模型需要对学习到的特征做正交化,以解除不同维度之间的相关性(详细内容请参考 ICA 一节)。因此在这种情况下,epsilon 要足够小(如 epsilon = 1e − 6)。

  • 在使用分类框架时,我们应该只基于训练集上的数据计算PCA/ZCA白化矩阵。需要保存以下两个参数留待测试集合使用:(a)用于零均值化数据的平均值向量;(b)白化矩阵。测试集需要采用这两组保存的参数来进行相同的预处理。

具体应用

自然灰度图像

灰度图像具有平稳特性,我们通常在第一步对每个数据样本分别做均值消减(即减去直流分量),然后采用 PCA/ZCA 白化处理,其中的 epsilon 要足够大以达到低通滤波的效果。

自然彩色图像

对于彩色图像,色彩通道间并不存在平稳特性。因此我们通常首先对数据进行特征缩放(使像素值位于 [0,1] 区间),然后使用足够大的 epsilon 来做 PCA/ZCA。在进行 PCA 变换前需要对特征进行分量均值归零化。

MINIS手写数据集

MNIST 数据集的像素值在 [0,255] 区间中。我们首先将其缩放到 [0,1] 区间。实际上,进行逐样本均值消去也有助于特征学习。注:也可选择以对 MNIST 进行 PCA/ZCA 白化,但这在实践中不常用。



Author: NYY
Link: http://yoursite.com/2018/11/08/deep_learning/data-normalization/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.