斯坦福CS231n课程笔记纯干货2

11. 神经网络的数据预处理

均值减法(Mean subtraction是预处理最常用的形式。它对数据中每个独立特征减去平均值,从几何上可以理解为在每个维度上都将数据云的中心都迁移到原点。在numpy中,该操作可以通过代码X -=np.mean(X, axis=0)实现。而对于图像,更常用的是对所有像素都减去一个值,可以X -= np.mean(X)实现,也可以在3个颜色通道上分别操作。

归一化(Normalization是指将数据的所有维度都归一化,使其数值范围都近似相等。有两种常用方法可以实现归一化。第一种是先对数据做零中心化(zero-centered)处理,然后每个维度都除以其标准差,实现代码为X /= np.std(X,axis=0)。第二种方法是对每个维度都做归一化,使得每个维度的最大和最小值是1和-1。这个预处理操作只有在确信不同的输入特征有不同的数值范围(或计量单位)时才有意义,但要注意预处理操作的重要性几乎等同于学习算法本身。在图像处理中,由于像素的数值范围几乎是一致的(都在0-255之间),所以进行这个额外的预处理步骤并不是很必要。

PCA和白化(Whitening)是另一种预处理形式。在这种处理中,先对数据进行零中心化处理,然后计算协方差矩阵,它展示了数据中的相关性结构。

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) # 对数据去相关性
np.linalg.svd 的一个良好性质是在它的返回值 U 中,特征向量是按照特征值的大小排列的。 这个操作也被称为主成分分析(  Principal Component Analysis  简称PCA)降维:
 
Xrot_reduced = np.dot(X,U[:,:100]) #Xrot_reduced 变成 [N x 100]

白化(whitening。白化操作的输入是特征基准上的数据,然后对每个维度除以其特征值来对数值范围进行归一化。该变换的几何解释是:如果数据服从多变量的高斯分布,那么经过白化后,数据的分布将会是一个均值为零,且协方差相等的矩阵。该操作的代码如下:

# 对数据进行白化操作:
# 除以特征值
Xwhite = Xrot / np.sqrt(S+ 1e-5)

PCA和白化主要是为了介绍的完整性,实际上在卷积神经网络中并不会采用这些变换

常见错误。进行预处理很重要的一点是:任何预处理策略(比如数据均值)都只能在训练集数据上进行计算,算法训练完毕后再应用到验证集或者测试集上。例如,如果先计算整个数据集图像的平均值然后每张图片都减去平均值,最后将整个数据集分成训练/验证/测试集,那么这个做法是错误的。应该怎么做呢?应该先分成训练/验证/测试集,只是从训练集中求图片平均值,然后各个集(训练/验证/测试集)中的图像再减去这个平均值。

12. 神经网络的权重初始化

错误:全零初始化。因为如果网络中的每个神经元都计算出同样的输出,然后它们就会在反向传播中计算出同样的梯度,从而进行同样的参数更新神经元之间就失去了不对称性的源头。

小随机数初始化。解决方法就是将权重初始化为很小的数值,以此来打破对称性。小随机数权重初始化的实现方法是:W = 0.01 * np.random.randn(D,H)。每个神经元的权重向量都被初始化为一个随机向量,而这些随机向量又服从一个多变量高斯分布,这样在输入空间中,所有的神经元的指向是随机的。

使用1/sqrt(n)校准方差。随着输入数据量的增长,随机初始化的神经元的输出数据的分布中的方差也在增大。我们可以除以输入数据量的平方根来调整其数值范围,这样神经元输出的方差就归一化到1了。建议将神经元的权重向量初始化为:w =np.random.randn(n) / sqrt(n)。其中n是输入数据的数量。

偏置(biases)的初始化。通常将偏置初始化为0。

实践。当前的推荐是使用ReLU激活函数,并且使用w =np.random.randn(n) * sqrt(2.0/n)来进行权重初始化。

批量归一化(Batch Normalization)。该方法减轻了如何合理初始化神经网络这个棘手问题带来的头痛。在实现层面,应用这个技巧通常意味着全连接层(或者是卷积层,后续会讲)与激活函数之间添加一个BatchNorm。在实践中,使用了批量归一化的网络对于不好的初始值有更强的鲁棒性。最后一句话总结:批量归一化可以理解为在网络的每一层之前都做预处理,只是这种操作以另一种方式与网络集成在了一起。

13. 神经网络的正则化

L2正则化可能是最常用的正则化方法了。可以通过惩罚目标函数中所有参数的平方将其实现。即对于网络中的每个权重w,向目标函数中增加一个

L1正则化是另一个相对常用的正则化方法。对于每个w我们都向目标函数增加一个L1L2正则化也可以进行组合:,这也被称作Elastic net regularizaton。在实践中,如果不是特别关注某些明确的特征选择,一般说来L2正则化都会比L1正则化效果好。

最大范式约束(Max norm constraints另一种形式的正则化是给每个神经元中权重向量的量级设定上限,并使用投影梯度下降来确保这一约束。即使在学习率设置过高的时候,网络中也不会出现数值爆炸,这是因为它的参数更新始终是被限制着的。

随机失活(Dropout),随机失活的实现方法是让神经元以超参数的概率被激活或者被设置为0

在测试过程中不使用随机失活,可以理解为是对数量巨大的子网络们做了模型集成(model ensemble),以此来计算出一个平均的预测。

14. 神经网络的损失函数

分类问题中,一个最常见的损失函数就是SVM(是Weston Watkins 公式):有些学者的论文中指出平方折叶损失(即使用)算法的结果会更好。第二个常用的损失函数是Softmax分类器,它使用交叉熵损失:

回归问题中,对于某个样本,L2范式计算如下: L1范式则是要将每个维度上的绝对值加起来:

注意L2损失比起较为稳定的Softmax损失来,其最优化过程要困难很多。所以在面对一个回归问题时,先考虑将输出变成二值化是否真的不够用。

当面对一个回归任务,首先考虑是不是必须这样。一般而言,尽量把你的输出变成二分类,然后对它们进行分类,从而变成一个分类问题。

15. 学习过程检查

训练期间第一个要跟踪的数值就是损失值,它在前向传播时对每个独立的批数据进行计算。下图展示的是随着损失值随时间的变化,尤其是曲线形状会给出关于学习率设置的情况:

右图显示了一个典型的随时间变化的损失函数值,而且指出了批数据的数量可能有点太小(因为损失值的噪音很大)。损失值的震荡程度和批尺寸(batch size)有关,当批尺寸为1,震荡会相对较大。当批尺寸就是整个数据集时震荡就会最小,因为每个梯度更新都是单调地优化损失函数(除非学习率设置得过高)。

在训练集准确率和验证集准确率中间的空隙指明了模型过拟合的程度。在图中,蓝色的验证集曲线显示相较于训练集,验证集的准确率低了很多,这就说明模型有很强的过拟合。遇到这种情况,就应该增大正则化强度(更强的L2权重惩罚,更多的随机失活等)或收集更多的数据。另一种可能就是验证集曲线和训练集曲线如影随形,这种情况说明你的模型容量还不够大:应该通过增加参数数量让模型容量更大些。

16. 神经网络的参数更新

普通更新x += -learning_rate* dx

动量(Momentum)更新

v = mu *v - learning_rate * dx # 与速度融合
x += v # 与位置融合

在这里引入了一个初始化为0的变量v和一个超参数mu。说得不恰当一点,这个变量(mu)在最优化的过程中被看做动量(一般值设为0.9,但其物理意义与摩擦系数更一致。这个变量有效地抑制了速度,降低了系统的动能,不然质点在山底永远不会停下来。通过交叉验证,这个参数通常设为[0.5,0.9,0.95,0.99]中的一个。和学习率随着时间退火(下文有讨论)类似,动量随时间变化的设置有时能略微改善最优化的效果,其中动量在学习过程的后阶段会上升。一个典型的设置是刚开始将动量设为0.5而在后面的多个周期(epoch)中慢慢提升到0.99

通过动量更新,参数向量会在任何有持续梯度的方向上增加速度。

Nesterov动量

Nesterov动量。既然我们知道动量将会把我们带到绿色箭头指向的点,我们就不要在原点(红色点)那里计算梯度了。使用Nesterov动量,我们就在这个“向前看”的地方计算梯度。

v_prev = v # 存储备份
v = mu * v -learning_rate * dx # 速度更新保持不变
x += -mu *v_prev + (1 + mu) * v # 位置更新变了形式

学习率退火

随步数衰减每进行几个周期就根据一些因素降低学习率。

指数衰减。数学公式是,其中是超参数,t是迭代次数(也可以使用周期作为单位)。

1/t衰减的数学公式是,其中是超参数,t是迭代次数。

在实践中,我们发现随步数衰减的随机失活(dropout)更受欢迎,因为它使用的超参数(衰减系数和以周期为时间单位的步数)比更有解释性。最后,如果你有足够的计算资源,可以让衰减更加缓慢一些,让训练时间更长些

逐参数适应学习率方法

Adagrad是一个由Duchi提出的适应性学习率算法

# 假设有梯度和参数向量x
cache += dx**2
x += - learning_rate *dx / (np.sqrt(cache) + eps)

Adagrad的一个缺点是,在深度学习中单调的学习率被证明通常过于激进且过早停止学习。

RMSprop

cache =  decay_rate * cache + (1 - decay_rate) * dx**2
x += - learning_rate *dx / (np.sqrt(cache) + eps)

在上面的代码中,decay_rate是一个超参数,常用的值是[0.9,0.99,0.999]

AdamAdam是最近才提出的一种更新方法,它看起来像是RMSProp的动量版。简化的代码是下面这样:

m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
x += - learning_rate *m / (np.sqrt(v) + eps)

论文中推荐的参数值eps=1e-8, beta1=0.9, beta2=0.999。在实际操作中,我们推荐Adam作为默认的算法,一般而言跑起来比RMSProp要好一点。

各优化器优化过程演示:


17. 超参数调优

神经网络最常用的设置有:初始学习率。学习率衰减方式(例如一个衰减常量)。正则化强度(L2惩罚,随机失活强度)。比起交叉验证最好使用一个验证集

模型集成

在实践的时候,有一个总是能提升神经网络几个百分点准确率的办法,就是在训练的时候训练几个独立的模型,然后在测试的时候平均它们预测结果。集成的模型数量增加,算法的结果也单调提升(但提升效果越来越少)。还有模型之间的差异度越大,提升效果可能越好。

同一个模型,不同的初始化。使用交叉验证来得到最好的超参数,然后用最好的参数来训练不同初始化条件的模型。这种方法的风险在于多样性只来自于不同的初始化条件。

18. 卷积神经网络基础

与常规神经网络不同,卷积神经网络的各层中的神经元是3维排列的:宽度高度深度(这里的深度指的是激活数据体的第三个维度,而不是整个网络的深度,整个网络的深度指的是网络的层数)。

左边是一个3层的神经网络。右边是一个卷积神经网络,图例中网络将它的神经元都排列成3个维度(宽、高和深度)。卷积神经网络的每一层都将3D的输入数据变化为神经元3D的激活数据并输出。

19. 卷积神经网络的结构

一个简单的卷积神经网络是由各种层按照顺序排列组成,网络中的每个层使用一个可以微分的函数将激活数据从一个层传递到另一个层。卷积神经网络主要由三种类型的层构成:卷积层汇聚(Pooling)层全连接层(全连接层和常规神经网络中的一样)。通过将这些层叠加起来,就可以构建一个完整的卷积神经网络。

卷积层

卷积层的参数是有一些可学习的滤波器集合构成的。每个滤波器在空间上(宽度和高度)都比较小,但是深度和输入数据一致。

直观地来说,网络会让滤波器学习到当它看到某些类型的视觉特征时就激活,具体的视觉特征可能是某些方位上的边界,或者在第一层上某些颜色的斑点,甚至可以是网络更高层上的蜂巢状或者车轮状图案。

在每个卷积层上,我们会有一整个集合的滤波器(比如12个),每个都会生成一个不同的二维激活图。将这些激活映射在深度方向上层叠起来就生成了输出数据。

局部连接:在处理图像这样的高维度输入时,让每个神经元都与前一层中的所有神经元进行全连接是不现实的。相反,我们让每个神经元只与输入数据的一个局部区域连接。该连接的空间大小叫做神经元的感受野(receptive field),它的尺寸是一个超参数(其实就是滤波器的空间尺寸)。在深度方向上,这个连接的大小总是和输入量的深度相等。需要再次强调的是,我们对待空间维度(宽和高)与深度维度是不同的:连接在空间(宽高)上是局部的,但是在深度上总是和输入数据的深度一致。

空间排列:上文讲解了卷积层中每个神经元与输入数据体之间的连接方式,但是尚未讨论输出数据体中神经元的数量,以及它们的排列方式。3个超参数控制着输出数据体的尺寸:深度(depth),步长(stride零填充(zero-padding

输出数据体的空间尺寸为(W-F +2P)/S+1,在计算上,输入数据体的长和宽按照该公式计算,深度依赖于滤波器的数量。

汇聚层(池化层 pooling)

最大汇聚的效果比平均汇聚要好。

卷积神经网络通常是由三种层构成:卷积层,汇聚层(除非特别说明,一般就是最大值汇聚)和全连接层(fully-connected简称FC)。ReLU激活函数也应该算是是一层,它逐元素地进行激活函数操作。

最常见的卷积神经网络结构如下:

INPUT ->[[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC

其中*指的是重复次数,POOL?指的是一个可选的汇聚层。其中N >=0,通常N<=3,M>=0,K>=0,通常K<3。例如,下面是一些常见的网络结构规律:

INPUT ->FC,实现一个线性分类器,此处N= M = K = 0

INPUT ->CONV -> RELU -> FC

INPUT ->[CONV -> RELU -> POOL]*2 -> FC -> RELU -> FC。此处在每个汇聚层之间有一个卷积层。

INPUT ->[CONV -> RELU -> CONV -> RELU -> POOL]*3 -> [FC -> RELU]*2-> FC。此处每个汇聚层前有两个卷积层,这个思路适用于更大更深的网络,因为在执行具有破坏性的汇聚操作前,多重的卷积层可以从输入数据中学习到更多的复杂特征。

几个小滤波器卷积层的组合比一个大滤波器卷积层好。

更多关于CNN的内容请移步这里:深度学习之卷积神经网络CNN

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值