神经网络总结(二)

Setting up the data and the model

这部分主要内容是数据预处理,权重初始化,损失函数

1.Data Preprocessing

通常有三种常用的数据预处理方式,输入数据是矩阵形式X[N x D], N是数据的数目,D是数据的维度

Mean subtraction 将数据的每一维特征都减去平均值:X -= np.mean(X, axis = 0),注意这里是每一行的均值,因为我们把一张图片的像素拉成了一行。
Normalization :归一化数据,使数据在相同尺度上。通常有两种归一化方法:第一种是每一维除它的标准差:X /= np.std(X, axis = 0),这样数据成为zero-centered。第二种方法是将数据归一化到[-1,1]范围内,在图像处理中,因为像素点的范围已经是[0,255],所以这种方法并不常用。
在这里插入图片描述

PCA and Whitening 首先按照上面的方法中心化,然后计算协方差矩阵并不用于卷积神经网络

# Assume input data matrix X of size [N x D]
X -= np.mean(X, axis = 0) # zero-center the data (important)
cov = np.dot(X.T, X) / X.shape[0] # get the data covariance matrix

数据协方差矩阵的(i,j)元素包含数据的第i维和第j维之间的协方差

U,S,V = np.linalg.svd(cov) #奇异值分解,其中 U 为特征向量(按其特征值排序),S为奇异值分解向量为特征向量的平方
Xrot = np.dot(X, U) # 去除数据相关性
Xrot_reduced = np.dot(X, U[:,:100]) #降维到 100 维,您可以通过在PCA减少的数据集上训练线性分类器或神经网络来获得非常好的性能,从而节省空间和时间。
# whiten the data:
# divide by the eigenvalues (which are square roots of the singular values)
Xwhite = Xrot / np.sqrt(S + 1e-5)#防止S=0

在这里插入图片描述


例如我们在CIFAR-10图像上直观的展示这个变换:
输入数据为 [50,000 x 3072],
在这里插入图片描述
最左侧: 49幅图组成的例子
2nd from Left :3072个特征向量中的前144个。顶部特征向量占数据中大部分方差,我们可以看到它们对应于图像中的较低频率。
2nd from Right: 第三张图片为通过PCA降维降到144维,使用的是图二中的前144维,可以看出大部分特征信息得到了保留。
Right: 白化后的图片
注:PCA/Whitening 这种变换并不用于卷积神经网络。。


常见的陷阱 :关于预处理非常重要的一点是任何统计特征(例如均值)必须在训练集上(training data)计算,然后应用于validation / test data。并不能在验证集和测试集上进行计算并应用于网络的训练。先将真个数据库计算均值然后减去均值,再划分train/validation/test data 的做法是错误的!相反,必须仅在训练数据上计算平均值,然后从所有分组(train/validation/test)中相等地减去平均值。


2.Weight Initialization

在开始训练网络之前,我们需要初始化网络的参数。当前的推荐是使用ReLU 激活函数和w = np.random.randn(n) * sqrt(2.0/n)初始化方法。
陷阱:所有参数应用零初始化是错误的。因为如果网络中的每个神经元计算相同的输出,那么它们也将在反向传播期间计算相同的梯度并经历完全相同的参数更新。

小随机数 :作为一种解决方案,通常将神经元的权重初始化为较小的数量,并将其称为对称性破坏 。实际的应用:W = 0.01* np.random.randn(D,H),其中randn是指随机样本是0均值,满足标准正态分布。
FBI Warning :严格意义上说并不一定是越小的数字会取得更好的效果。例如,在反向传播期间具有非常小权重的神经网络层将在其数据上计算非常小的梯度(因为该梯度与权重的值成比例)。这会大大减少通过网络向后流动的“梯度信号”,并且可能成为深度网络的关注点。

校准方差 1/sqrt(n)w = np.random.randn(n) / sqrt(n),最新推荐使用w = np.random.randn(n) * sqrt(2.0/n)

初始化偏差(bias) :将偏差初始化为零是可能的,也是常见的,因为不对称破坏是由权重中的小随机数提供的。很常见的是将偏置项设置为0,ReLu 激活函数有些人会设置为 0.01,但更多的还是将偏置项初始化为0.


3.Batch Normalization

cite:Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift

引用博客:http://blog.csdn.net/hjimce/article/details/50866313
作者:hjimce

这是最新(2015年论文)开发的一项技术:随机梯度下降方法对于训练深度网络十分高效,但仍存在许多问题,例如就是需要我们人为的去选择参数,比如学习率、参数初始化、权重衰减系数、Drop out比例等。以至于我们很多时间都浪费在这些的调参上,那么学完这篇文献之后,你可以不需要那么刻意的慢慢调整参数。BN算法(Batch Normalization)其强大之处如下:

  1. 你可以选择比较大的初始学习率,让你的训练速度飙涨。以前还需要慢慢调整学习率,甚至在网络训练到一半的时候,还需要想着学习率进一步调小的比例选择多少比较合适,现在我们可以采用初始很大的学习率,然后学习率的衰减速度也很大,因为这个算法收敛很快。当然这个算法即使你选择了较小的学习率,也比以前的收敛速度快,因为它具有快速训练收敛的特性;
  2. 你再也不用去理会过拟合中drop out、L2正则项参数的选择问题,采用BN算法后,你可以移除这两项了参数,或者可以选择更小的L2正则约束参数了,因为BN具有提高网络泛化能力的特性。
  3. 再也不需要使用使用局部响应归一化层了(局部响应归一化是Alexnet网络用到的方法,搞视觉的估计比较熟悉),因为BN本身就是一个归一化网络层。
  4. 可以把训练数据彻底打乱(防止每批训练的时候,某一个样本都经常被挑选到,文献说这个可以提高1%的精度,这句话我也是百思不得其解啊)。

首先思考一个问题:为什么神经网络训练前,都要对输入数据进行归一化?归一化后有什么好处呢?原因在于神经网络学习过程本质就是为了学习数据分布 ,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对数据都要做一个归一化预处理的原因。
对于深度网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。
我们知道网络一旦train起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。Paper所提出的算法,就是要解决在训练过程中,中间层数据分布发生改变的情况,于是就有了Batch Normalization.

在实现中,应用此技术通常相当于在完全连接的层(或卷积层,我们很快就会看到)之后以及非线性之前立即插入BN层。另外,批量标准化可以被解释为在网络的每个层进行预处理,但是以可区分的方式集成到网络本身中。牛!

详细内容待拜读论文后再次记录Mark!

4.Regularization (L2/L1/Maxnorm/Dropout)

有几种方法可以防止神经网络过拟合
L2范式:它可以通过直接在目标中惩罚所有参数的平方来实现。对每个权重矩阵w,我们增加1/2 *λw^2 项,其中λ是规范化强度。
L1范式: w = w + λ|w| 向量各元素绝对值之和
L1会趋向于产生少量的特征,而其他的特征都是0,而L2会选择更多的特征,这些特征都会接近于0
Drop out :是一种简单有效的方法,完善了其他方法。Dropout是指在模型训练时随机让网络某些隐含层节点的权重不工作,不工作的那些节点可以暂时认为不是网络结构的一部分,但是它的权重得保留下来(只是暂时不更新而已),因为下次样本输入时它可能又得工作了。如下图所示
在这里插入图片描述

""" Vanilla Dropout: Not recommended implementation (see notes below) """

p = 0.5 # probability of keeping a unit active. higher = less dropout

def train_step(X):
  """ X contains the data """
  
  # forward pass for example 3-layer neural network
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = np.random.rand(*H1.shape) < p # first dropout mask 这里*的作用是把a.shape想用位置的参数传到rand的相应位置,用法非常精妙!
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = np.random.rand(*H2.shape) < p # second dropout mask
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3
  
  # backward pass: compute gradients... (not shown)
  # perform parameter update... (not shown)
  
def predict(X):
  # ensembled forward pass
  H1 = np.maximum(0, np.dot(W1, X) + b1) * p # NOTE: scale the activations
  H2 = np.maximum(0, np.dot(W2, H1) + b2) * p # NOTE: scale the activations
  out = np.dot(W3, H2) + b3

在上面train_step函数中应用了两次dropout,在predict函数中不需要应用dropout,但我们需要执行两次缩放,我们希望测试时神经元的输出与训练时的预期输出相同

For example, in case of p=0.5, the neurons must halve their outputs at test time to have the same output as they had during training time (in expectation). To see this, consider an output of a neuron x (before dropout). With dropout, the expected output from this neuron will become px+(1−p)0, because the neuron’s output will be set to zero with probability 1−p. At test time, when we keep the neuron always active, we must adjust x→px to keep the same expected output. It can also be shown that performing this attenuation at test time can be related to the process of iterating over all the possible binary masks (and therefore all the exponentially many sub-networks) and computing their ensemble prediction.

上述方案的缺点是我们必须在测试时按p缩放激活。因为测试时间性能宝贵,所以更多的是使用inverted dropout

""" 
Inverted Dropout: Recommended implementation example.
We drop and scale at train time and don't do anything at test time.
"""

p = 0.5 # probability of keeping a unit active. higher = less dropout

def train_step(X):
  # forward pass for example 3-layer neural network
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = (np.random.rand(*H1.shape) < p) / p # first dropout mask. Notice /p!
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = (np.random.rand(*H2.shape) < p) / p # second dropout mask. Notice /p!
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3
  
  # backward pass: compute gradients... (not shown)
  # perform parameter update... (not shown)
  
def predict(X):
  # ensembled forward pass
  H1 = np.maximum(0, np.dot(W1, X) + b1) # no scaling necessary
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  out = np.dot(W3, H2) + b3

Bias regularization :不需要对偏置项进行规范化

Loss functions

多标签分类问题:可以使用Hierarchical Softmax
回归问题:回归是预测实值数量的任务,例如房屋价格或图像中某物的长度。对于此任务,通常计算预测数量和真实答案之间的误差,然后测量L2平方范数或差值的L1范数。

When faced with a regression task, first consider if it is absolutely necessary. Instead, have a strong preference to discretizing your outputs to bins and perform classification over them whenever possible.

这里作者给出了由衷的建议:当碰到回归问题时,我们首先想到的不是要用哪个模型,而是想回归是不是必须的,有没有必要。是不是可以将你的输出离散化为bins,并尽可能对其进行分类

Summary

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值