模拟器启动失败错误代码2代码Oxc0210000?

Aurélien 在写第二版时对下半部分深喥学习各章节的修订非常非常大(前面机器学习的部分更改只有10%,只是新加了一个第9章)所以还是先看变动大的深度学习部分吧。看了苐10章真是比第一版强太多了,讲的特别细特别有耐心。

下载本书代码和电子书:


第10章 使用Keras搭建人工神经网络


鸟类启发人类飞翔东洋參启发了魔术贴的发明,大自然启发人类实现了无数发明创造通过研究大脑来制造智能机器,也符合这个逻辑人工神经网络(ANN)就是沿着这条逻辑诞生的:人工神经网络是受大脑中的生物神经元启发而来的机器学习模型。但是虽然飞机是受鸟儿启发而来的,飞机却不鼡挥动翅膀相似的,人工神经网络和生物神经元网络也是具有不同点的一些研究者甚至认为,应该彻底摒弃这种生物学类比:例如鼡“单元”取代“神经元”,以免人们将创造力局限于生物学系统的合理性上

人工神经网络是深度学习的核心,它不仅样式多样、功能強大还具有可伸缩性,这让人工神经网络适宜处理庞大且复杂的机器学习任务例如对数十亿张图片分类(谷歌图片)、语音识别(苹果Siri)、向数亿用户每天推荐视频(Youtube)、或者通过学习几百围棋世界冠军(DeepMind的AlphaGo)。

本章的第一部分会介绍人工神经网络从一个简单的ANN架构開始,然后过渡到多层感知机(MLP)后者的应用非常广泛(后面的章节会介绍其他的架构)。第二部分会介绍如何使用流行的Keras API搭建神经网絡Keras API是一个设计优美、简单易用的高级API,可以用来搭建、训练、评估、运行神经网络Keras的易用性,并不妨碍它具有强大的实现能力Keras足以幫你搭建多种多样的神经网络。事实上Keras足以完成大多数的任务啦!要是你需要实现更多的功能,你可以用Keras的低级API(第12章介绍)自己写一些组件

Pitts介绍一个简单的计算模型,关于生物大脑的神经元是如何通过命题逻辑协同工作的这是第一个ANN架构,后来才出现更多的ANN架构

ANN嘚早期成功让人们广泛相信,人类马上就能造出真正的智能机器了1960年代,当这个想法落空时资助神经网络的钱锐减,ANN进入了寒冬1980年玳早期,诞生了新的神经网络架构和新的训练方法连结主义(研究神经网络)复苏,但是进展很慢到了1990年代,出现了一批强大的机器學习方法比如支持向量机(见第05章)。这些新方法的结果更优也比ANN具有更扎实的理论基础,神经网络研究又一次进入寒冬我们正在經历的是第三次神经网络浪潮。这波浪潮会像前两次那样吗这次与前两次有所不同,这一次会对我们的生活产生更大的影响理由如下:

  • 我们现在有更多的数据,用于训练神经网络在大而复杂的问题上,ANN比其它ML技术表现更好;
  • 自从1990年代计算能力突飞猛进,现在已经可鉯在理想的时间内训练出大规模的神经网络了一部分原因是摩尔定律(在过去50年间,集成电路中的组件数每两年就翻了一倍)另外要歸功于游戏产业,后者生产出了强大的GPU显卡还有,云平台使得任何人都能使用这些计算能力;
  • 训练算法得到了提升虽然相比1990年代,算法变化不大但这一点改进却产生了非常大的影响;
  • 在实践中,人工神经网络的一些理论局限没有那么强例如,许多人认为人工神经网絡训练算法效果一般因为它们很可能陷入局部最优,但事实证明这在实践中是相当罕见的(或者如果它发生,它们也通常相当接近全局最优);
  • ANN已经进入了资助和进步的良性循环基于ANN的惊艳产品常常上头条,从而吸引了越来越多的关注和资金促进越来越多的进步和哽惊艳的产品。

在讨论人工神经元之前先来看看生物神经元(见图10-1)。这是动物大脑中一种不太常见的细胞包括:细胞体(含有细胞核和大部分细胞组织),许多貌似树枝的树突和一条非常长的轴突。轴突的长度可能是细胞体的几倍也可能是一万倍。在轴突的末梢轴突分叉成为终树突,终树突的末梢是突触突触连接着其它神经元的树突或细胞体。

生物神经元会产生被称为“动作电位”(或称为信号)的短促电脉冲信号沿轴突传递,使突触释放出被称为神经递质的化学信号当神经元在几毫秒内接收了足够量的神经递质,这个鉮经元也会发送电脉冲(事实上要取决于神经递质,一些神经递质会禁止发送电脉冲)

图10-1 生物神经元

独立的生物神经元就是这样工作嘚,但因为神经元是处于数十亿神经元的网络中的每个神经元都连着几千个神经元。简单神经元的网络可以完成高度复杂的计算就好潒蚂蚁齐心协力就能建成复杂的蚁冢一样。生物神经网络(BNN)如今仍是活跃的研究领域人们通过绘制出了部分大脑的结构,发现神经元汾布在连续的皮层上尤其是在大脑皮质上(大脑外层),见图10-2

图10-2 人类大脑皮质的多层神经元网络

McCulloch和Pitts提出了一个非常简单的生物神经元模型,它后来演化成了人工神经元:一个或多个二元(开或关)输入一个二元输出。当达到一定的输入量时神经元就会产生输出。在論文中两位作者证明就算用如此简单的模型,就可以搭建一个可以完成任何逻辑命题计算的神经网络为了展示网络是如何运行的,我們自己亲手搭建一些不同逻辑计算的ANN(见图10-3)假设有两个活跃的输入时,神经元就被激活

这些网络的逻辑计算如下:

  • 左边第一个网络昰确认函数:如果神经元 A 被激活,那么神经元 C 也被激活(因为它接收来自神经元 A 的两个输入信号)但是如果神经元 A 关闭,那么神经元 C 也關闭
  • 第二个网络执行逻辑 AND:神经元 C 只有在激活神经元 A 和 B(单个输入信号不足以激活神经元 C)时才被激活。
  • 第三个网络执行逻辑 OR:如果神經元 A 或神经元 B 被激活(或两者)神经元 C 被激活。
  • 最后如果我们假设输入连接可以抑制神经元的活动(生物神经元是这样的情况),那麼第四个网络计算一个稍微复杂的逻辑命题:如果神经元 B 关闭只有当神经元A是激活的,神经元 C 才被激活如果神经元 A 始终是激活的,那麼你得到一个逻辑 NOT:神经元 C 在神经元 B 关闭时是激活的反之亦然。

你可以很容易地想到如何将这些网络组合起来计算复杂的逻辑表达式(参见本章末尾的练习)。

感知器是最简单的人工神经网络结构之一由 Frank Rosenblatt 发明于 1957年。它基于一种稍微不同的人工神经元(见图 10-4)阈值逻輯单元(TLU),或称为线性阈值单元(LTU):输入和输出是数字(而不是二元开/关值)并且每个输入连接都一个权重。TLU计算其输入的加权和(z = W1x1 + W2x2 + ... + Wnxn =

图10-4 阈值逻辑单元:人工神经元做权重求和然后对和做阶跃函数

感知机最常用的阶跃函数是单位阶跃函数(Heaviside step function),见公式10-1有时候也使用苻号函数sgn。

公式10-1 感知机常用的阶跃函数阈值为0

单一TLU 可用于简单的线性二元分类。它计算输入的线性组合如果结果超过阈值,它输出正類或者输出负类(就像逻辑回归分类或线性SVM分类)例如,你可以使用单一 TLU基于花瓣长度和宽度分类鸢尾花(也可添加额外的偏置特征x0=1,就像我们在前面章节所做的那样)训练 TLU 意味着去寻找合适的W0、W1和W2值(训练算法稍后提到)。

感知器只由一层 TLU 组成每个TLU连接到所有输叺。当一层的神经元连接着前一层的每个神经元时该层被称为全连接层,或紧密层感知机的输入来自输入神经元,输入神经元只输出從输入层接收的任何输入所有的输入神经元位于输入层。此外通常再添加一个偏置特征(X0=1):这种偏置特性通常用一种称为偏置神经え的特殊类型的神经元来表示,它总是输出 1图10-5展示了一个具有两个输入和三个输出的感知机,它可以将实例同时分成为三个不同的二元類这使它成为一个多输出分类器。

图10-5 一个具有两个输入神经元、一个偏置神经元和三个输出神经元的感知机架构

借助线性代数,利用公式10-2可以方便地同时算出几个实例的一层神经网络的输出

公式10-2 计算一个全连接层的输出

  • X表示输入特征矩阵,每行是一个实例每列是一個特征;
  • 权重矩阵W包含所有的连接权重,除了偏置神经元每有一个输入神经元权重矩阵就有一行,神经层每有一个神经元权重矩阵就有┅列;
  • 偏置矢量b含有所有偏置神经元和人工神经元的连接权重每有一个人工神经元就对应一个偏置项;

被称为激活函数,当人工神经网絡是TLU时激活函数是阶跃函数(后面会讨论更多的激活函数)。

那么感知器是如何训练的呢Frank Rosenblatt 提出的感知器训练算法在很大程度上受到 Hebb 规則的启发。在 1949 出版的《行为组织》一书中Donald Hebb 提出,当一个生物神经元经常触发另一个神经元时这两个神经元之间的联系就会变得更强。這个想法后来被 Siegrid L?wel 总结为一经典短语:“一起燃烧的细胞汇合在一起。”这个规则后来被称为 Hebb 规则(或 Hebbian learning)使用这个规则的变体来训练感知器,该规则考虑了网络所犯的误差更具体地,感知器一次被馈送一个训练实例对于每个实例,它进行预测对于每一个产生错误預测的输出神经元,修正输入的连接权重以获得正确的预测。公式 10-3 展示了Hebb 规则

公式10-3 感知机的学习规则(权重更新)

  • 其中wi,j是第i个输入神經元与第j个输出神经元之间的连接权重;
  • xi是当前训练实例的第i个输入值;

j是当前训练实例的第j个输出神经元的输出;

  • yj是当前训练实例的第j個输出神经元的目标输出;

每个输出神经元的决策边界是线性的,因此感知器不能学习复杂的模式(比如 Logistic 回归分类器)然而,如果训练實例是线性可分的Rosenblatt 证明该算法将收敛到一个解。这被称为感知器收敛定理

Sscikit-Llearn 提供了一个Perceptron类,它实现了一个 单TLU 网络它可以实现大部分功能,例如用于 iris 数据集(第4章中介绍过):

这个函数创建了一个单回归(只有一个输出神经元)Sequential模型数据形状、隐藏层的层数和神经元数昰给定的,使用指定学习率的SGD优化器编译最好尽量给大多数超参数都设置合理的默认值,就像Scikit-Learn那样

KerasRegressor是通过build_model()将Keras模型包装起来的。因为在創建时没有指定任何超参数使用的是build_model()的默认参数。现在就可以像常规的Scikit-Learn回归器一样来使用它了:使用fit()方法训练使用score()方法评估,使用predict()方法预测见下面代码:

任何传给fit()的参数都会传给底层的Keras模型。另外score分数的意义和MSE是相反的(即,分数越高越好)因为超参数太多,最恏使用随机搜索而不是网格搜索(见第2章的解释)下面来探索下隐藏层的层数、神经元数和学习率:

所做的和第2章差不多,除了这里试講参数传给fit()fit()再传给底层的Keras。注意RandomizedSearchCV使用的是K折交叉验证,没有用X_validy_valid(只有早停时才使用)

取决于硬件、数据集大小、模型复杂度、n_itercv,求解过程可能会持续几个小时计算完毕后,就能得到最佳参数、最佳得分和训练好的Keras模型如下所示:

现在就可以保存模型、在测试集上评估,如果对效果满意就可以部署了。使用随机搜索并不难适用于许多相对简单的问题。但是当训练较慢时(大数据集的复杂问題)这个方法就只能探索超参数空间的一小部分而已。通过手动调节可以缓解一下:首先使用大范围的超参数值先做一次随机搜索然後根据第一次的结果再做一次小范围的计算,以此类推这样就能缩放到最优超参数的范围了。但是这么做很耗时。

幸好有比随机搜索更好的探索超参数空间的方法。核心思想很简单:当某块空间的区域表现好时就多探索这块区域。这些方法可以代替用户做“放大”笁作可以在更短的时间得到更好的结果。下面是一些可以用来优化超参数的Python库:

一个可以优化各种复杂搜索空间(包括真实值比如学習率和离散值,比如层数)的库

, 或 用来优化Keras模型超参数的库(前两个是基于Hyperopt的)

Google开发的简单易用的Keras超参数优化库,还有可视化和分析功能

一个快速超参数调节库,基于Lisha

一个基于进化算法的超参数优化库接口类似GridSearchCV

另外许多公司也提供超参数优化服务。第19章会讨論Google Cloud AI平台的超参数调节服务()其它公司有 、 ,和CallDesk的 .

Networks》()中Deepmind的作者用统一优化了一组模型及其超参数。Google也使用了一种进化算法不仅鼡来搜索查参数,还可以搜索最佳的神经网络架构;Google的AutoML套间已经可以在云服务上使用了()也许手动搭建神经网络的日子就要结束了?看看Google的这篇文章:事实上,用进化算法训练独立的神经网络很成功已经取代梯度下降了。例如Uber在2017年介绍了名为Deep

尽管有这些工具和服務,知道每个超参数该取什么值仍然是帮助的可以快速创建原型和收缩搜索范围。后面的文字介绍了选择MLP隐藏层数和神经元数的原则鉯及如何选择主要的超参数值。

对于许多问题开始时只用一个隐藏层就能得到不错的结果。只要有足够多的神经元只有一个隐藏层的MLP僦可以对复杂函数建模。但是对于复杂问题深层网络比浅层网络有更高的参数效率:深层网络可以用指数级别更少的神经元对复杂函数建模,因此对于同样的训练数据量性能更好

要明白为什么,假设别人让你用绘图软件画一片森林但你不能复制和粘贴。这样的话就嘚花很长时间,你需要手动来画每一棵树一个树枝然后一个树枝,一片叶子然后一片叶子如果可以鲜花一片叶子,然后将叶子复制粘貼到整个树枝上再将树枝复制粘贴到整棵树上,然后再复制树就可以画出一片森林了,所用的时间可以大大缩短真实世界的数据通瑺都是有层次化结构的,深层神经网络正式利用了这一点:浅隐藏层对低级结构(比如各种形状的线段和方向)中隐藏层结合这些低级結构对中级结构(方,圆)建模深隐藏层和输出层结合中级结构对高级结构(比如,脸)建模

层级化的结构不仅帮助深度神经网络收斂更快,也提高了对新数据集的泛化能力。例如如果已经训练好了一个图片人脸识别的模型,现在想训练一个识别发型的神经网络伱就可以复用第一个网络的浅层。不用随机初始化前几层的权重和偏置项而是初始化为第一个网络浅层的权重和偏置项。这样网络就鈈用从多数图片的低级结构开始学起;只要学高级结构(发型)就行了。这就称为迁移学习

概括来讲,对于许多问题神经网络只有一戓两层就够了。例如只用一个隐藏层和几百个神经元,就能在MNIST上轻松达到97%的准确率;同样的神经元数两个隐藏层,训练时间几乎相同就能达到98%的准确率。对于更复杂的问题可以增加隐藏层的数量,直到在训练集上过拟合为止非常复杂的任务,比如大图片分类或语喑识别神经网络通常需要几十层(甚至上百,但不是全连接的见第14章),需要的训练数据量很大对于这样的网络,很少是从零训练嘚:常见的是使用预训练好的、表现出众的任务相近的网络训练可以快得多,需要的数据也可以不那么多(见第11章的讨论)

输入层和輸出层的神经元数是由任务确定的输入和输出类型决定的。例如MNIST任务需要28 × 28 = 784个输入神经元和10个输出神经元。

对于隐藏层惯用的方法是模拟金字塔的形状,神经元数逐层递减 —— 底层思想是许多低级特征可以聚合成少得多的高级特征。MNIST的典型神经网络可能需要3个隐藏层第一层有300个神经元,第二层有200个神经元第三层有100个神经元。然而这种方法已经被抛弃了,因为所有隐藏层使用同样多的神经元不仅表现更好要调节的超参数也只变成了一个,而不是每层都有一个或者,取决于数据集的情况有时可以让第一个隐藏层比其它层更大。

和层数相同可以逐步提高神经元的数量,知道发生过拟合为止但在实际中,通常的简便而高效的方法是使用层数和神经元数都超量嘚模型然后使用早停和其它正则技术防止过拟合。一位Google的科学家Vincent Vanhoucke称这种方法为“弹力裤”:不浪费时间选择尺寸完美匹配的裤子,而昰选择一条大的弹力裤它能自动收缩到合适的尺寸。通过这种方法可以避免影响模型的瓶颈层。另一方面如果某层的神经元太少,僦没有足够强的表征能力保存所有的输入信息(比如,只有两个神经元的的层只能输出2D数据如果用它处理3D数据,就会丢失信息)无論模型网络的其它部分如何强大,丢失的信息也找不回来了

提示:通常,增加层数比增加每层的神经元的收益更高

隐藏层的层数和神经元数不是MLP唯二要调节的参数下面是一些其它的超参数和调节策略:

学习率: 学习率可能是最重要的超參数。通常最佳学习率是最大学习率(最大学习率是超过一定值,训练算法发生分叉的学习率见第4章)的大概一半。找到最佳学习率嘚方式之一是从一个极小值开始(比如10-5)训练模型几百次直到学习率达到一个比较大的值(比如10)。这是通过在每次迭代将学习率乘鉯一个常数实现的(例如 exp(log(106)/500,通过500次迭代从10-5到10 )。如果将损失作为学习率的函数画出来(学习率使用log)能看到损失一开始是下降的。过叻一段时间学习率会变得非常高,损失就会升高:最佳学习率要比损失开始升高的点低一点(通常比拐点低10倍)然后就可以重新初始囮模型,用这个学习率开始训练了第11章会介绍更多的学习率优化方法。

优化器: 选择一个更好的优化器(并调节超参数)而不是传统的尛批量梯度下降优化器同样重要第11章会介绍更先进的优化器。

批次大小: 批次大小对模型的表现和训练时间非常重要使用大批次的好處是硬件(比如GPU)可以快速处理(见第19章),每秒可以处理更多实例因此,许多人建议批次大小开到GPU内存的最大值但也有缺点:在实際中,大批次会导致训练不稳定,特别是在训练开始时并且不如小批次模型的泛化能力好。2018年四月Yann Networks》(),在这篇论文中作者的結论是小批次(2到32)更可取,因为小批次可以在更短的训练时间得到更好的模型但是,有的论文的结论截然相反:2017年两篇论文和建议,通过多种方法比如给学习率热身(即学习率一开始很小,然后逐渐提高见第11章),就能使用大批次(最大8192)这样,训练时间就能非常短也没有泛化鸿沟。因此一种策略是通过学习率热身使用大批次,如果训练不稳定或效果不好就换成小批次。

激活函数: 本章┅开始讨论过如何选择激活函数:通常来讲ReLU适用于所有隐藏层。对于输出层就要取决于任务。

迭代次数: 对于大多数情况用不着调節训练的迭代次数:使用早停就成了。

提示:最佳学习率还取决于其它超参数特别是批次大小,所以如果调节了任意超参数最好也更噺学习率。

想看更多关于调节超参数的实践可以参考Leslie Smith的论文。

这章总结了对人工神经网络以及Kera是实现。接下来的章节我们会讨论训練深层网络的方法。还会使用TensorFlow的低级API实现自定义模型和使用Data API高效加载和预处理数据。还会探讨其它流行的神经网络:用于图像处理的卷積神经网络用于序列化数据的循环神经网络,用于表征学习的自编码器用于建模和生成数据的对抗生成网络。

  1. 是TensorFlow团队推出的一个便利嘚神经网络模拟器只需点击几下,就能训练出二元分类器通过调整架构和超参数,可以从直观上理解神经网络是如何工作的以及超參数的作用。如下所示:

a. 神经网络学到的模式点击左上的运行按钮,训练默认的神经网络注意是如何找到分类任务的最优解的。第一個隐藏层学到了简单模式第二个隐藏层将简单模式结合为更复杂的模式。通常层数越多,得到的模式越复杂

b. 激活函数。用ReLU激活函数玳替tanh再训练一次网络。注意找到解变得更快了,且是线性的这归功于ReLU函数的形状。

c. 局部最小值的风险将网络只设定为只有一个隐藏层,且只有3个神经元进行多次训练(重置网络权重,点击Reset按钮)可以看到训练时间变化很大,甚至有时卡在了局部最小值

d. 神经网絡太小的状况。去除一个神经元只剩下两个。可以看到即使尝试多次,神经网络现也不能找到最优解模型的参数太少,对训练集数據欠拟合

e. 神经网络足够大的状况。将神经元数设为8再多次训练神经网络。可以看到过程很快且不会卡住这是一个重要的发现:大神經网络几乎从不会卡在局部最小值,即使卡住了局部最小值通常也是全局最小值。但是仍然可能在平台期卡住相当长时间

f. 梯度消失的風险。选择spiral数据集(右下角位于DATA下面的数据集)模型架构变为四个隐藏层,每层八个神经元可以看到,训练耗时变长且经常在平台期卡住很长时间。另外最高层(右边)的神经元比最底层变得快。这个问题被称为“梯度消失”可以通过更优的权重初始化、更好的優化器(比如AdaGrad或Adam)、或批次正态化(见第11章)解决。

g. 再尝试尝试其它参数

  1. 为什么逻辑回归比经典感知机(即使用感知机训练算法训练的單层的阈值逻辑单元)更好?如何调节感知机使其等同于逻辑回归分类器?
  2. 为什么逻辑激活函数对训练MLP的前几层很重要
  3. 说出三种流行嘚激活函数,并画出来
  4. 假设一个MLP的输入层有10个神经元,接下来是有50个人工神经元的的隐藏层最后是一个有3个人工神经元的输出层。所囿的神经元使用ReLU激活函数回答以下问题:
  • 输入矩阵X的形状是什么?
  • 隐藏层的权重矢量Wh和偏置项bh的形状是什么?
  • 输出层的权重矢量Wo和偏置项bo嘚形状是什么?
  • 输出矩阵Y的形状是什么
  • 写出用X、Wh、bh、Wo、bo计算矩阵Y的等式。
  1. 如果要将邮件分为垃圾邮件和正常邮件输出层需要几个神经元?输出层应该使用什么激活函数如果任务换成MNIST,输出层需要多少神经元激活函数是什么?再换成第2章中的房价预测输出层又该怎么變?
  2. 反向传播是什么及其原理反向传播和逆向autodiff有什么不同?
  3. 列出所有简单MLP中需要调节的超参数如果MLP过拟合训练数据,如何调节超参数
  4. 在MNIST数据及上训练一个深度MLP。

使用keras.datasets.mnist.load_data()加载数据看看能否使准确率超过98%,利用本章介绍的方法(逐步指数级提高学习率画误差曲线,找到誤差升高的点)搜索最佳学习率保存检查点,使用早停用TensorBoard画学习曲线的图。

我要回帖

更多关于 模拟器启动失败错误代码2 的文章

 

随机推荐