分享

斯坦福大学深度学习公开课cs231n学习笔记(6)神经网路输入数据预处理(归一化,PCA等)及参数初始化

 文明世界拼图 2020-01-19

该节课中主要讲述了针对神经网络输入数据的一些预处理操作,例如:均值化,归一化,PCA与白化等,另外还讲述了损失函数及其正则化。数据预处理在深度学习算法中起着重要作用,在实际的计算过程中,将数据做归一化和白化等处理后,算法往往能够取得较好的效果。

数据预处理之:归一化

均值减法:即将样本数据减去它们的均值。python中操作:

X=X-np.mean(X,axis=0);
示例:

  1. import numpy as np
  2. x=[2 ,4 ,-2 ,-6 ,1]
  3. y1=x-np.mean(x,axis=0)
  4. y1
  5. array([ 2.2, 4.2, -1.8, -5.8, 1.2])
如果数据是平稳的(即数据每一个维度的统计都服从相同的分布),那么可以考虑将每个样本数据都减去它们的平均值(逐样本计算)。对于图像,可以移除图像的平均亮度值,因为很多情况下我们对图像照度并不感兴趣,而是关注其内容,所以将图像整体减去像素均值是有意义的。注意:在处理彩色图像时需要格外小心,因为不同色彩通道中的像素并不都存在平稳特性。
归一化是:将数据的所有维度都归一化,使数值范围近似相等,归一化可以将有量纲的表达式,变换为无量纲的表达式,成为纯量。有两种常用的归一化方法:

(1)先对数据进行零中心化(zero-centered),然后每个维度都除以标准差,由上面的实例继续:

  1. >>> y2=y1/np.std(y1,axis=0)
  2. >>> y2
  3. array([ 0.63089327, 1.2044326 , -0.5161854 , -1.66326407, 0.3441236 ])

对于y2,其标准差为1,证明过程见下图:


(2)对每个维度都做归一化,使每个维度的最大和最小值分别为1和-1。该方法的前提是不同的输入特征具有不同的数值范围(或计量单位)。

上图1中,左边是原始的2维输入数据;中间是数据每个维度上都减去其平均值,得到零中心化数据;右边是数据每个维度都除以其标准差得到的数据。红线表示数据各维度上的数值范围,我们发现零中心化的数据,其范围并不相同,但右边归一化后的数据的范围是相同的。

数据与处理之:PCA和白化

PCA:先对数据进行零中心化处理,然后计算其协方差矩阵,展示数据的相关性结构。

  1. # Assume input data matrix X of size [N x D]
  2. X -= np.mean(X, axis = 0) # zero-center the data (important)
  3. cov = np.dot(X.T, X) / X.shape[0] # get the data covariance matrix
协方差矩阵是对称和半正定的,可以对协方差矩阵进行奇异值分解(SVD):
U,S,V = np.linalg.svd(cov)
其中,U的列是特征向量,S是含有奇异值的一维数组。为了去除数据相关性,可以将零中心化后的数据投影到特征基准上:
Xrot = np.dot(X, U) # decorrelate the data
其中,U的列是范式为1的标准正交集,所以可以将其看作标准正交基向量。Xrot的协方差矩阵是对角线对称的。np.linalg.svd 的返回值U中,特征向量是按照特征值的大小进行排列的。利用这个性质可以对数据降维,只选用前面的小部分特征向量,这个过程就是主成分分析(PCA)。例如:

Xrot_reduced = np.dot(X, U[:,:100]) # Xrot_reduced 变成 [N x 100]
上面的语句将原始数据集大小降到[N x 100],即只留下数据中包含最大方差的100个维度。使用降维数据训练线性分类器和神经网络会有非常好的性能,同时还能节省时间和存储空间。
白化:白化操作的输入是特征基准上的数据,然后对每个维度的数据除以其特征值来归一化。其几何解释是:如果数据服从多变量高斯分布,白化后数据是具有零均值和恒定协方差矩阵的高斯分布:
  1. # whiten the data:
  2. # divide by the eigenvalues (which are square roots of the singular values)
  3. Xwhite = Xrot / np.sqrt(S + 1e-5)
代码中,分母加了1e-5(或更小的常数)防止分母出现为0的情况。该变换的缺陷是可能夸大数据中的噪声,因为它将所有维度都拉伸到相同的数值范围,而这些维度中含有噪声的维度才是大多数的。在实际操作中,可以使用更强的平滑来解决上述问题(如采用比1e-5更大的值)。


上图2中,左边是二维的原始输入数据;中间是经过PCA操作的数据,其结果是零中心化的,并且变换到了数据协方差矩阵的基准轴上。右边是白化后的数据,每个维度的数据都通过特征值调整范围,协方差矩阵变为恒等矩阵(这里理解的不是很好)。几何意义是将数据在各个方向上进行伸缩,使之服从高斯分布。

备注:课中提到了在实际的卷积神经网络应用中并不一定采用PCA和白化操作,但对数据进行零中心化、对图像像素进行归一化却是很常见的。并且正确的处理策略应该是:先将样本数据分成训练/验证/测试集,只是从训练集中求图片平均值,然后将各个集(训练/验证/测试集)中的图像再减去这个平均值。

权重初始化

对于一个神经网络结构,在开始训练之前,需要初始化网络参数。

首先,全零初始化是一个错误的方法。因为如果权重被初始化为相同的值,神经元就失去了不对称性的源头。正确的初始化方法应该是小随机数初始化,即权重初始值要接近0但又不能是0,此时可以将权重初始化为很小的数值,以此来打破对称性。实现方法:W = 0.01* np.random.randn(D,H),其中randn函数是基于零均值和标准差的高斯分布。当然,并不是初始权重越小越好,因为太小的权重会导致在反向传播过程中计算出的梯度非常小(因为梯度与权重是线性相关的),这会减小反向传播中的“梯度信号”,这在深度网络中可能会出现问题。

上面的方法还存在一个问题是:随着输入数据量的增长,随机初始神经元输出数据的方差也增大。解决方法是:除以输入数据量的平方根来调整数值范围,使神经元输出的方差归一化为1。实现方法:w = np.random.randn(n) / sqrt(n),其中n是输入数据的数量。

偏置初始化

通常将偏置初始化为0,因为小随机数初始权重已经打破了对称性。对于ReLU非线性激活函数,有研究人员喜欢使用如0.01这样的小数值作为所有偏置的初始值,他们认为这样能够让所有的ReLU单元从开始就被激活,从而保存和传播一些梯度。然而,这样做并不一定总能提高算法的性能,通常还是使用0来初始化偏置参数。

在论文《Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification》中,作者He等人给出了一种针对ReLU神经元的特殊初始化方法,并给出结论:网络中神经元的方差应为:2.0/n。实现方法为:

w = np.random.randn(n) * sqrt(2.0/n)。这也是当前神经网络算法使用ReLU神经元时的最佳推荐。

参考:

http://cs231n./neural-networks-2/

https://zhuanlan.zhihu.com/p/21560667?refer=intelligentunit

https://en./wiki/Variance

http://blog.csdn.net/pipisorry/article/details/52247379

https:///community/share/56c3e9c6228e5b0fe6b17d95

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多