神经网络之数据预处理
本教程参考StudyAI,仅作为个人读书笔记
对于数据预处理,我们有3个常用的符号,数据矩阵X,假设其尺寸是[NxD](N是数据样本的数量,D是数据的维度).数据预处理方法大约有一下几种:
均值减法
它对数据中每个独立特征减去平均值,从几何上理解为每个维度上都将数据云的中心都迁移到原点.numpy代码如下:
X -= np.mean(X,axis=0)
而对于图像来说,更常用的是对所有像素都减去一个值,用X -= np.mean(X)
实现,也可以在3个通道上分别进行操作.
归一化
归一化指将数据的所有维度都归一化,使其数值范围都近似相等.有两种常用方法可以实现归一化.
先对数据做零中心化处理,然后对每个维度都除以其标准差.
# 零中心化 X -= np.mean(X,axis=0) # 标准差 X /= np.std(X,axis=0)
对每个维度都做归一化,使得每一个维度的最大和最小值是1和-1.
这个预处理操作只有在确信不同的输入特征有不同的数值范围(或计量单位)时才有意义.
一般的预处理流程:
原始的2维输入数据.
在每个维度上都减去平均值后得到零中心化数据,现在数据云以原点为中心.
每个维度都除以其标准差来调整其数值范围.
红色的线指出了数据各个维度的数值范围,在第2张图片的零中心化数据的数值范围不同,但在第3张归一化数据中数值范围相同.
PCA
PCA是对数据进行零中心化处理,然后计算协方差矩阵,它展示了数据中的相关性结构。假设输入数据矩阵X的尺寸为[NxD].
对数据进行零中心化(重要)
X -= np.mean(X,axis=0)
计算数据的协方差矩阵
cov = np.dot(X.T, X) / X.shape[0]
数据协方差矩阵的第(i,j)个元素是数据第i个和第j个维度的协方差,而对角线上的元素即方差.另外协方差矩阵是对称和半正定的,我们可以对数据协方差矩阵进行SVD(奇异值分解)运算.
SVD奇异值分解
U,S,V = np.linalg.svd(cov)
U的列是特征向量,S是装有奇异值的1维数组(因为cov是对称且半正定的,所以S中元素是特征值的平方),
为了去除相关性,将已经零中心处理过的原始数据投影到特征基准上
Xrot = np.dot(X,U) # X为已经零中心处理过的原始数据集
- 注意,U的列是标准正交向量的集合(范式为1,列之间标准正交),所以可以把它们看做标准正交基向量.因此,投影对应X中的数据的一个旋转,旋转产生的结果就是新的特征向量.如果计算Xort的协方差矩阵,将会看到它是对角对称的.
np.linalg.svd
的一个良好性质是在它的返回值U中,特征向量按照特征值的大小排列,我们可以利用这个性质来对数据降维,只使用前面的小部分特征向量,丢弃掉那些包含数据没有方差的维度.
主成分分析(PCA)降维
具体操作如下:
Xrot_reduced = np.dot(X,U[:,:100])
经过上面操作,将数据集的大小由[NxD]降到了[Nx100],留下了数据中包含最大方差的100个维度.通常使用PCA降维过的数据训练线性分类器和神经网络会达到非常好的性能效果,同时还能节省时间和存储空间.
完整代码如下:
假设输入数据矩阵X的尺寸为[NxD].
# 1.对数据进行零中心化处理 X -= np.mean(X,axis=0) # 2.计算协方差矩阵 cov = np.dot(X.T, X) / X.shape[0] # 3.对协方差矩阵进行SVD(奇异值分解) U,S,V = np.linalg.svd(cov) # 4.将已经领中心化处理过的原始数据投影到特征基准上,并只取前面的部分.(PCA降维) Xrot_reduced = np.dot(X,U[:,:100]) #Xrot_reduced即主成分
白化
白化操作输入是特征基准上的数据,然后对每个维度除以其特征值进行归一化.之前的操作与PCA降维相类似,如下:
# 1.对数据进行零中心化处理 X -= np.mean(X,axis=0) # 2.计算协方差矩阵 cov = np.dot(X.T, X) / X.shape[0] # 3.对协方差矩阵进行SVD(奇异值分解) U,S,V = np.linalg.svd(cov)
对数据每个维度除以特征值进行归一化,即白化操作:
Xwhite = Xrot / np.sqrt(S + 1e-5)
- 在分母中添加了1e-5(或一个更新的常量)是为了防止分母为0.该变换的一个缺陷在于变换过程中可能会夸大数据中的噪声.因为它将所有维度都拉伸到相同的数据范围,这些维度中也包含了那些只有极少差异性(方差小)而大多数是噪声的维度.
- 在实际操作中,这个问题可用更强的平滑来解决(例如采用比1e-5更大的值)
PCA和白化可视化效果
实际操作
PCA和白化只是为了介绍的完整性,实际上在卷积神经网络中并不会采用这些变换.然而对数据进行零中心化操作还是非常重要的,对每个像素进行归一化也很常见.
常见错误
进行预处理很重要的一点是,任何预处理策略(比如数据均值)都只能在训练集数据上进行计算,算法训练完毕后再应用到验证集或者测试集上.
- 例如,如果计算整个数据集图像的平均值,然后每张图片都减去平均值,最后才将整个数据集划分成训练/验证/测试集,这个做法是错误的.
- [x] 正确做法是,应该先分成训练/验证/测试集,只是从训练集中秋图片平均值,然后各个集(训练/验证/测试集)中的图像再减去这个平均值