如何求导 洛必达法则如何求导( 二 )


首先将数据零均值化,再计算协方差矩阵(convariance matrix)来观察数据中的相关结构 。
X-=np.mean(X,axis=0)
cov=np.dot(X.T,X)/X.shape[0] #计算协方差矩阵
X-=np.mean(X,axis=0)
cov=np.dot(X.T,X)/X.shape[0] #计算协方差矩阵
然后做去相关操作,即通过将原始数据(零均值化后的数据)投影到特征基空间(eigenbasis) 。
U,S,V=np.linalg.svd(cov) #计算数据协方差矩阵的奇异值分解(SVDfactorization)
Xrot=np.dot(X,U) #对数据去相关
U,S,V=np.linalg.svd(cov) #计算数据协方差矩阵的奇异值分解(SVDfactorization)
Xrot=np.dot(X,U) #对数据去相关
较后一步变换是白化,即把特征基空间的数据除以每个维度的特征值来标准化尺度 。
Xwhite=Xrot/np.sqrt(S+1e-5) #除以奇异值的平方根,注意到这里加了个1e-5是为了防止分母是0的情况 。
Xwhite=Xrot/np.sqrt(S+1e-5) #除以奇异值的平方根,注意到这里加了个1e-5是为了防止分母是0的情况 。
PCA白化的一个缺点是会增加数据中的噪声,因为它把输入数据的所有维度都延伸到相同的大小,这些维度中就包含噪音维度(往往表现为不相关的且方差较小) 。这种缺点在实际操作中可以通过把1e-5增大到一个更大的值来引入更强的平滑 。
3. 初始化3.1 不要将参数全部初始化为零
几乎所有的CNN网络都是堆成结构,将参数零初始化会导致流过网络的数据也是对称的(都是零),并且没有办法在不受扰动的情况下打破这种数据对称,从而导致网络无法学习 。
参数零初始化时,无论输入是什么,中间神经元的激活值都是相同的(任意一个神经元的激活值a=f(WTX),当权重W是零向量时,WTX也是零向量,因此经过激活函数后激活值都相同),反向传播过程中计算的梯度也是相同,每个权重参数的更新因此也是相同的,网络因此失去了不对称性 。
3.2 用小的随机数初始化
初始化参数应该非常接近于零(但不全等于零),来打破网络的对称性 。初始参数应该是随机且独立的来保证每个参数更新过程是不同的 。给每个参数随机赋予一个接近零的值:
W=0.01*numpy.Random.randn(D,H)
W=0.01*numpy.Random.randn(D,H)
randn方法生成一个零均值,方差为1的正态分布的随机数,同样也可以换用数值较小的均匀分布来产生初始化参数,但在实践中两种方法较终结果差别不大
3.3 方差归一化
用随机初始化方法来初始化参数会导致输出S的方差随输入数量(X或W向量的维度)增加而变大 。
独立随机变量和的方差具有以下性质:
Var(A+B+C)=Var(A)+ Var(B)+ Var(C)
S = w1*x1 + w2*x2 +…+wi*xi+ b
Var(A+B+C)=Var(A)+ Var(B)+ Var(C)
S = w1*x1 + w2*x2 +…+wi*xi+ b
S是多个随机变量的加权和,假设W各维度之间相互独立,随着数据维度增长,S的方差将会线性积累,由于数据的维度随任务的不同,是不可控的,所以我们希望将S的方差做归一化,这只需要对W做处理就可以了:
W=numpy.random.randn(n)/sqrt(n) #n是数据维度
W=numpy.random.randn(n)/sqrt(n) #n是数据维度
上面操作是正确的推导过程:
令 n*Var(W) = 1,就得到std(W) = 1 / sqrt(n) 。
注意:现在更多的论文中在实际中都在用ReLUs函数,针对ReLUs推荐:
w=numpy.random.randn(n)*sqrt(2.0/n)
令 n*Var(W) = 1,就得到std(W) = 1 / sqrt(n) 。
注意:现在更多的论文中在实际中都在用ReLUs函数,针对ReLUs推荐:
w=numpy.random.randn(n)*sqrt(2.0/n)
输入数据较好是2的整数幂次方,比如32(CIFAR-10中图片尺寸),64,224(ImageNet中常见的尺寸) 。此外采用较小尺寸的滤波器(例3x3),小的步长(例1)和0值填充,不仅会减少参数数量,还会提升整个网络的准确率 。当用3x3的滤波器,步长为1,填充(pad)为1时,会保持图片或特征图的空间尺寸不变 。池化层经常用的池化大小是2x2 。