目录
提要
本书是使用python进行深度学习实践的一本初学指南。
介绍深度神经网络的两项任务——分类和回归。
第1章 如何阅读本书
第2章 深度学习入门
2.2什么是深度学习
深度学习是机器学习与神经网络、人工智能、图形化建模、优化、模式识别和信号处理等技术融合后产生的一个领域。
2.2.2有监督学习和无监督学习
有监督学习:训练的数据包含已知的结果。模型相对于这些结果进行训练。有监督学习的基本目标是学习给定训练样本的预测器。
无监督学习:训练数据不包含任何已知的结果。算法自行发现数据中的联系。无监督学习的目标是将一组为标注的数据分成不同的种类或者类聚。
半监督学习使用大量的未标注数据和非常少量的标注数据。半监督学习技术,在减少获取专业标注数据集所耗费时间和成本方面有明显的好处。
2.2.3深度学习的流程
用数据进行学习的目标是预测响应变量或者用一组给定的属性对响应变量分类。
其他流行的数据学习技术有决策树(decision tree)、随机森林(random forest)和支持向量机(support vector machine)。这些技术虽然强大,但是并不深入。决策树和随机森林工作在原始输入数据上,不进行变换,也不生成新特征;支持向量机层次较浅,因为它们仅由核函数和线性变换组成。类似地,单隐藏层神经网络也不被视为深度神经网络,因为它们只包含一个隐藏层。
2.3深度学习能解决什么问题
深度学习的威力来自于适量的并行非线性步骤对非线性数据进行分类或预测的能力。从原始输入数据到数据的实际分类的过程中,深度学习模型学习输入数据的分层特征。每一层从前一层的输出中提取特征。擅长识别数据中的复杂模式,并可以解决非结构化数据难题。
第3章 神经网络基础
3.2神经网络的拓扑结构
神经网络由大量相互连接的的节点——通常称之为神经元——构成。
一个典型的前馈神经网络至少有一个输入层、一个隐藏层和一个输出层。隐藏层一般用来对原始输入属性进行非线性转换。
因为信息向前流经网络,所以称之为前馈神经网络。
3.3神经元的作用
神经元的产生是由于模拟人脑生理结构和功能的愿望。数学节点、单元或者神经元是人工神经网络的核心。它是基本的处理单位。从本质上讲,神经元通过加权和相互激活。这保证了两个神经元之间连接强度的大小由处理信息的权重来确定。(加权和激活是神经元的计算方式)。
3.4理解激活函数
每个神经元都包含一个激活函数和一个阈值。阈值是输入信息激活神经元所必需的最小值。激活函数作用后,输出被传递到网络中后面的神经元。
激活函数被设计用于限制神经元的输出,输出通常为0到1,或者-1到+1之间的值。在大多数情况下,网络中的所有神经元都使用相同的激活函数。
神经元的任务是对输入信号进行加权求和并应用于激活函数,然后将输出传递到下一层。
隐藏层节点的激活函数将非线性引入网络中。隐藏层可以被认为是非常复杂的特征转换。
3.4.1数学计算
参数是连接的权重,参数
被称为偏差,与线性回归模型中的截距相似。
神经网络的大小通常由需要估计的参数数量来度量。权重数量与偏差数量的和,注意输入层只有权重,输出层只有偏差。
3.4.2sigmoid函数
sigmoid函数(S形函数或Logistic函数)是二元分类问题中的流行选择。它是一个S形的可微分激活函数。
其计算公式为:
3.5神经网络如何进行学习
反向传播网络是第一个广泛使用的学习算法,目前仍被广泛使用。它使用梯度下降算法作为核心学习机制。开始给定随机的权重,反向传播算法计算网络权重,做出微小的调整,并逐步根据网络产生的结果和预期结果之间的误差做出调整。
神经网络通过设置随机值的权重和偏差进行初始化。一个经验法则是将随机值设置在范围(-2n~2n)内,其中n是输入属性的数量。
3.6解释梯度下降算法
梯度下降是神经网络中流行的优化算法之一。梯度下降算法迭代地更新参数,使整体网络的误差最小化。该算法在损失函数(损失函数是用来估量模型地预测值与真是值得不一致程度,它是一个非负值函数)的梯度上迭代地更新权重参数,,直至达到最小值。
随机梯度下降(SGD)是真实梯度的近似值。在每次迭代中,它随机选择一个样本来更新参数,并在该样本的相关梯度上移动。因此,它遵循一条曲折的通往极小值的梯度路径。在某种程度上,由于其缺乏冗余,它往往能比传统梯度下降更快地收敛到解决方案。随机梯度下降的一个非常好的理论特性是,如果损失函数是凸函数,那么保证能找到全局最小值。
进化算法是神经网络众多的训练算法之一。实际上我发现进化算法效率低下,而且速度相对较慢。
第4章 深度神经网络(DNN)简介
我们可以将DNN视为多个回归模型的组合。一个关键的观点是,由于典型DNN中有很多层,所以隐藏层可以看作是一对对数线性模型,在给定输入属性的情况下,这些模型共同地逼近相应类地后验概率。
第5章 如何构建可定制的深度预测模型
5.4标准化的重要性
在传统的统计分析中,通常将变量进行标准化,以使其分布近似为高斯分布。
5.5使用训练样本和测试样本
sklearn软件包一个很好的功能是可以简单轻松地构建训练样本和测试样本。
5.6创建深度神经网络回归模型的极简方式
from sknn.mlp import Regressor,Layer
fit1=Regressor(
Layers=[
Layer("Sigmoid",units=6),
Layer("Sigmoid",units=14),
Layer("Linear")],
learning_rate=0.02,
random_state=2016,
n_iter=10)
我们构建了一个有两个隐藏层的深度神经网络。其中第一个隐藏层有6个节点,第二个隐藏层有14个节点。
下面是代码中需要注意的几点。
- 我们用的是scikit-neuralnetwork软件包中的sknn.mlp模块。
- 因为要构建一个预测模型,代码第一行从sknn.mlp中引入Regressor和Layer。
- 创建模型fit1,包含两个使用Sigmoid激活函数的隐藏层。
- 输出层使用线性激活函数,输出神经元的激活函数是隐藏层输出的加权和。
- 学习速率设为0.02,模型允许的最大迭代数为10。
- random_state参数用来再现相同的数据。
如果使用的是python的标准发行版,可以通过pip安装scikit-neuralnetwork软件包。在python脚本目录中输入:
pip install scikit-neuralnetwork
5.7学习速率详解
学习速率决定了梯度下降法达到极小值的步长大小。
学习速率过高会导致系统偏离目标函数,过小会降低学习速度。
最佳学习速率通常接近最大学习速率的一半,不会造成训练标准的偏差。从一个大的学习速率开始,如果偏离了训练标准,则再次尝试该学习速率的1/3值,如此反复,直到没有观察到偏差为止。
5.8评估模型在训练集性能表现的几种方式
相关系数,范围是-1到+1之间。
平方相关系数,范围是0到+1之间。
均方差(MSE),值越小,预测值越接近观测的目标值数据。
均方根误差(RMSE),RMSE可以解释为以目标变量为单位度量的预测值和观测值之间的平均距离。
第6章 提高性能的一些技巧
6.1sigmoid激活函数的局限
sigmoid激活函数的一个局限性是当x增大或减小时,它的梯度变的越来越小。如果使用梯度下降或类似地方法,这就是一个问题,该问题成为梯度消失问题。
由于网络输出层的梯度相对于前面层中的参数可能变得非常小,因此随着层数的增加,学习速度的降低会被放大。
需要掌握的另一个激活函数
使用不会将输入空间挤压成狭小范围的激活函数,可以避免梯度消失问题。
非挤压式函数——线性整流单元(ReLU)。它的定义是:
其中x是神经元的输入,该函数执行一个阈值操作,任何小于0的输入都被设置为0。
该函数只有在输出神经元为正的时候,它才会允许激活。这也提高了神经网络视为稀疏性,因为当随机初始化的时候,整个网络中大约一半的神经元将被设置为0。稀疏性把神经元在大部分时间限制在不活跃的状态。这通常会得到更好的泛化性能。
6.2选择最佳层数的原则
一个简单的经验法则——函数越复杂,需要使用的层数就越多。
最佳迭代数
深度神经网络的一个关键特征是迭代式的学习过程。通常简单地增加迭代的数量就可以提高性能。当然,给定的迭代次数越多,训练神经网络需要的时间就越多。
最终,数据科学取得巨大成功的关键是进行大量的实验——对于特定问题选择最大迭代次数。
6.3如何快速改进模型
奥卡姆(Ocams Razor)剃刀法则 的几种解释如下。
- 如果较小的一组属性能充分拟合观测值,便使用这些属性,避免“叠加”附加属性来提高模型地拟合度。
- 选择需要最少假设的建模方法。
- 只保留那些与假设的预测有明显差异的假定子集。
- 如果几种假设能同样好地解释一种现象,通常在开始选择最简单的一个。
- 如果两个或更多模型具有相同的预测精度,选择最简单的模型。
6.4避免过度拟合
在构建深度神经网络时,你将面临一个永远存在的的问题是过度拟合。
这是因为相对于要解决的问题,你的模型太复杂了。过度拟合的关键结果是对未来(不可见的)数据的泛化(预测)能力较差。
为了降低深度神经网络的复杂度并提高泛化能力的一个常见网络限制方法是正则化。
正则化有两种。第一种是L1正则化,使用权重绝对值的和。第二种是L2正则化,使用权重的平方和。
6.5应该包含多少个神经元
思考这个问题的一种方法是,要注意你想要从数据中提取的特征模式包含着变体。
一个想法是在每层使用更多的神经元来检测数据中的良好结构。然而,使用的隐藏的神经元越多,过度拟合的风险就越大。因为神经元越多,DNN同时学习模式和噪声,而不是数据隐藏的统计结构的可能性就越大,过度拟合就是这样产生的。过度拟合的结果是DNN在训练样本中表现非常好,但在训练样本之外却表现不佳。
在构建DNN模型时,请牢记这一点。为了获得最好的泛化能力,DNN应该用尽可能少的神经元来解决手头的问题,并且有一个可容忍的误差。训练模式的数量越多,可以使用的神经元数量越多,同时能仍然保持DNN的泛化能力。
6.6评估测试数据集上的性能
6.7冻结网络权重
冻结优化模型的权重后,你可以将其用于未来的数据而不必重新训练模型。
你也可以冻结特定的层,如果你想调查非冻结层的权重如何影响输入属性,这样做就会很有用。
6.8保存网络以供将来使用
第7章 二元分类神经网络的奥秘
二元分类的本质特征是学习算法将一个对象分配到两个预定义类别中的一个。
7.3使用python从网络下载数据
我们需要的数据存储在UCI机器学习资源库中。urllib软件包是一个非常强大的python模块,在处理URL(统一资源定位符)相关的工作上非常有用。下面是获取数据的示例代码:
import numpy as np
import urllib
url="http://goo.gl/j0Rvxq"
raw_data=urllib.urlopen(url)
dataset=np.loadtxt(raw_data,delimiter=",")
前两行加载numpy和urllib软件包。第三行保存指向数据的url。然后从UCI机器学习资源库中直接读取数据并保存到python对象raw_data中。最后,使用numpy的loadtxt函数的分隔符参数整理一下数据,并保存到python对象dataset中。
7.4处理缺失的观测值
7.5保存数据
7.6冲量简单入门
另一个帮助网络脱离局部极小值的技术是冲量。它的取值在0到1之间。它将前一个权重更新的一部分加到当前的权重中。
一条经验法则是在使用大的冲量时降低学习速率。
7.7留出法的秘密
在留出法(hold out)(通常称为验证集)中,用来训练模型的数据集被分为不重叠的两组——用于训练分类器的实际训练集和用于估计训练的分类器的误差率的验证集。
我们通常留出训练样本观测值的20%~25%用于留出验证。但是,因为留出验证包含了一个单独的训练和测试过程,估计的误差率可能取决于如何进行数据的分割。次优分割(sub-optimal split)可能会产生误导性的误差率。
7.8如何用python快速构建一个深度神经网络二元分类器
- 打开样本数据文件
- 生成训练集和测试集
- 指定模型
- 拟合模型
- 混淆矩阵
第8章 构建优秀模型之道
8.1尝试最简单的想法提高成功率
8.2随机失活的威力
随机省略一部分隐藏神经元的过程称为随机失活(dropout)。
这个想法非常简单,并会导致在每个epoch得到较弱的学习模型。弱模型本身具有较低的预测能力,然而许多弱模型的预测可以被加权并组合以产生具有更强预测能力的模型。
8.3相似性
事实上,随机失活与bagging这种机器学习技术背后的想法非常相似。bigging是一种模型平均方法,从训练数据的自举样本上训练的分类器中获得大多数投票。实际上,你可以将dropout视为几个神经网络模型的隐式bagging。
因此,随机失活可以被认为是在许多不同的神经网络上进行模型平均的有效方法。
8.4共适应
然而,在实际中,两个或多个神经元开始重复地检测相同的特征是很常见的。这叫做共适应(coadaptation)。这意味着DNN并没有充分利用其全部能力,实际浪费了计算资源来计算激活冗余神经元,而这些神经元都在做同样的事情。
在训练的前馈阶段,随机失活通过去除一定比例神经元的激活来阻止隐藏层的神经元出现共适应的情况。随机失活也可以用于输入。在这种情况下,算法会随机忽略一定比例的输入属性。
8.5一个教训
DNN 中的随机失活不能绝对保证会提高性能,但通常值得一试。
在开发自己的DNN模型时,请牢记以下3点。
- 通过在DNN中创建多条通往正确分类的路径,随机失活能降低噪声样本中共适应的可能。
- 随机失活的比例越大,训练中引入的噪声就越多,这会降低学习速度。
- 随机失活在非常大的DNN模型上的效果最佳。
8.6双曲正切激活函数的威力以及如何有效地使用
双曲正切(Tanh)函数的形式:
与sigmoid激活函数一样,tanh函数也是反曲形(S形状)的,但输出范围为-1到+1。因为tanh函数本质上是一个缩放的sigmoid函数,所以它有许多相同的性质。但是,因为它的输出范围较宽,在复杂非线性关系建模时,有时更有效。
8.7如何从小批量方法中获益
小批量方法是加速神经网络计算的常用方法之一。它在几个训练样本(批次)上一起计算梯度,而不是像在原始随机梯度下降算法中那样针对每个单独的样本计算梯度。
一个批次由一个前向/反向传播中的多个训练样本组成。请注意,批次越大,运行模型所需的内存就越多。
一个常见的问题是什么时候应该使用小批量方法?答案取决于所构建DNN的大小。模型中的神经元越多,小批量方法的潜在收益就越大。
另一个常见的问题是关于最佳小批量的大小。最好的建议是尝试一下不同的值,看看在你的样本和特定的DNN体系架构下哪一个合适。
8.8重建模型
性能准确率
准确率=正确数量/总样本数
8.9关于不平衡样本你应该知道的事
实际上,对于不平衡样本,通常会记录平均类别准确率。它是通过计算每个类别的平均准确率得到:
平均类别准确率=(类别1准确率+类别2准确率)/2
8.10小结
记住,在实际应用中,你应该基于训练样本选择模型,然后仅在测试集上运行一次。如果用测试样本测试多个模型,则会增加模型在新数据上不能很好泛化的可能性。
第9章 深度神经网络在多元分类问题的简单应用
9.1分类问题描述
手写识别是一个经典的机器学习问题。
9.2关于softmax激活函数的说明
softmax激活函数(有时称为多项式指数函数)是sigmoid激活函数在多项式环境的推广。
其中,第j层第i个神经元的输出(概率)。
softmax激活函数的输出位于0和1之间,并且总和为1.可以把它们解释为分类目标变量的后验概率。
对于softmax激活函数,单个神经元的输出取决于该层上的其他神经元。它可以被看作一组二元节点。,它们的状态是相互制约的,这样,如果k个状态中一个为1,那么其余的皆为0。
9.3使用rmsprop算法构建多项式模型
随机梯度下降算法使用一种静态调整形式(即设置全局学习速率为一个指定值,不需要记住该值)。在随机梯度下降期间,权重的更新向量分量会有许多值,有些更新非常大,但有些很小。无论大小或者方向,唯一的学习权重会应用到所有更新中。虽然这是一个非常流行的学习规则,但能否成功很大程度上取决于如何调整学习速率。
有证据表明,随机梯度下降过程中的自动学习速率调整能够提高网络的性能。rmsprop算法对每个更新向量分量使用不同的学习速率。它使用每个参数的梯度幅度的指数移动平均值除以该平均值的平方根对梯度进行归一化。
9.4Adagrad学习算法概述
Adagrad算法变得越来越流行。它是为了回答“所有特征应该使用相同的学习速率吗”的问题而设计的。这是一个非常重要的问题,因为在高维特征空间,许多特征是不相关的。然而有些少量的特征往往包含了非常丰富的信息。有效的数据学习建议将不相关的特征应该使用低的学习速率,而对信息丰富的特征使用大的学习速率。这是该算法背后的基本思想。
Adagrad学习算法的工作原理是,对于训练样本中很少出现的特征使用较大的学习速率,降低稀疏特征的学习速率。它是一种动态合并的方法。
在该算法中,梯度是通过对累积历史观测的梯度平方和的平方根归一化动态调整的。
关键点:Adagrad通过结合过去观测值的几何结构来采用一个适应特定特征的学习速率。
9.5如何尝试其他学习算法
9.5.1Nesterov的加速梯度下降算法
Nesterov的加速梯度下降算法被称为一阶优化算法,旨在提高稳定性并加快常规梯度下降的收敛速度。Nesterov算法向梯度更新中添加了一个冲量。
Nesterov的加速梯度下降算法已经被证明是平滑凸优化的最佳方法。
9.5.2尝试冲量法
9.5.3常规随机梯度下降法
9.5.4在模型中使用Adadelta算法
Adadelta算法是Adagrad算法的一种改进。它使用固定大小的窗口上的累积的梯度平方和,而不是所有迭代累积的梯度平方和。