往后的文章的改动主要在语雀上
后面还有三篇,都在语雀上,直接转过来有点麻烦,格式不好调整,大家喜欢可以看到语雀上看。
https://www.yuque.com/lart/ml-newer
数据预处理
数据归一化
虽然这里有一系列可行的方法,但是这一步通常是根据数据的具体情况而明确选择的.++这一方法对诸如自然图像这类数据是有效的,但对非平稳的数据则不然++.特征归一化常用的方法包含如下几种:
-
简单缩放
通过对数据的每一个维度的值进行重新调节(这些维度可能是相互独立的),使得最终的数据向量 落在 [0,1]或[ -1,1] 的区间内(根据数据情况而定).这对后续的处理十分重要,因为很多 默认参数(如 PCA-白化中的 epsilon)都假定数据已被缩放到合理区间.
例子 在处理自然图像时,我们获得的像素值在 [0,255] 区间中,常用的处理是将这些像素值除以 255,使它们缩放到 [0,1] 中.
-
逐样本均值消减(也称为移除直流分量)
前提:数据要求是平稳的.
对于每个图像样本,减去各自各个通道上的整幅图像的均值.
因为具体来说,是因为不同色彩通道中的像素并不都存在平稳特性.例子 在实验中,在ZCA whitening前进行数据预处理时,每列代表一个样本,但为什么是对patches每一维度0均值化?
(具体做法是:首先计算每一个维度上数据的均值,使用全体数据计算,之后再每一个维度上都减去该均值)
而以前的实验都是对每个样本整体进行0均值化(即:逐样本均值消减)?- 因为以前是灰度图,现在是RGB彩色图像,如果现在对每列平均就是对三个通道求平均,这肯定不行.因为不同色彩通道中的像素并不都存在平稳特性,而要进行逐样本均值消减(即:单独每个样本0均值化)有一个必须满足的前提:该数据是平稳的.
- 因为以前是自然图像,自然图像中像素之间的统计特性都一样,有一定的相关性,而现在是人工分割的图像块,没有这种特性.
-
特征标准化(使数据集中所有特征都具有 零均值和单位方差)
独立地使得数据的每一个维度具有零均值和单位方差.
这是归一化中最常见的方法并被广泛地使用.特征标准化的具体做法是:
- 首先计算每一个维度上数据的均值(使用全体数据计算)
- 之后在每一个维度上都减去该均值
- 下一步便是在数据的每一维度上除以该维度上数据的标准差.
例子
- 在使用支持向量机(SVM)时,特征标准化常被建议用作预处理的一部分.
- 处理音频数据时,常用 Mel 倒频系数 MFCCs 来表征数据.然而MFCC特征的第一个分量(表示直流分量)数值太大,常常会掩盖其他分量.这种情况下,为了平衡各个分量的影响,通常对特征的每个分量独立地使用标准化处理.
白化(协方差矩阵为单位矩阵)
https://blog.csdn.net/danieljianfeng/article/details/42147109
白化可以降低输入的冗余性,降低特征之间的相关性,使得所有的特征具有相同的方差.
在做完简单的归一化后,白化通常会被用来作为接下来的预处理步骤,它会使我们的算法工作得更好.实际上许多深度学习算法都依赖于白化来获得好的特征.
在进行白化时,首先使 特征零均值化是很有必要的.
白化处理分PCA白化和ZCA白化.
- PCA白化 先PCA进行基转换,降低数据的相关性,再对每个输入特征进行缩放(除以各自的特征值的开方),以获得单位方差.此时的协方差矩阵为单位矩阵I.
- ZCA白化 ZCA白化只是在PCA白化的基础上做了一个逆映射操作,使数据转换为原始基下,使得白化之后的数据更加的接近原始数据.
ZCA白化首先通过PCA去除了各个特征之间的相关性,然后使得输入特征具有相同方差,此时得到PCA白化后的处理结果.然后再把数据旋转回去,得到ZCA白化的处理结果.
二者的差异:
- PCA白化保证数据各维度的方差为1,ZCA白化保证数据各维度的 方差相同
- PCA白化可以用于降维也可以去相关性,而ZCA白化主要用于去相关性,且尽量使白化后的数据接近原始输入数据.
# 假设输入数据矩阵X的尺寸为[N x D]
X -= np.mean(X, axis = 0) # 对数据进行零中心化(重要)
cov = np.dot(X.T, X) / X.shape[0] # 得到数据的协方差矩阵
U,S,V = np.linalg.svd(cov)
Xrot = np.dot(X, U) # 对数据去相关性
# 对数据进行白化操作 除以特征值->PCA白化
Xwhite = Xrot / np.sqrt(S + 1e-5)
# 转换为原始基->ZCA白化
Xzcawhite = np.dot(Xwhite, U.T)
注意 对于大图像,采用基于 PCA/ZCA 的白化方法是不切实际的,因为协方差矩阵太大.在这些情况下我们退而使用 1/f 白化方法.
接下来在 PCA/ZCA 白化中我们需要选择合适的 epsilon
(回忆一下,这是规则化项,对数据有低通滤波作用). 选取合适的 epsilon
值对特征学习起着很大作用,这里可以看ML预处理.md文档 PCA/ZCA白化 一节.
实际建议
在卷积神经网络中并不会采用这些PCA以及白化变换.然而对数据进行零中心化操作还是非常重要的,对每个像素进行归一化也很常见.
在这一部分中,我们将介绍几种在一些数据集上有良好表现的预处理标准流程.
- 自然灰度图像
==均值消减->PCS/ZCA白化==
灰度图像具有平稳特性,通常在第一步对每个数据样本分别做均值消减(即减去直流分量),然后采用 PCA/ZCA 白化处理.
其中的 epsilon
要足够大以达到低通滤波的效果.
- 彩色图像
==分通道均值消减->PCA/ZCA白化==
对于彩色图像,++色彩通道间并不存在平稳特性++.通常需要分通道均值消减,并且对数据进行特征缩放(使像素值位于 [0,1] 区间).
使用足够大的 epsilon
来做 PCA/ZCA.
- 音频 (MFCC/频谱图)
==特征标准化->PCA/ZCA 白化==
对于音频数据 (MFCC 和频谱图),每一维度的取值范围(方差)不同.
即使得数据的每一维度均值为0、方差为1,然后进行PCA/ZCA白化(使用合适的 epsilon
).
- MNIST 手写数字
==简单缩放/逐样本均值消减(->PCA/ZCA 白化)==
MNIST 数据集的像素值在 [0,255] 区间中.我们首先将其缩放到 [0,1] 区间.
实际上,进行逐样本均值消去也有助于特征学习.
注:也可选择以对 MNIST 进行 PCA/ZCA 白化,但这在实践中不常用.
one-hot独热编码(离散数据)
独热编码即 One-Hot 编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效.
可以这样理解,对于每一个特征,如果它有m个可能值,那么经过独热编码后,就变成了m个二元特征.并且,这些特征互斥,每次只有一个激活.因此,数据会变成稀疏的.
稀疏数据相比密集数据而言,对于计算机加载处理也更为有优势.
这样做的好处主要有:
- 解决了分类器不好处理属性数据的问题
- 在一定程度上也起到了扩充特征的作用
实际建议
对于标签数据可以转化为独热编码形式,这对于网络的分类输出而言,是更为实际的表达形式.
from keras.utils import np_utils
...
Y_train = np_utils.to_categorical(y_train, num_classes)
而对于真实的类别序号可以通过使用NumPy argmax()
函数来找到(这里的查找,也不一定对one-hot后的数据进行查找,对于得分数据亦可以,对于softmax计算后的也可以,因为是增函数).
数据增强(数据量有限)
https://blog.csdn.net/mzpmzk/article/details/80039481
https://blog.csdn.net/u010555688/article/details/60757932?utm_source=blogxgwz1
深层神经网络一般都需要大量的训练数据才能获得比较理想的结果。在数据量有限的情况下,可以通过数据增强(Data Augmentation)来增加训练样本的多样性, 提高模型鲁棒性,避免过拟合。
图片数据增强通常只是针对训练数据,对于测试数据则用得较少。测试数据常用的是:做 5 次随机剪裁,然后将 5 张图片的预测结果做均值。
常用手段:
- 翻转flip
- 旋转rotation
- 平移shift
- 缩放resize/尺度变换Random Scale
- 随机裁剪或补零Random Crop or Pad
- 色彩抖动Color jittering:HSV颜色空间随机改变图像原有的饱和度和明度(即,改变 S 和 V 通道的值)或对色调(Hue)进行小范围微调。
- 对比度变换contrast:在图像的HSV颜色空间,改变饱和度S和V亮度分量,保持色调H不变. 对每个像素的S和V分量进行指数运算(指数因子在0.25到4之间), 增加光照变化;
- PCA抖动PCA Jittering:首先按照RGB三个颜色通道计算均值和标准差,再在整个训练集上计算协方差矩阵,进行特征分解,得到特征向量和特征值,用来做PCA Jittering;
- 加噪声(Noise)
- 特殊的数据增强方法:
- Fancy PCA(Alexnet)& 监督式数据扩充(海康)
- 使用生成对抗网络(GAN) 生成模拟图像
保存数据
将训练集数据/标签,以及测试数据(可能有的标签),都事先处理后, 并转化好 .npy
或者其他的整合的数据文件, 便于后期的分布处理,而且也可以减少训练过程在读入数据上的处理时间.
https://gist.github.com/lartpang/e2343fb06f25b36a8af03e68923dea06
补充
处理离散型特征和连续型特征并存的情况时,必须进行特征的归一化,每个特征都单独进行归一化.对于连续型特征归一化的常用方法是放缩后标准化,对于离散的特征基本就是按照one-hot编码,该离散特征有多少取值,就用多少维来表示该特征.
基于树的方法是不需要进行特征的归一化,例如随机森林, bagging 和 boosting等.基于参数的模型或基于距离的模型,都是要进行特征的归一化.
-
进行预处理很重要的一点是:任何预处理策略(比如数据均值)都 只能在训练集数据上进行计算,算法训练完毕后再应用到验证集或者测试集上。
例子 如果先计算整个数据集图像的平均值然后每张图片都减去平均值,最后将整个数据集分成训练/验证/测试集,那么这个做法是错误的。应该怎么做呢?应该先分成训练/验证/测试集,只是从训练集中求图片平均值,然后各个集(训练/验证/测试集)中的图像再减去这个平均值。
-
对于神经网络模型而言,图片需要进行预处理的原因:
- 适应神经网络结构:网络结构可以接收的数据格式/类型是固定的,因此在训练过程之前,需要将训练样本预处理成为可以被神经网络读取的格式/类型;
- 对训练样本进行 提纯:训练样本中可能存在“不好的数据”,通过预处理手段,可以将这部分数据剔除掉,或者消除掉它的影响,训练图片是越“纯”越好,也就是让网络只关注你想让它记住的;
- 进行数据 增强:对训练样本进行预处理,可以增加数据的多样性。例如通过旋转、镜像、裁切等手段,将图片的空间多样性呈现出来,据此训练出来的模型也将具有更好的鲁棒性,可以提升泛化能力.
数据增强的目的是增加样本数量,这在数据很少的情况下是非常有效的,Caffe自己的数据输入层自带裁剪、镜像等功能,一般做法是把训练数据放大到输入尺寸的1.1倍左右,然后随机裁剪到输入尺寸,这个效果非常好。
不好的数据增强容易带来模型过拟合,因为我们只是增加了数据并非泛化了数据分布; - 数据归一化:预处理可以将不同规格的数据转换成相同规格的训练数据,最典型的的例子就是图片的尺寸归一化。
上面提到的减均值除以方差的方式,在Batch Normalization(BN)出现之前是很有必要的,因为这样拉到均值附近,学习的时候更加容易,毕竟激活函数是以均值为中心的,学习到这个位置才能将不同的类分开。
但是BN出现之后,这个操作就完全没必要了,因为每次卷积后都有BN操作,BN就是把数据拉到0均值1方差的分布,而且这个均值和方差是动态统计的,不是只在原始输入上统计,因此更加准确。即采用BN后该预处理无必要。 - 压缩数据体积:预处理还可以减小训练数据的尺寸。例如原始数据是FHD尺寸的,若压缩至QQVGA则会大幅缩减数据体积;
- 将数据处理为某种组织形式的存储格式,比如tfrecord,这是为了加速训练,这一步可不得小觑,大的模型训练是非常耗时的,提前做预处理可节省不少时间还可降低对设备内存要求等;
- 如果训练数据存在极度不均衡情况,那么需要做图像预处理,欠采样或过采样或补充,目的是不让模型结果偏向于数据大的类别;