中文字幕AV中文字幕AV翻译

18个月自学AI,2年写就三万字长文,过来人教你怎样掌握这几个AI根底看法

道雪、思源、张倩
编译

David Code 有众个身份:他是旅游作家,晓得众国言语,他照旧一名「AI 教师」。没稀有学和软件配景的 David 用 18 个月的时间通过线课程和博客自学 AI,并花费两年时间撰写了一篇长文。为了使和他相同没稀有学根底的人也能初学人工智能,他这篇作品中运用了大宗类比、例子、故事、图示,将主要的常识点或方法重复夸张。这是一篇真正针对初学者的 AI 教程,不光讲看法,还讲看法的底层原理。

因为原文过长,中文字幕AV编译进程中举行了少量删省。念了解更众细节,请查看原文链接:https://colab.research.google.com/drive/1VdwQq8JJsonfT4SV0pfXKZ1vsoNvvxcH#scrollTo=C810qURdm3hZ。

念学 AI 又担忧没稀有学配景或软件被页究没联系,这篇博客十分适合你。

我一经花费一年半的时间自学种种线课程和博客,进程中有太众专家、太众新闻,而且他们的许众看法另有冲突。我进修进程中常常充满自我疑心。

我不念要许众专家帮我进修,我只念要一个教师。我期望有人可以拉着我的手说:「Dave,这便是你需求学的东西,请按照这个序次学。现我将用丹青、幽默的故事、实行示例和粗浅易懂的言语教你进修 AI。」

而现,我便是谁人教师。

为什么是我?和网上的专家差别,我没稀有学或编程被页粳不过我曾就读于耶鲁大学和普林斯顿大学,环游过 100 众个国家,是一名旅游作家,我曾《周六夜现场》义务,我的作品得过奖。也便是说,我晓得怎样通过写作来传达繁杂的看法,晓得怎样讲故事。我热爱教学,也擅长发明好的教师。进修深度进修进程中我碰到了四位精良的教师,他们是 Andrew Trask、Grant Sanderson、Kalid Azad 和我的导师 Adam Koenig。

最主要的是,我了解你正阅历的苦楚。你据说过「专家盲区」(expert blindness)吗?专家向新手教学某个学科时,因为他成为专家的时间太久,会忘了初学者对教材的感觉。于是专家会疾速先容少许繁杂的看法,而这些看法需求剖析成小块才干便当初学者掌握。或者他们不运用类比、丹青或示例来帮帮初学者掌握看法,导致初学者十分受挫。

每一个初学者都念要专家来教他们 AI。而终究上,你需求的不是专家,而是一名教师。

最好的教师便是谁人方才学过这些常识的人,因为他仍然记得本人挣扎过的地方以及抑制方法,而且他可以向你传授捷径。而我便是这私人。我不是专家,但我是个好教师,而且丰饶激情。

本文运用指南

本文的阅读进程和小说差别,只读一次是无法了解和掌握所有实质的。我学数学的朋侪告诉我,他们常常需求读起码 7 遍数学文本才干开端了解。这不是开玩乐……

为便当教学,我运用了类比、丹青、示例和几何外示。可是请定心,本文数学层面上是准确而厉谨的。请做好阅读本文五遍的准备,无法立即体会也不要着急。

我进修繁杂材料的时分,一般会修立计时器,每五分钟响一次,不时地提示本人不要失望中重沦,要微乐、耐心并保持下去。这真的有用,置信我。

以下是少许宏观要点:

深度进修包罗四个主要看法。本文的目标是让读者掌握这四个深度进修根底看法:

之前对这四个看法一窍欠亨?没联系,起首我会运用类比和图示尽量简单地教学这些常识,然后不时地回到这四个看法,议论此中的细节。你应当将本文看作一个「螺旋上升」的进修进程,每一次回到这些看法时你都会劳绩更众睹地。

本文共有五个部分:

1. 深度进修概览:示例、类比、图示、玩乐

2. 28 行代码创立神经收集:神经元和突触

3. 前馈:做出有依据的猜念,60000 次迭代

4. 从试错中进修:梯度下降和全部最小值

5. 反向传达:链式法则

1. 深度进修概览

1.1 示例

念象你是一家宠物店的老板,遗迹策划得很成功,而这成功很洪流平上是因为你善用 AI 技能。你构修了一个深度神经收集,来挑选潜新顾客,并向他们发送广告。一个月前,你上线了一款新猫砂「Litter Rip!」。你试图找到乐意给本人的猫运用这款猫砂的顾客。

而你的秘密武器是数据集。新猫砂上线一个月后,你对宠物店顾客举行了考察并搜罗了少许数据。考察包罗以下题目:

这四个题目的谜底即之前顾客的「特征」(feature)。

那么题目来了:什么使得 AI 收集云云强大?

谜底是:它运用考察结果举行教练,从而准确地预测未来顾客的置办方法。

起首,你需求将之前顾客的考察数据和他们对前三个题目的答复输入到收集中,举行教练。该收集运用这些数据预测某位顾客是否确实置办了新款猫砂。然后收集再将预测结果与顾客第四个题目的谜底举行比照。第四个题目的谜底便是标签,举措终究供收集举行比照。比如,假如收集预测结果是「是的,我认为这位顾客买过 Litter Rip! 猫砂」,而这位顾客第四个题目的谜底确实是「Yes」,那么你就具有了一个成功的神经收集。

神经收集通过试错举行自我教练:收集先预测,然后比照预测结果与第四个题目的真正谜底,再从过失中进修,并众次迭代中不时改良。

神经收集一般一个数据集上教练,另一个数据集上施行预测,了解这一点很主要。一朝你的神经收集很擅长依据之前顾客的考察数据预测新款猫砂的置办状况,那么你就可以换一个新的数据集,该数据集包罗潜新顾客的名单。

你从兽医那里取得了新的数据集,这些被考察者答复了前三个题目。现,假如让你用教练好了的收集潜新顾客中预测广告投放的最佳对象,你该怎样做呢?

我们来看下一节。

1.2 类比:神经元和突触

下图是我们将要构修的 3 层神经收集,图中运用的是常睹的「神经元和突触」样式:

我们先来看这张图,图中是一个三层的前馈神经收集。左侧为输入层:三个圆圈外示神经元(即节点或特征,该收集将运用前三个考察题目举措特征)。现,你看着这一列圆圈,念象它们区分代外一位顾客的谜底。左上的圆圈包罗题目 1「你有猫吗?」的谜底,左中圆圈包罗题目 2「你喝进口啤酒吗?」的谜底,左下圆圈外示题目 3「你是否拜访过我们的网站 LitterRip.com?」的谜底。那么,假如顾客 1 对这三个题目的谜底是「Yes/No/Yes」,则左上圆圈包罗 1,左中圆圈包罗 0,左下圆圈包罗 1。

突触(连接这些圆圈和躲藏层的所有线)是神经收集用来「考虑」的部位。右侧的单个圆圈(它仍然和四个突触相连)是收集的预测结果,即「基于输入到收集的特征组合,此处展现了这位顾客置办新款猫砂的概率。」

最右侧标注「y」的单个圆圈外示真值,即每个顾客对第四个考察题目「你是否置办过 Litter Rip! 猫砂?」的答复。这个圆圈有两个挑选:0 外示没买过,1 外示买过。神经收集将输出一个预测概率,并将其与 y 举行比照,查看准确率,然后下一次迭代中吸取教训。神经收集数秒时间内可以完毕数万次试错。

上图是神经收集的典范图示。实质上,它描画的是前馈,即我们要先容的第一个主要看法。你可以认为神经元是该进程中最主要的部分,可是这里的类比仿佛保管少许误导性。终究上,本文要先容的四个深度进修主要看法的配合驱动力是突触。于是,目前这部分最主要的常识点是:突触使得预测爆发。下面一节我会把这一看法类比为落进碗里的乒乓球。

举行下一个类比之前,我念起首精细标明一下神经收集之以是强大的启事。

1.3 类比:碗与球

要点来了!人工智能云云强大的启事是:神经收集运用概率对下一次预测举行渐进式的改良。该进程将试错进修晋升到一个全新的目标。

我们先来看一下人类是怎样预测的:假设你的桌子上有少许之前顾客的考察结果,旁边另有一叠潜新顾客的考察结果(即兽医供应应你的考察数据)。人类怎样运用之前顾客的考察结果预测未来顾客的置办方法呢?你可以会念:「我的模糊逻辑告诉我,喝进口啤酒的顾客和买新款猫砂的顾客没相联系。我查看了顾客考察结果,试图寻寻得一种方式,我认为具有猫和拜访过 LitterRip.com 网站的顾客置办过 Litter Rip! 猫砂。」

只要三个考察题目、四名被考察顾客时,这是可行的。可是假如有 40 个题目、4000 名顾客呢?人类怎样决议哪一个题目举步伐行准确预测的中心因素?人类大脑可以容纳的数目是有限的,我们很难量化 40000 名顾客中的某一位置办新款猫砂的概率。这个数字是 67% 照旧 68%?谁晓得呢!

现我们来看神经收集怎样施行预测:神经收集不会将预测范围于直截了当的「是」或「否」,相反,它会预测出一个 0 和 1 之间的数字——概率。比如,0.67 外示「该顾客有 67% 的可以置办新款猫砂」,0.13 外示「该顾客有 13% 的可以置办新款猫砂,可以性较小。」

这就阐清楚为什么给出一个 0 到 1 之间的概率数字是明智的:就合盘算机的第一次预测结果与实行状况天差地别也没相联系。真正主要的是,收集会将概率 0.13 与真值举行比照(假设真值是 1,即该顾客置办了新款猫砂),收集会当心到它的预测结果偏离真值 0.87,这是一个比较大的偏向,于是收集会举行调解。收集将保持数字分明展现,同时调解数字,添加少许值低沉另少许值,以找到更好的题目组合,从而使下一次预测可以取得更加准确的预测结果。将该方法重复数万次,直到盘算机最终可以自大地说:「我很速乐地发布,现我的预测结果可以媲美真值了,偏向几近于零。现我可以准确预测了。」

现,你晓得了深度神经收集的强大启事,它运用概率和试错进修方法,渐进式地改良下一次预测的结果。

我可以用一幅简单分明的丹青描画试错进修进程:收集的试错进修就像顺着碗边滚落的乒乓球,最终将落碗底。

前面我标清楚神经收集怎样施行预测:盘算偏向,改良下一次的预测结果,直到偏向淘汰到确实为零。施行预测的神经收集就像顺着碗侧滚落的乒乓球。我们假设碗底便是「乌托邦」——准确的预测结果,那么收集的第一次预测便是该「预测球」(乒乓球)的起始位置;第二次预测时,乒乓球沿着碗侧向底部行进一点间隔;第三次预测时,球又向碗底行进一点……如下图所示,收集的每一次预测便是乒乓球向碗底行进时的新位置。

预测球滚落以及抵达完美位置(碗底)之前的准确率改良进程包罗四步:

收集每次举行更好的预测时,粉色的预测球沿着碗侧向底部全部最小偏向值行进。每一次预测后,收集将预测结果与第四个题目的谜底举行比照,这相似于特准时候权衡预测球与碗底的间隔。权衡预测结果与真值的间隔叫做「寻得偏向」。收集每次预测的目标都是继续地缩抖蓦全部最小值之间的偏向。

换句话说:

记住:我们现只是大约了解,以是即使有些地方没有掌握也不要担忧。

精细标明这些看法之前,我念把「碗和球」的类比再促进一步。上图展现了神经收集教练进程中的四个主要方法,但过于简化。它准确地外示了只要一个考察题目的收集,该收集也仅基于这一个题目做出预测。

可是,我们念做的是联合三个考察题目寻得最佳预测。于是,假如收集试错迭代进程中运用差别题目组合举行试验,碗会是什么式样呢?谜底是:一只上下不屈的碗。

如下图所示:

图源:https://www.youtube.com/watch?v=IHZwWFHWa-w&t=2s&index=3&list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi

上图中血色的碗有少许特出和凹陷,为什么会如许呢?

起首,我们必需了解血色碗由什么构成。从图中看它仿佛是塑料做的……不过并不是,念象它由数百万个红点构成,每个红点都是 3D 网格中的一个点。每个点外示一个可以的考察题目组合,以及该组合中哪个题目关于收集施行预测的品级更高。这个上下不屈的碗让我们看到了所有可以组合的上下不屈的外面。

记住这幅图:血色碗是「所有排列组合的外面」,它像山脉相同有高峰、幽谷、山岭、河床。收集无法穷尽浩繁宇宙中每一个可以的排列组合,这会花费太众盘算时间。于是,它从你随机「扔掷预测球」的位置动身,一道向下走向谷底(即全部最小值)。收集不需求管它从哪里开端动身,它只需求意从随机的起始点抵达碗底即可。

标明血色的上下不屈处之前,我们先来看从红碗右上角开端的白色虚线。这条线的顶端便是收集的第一次预测。还记得上文先容的血色乒乓球吗?假设乒乓球就白线顶端处,白色虚线外示收集预测结果从起始点到全部最小值的道径。也便是说乒乓球沿着这条白色虚线走到偏向最小、预测准确率最高的地方。

可是为什么这条白色虚线道径云云弯曲呢?启事于,收集的常规试验需求思索组合哪些题目、每个题目的权重众大,才干取得偏向最小的最佳预测结果。收集的常规目标是尽可以低沉偏向,即让乒乓球尽速抵达红碗底部。于是收集一般采用虚线上球所点的坡度,来确定哪个偏向具备最陡峭的坡度,可以完成最速的向下道径。因为坡度不时改动,这条道径就很迂回。我们来看一个简单的例子:

人类第一眼就会判别这两个题目(「你有猫吗?」和「你拜访过我们网站吗?」)是做出预测的根底题目。可是哪个题目对预测准确度影响最大呢?第一个题目影响更大,照旧二者五五分?

收集念用这两个题目的差别权重组合举行试验,从而寻得完成准确预测的最佳组合。上图血色碗中的每个特出都外示「走过失道道上」的题目组合和题目权重,因为每个特出都使收集的「预测球」愈发偏离底部的全部最小值。而碗中的每个凹陷都外示「走准确道道上」的题目组合,因为它使预测球离碗底更近。

可是,假如收集寻得了三个考察题目的完美权重组合,但预测准确率仍然只要 60% 尊驾,该怎样办?不要怕,收集另有另一个本领:推测题目(inferred question)。

下面我们用一个简单示例讲述这个主要看法:

我们回过头看关于进口啤酒的谁人题目。神经收集不停实验差别的题目组合。那么举例来说,大约只要富人才有钱买进口喜力啤酒,而我们都晓得养猫的人很可以是富人。(本猫奴的心里:不,我不是,我没有……)那么也许当「你喝进口啤酒吗?」和「你有猫吗?」这两个题目收集盘算进程中是组合题目且权重较高时,预测结果会取得改良。

这里的推测题目便是「富人更有可以置办 Litter Rip 猫砂吗?」。不过我们刚踩遇了一个(愚昧的)推测:喝进口喜力啤酒和养猫的人可以比较丰饶。

可是,跟着粉色预测球血色碗中兜兜转转,它到了特出处,而启事于收集运用了这个推测题目举行试验。也便是说该推测题目关于改良预测准确率并没有帮帮。(可以是因为猫砂不是糜费品而是养猫者的必需品。)接下来的迭代中,预测球分开特出处,不再运用这个无用的推测题目。可是它也有可以因为有用的推测题目掉进凹陷处,从而帮帮它更速地抵达碗底。

上文的示例展现了怎样测试推测题目能否有用帮帮完成更准确的预测结果。人类运用模糊逻辑探究推测题目,而神经收集实验穷尽每一种排列组合。假如试验取得了较好的预测结果,它会保管该题目。假如试验取得了更糟的预测结果,收集将扔弃该题目。

总之,血色碗外面上每一个红点外示收集运用特定题目组合和权重组合举行的一次试验。每一个凹陷外示「这一步走了准确的道道上」,收集当心到这一点并将继续保持。每一个特出处外示「这一步走错了偏向」,收集也会当心到并摒弃它。预测球的道径(白色虚线)歪歪扭扭,是因为预测球通往碗底的道上不时寻找凹陷处、避免特出处。你可以说白色虚线是预测球通往碗底的最高效道径。

现我们转回来,更精细地了解一下「前馈」、「全部最小值」、「反向传达」和「梯度下降」。

1.3.1 前馈:将穿孔卡片输入到 1960 年的 IBM 盘算机

前馈的目标是创立预测。假设每一次预测是预测球向碗底行进进程中的一个新位置。上图血色碗中,收集做的第一次预测由白色虚线右上角的点外示,我们假设预测球就这个点上。前馈是创立第一次预测的进程。白色虚线上的下一个点即是第二次预测,如许预测球挪动到下一个点,之后再举行第三次预测。

阵势部 AI 课程和博客不会提及,预测球所的每个位置由血色碗底部白色网格的两个坐标轴决议。血色碗并非空间中漂移,它位于白色网格之上,该网格具备 X 轴和 Y 轴。

还记得上图先容全部最小值时所用的图像吗?黄色碗位于桌面上。同理,血色碗位于白色网格上。白色网格即「桌面」,「完美、无偏向的预测位置」即血色碗实行位于的点。当心,碗与桌面独一的连接点是碗底,即白色虚线完毕的点(全部最小值)。

预测球血色碗中的每次停留,即每次预测点,都由 3 个坐标轴决议:X 轴和 Y 轴外示网格位置,Z 轴外示预测球到网格的间隔。

现让我们跳出笼统描画。3D 空间中这三个坐标轴实行生存中外示什么?

追念一下,血色碗外面上每一个红点外示收集运用特定题目组合和权重组合举行的一次试验,那么收集怎样施行试验呢?它运用 X 轴和 Y 轴白色网格上定一个位置,外示特定的题目组合。X 轴和 Y 轴必定会问:「嗨,Z 轴你好,这个组合怎样样?」Z 轴将告诉我们该组合的效果——Z 轴认真权衡偏向。

我们之条件到,碗底,即碗与白色网格相连接的位置,是完美的预测。那么碗中每一个红点都外示偏向,离白色网格越远,偏向就越大。

这点十分主要:白色网分外示收集可以实验的题目及权重组合。关于白色网格上的每一个点,其上方的红点外示该组合的偏向值。也便是说,血色碗上的每个红点外示其系澜预测的偏向。血色碗便是「偏向构成的碗」。只要碗底,红点接触白色网格的地方,二者之间没有间隔,也于是没有偏向。参睹下图:

上图中的锥形黄色箭头外示 Z 轴,用于权衡偏向。它很有用,你可以从中了解偏向值并进修,以便下次取得更加准确的预测结果。

念象一下,粉色的预测球白色虚线上挪动,黄色箭头老是预测球系澜,并随之挪动。粉色球外示收集做出的每次预测,黄色箭头权衡预测球到白色网格的间隔,即权衡每次预测的偏向。它的运转原理是什么?

你可以会念到前馈——以前三个考察题目举措输入并用差别方法举行题目组合,再施行预测,预测结果为 0 到 1 之间的数字,即概率。念象预测球所的点外示白色虚线上的数字。我们晓得第四个题目的谜底是「1」,于是真值是该顾客买过新款猫砂。真值即是全部最小值,是我们改良预测结果的目标,也是血色碗和白色网格的接触点。于是,收集用 1 减去预测概率。举例来说,假如收集的第一次预测为 0.5,即该顾客有 50% 的可以性置办过这款猫砂,1 减去 50% 所得的数字外示偏向,黄色箭头就用于权衡该偏向。某种程度上可以说,「真值数字 - 预测球数字 = 黄色箭头数字」。该示例中,即 1 - 0.5 = 0.5。偏向(黄色箭头的长度)为 0.5(偏向一般用绝对值外示,不行为负值)。

没有第四个考察题目的话,你无法教练收集,因为你需求真值来测试预测结果。黄色箭头权衡收集预测与真值的间隔,即偏向,这个例子中真值为 1。我们的第一次预测(0.5)准确率并不高,0.99 的预测才可以说比较准确。

1.3.2 找到全部最小值

我们的目标是教练神经收集寻得淘汰预测偏向的最速方法,也便是说让黄色箭头变短,这意味着我们需求预测球从起始点到碗底的最高效道径。碗底即「乌托邦」,那里黄色箭头(预测偏向)的长度确实为 0(全部最小值),即我们的预测具备最小偏向,收集抵达十分高的准确率。而预测球抵达碗底的最高效道径是那条白色虚线。一朝我们运用第一个数据汇合束教练,收集就可以准确预测另一拨潜新客户置办新款猫砂的概率。

现念象这个场景:预测球从白色虚线顶端开端,此时黄色箭头(即第一次预测的偏向值)等于 0.5。我们怎样让球抵达碗底呢?也便是说,我们怎样调解收集,使预测球(目前 X,Y 坐标为 (3,3))白色网格上挪动到碗底(碗底点的坐标大致为 (3,0))。目前,我们仅能基于顾客 1 的谜底施行预测。那么,我们怎样基于每个顾客的答复改良之后每一次预测的结果,直到预测偏向确实为 0?也便是预测球抵达碗底,收集教练得足够好,可以应用新数据集做出预测。

找到从不那么准确的预测结果 0.5 到最终第 6 万次预测结果 0.9999 的每一步道径,这便是梯度下降进程。

1.3.3 梯度下降和反向传达

梯度下降外示收集的试错进修进程。关于数学 nerd 来说,它可定义为一个总体计划:改动突触权重、每次迭代时最洪流平上低沉偏向。

关于一般人来说,这里有一个更好的标明:将小球沿兹宇陡峭的坡度滚下,尽速地抵达碗底。反向传达是一种盘算梯度的方法,梯度实便是坡度(slope)。反向传达告诉你预测球所位置的坡度。

坡度这里十分主要。所有专家都会运用术语「梯度下降」,而梯度的意义便是「坡度」。找到预测球碗外面位置点的坡度,可以指示出球尽速抵达碗底应当挪动的偏向。

可是,为什么是坡度呢?请思索梯度下降的进程:

起首,盘算机施行前馈预测。用真值(全部最小值所位置,即碗底)减去预测取得偏向(黄色箭头长度),然后运用反向传达盘算偏向的坡度。坡度决议了预测球滚动的偏向和速率(即收集应当数字方面做出众大的调解)。

寻得坡度是反向传达的主要东西。假如说梯度下降是总体计划,那么反向传达便是告竣计划的主要东西。

2. 28 行代码创立神经收集

现我们来看代码。我将起首展现本日要进修的通通代码,然后再举行精细的方法讲解。倡议两个窗口中翻开本文,一个窗口显示代码,另一个继续往下阅读。从下文代码解释中可以看到,我将构修神经收集的进程剖析成了 13 个方法。现准备好观看盘算机从它所犯的过失中进修并最终识别出方式了吗?

不过,起首我们先来了解矩阵和线性代数的看法。

下文的代码中,你会看到单词「matrix」或「matrices」(矩阵)。它十分主要:矩阵是这辆汽车的引擎。没有矩阵,神经收集哪儿都去不了。

矩阵是众行数字的汇合。你将碰到的第一个矩阵如下所示,它容纳了宠物店顾客考察的数据。

[1,0,1],
[0,1,1],
[0,0,1],
[1,1,1]

将每一行念象为一名顾客,那么以上矩阵中共有 4 位顾客,每一行的方括号中包罗三个数字(1 和 0 区分外示「是」和「否」)。 1.2 节中,我们看到顾客 1 对前三个考察题目的谜底是「Yes/No/Yes」,于是该矩阵的第一方法 1, 0 ,1。第一列是四位顾客对第一个题目「你有猫吗?」的答复。

为了更精细地先容矩阵这一看法,请看下图。图中外示的矩阵与上面的矩阵相同,不过它众了少许标签和颜色,用于夸张顾客的再起是一行,特征/题目是一列:

上图厘清了一个最初使我十分疑心的点:行与列之间的联系。

该矩阵中,每一位顾客的数据被外示为一行中的三个数字。神经收集图示中(神经元和突触样式),输入层是一个包罗三个圆形神经元的列。你需求当心到,每个神经元并不过示一位顾客,即矩阵中的一行数据。相反,每个神经元外示一个特征,即矩阵中的一列数据。于是,一个神经元内包罗所有顾客对同一个题目/特征的谜底。拿第一个题目「你有猫吗?」举例,我们只采纳了四位顾客的数据,于是上图中该题目的再起中只要四个数字(两个 0、两个 1),而假如我们采纳了一百万名顾客的数据,则上图中该神经元内会包罗一百万个数字,外示这些顾客对该题目的再起。

到这里,我期望大师可以了解我们为什么需求矩阵:因为我们有不止一位顾客。下面的神经收集示例中,我们描画了四位顾客,以是我们需求四行数字。

该收集包罗不止一个题目。每个题目需求一列,于是我们有三列,区分外示对前三个考察题目的答复(第四个题目将呈现后面的另一个矩阵中)。

于是我们的矩阵很小,4 行 X 3 列(4 by 3)。不过实神经收集的矩阵可以拥稀有百万位顾客和数百个考察题目。做图像识另外神经收集可以具备数十亿个「顾客」行和特征列。

总结一下,我们需求矩阵使所稀有据分明展现,便当我们其上举行盘算,如许矩阵就把数据构造成都雅、整洁的行与列。

下面我们来看代码,代码采纳自 Andrew Trask 的博客,不过解释是我写的。

代码

#This is the "3 Layer Network" near the bottom of: 
#http://iamtrask.github.io/2015/07/12/basic-python-network/

#First, housekeeping: import numpy, a powerful library of math tools.
5 import numpy as np

#1 Sigmoid Function: changes numbers to probabilities and computes confidence to use in gradient descent
8 def nonlin(x,deriv=False):
9   if(deriv==True):
10    return x*(1-x)
11  
12  return 1/(1+np.exp(-x))

#2 The X Matrix: This is the responses to our survey from 4 of our customers, 
#in language the computer understands.  Row 1 is the first customer's set of 
#Yes/No answers to the first 3 of our survey questions: 
#"1" means Yes to, "Have cat who poops?" The "0" means No to "Drink imported beer?"
#The 1 for "Visited the LitterRip.com website?" means Yes.  There are 3 more rows
#(i.e., 3 more customers and their responses) below that.  
#Got it?  That's 4 customers and their Yes/No responses 
#to the first 3 questions (the 4th question is used in the next step below).  
#These are the set of inputs that we will use to train our network.
23 X = np.array([[1,0,1],
24               [0,1,1],
25               [0,0,1],
26               [1,1,1]])
#3The y Vector: Our testing set of 4 target values. These are our 4 customers' Yes/No answers 
#to question four of the survey, "Actually purchased Litter Rip?"  When our neural network
#outputs a prediction, we test it against their answer to this question 4, which 
#is what really happened.  When our network's
#predictions compare well with these 4 target values, that means the network is 
#accurate and ready to take on our second dataset, i.e., predicting whether our 
#hot prospects from the (hot) veterinarian will buy Litter Rip!
34 y = np.array([[1],
35               [1],
36               [0],
37               [0]])
#4 SEED: This is housekeeping. One has to seed the random numbers we will generate
#in the synapses during the training process, to make debugging easier.
40 np.random.seed(1)
#5 SYNAPSES: aka "Weights." These 2 matrices are the "brain" which predicts, learns
#from trial-and-error, then improves in the next iteration.  If you remember the 
#diagram of the curvy red bowl above, syn0 and syn1 are the 
#X and Y axes on the white grid under the red bowl, so each time we tweak these 
#values, we march the grid coordinates of Point A (think, "moving the yellow arrow")
#towards the red bowl's bottom, where error is near zero.
47 syn0 = 2*np.random.random((3,4)) - 1 # Synapse 0 has 12 weights, and connects l0 to l1.
48 syn1 = 2*np.random.random((4,1)) - 1 # Synapse 1 has 4 weights, and connects l1 to l2.

#6 FOR LOOP: this iterator takes our network through 60,000 predictions, 
#tests, and improvements.
52 for j in range(60000):

  #7 FEED FORWARD: Think of l0, l1 and l2 as 3 matrix layers of "neurons" 
  #that combine with the "synapses" matrices in #5 to predict, compare and improve.
  # l0, or X, is the 3 features/questions of our survey, recorded for 4 customers.
57  l0=X
58  l1=nonlin(np.dot(l0,syn0))
59  l2=nonlin(np.dot(l1,syn1))

  #8 The TARGET values against which we test our prediction, l2, to see how much 
  #we missed it by. y is a 4x1 vector containing our 4 customer responses to question
  #four, "Did you buy Litter Rip?" When we subtract the l2 vector (our first 4 predictions)
  #from y (the Actual Truth about who bought), we get l2_error, which is how much 
  #our predictions missed the target by, on this particular iteration.
66  l2_error = y - l2

  #9 PRINT ERROR--a parlor trick: in 60,000 iterations, j divided by 10,000 leaves 
  #a remainder of 0 only 6 times. We're going to check our data every 10,000 iterations
  #to see if the l2_error (the yellow arrow of height under the white ball, Point A)
  #is reducing, and whether we're missing our target y by less with each prediction.
72  if (j% 10000)==0:
73    print("Avg l2_error after 10,000 more iterations: "+str(np.mean(np.abs(l2_error))))



#10 This is the beginning of back propagation.  All following steps share the goal of 
  # adjusting the weights in syn0 and syn1 to improve our prediction.  To make our 
  # adjustments as efficient as possible, we want to address the biggest errors in our weights.  
  # To do this, we first calculate confidence levels of each l2 prediction by
  # taking the slope of each l2 guess, and then multiplying it by the l2_error.  
  # In other words, we compute l2_delta by multiplying each error by the slope 
  # of the sigmoid at that value.  Why?  Well, the values of l2_error that correspond 
  # to high-confidence predictions (i.e., close to 0 or 1) should be multiplied by a 
  # small number (which represents low slope and high confidence) so they change little.
  # This ensures that the network prioritizes changing our worst predictions first, 
  # (i.e., low-confidence predictions close to 0.5, therefore having steep slope). 
88  l2_delta = l2_error*nonlin(l2,deriv=True)

  #11 BACK PROPAGATION, continued: In Step 7, we fed forward our input, l0, through 
  #l1 into l2, our prediction. Now we work backwards to find what errors l1 had when
  #we fed through it.  l1_error is the difference between the most recent computed l1 
  #and the ideal l1 that would provide the ideal l2 we want.  To find l1_error, we 
  #have to multiply l2_delta (i.e., what we want our l2 to be in the next iteration) 
  #by our last iteration of what we *thought* were the optimal weights (syn1). 
  # In other words, to update syn0, we need to account for the effects of 
  # syn1 (at current values) on the network's prediction.  We do this by taking the 
  # product of the newly computed l2_delta and the current values of syn1 to give 
  # l1_error, which corresponds to the amount our update to syn0 should change l1 next time.
100  l1_error = l2_delta.dot(syn1.T)
  #12 Similar to #10 above, we want to tweak this 
  #middle layer, l1, so it sends a better prediction to l2, so l2 will better 
  #predict target y.  In other words, tweak the weights in order to produce large 
  #changes in low confidence values and small changes in high confidence values.

  #To do this, just like in #10 we multiply l1_error by the slope of the 
  #sigmoid at the value of l1 to ensure that the network applies larger changes 
  #to synapse weights that affect low-confidence (e.g., close to 0.5) predictions for l1.
109  l1_delta = l1_error * nonlin(l1,deriv=True)

  #13 UPDATE SYNAPSES: aka Gradient Descent. This step is where the synapses, the true
  #"brain" of our network, learn from their mistakes, remember, and improve--learning!
  # We multiply each delta by their corresponding layers to update each weight in both of our 
  #synapses so that our next prediction will be even better.
115  syn1 += l1.T.dot(l2_delta)
116  syn0 += l0.T.dot(l1_delta)

#Print results!
119 print("Our y-l2 error value after all 60,000 iterations of training: ")
120 print(l2)

2.1 Sigmoid 函数:行 8-12

sigmoid 函数收集进修进程中起到十分主要的感化。

「nonlin()」是一种 sigmoid 函数类型,叫做 logistic 函数。logistic 函数科学、统计学和概率论中非常常睹。此处该函数的外达有些繁杂,因为这里它举措两个函数运用:

第一个函数是将矩阵(此处外示为 x)放入括号内,将每个值转换为 0 到 1 之间的数字(即统计概率)。转换进程通过代码行 12 完成:return 1/(1+np.exp(-x))。

那么为什么需求统计概率呢?神经收集不会预测 0 或 1,它不会直接吼「哇,顾客 1 绝对会买这款猫砂!」,而是预测概率:「顾客 1 有 74% 的可以置办这款猫砂」。

这里的区别很大,假如你直接预测 0 和 1,那么收集就没有改良空间了。要么对要么错。可是运用概率的话就有改良空间。你可以调解系统,每一次使概率添加或淘汰几个点,从而晋升收集的准确率。这是一个受控的增量进程,而不是盲猜。

将数字转换成 0 到 1 之间的数字这一进程十分主要,它带给我们四大优势。下文将精细议论这些优势,现我们先来看 sigmoid 函数怎样将其括号内每个矩阵的每个数字转换成 0 到 1 之间的数字,并使其落下图的 S 弧线上:

图源:https://iamtrask.github.io/2015/07/12/basic-python-network/

sigmoid 的第一个函数将矩阵中的每个值转换为统计概率,而它的第二个函数如代码行 9 和 10 所示:

' if(deriv==True):
return x*(1-x)'

该函数将给定矩阵中的每个值转换成 sigmoid 函数 S 弧线上特定点处的坡度。该坡度值也叫做置信度(confidence measure)。也便是说,该数值答复了这个题目:我们对该数值可以准确预测结果的自大程度怎样?你可以会念:这又能怎样样呢?我们的目标是神经收集牢靠地做出准这是我们的标签确的预测。而完成这一目标的最速方法便是修复置信度低、准确率低的预测,不改动置信度高、准确率高的预测。「置信度」这一看法十分主要,下文我们将深化解读它。

接下来我们看第 2 步:

2.2 创立输入 X:行 23-26

代码行 23-26 创立了一个输入值的 4x3 矩阵,可用于教练收集。X 将成为收集的 layer 0(或 l0),现开端创立神经收集吧!

以下是我们从顾客考察中取得的特征集,只不过用盘算功用了解的言语外达出来:

Line 23 creates the X input (which becomes l0, layer 0, in line 57)
X: 
[1,0,1],
[0,1,1],
[0,0,1],
[1,1,1]

我们有四个顾客,他们区分答复了三个题目。前面我们议论过第一行 1,0,1 是顾客 1 的谜底。将这个矩阵的每一行看作即将输入收集的教练样本,每一列便是输入的一个特征。于是矩阵 X 可被描画为下图,该矩阵即为图中的 l0:

你可以会念:矩阵 X 是怎样变成图中的 layer 0 的?稍后我会标明这一点。

接下来,我们将创立准确谜底列外。

2.3 创立输出 y:行 34-37

这是我们的标签,即第四个考察题目「你是否置办过新款猫砂?」的谜底。看下面这列数字,顾客 1 答复的是「Yes」,顾客 2 答复的是「Yes」,顾客 3 和 4 答复的是「No」。

假如把 y 看作「目标」值的话,我将画一个箭靶。跟着收集的改良,它射出的箭离靶心越来越近。一朝收集可以依据矩阵 X 供应的输入准确预测 4 个目标值,则收集准备停当,可以其他数据集上施行预测了。

2.4 生成随机数:行 40

这一步是「做家务」。我们必需生成随机数(随机数将教练进程的下一步生成突触/权重),以使 debug 过车傈加简单。你不必了解这行代码的义务原理,只需求运用它就好了。

生成随机数的启事是,你必需从某个地方开端。于是我们从一组捏制数字开端,然后 6 万次迭代中垂垂改动每一个数字,直到它们输出具备最小偏向值的预测。这一步使得测试可重复(即运用同样的输入测试众次,结果仍然相同)。

2.5 创立突触(即权重):行 47-48

第一次看到下图时,你可以会认为神经收集的「大脑」是那些圆圈(神经元)。而终究上,神经大脑的真正中心是那些可以进修和改良的部分——突触,也便是图中那些连接圆圈的线。这两个矩阵——syn0 和 syn1 才是收集的真正大脑。它们是收集用来试错进修、施行预测、比照目标值和预测,进而改良下一次预测结果的部分。

当心代码 syn0 = 2np.random.random((3,4)) - 1 创立了 3x4 矩阵,并为它生成随机数。这将是突触(或权重)的第一层 Synapse 0,它连接 l0 和 l1。该矩阵如下所示:

我一经这里犯了一个错:我无法了解为什么 syn0 应当是 3x4 矩阵。我认为它应当是 4x3 矩阵,因为 syn0 必需与 l0 相乘,然后者是 4x3 矩阵,我们为什么不让两个矩阵的数字按行与列排列同等呢?

而这便是我的过失:4x3 乘 4x3 可以使数字排列同等?这是错的。终究上,假如我们念要数字排列同等,我们就应当让 4x3 乘 3x4。这是矩阵乘法里的一项根底且主要的规矩。细心查看下图中的第一个神经元,该神经元内是每位顾客对「你有猫吗?」这个题目的再起。以下是 4x3 layer0 矩阵的第一列:

[1]
[0]
[0]
[1]

现当心,有四条线(突触)将 l0 中「你有猫吗?」这个神经元与 l1 的四个神经元连接起来。这意味着上述列 1,0,0,1 中的每个数字都要与四个差别权重相乘,于是取得 16 个值。l1 确实是一个 4x4 矩阵。

当心,现我们要对第二个神经元内的四个数字施行同样的操作,也取得 16 个值。我们将这 16 个值中的每个值与方才创立的值中的对应值相加。

重复这个方法,直到将第三个神经元中的四个数字也处理完毕。如许 4x4 l1 矩阵就有 16 个值,每个值是三次乘法所得值的对应相加结果。

也便是说,3 个考察题目 x 4 位顾客 = 3 个神经元 x 4 个突触 = 3 个特征 x 4 个权重 = 3x4 矩阵。

看起来很繁杂?习气就好了。而且盘算时机替你施行乘法操作。我只是念帮帮大师了解其下的底层操作。当你看到下图时,这些线不会扯谎。

也许你会疑心,代码行 47 中的「2」和「-1」是哪儿来的。np.random.random 函数生成平均分布于 0 到 1 之间的随机数(对应的平均值为 0.5),而我们念让随机数初始值的平均值为 0。如许该矩阵中的初始权重不会保管偏向于 1 或 0 的先验偏置(最开端的时分,收集不晓得接下来会爆发什么,于是它对其预测结果是没有决心的,直到我们每个迭代后更新它)。

那么,我们怎样将一组平均值为 0.5 的数字改变为平均值为 0 的数字呢?起首,将所有随机数乘 2(如许所稀有字分布 0 到 2 之间,平均值为 1),然后减去 1(如许所稀有字分布-1 到 1 之间,平均值为 0)。这便是「2」和「-1」呈现的启事。

接下来看下一行代码:syn1 = 2np.random.random((4,1)) - 1 创立了一个 4x1 向量,并为它生成随机数。这便是收集第二层的权重 Synapse 1,它连接 l1 和 l2。

for loop 使收集施行 6 万次迭代。每次迭代中,收集运用顾客考察数据 X 举措输入,基于该数据得出对顾客置办新款猫砂概率的最佳预测。然后将预测与真值举行比照,再从过失中进修,下次迭代中做出更好的预测。该进程继续 6 万次,直到收集通过试错学会怎样准确预测。然后这个收集可以运用恣意输入数据,并准确预测可以置办新款猫砂的顾客。

2.6 For Loop:行 52

for loop 使收集施行 6 万次迭代。每次迭代中,收集运用顾客考察数据 X 举措输入,基于该数据得出对顾客置办新款猫砂概率的最佳预测。然后将预测与真值举行比照,再从过失中进修,下次迭代中做出更好的预测。该进程继续 6 万次,直到收集通过试错学会怎样准确预测。然后这个收集可以运用恣意输入数据,并准确预测可以置办新款猫砂的顾客。

3. 前馈:做出有依据的猜念,60000 次迭代

收集这一方法开端施行预测。这是深度进修进程中最令人兴奋的部分,以是我方案从三个差别角度先容这个看法:

3.1 城堡和生命的原理:前馈收集

念象你本人是一个神经收集。恰恰你是一个有驾照的神经收集,而且喜爱开速车和秘密的精神之旅。你急切念找到生命的原理。巧妙的是,你恰恰发明只消驱车前去某个城堡,秘密先知将告诉你生命的原理。天啊!

不必说,你一定特别念找到先知的城堡。先知就代外真值,也便是秘密题目「你买过新款猫砂吗?」的谜底。也便是说,假如你的预测与真值立室,那么你就抵达先知城堡,即 l2 偏向为 0、黄色箭头的长度为 0、粉色乒乓球抵达碗底。

不过,找到先知城堡需求少许耐心和保持,你需求实验数千次,迷道数千次。(小提示:数千次路程 = 迭代,不时迷道 = l2 预测保管偏向,偏向使得你离先知城堡 y 另有间隔。)

可是也有好新闻:你晓得跟着时间的流逝,每一次路程并不是没有原理,你会越来越接近先知(先知城堡 y 正闪耀……)。而坏新闻是每一次当你无法抵达城堡时,第二天醒来你又回到了原点(即 Layer 0,输入特征,3 个考察题目),必需从那里从头动身(新的迭代)。这个过扯菪点像下图:

侥幸的是,这个故事有一个完美的结果,你不停实验、不时改正道径,举行了 58000 次试验后毕竟抵达了目标。这很值得。

我们来看一下从你的房子 X 到先知城堡 y 的此中一次路程(迭代):每一次路程都是代码行 57-59 所施行的前馈,每天你都抵达一个新地方,可是它们都不是你的目标地。你当然念晓得怎样下一次路程中更接近城堡,我会这个故事的后续篇中标明。

接下来,我们来看一个更简单的示例。

3.2 关于前馈的漂亮画作

接下来我们来看 16 个权重中的此中一个。这个权重是 syn0,12 条线中最上方那条,连接 l0 和 l1 最上方的神经元。出于简明性思索,我们称其为 syn0,1(syn0(1,1) 的简化,外示矩阵 syn0 的行 1 列 1)。如下图所示:

为什么外示 l2 和 l1 神经元的圆圈被从中心支解开了?圆圈的左半边(带有 LH 字样)是 sigmoid 函数的输入值,右半边是 sigmoid 函数的输出:l1 或 l2。这个语境下,sigmoid 函数只是将前一层与前一个突触相乘,并转换为 0 到 1 之间的值。代码如下:

return 1/(1+np.exp(-x))

这里的前馈运用了我们的一个教练样本,l0 的第 1 行,即「顾客 1 对 3 个考察题目的再起」:[1,0,1]。于是,我们起首将 l0 的第一个值与 syn0 的第一个值相乘。假设 syn0 矩阵曾颠末众次教练迭代(我们 2.4 节曾经举行过初始化了),现该矩阵如下所示:

syn0: 
[ 3.66 -2.88   3.26 -1.53]
[-4.84  3.54   2.52 -2.55]      
[ 0.16 -0.66  -2.82  1.87]

到这里,大约你会疑心:为什么 syn0 的值与 2.4 节创立的 syn0 云云差别?好题目。前面先容的许众矩阵有传神的初始值,就仿佛它们刚被盘算机通过随机种子创立出来相同。而这里和下面的矩阵并非初始值。它们是颠末众次教练迭代的,于是它们的值曾经进修进程中颠着末更新和改动。

现,我们用 l0 的第一个值 1 与 syn0 的第一个值 3.66 相乘,看看会取得什么:

下面是前馈的伪代码,你可以借帮上图(葱◇至右的序次)帮帮了解。

下面,我们再从另一个角度看前馈进程的底层数学原理。

3.3 前馈的数学原理

l0 x syn0 = l1LH,这个示例中即 1 x 3.66 = 3.66,不要遗忘还要加上另外两个 l0 值和 syn0 对应权重的乘积。该示例中,l0,2 x syn0,2= 0 x something = 0,l0,3 x syn0,3 中 l0,3=1,从上一节中我们晓得 syn0,3 = 0.16,于是 l0,3 x syn0,3 = 1 x 0.16 = 0.16。于是 l0,1 x syn0,1 + l0,3 x syn0,3 = 3.66 + 0.16 = 3.82,即 l1_LH = 3.82。

接下来,我们将 l1_LH 输入 nonlin() 函数,将该数字转换为 0 到 1 之间的概率。Nonlin(l1_LH) 运用代码 return 1/(1+np.exp(-x)),于是该示例中,1/(1+(2.718^-3.82))=0.98,l1 = 0.98。

那么,公式 1/(1+np.exp(-x)) = [1/(1+2.718^-3.82))] = 0.98 中爆发了什么呢?盘算机运用代码 return 1/(1+np.exp(-x)) 替代了我们的人工盘算,我们可以通过下图看到 sigmoid 弧线上 x = 3.82 所对应的 y 值:

图源:https://iamtrask.github.io/2015/07/12/basic-python-network/

当心,X 轴上 3.82 蓝色弧线上对应点的对应 y 值是 0.98,而代码将 3.82 转换为 0 到 1 之间的概率。上图有帮于大师了解该盘算并不秘密,也不笼统,盘算机只不过做了和我们相同的事:它运用数学查看上图中 X 轴上 3.82 对应的 y 值,仅此罢了。

同理,我们重复以上方法,盘算出 l2_LH 和 l2 的值。至此,我们就完毕了第一次前馈。

现,为了简明起睹,我们把所有变量放一同,如下所示:

l0=1
syn0,1=3.66
l1_LH=3.82
l1=0.98
syn1,1=12.21
l2_LH=0
l2=~0.5
y=1 (this is a "Yes" answer to survey Question 4, "Actually bought Litter Rip?")
l2_error = y-l2 = 1-0.5 = 0.5

现,我们来看让这通通完成的矩阵乘法(对矩阵乘法和线性代数生疏的朋侪,可以先进修 Grant Sanderson 的课程:https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab)。

起首,代码行 58,我们将 4x3 l0 和 3x4 Syn0 相乘,创立(躲藏层)l1,它是一个 4x4 矩阵:

第 58 行代码中,我们将 l1 输入 nonlin() 函数,取得一个 0 到 1 之间的概率值:

1/(1 + 2.781281^-x)

This creates layer 1, the hidden layer of our neural network:
l1:  
[0.98 0.03 0.61 0.58]
[0.01 0.95 0.43 0.34]
[0.54 0.34 0.06 0.87]
[0.27 0.50 0.95 0.10]

看不懂也没联系,我们来看一个简单的教练示例。第一行(顾客 1 的考察数据)[1,0,1] 是一个 1x3 矩阵。我们将其乘以 syn0(3x4 矩阵),取得的 l1 是 1x4 矩阵。进程如下所示:

当心,代码第 58 行 l1=nonlin(np.dot(l0,syn0)),我们将 l1 输入 sigmoid 函数,因为我们需求一个 0 到 1 的数值。

从这行代码中,我们可以看到 sigmoid 函数的第一大优势。当我们将 l0 和 syn0 的点乘矩阵输入到 nonlin() 函数时,sigmoid 函数将矩阵中的每个值转换成 0 到 1 之间的概率。

3.4 中心要点:躲藏层中的推测题目

我们为什么要体恤统计概率呢?我认为启事于,统计概率是让一堆重默矩阵焕爆发机并像小孩相同窗习的主要因素!

第一层中,当我们将 l0 乘以 syn0 时,为什么要实验给 syn0 的权重赋差别的值呢?因为我们念实验差别的特征题目组合,发明对预测结果帮帮最大的题目组合。上文举过少许差劲的例子,推测出有猫且喝进口啤酒的人更有可以置办新款猫砂,从而应用权重深化这两个特征组合。

另一个例子:假如少许顾客没有养猫,但他们喝进口啤酒且拜访过 Litter Rip.com (http://rip.com/) 网站,我们可以推测出这些顾客热衷技能:他们喝进口啤酒因为他们观赏其供应链物流,他们拜访网站,种种各样的网站,阐明他们很分明热衷技能。于是我们可以推测出,这些顾客可以会出于对这款猫砂先辈技能的观赏而置办它,尽管他们可以实行上并没有养猫。以是我们大约需求调解 syn0 的权重,深化这些特征之间的连接。

现你清楚了吗?当我们将考察题目的再起 l0 与 syn0 中的权重(每个权重外示我们对一个推测题目对预测结果的主要程度的最佳猜念)相乘时,我们是实验差别的谜底组合,以查看哪些组合对预测结果最有帮帮。很分明, 6 万次迭代中,拜访过猫砂网站的猫主人更有可以置办这款猫砂,于是迭代的进程中它们对应的权重会添加,即其统计概率更接近 1 而不是 0。而喝进口啤酒却没有猫的人置办这款猫砂的可以性较低,于是对应的权重较小,即其统计概率更接近 0 而不是 1。是不是很巧妙?这就像数字谱写的诗歌,这些是会推理和考虑的矩阵!

这也是我为什么大费周章先容这个的启事。你是否阅历过,少许骄傲的软件工程师或制制惊慌的记者告诉你,神经收集躲藏层是潘众拉的魔盒?而终究上它的底层并没有什么「巧妙邪术」。这些数学常识分明、斯文而漂亮。你可以掌握它,只消有耐心肯保持。

接下来我们继续看矩阵乘法。

3.5 用神经元和突触的方式可视化矩阵乘法

我们用神经元和突触的方式可视化 l0 和 syn0,如下图所示:

上图展现了输入 l0 的行 1 怎样完毕收集中的第一步。第一行代外顾客 1 对三个考察题目的谜底。这三个数字需求乘以 syn0 的 12 个值,然后收集还要对其他三位顾客的谜底举行同样的处理,那么怎样分明地展现这些数字并举行盘算呢?

这里的要害于,将四位顾客看作一个「batch」(批次),他们此中堆叠一同,即一共 4 个 stack。那么,最上面的谁人 stack 便是第一行(顾客 1),依此类推。如上图所示,你将第一行的三个数字和 syn0 的 12 个值相乘,再相加,着末取得 l1 最上面 stack 的四个值。

叫∨是 batch 中的第二个 stack——顾客 2 的答复是 0,1,1。将这三个数字和 syn0 的 12 个值相乘,再相加,着末取得 l1 第二个 stack 的四个值。

依此类推。其中心于一次盘算一个 stack,如许不管 batch 中有众少个 stack,四个照旧四百万个,你都可以很好地处理。你可以会说每个特征都有一个 batch,猫砂这个示例中,每个考察题目(特征)的 batch 为 4,因为只要四位顾客的谜底。但它也可以是四百万。「full batch configuration」的看法好坏常常睹的模子,接下来我将标明这一点。

实认为给定特征具备一个 batch 的值是最容易了解的。当你看到一个特征时,你晓得它底下有一个 batch 的值。

就像代码行 59 所示,我们把 4x4 l1 和 4x1 syn1 相乘,然后输入 sigmoid 函数得出 4x1 l2,其每个值都是 0 到 1 的统计概率。

l1 (4x4):  
[0.98 0.03 0.61 0.58]               [ 12.21]
[0.01 0.95 0.43 0.34]       X       [ 10.24]     =
[0.54 0.34 0.06 0.87]               [ -6.31]
[0.27 0.50 0.95 0.10]               [-14.52]

Then pass the above 4x1 product through "nonlin()" and you get l2, our prediction:
l2: 
 [ 0.50]
 [ 0.90]
 [ 0.05]
 [ 0.70]

那么这四个预测结果告诉我们什么呢?预测值间隔 1 越近,则该顾客置办这款猫砂的可以性越高;预测值间隔 0 越近,则该顾客置办这款猫砂的可以性越低。

现我们完毕了前馈部分。接下来我们将看 6 万次迭代进程中怎样调解收集权重,使预测结果越来越好。

4. 从试错中进修:梯度下降

4.1 梯度下降概览

梯度下降的目标是什么?是为了更好地调解收集权重,从而下次迭代中取得更好的预测结果。也便是说,收集的突触矩阵中的某些值要被增减。为了调解这些值,我们必需答复以下两个主要题目:

我应当按什么偏向调解数字?应当添加照旧淘汰数值?正偏向照旧负偏向?……

数值应当增减众少?

下面我们将精细标明这两个根底题目。还记得上文的血色碗吗?「梯度」便是「坡度」,「梯度下降」即盘算出使小球从碗外面上的某个点尽速下降到碗底的最优坡度。

梯度下降的第一步即,盘算目今的预测结果与真值 y(1/yes 或 0/no)之间的差异。

4.2 预测结果与考察题目 4 的谜底比较有众大差异?

代码行 66:

l2_error = y - l2

第一次预测结果间隔目标值「Yes/1」(顾客 1 对第四个考察题目的答复真值是「置办过」)有众远间隔呢?我们需求将 l2 预测值与 y 值(1)举行比照,即 y 值减去 l2 取得的便是 l2_error——「预测值间隔目标值 y 的间隔」。

于是,我们可以念象这幅图景:收集运用每位顾客的再起举措输入,并操作这些数据,以取得顾客是否置办猫砂的预测结果。

我们有四位顾客,收集就做了四次预测。于是 l2_error 是四次偏向的向量(每个偏向针对一次预测)。接下来我们将打印出该偏向:

打印偏向:行 72-73

72 if (j% 10000)==0:
73 print("Avg l2_error after 10,000 more iterations: "+str(np.mean(np.abs(l2_error))))

行 72 使盘算机每隔一万次迭代打印一次 l2_error。这有帮于我们每隔一万次查看收集的进修效果和希望。if (j% 10000)==0: 外示「假如你的迭代器所处的迭代次数除以 10000 后没众余数,则……」。j%10000 共有六次没众余数的状况:迭代数为 10000、20000、30000、40000、50000、60000 时。该打印输出会帮帮我们很好地了解收集的进修希望。

代码 + str(np.mean(np.abs(l2_error)))) 取偏向的绝对值,然后求平均数并打印出来,从而简化了打印进程。

现我们曾经晓得预测结果(l2)间隔真值(y)的间隔,并打印了出来。可是,我们和城堡的间隔实太远,我们要怎样低沉目前令人失望的预测偏向 0.5,最终抵达目标地呢?

一步步来。接下来,我们将了解调解收集的哪一部分才干改良下一次预测的结果,之后会议论怎样调解收集。

4.3 我们需求调解收集的哪一部分?

先看下图,神经收集真正用来进修和记忆的中心部分是突触,而不是神经元。我们的收集中有 16 个变量:3x4 矩阵 syn0 中的 12 个变量和 4x1 向量 syn1 中的 4 个变量。查看下图,你会发明每一条线(「边」或「突触」)外示一个变量,它包罗一个数值,这便是权重。

我们可以掌握这 16 个权重。

输入 l0 是固定的,不行改动。l1 由 syn0 中的权重决议(l1 = syn0 x l0),l2 由 syn1 中的权重决议(l2 = syn1 x l1)。上图中的 16 条线(突触、权重)是神经收集抵达目标进程中独一可以调解的数字。

现我们晓得了预测值与真值的间隔,晓得了 l2_error。那么我们怎样应用这些数值调解两个矩阵中的 16 个权重呢?这个谜底便是 AI 最巧妙的属性之一:这是一个统计学和概率看法,叫做置信度。

4.4 置信度:使冷飕飕的数字像人类相同考虑

代码行 88:

 l2_delta = l2_error*nonlin(l2,deriv=True)

「置信度」这个术语可以比较笼统,可是它实行上便是我们每天都用的东西。我用一个幽默的故事来提示你:

先知城堡 2:你必需清楚你实不停运用置信度!

先知城堡的故事中,你施行前馈,驱使 l2 向最佳预测 y(城堡)行进,可是当你抵达 l2 后却发明你虽然间隔城堡更近了,却仍未抵达。第二天早上你发明本人家中醒来(回到 l0),然后开端再一次的路程(新的迭代)。

你该怎样改良驾驶偏向,才干做有用功呢?

起首,你本日的路程完毕时,你迫切地讯问外埠的骑士这个地方间隔城堡另有众远,骑士告诉你谜底(即 l2_error)。每天的路程完毕时,你都要盘算怎样改动权重才干使他日的 l2 预测比本日更好,并最终时ャ抵达城堡。这便是 l2_delta(参睹下图),即要念使他日的 l2 抵达城堡,本日你需求对权重做出的改动。

要点来了:

当心 l2_delta 与 l2_error 差别,l2_error 仅告诉你与城堡的间隔,而 l2_delta 则影响你对偏向的决心。你权衡决心。这些置信度数字便是导数(不过,这里暂且遗忘微积分吧,我们暂时运用这个词「坡度」),即 l2 每个值的坡度。这些坡度便是你对本日路程中每一次转向的自大程度。有些偏向你十分确定且自大,而有些则否则。

运用置信度这一看法来盘算他日能到哪里仿佛有点笼统?实行上,你常常候刻都运用置信度导航,只不过你没看法到罢了。接下来我们就让你「恢复」这一看法。

追念一下你的迷道阅历。一开端,你按照本人认为准确的道道行进,你十分自大。可是垂垂地你发明旅途仿佛比预期更加漫长,你开端疑心是否遗忘拐弯。你没最初那么自大了。跟着时间的流逝,你本来应当曾经抵达目标地了,然而你还道上,此时你更加确定错过了一次拐弯。这时分你的自大度很低。你晓得本人没有抵达目标地,但你不确定怎样从现的位置抵达目标地。于是你决议停下来问道,可是被问道的密斯告诉你的拐弯和道标太众,你没记全,你沿着她指的偏向走到一半又不晓得怎样走了。这时你会再次问道,不过这一次你离目标地更近,行进的偏向也更加简单,你沿着偏向行进最终抵达目标地。

这段讲述中,你需求当心以下几件事:

起首,你通过试错举行进修,你的决心不停改造。稍后我会标明为什么置信度使得收集试错进修,以及 sigmoid 函数怎样供应主要的置信度。

其次,当心你的路程分为两部分:第一部分从你动身到第一次问道(l1),第二部分是从第一次问道到 l2(你认为曾经抵达目标地了)。可是厥后你看法到这里并不是尽头,不得不讯问离真正的尽头另有众远。

你看到置信度路程中的脚色了吗?一开端,你确定本人走准确的道上,然后你疑心本人少拐了个弯,之后你确定本人少拐了个弯,决议停下来问道。图中这两个支解的部分就像狗腿相同弯,但跟着每日路程的改良,狗腿将一点点变直。

这和你前去城堡的进程相同:

每天,你(3 层神经收集)沿着一组偏向(syn0)前去城堡。完毕时你发明本人停了 l1,就讯问接下来的偏向(syn1)。这些偏向使得你抵达当天的尽头(预测结果),你认为那里便是目标地城堡。但终究上你目下并没有城堡。于是你讯问骑士:「我离城堡另有众远?」(l2_error 的值是众少?)你是一个禀赋,于是你将 l2_error 与你对每一次转向的置信度(l2 的坡度)相乘,得出了他日可以抵达的地方(l2_delta)。

当心:这个比喻有一点不妥当,即当你停 l1 问道时,密斯告诉你新的偏向。而终究上,你的偏向(syn1 值)是你准备更新上一次迭代时就曾经挑选好的。于是准确来说,那位密斯并没有和你语言,只是举起了你昨天那里消逝之前给她的道牌,因为你晓得本日会再次道过她身旁。

继续之前,你需求厘清 3 项终究:

了解这三项终究后,你可以盘算行进偏向(即突触权重)需求做的改动。接下来,我们来看怎样运用 sigmoid 函数取得置信度,并应用置信度盘算 l2_delta。

4.5 怎样应用 Sigmoid 函数的弧线特征得出置信度

sigmoid 函数的四步魔鬼操作将让你眼力到她的魅力。对我而言,神经收集的进修才能很洪流平上基于这四步操作。

2.5 节标清楚 nonlin() 函数可以将 l2_LH 的值转换成统计概率(l2),这是 sigmoid 函数四大优势中的第一点。

而 sigmoid 函数的第二部分 nonlin(l2,deriv=True) 可以将 l2 中的 4 个值转换成置信度。这便是 sigmoid 函数的第二大优势。假如收集每个预测(l2 中的 4 个值)都具备高准确率、高置信度,则这是一次不错的预测。我们不会改动带来云云精良预测结果的 syn0、syn1 权重,只念改动那些不 work 的权重。接下来,我将先容 nonlin(l2,deriv=True) 怎样告诉我们哪些权重需求分外当心。

置信度帮帮我们起首确定哪些权重需求改动。假如 nonlin(l2) 生成的置信度为 0.999,则该收集「很确定该顾客置办了这款猫砂」,而置信度 0.001 则等同于「我很确定该顾客没有置办这款猫砂」。可是处于中心的数字怎样办呢?低置信度数字一般 0.5 尊驾。比如,置信度 0.6 意义是「该顾客可以会买这款猫砂,不过我不确定。」置信度 0.5 外示「两条道都可行,而我站中心犹豫不决……」

也于是我们需求体恤中心的数字:0.5 四周的数字都不刚强,都缺乏决心。那么,我们应当怎样改动收集才干使 l2 的四个值都具备高准确率和高置信度呢?

要害于权重。上文曾经提到,syn0 和 syn1 是神经收集的绝对中心。我们将对 l2_error 的四个值施行数学盘算,取得 l2_delta。l2_delta 即「要使收集输出 (l2) 更接近 y(真值),我们念看到的 l2 改动。」也便是说,l2_delta 即你念下次迭代中看到的 l2 改造。

这便是 Sigmoid 函数四大优势的第三点:l2 的四个概率值都是位于 sigmoid 函数 S 弧线图上的某个点(睹下图)。比如,l2 的第一个值为 0.9,我们下图中找 0.9 所对应的 Y 轴位置,会发明它对应下图中的绿色点:

图源:https://iamtrask.github.io/2015/07/12/basic-python-network/

除了绿色点,你当心到穿过该点的绿色线吗?这条线外示该点的坡度(正切值)。盘算一个点的坡度不需求你懂微积分,盘算时机帮你做这些。可是你需求当心,S 弧线上上限(接近 1)和下限(接近 0)的位置的坡度很浅。sigmoid 函数弧线上的浅坡度正好对应预测结果的高置信度!

你还需求了解 S 弧线上的浅坡度意味着坡度值较小,这是一个好新闻!

因为,当我们更新突触(权重)时,我们并不念改动能带来高置信度、高准确率的权重,它们曾经足够好了。以是我们只念对其引入微细的改动。终究上,这些权重的改动(l2_delta)是由原数值乘以特别小的数字(坡度)来举行的,这恰恰契合我们的希冀。

这便是 Sigmoid 函数四大优势中的着末一项。

高置信度对应 S 弧线上的浅坡度,浅坡度对应一个很小的数字。从而使得 syn0 和 syn1 的值乘以这些小数字后可以满意我们的希冀,即突触中有用的权重值基本上改造不大,如许就可以保持 l2 的置信度和准确率。

同理,低准确率的 l2 值(对应 S 弧线的中心点)即是 S 弧线上坡度最大的数字。即上图 Y 轴 0.5 尊驾的值对应 S 弧线的中心点,这里坡度最陡,因此坡度值也最大。这些大数值意味着当我们将它们与 l2 中的低准确率值相乘时,这些值会爆发很大改动。

精细来讲,我们应当怎样盘算 l2_delta 呢?

我们曾经找到了 l2_error,即第一次预测 l2 与目标值 y 的间隔。而我们特别体恤「大偏向」(Big Miss)。

代码行 88 中,我们要做的第一件事便是运用 sigmoid 函数的第二部分 nonlin(l2,deriv=True) 寻得 l2 预测中 4 个值各自的坡度。坡度将告诉我们哪些预测可托度高,哪些比较牵强。这便是我们寻得并修复神经收集中最弱要害(低置信度预测)的方法。接下来,将这 4 个坡度(置信度)与 l2_error 中的四个偏向值相乘,取得的便是 l2_delta。

这一步十分主要。你当心到我们将大偏向与低准确率、高坡度值的 l2 预测相乘吗?这是最主要的部分,稍后我将给大师标明。

现,我们先看这部分的可视化展现,如下所示:

y:        l2:        l2_error:    
[1]      [0.50]      [ 0.50]
[1]  _   [0.90]   =  [ 0.10]
[0]      [0.05]      [-0.05]
[0]      [0.70]      [-0.70]

下面的公式是了解神经收集进修原理的要点:

l2 slopes after nonlin():    l2_error:                l2_delta: 
[0.25] Not Confident        [ 0.50] Big Miss         [ 0.125] Big change
[0.09] Fairly Confident  X  [ 0.10] Small Miss    =  [ 0.009] Small-ish Change
[0.05] Confident            [-0.05] Tiny miss        [-0.003] Tiny change
[0.21] Not Confident        [-0.70] Very Big Miss    [-0.150] Huge Change

当心,大偏向即 l2_error 中值较大的数字,而低准确率的 l2 值的坡度也最陡,即它们 nonlin(l2,deriv=True) 中的数字最大。于是,当我们用大偏向乘以低准确率 l2 值时,便是大数字与大数字相乘,于是也将取得 l2_delta 向量中最大的数字。

l2_delta 即「下一次迭代中我们期望看到的 l2 改动」。较大的 l2_delta 值意味着下一次迭代中 l2 预测会有很大的改动,而这恰是通过大幅改动对应的 syn1 和 syn0 值来完成的。将这些大数值与 syn1 中已有的值相加,取得的更新权重将下一次迭代中带来更好的 l2 预测结果。

为什么要运用 l2 的坡度呢?

此举的目标是为了更速地修复 16 个权重中最过错适的那些。上文我们提到 sigmoid 函数的 S 弧线图时说过,l2 坡度与置信度相关。也便是说,大坡度值等于低置信度,最小坡度值等于最高置信度。于是,将小数字与 l2_error 中的对应值相乘不会给 l2_delta 带来大的改造,而我们也恰恰不念改动那些权重,它们曾经做得很好了。

可是置信度最低的 l2 预测具备最陡的坡度,坡度值也最大。当我们将这个大数字乘以 l2_error 时,l2_delta 的数字也会很大。之后当我们更新 syn1 时,大的乘数意味着大的积、大的改动或调解。正该云云,因为我们念最洪流平地改动置信度最低的权重,这也是调解权重大小时使我们取得最大收益的地方。总之,l2 坡度指示了每个 l2 预测值的置信度,从而容许我们决议哪些数字最需求调解,以及怎样最速地调解它们。

可是精美的部分还未完毕,回到关于推测题目这一要点上。

3.4 节我们议论了,改动 syn0 的权重相似于改动对预测最有用的推测题目。比如,拜访过猫砂网站的养猫人更有可以置办这款猫砂,而喝进口啤酒但不养猫的人置办猫砂的几率相对较低。这便是 l2_delta 的用武之地。l2_delta 添夹☆有用推测题目的主要性(权重),低沉不那么有用推测题目的主要性。接下来,我们将了解怎样确定躲藏层 1 中每个推测题目的效用。

不过,起首我们先确定本人是否完备了解 l2 置信度怎样改正 syn1 中的权重。sigmoid 函数随机采纳矩阵中的任一数字,

sigmoid 函数是一个遗迹,它让矩阵中的数字可以依据置信度举行进修,数学何等秘密!

接下来,我们来看置信度怎样告诉我们要对 syn0 做怎样的改动才干完成更加准确的层 1,然后完成更加准确的层 2。

4.6 将「大偏向/小偏向」置信度运用于层 1

代码行 100:

 l1_error = = l2_delta.dot(syn1.T)

城堡的故实狼常有用:那幅图中,我们可以看到 l2_error 代外 l2 预测与城堡的间隔,也可以了解到 l2_delta 是目前的预测与下一次迭代中预测结果之间的间隔。方才先容的「进修大偏向/小偏向」的方法可以帮帮我们了解,怎样调解目今的 syn1(睹代码行 115)。

现你曾经准备好用来更新 syn1 的 l2_delta 了,那么为什么不也更新一下 syn0 呢?

怎样做?回到 4.2 节,我们找到了 l2_error,晓得 l2,也晓得我们要追寻的「完美 l2」——y。可是, l1_error 这里,状况变了,我们不晓得「完美 l1」是什么。

怎样找到「完美 l1”ヘ?让我们再次回到推测题目。

回到 3.4 和 4.5 节,关于推测题目(特征)的看法,以及特征题目组合。当我们改动 syn1 中的权重时,我们真正做的实是用我们念付与该题目或题目组合的主要性举行试验。关于 syn0 也是相同,我们念寻得可以帮帮确定 l1_error 的数学方法,因为 l1_error 将告诉我们哪些题目的优先级被过失分派了或者哪些题目被过失地组合了一同。当我们叫∨盘算 l1_delta 时,l1_delta 将告诉我们下一次迭代中更好的题目优先级和题目组合。

比如,syn0 最初的权重提示推测题目「这私人丰饶吗?」是主要的题目。然而,跟着教练的展开,收集看法到猫砂并非糜费品,是否丰饶并不主要,于是收集决议调解 syn0 的值,以低沉推测题目「这私人丰饶吗」的主要性。怎样低沉呢?将 syn0 中该题目的对应值乘以较大的 l1_delta 值,不过该值前面带有一个负号。然后收集将更新新的推测题目「这私人对猫屎过敏吗?」。更械澜法是将该题目对应的 syn0 值乘以较大的 l1_delta 值(正值)。

这两个推测题目的优先级不时改造。可是另一个推测题目「这私人晓得怎样收集购物吗」不停都很主要,因为目标受众是喜皇边购物的人。于是收集将该题目对应的 syn0 值乘以较小的 l1_delta 值。如许,其优先级就会保持稳定。

另一个谜题是你需求众少推测题目?这个收集中,我们一次只可容纳四个推测题目。这是由 syn0 的大小决议的。假如你没有足够的推测题目,那收集可以就无法做出准确的预测。而题目太众则会糜费过众精神。

现,我们晓得改动 syn0 的值会改动某个推测题目关于 l1 的奉献,进而影响 l1 对 l2 准确预测的奉献程度。syn1 运用特征题目组合,并进一步优化从而取得更加准确的 l2。

我这个阶段提出的题目是:为什么要运用 l2 的坡度?

上文提到,我们运用 l2 坡度来更速地调解权重:l2 坡度告诉我们每个 l2 预测的置信度,从而容许我们决议哪些数字最需求调解,以及怎样最速地调解它们。

我们来看数学部分。现我们晓得下一次迭代中 l2 预测要做的改动是 l2_delta,也晓得抵达目前预测结果的 syn1 值。那么主要的题目来了:假如我们用 l2_delta 乘以此次迭代的 syn1 值会怎样样?

这就像好莱坞编剧相同:你写了一个悲伤结果的影戏,主角被龙喷出的火焰灼伤然后被吃掉,以是未能抵达城堡。导演看了脚本满屋怒吼:「我要 happy ending,我要主角击败恶龙,发明生命的原理,然后回身分开!」

你赞同按老板的意义改正脚本。你晓得了要抵达的结果,就转回去寻找哪个举措出了错。哪个情节使得你没有成为俊杰反而被龙吃掉?

数学便是做如许的事故:假如你把 l2_delta(希冀的完美结果)乘以 syn1(导致过失结果的情节),那么你将劳绩 l1_error。改动变成过失结果的情节,下一版脚本将变得更好。

再次提示:假如你将下一次念去的地方(l2_delta)与路程第二部分的过失偏向(现的 syn1)相乘,则乘积将是「路程第一部分堕落的地方」,即 l1_error。

晓得了 l1_error,你就可以盘算下次迭代中将 l1 改动众少才干取得更好的 l2 预测,而这便是 l1_delta。

代码行 109:

l1_delta = l1_error * nonlin(l1,deriv=True)

l1_delta 的盘算方法和 l2_delta 相同,此处不再赘述。

4.7 更新突触

代码行 115-116:

 115  syn1 += l1.T.dot(l2_delta)
  116  syn0 += l0.T.dot(l1_delta)

代码的末结果部是高光时候:所有的义务完毕了,我们崇敬地将 l1_delta 和 l2_delta 搬到神圣的指导者「突触国王」目下,他才是所有操作的真正中心。

盘算 syn0 更新的第一步是 l1_delta 乘输入 l0,然后将乘积与目前的 syn0 相加。这就使得 syn0 的构成部分爆发很大改动,从而对 l1 发生更强影响。也便是说,我们低沉了此次迭代中误认为主要的题目或题目组合的主要性。它们并没有我们念象的那么主要,于是用 l1_delta 准确的偏向上改正过失,从而使我们下一次迭代中间隔城堡更近。

「试错进修」,这便是收集所做的事故。以下先容了收集怎样应用试错来进修:

你可以会说:「神经元将通通聚集一同!」(瞄准确预测奉献最众的特征组合收集中的最终优先级最高)。是突触权重将通通特征串联起来,从而做出着末的预测。

4.8 置信度的坡度与血色碗外面的坡度相同!

追念一下 1.3 提到的血色碗,我们本文中先容的所有本领都呈现这个碗中。

当我们运用旧层和新 delta 的乘积更新突触时,它促进突触准确的偏向上行进,去往置信度高、准确率高的预测结果。「准确的偏向上促进」意味着:

l2_delta 的少许值可以是负的。l2_delta 为负值意味着下一个迭代中的 l2 接近 0,这会以众种方法突触中呈现。于是寻得给予我们「偏向感」的坡度十分主要。偏向感,或者说坡度,是促进球抵达碗底的要害。收集的义务是添加权重,使得下一个 l2 被 l2_delta 撼动。

上面这幅简单的二维图展现了梯度下降的小球。

代码行 88 盘算出 l2 每个值的坡度值。上图的 3 个凹陷中(或者说「碗」),很分明真正的全部最小值是最左侧最深的碗。出于简明思索,我们伪装中心的碗是全部最小值。那么,向右下的陡峭坡度(即负坡度值,如上图绿色线所示)意味着小球会这个偏向上滚动很大幅度,导致 syn1 中的对应权重呈现较大的负值调解,而该权重将用于下一次迭代中预测 l2。也便是说,四个 l2 值中有少许会接近 0,则预测结果便是该顾客不置办这款猫砂。

可是,假如左下有一个浅坡度,这意味着预测值曾经具备高准确率和置信度,以是坡度值是小的正数,球只会向左稍微挪动一点,syn1 中的对应权重也只会有些微调解,如许下一次迭代中该值的预测结果不会有太大改动。这奏效的启事是,跟着收集预测的准确率越来越高,小球的来回挪动幅度将越来越小,直到它抵达全部最小值——碗底,不需求再挪动为止。

现第四部分「从试错中进修:梯度下降」即将完毕。是时分坦率一个终究了:你实行上曾经做微积分了,只不过我们没有指明它是微积分!

这个朴实的原形便是:

l2 每个值的置信度 = l2 的坡度 = l2 的导数

但置信度只是冰山一角,接下来我们将先容可用于更繁杂神经收集(具备更众层和特征)的计谋——反向传达。

5. 反向传达

5.1 打破反向传达的迷思

反向传达是施行梯度下降的中心东西,但它以难学而著称……不过反向传达是为了帮帮我们,它只要好的企图。

关于反向传达有两个迷思,接下来我们就来一一打破。

迷思 1:反向传达十分难

错。反向传达只是需求耐心和保持罢了。假如你只读过一次关于反向传达的文本就举手投诚,那你就完了!可是假如你把 Grant Sanderson 关于反向传达的视频 3 慢速看 5 遍,再把关于反向传达数学常识的视频 4 看 5 遍,你会认为很随手。(视频地址:https://www.youtube.com/playlist?list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi)

迷思 2:了解反向传达,必需会微积分

许众线作品称,你需求了解众变量微积分才干了解 AI。这种说法并过错。深度进修大牛 Andrew Trask 外示,假如你上过三个学期的大学微积分课,此中只要一小部分材料对进修反向传达有用:链式法则。然而,即时ャ学了 3 学期大学微积分课程,反向传达中的链式法则与你大学课堂上睹到的并不相同。你最好把 Kalid Azad 关于链式法则的书读五遍。

我之前一看到「导数」这个词就发窘,还没怎样兹釉己就先认输了。大师不要重蹈我的覆辙。你必需用如许的心里声响劝诫本人:「我不需求任何配景也能掌握这个看法。」

5.2 反向传达的定义

5.2.1 反向传达之于梯度下降,相当于链式法则之于反向传达

第四章先容的梯度下降进程是了解梯度下降的主要方法,不过第五章将从差别的角度了解梯度下降,它可运用于阵势部神经收集。

反向传达是了解神经收集的须要要害。其斯文的数学运算容许我们同时调解每一个权重,而这是通过链式法则完成的。

什么是链式法则?我先先容数学定义,再用类比的方法帮帮你了解它。

数学定义:链式法则的实质是,嵌套函数的导数是构成嵌套函数的每个函数的导数乘积。即,最终导数等于构成函数的导数乘积。

类比:把链式法则看作马戏团的杂耍人。神经收集有 16 个权重,于是我们把这些权重念象为 16 个保龄球瓶,杂耍人需求使它们同时中止空中。假设这些球瓶大小纷歧,则杂耍人必需足够娴熟才干用适宜的力道妥当的时间点扔出每个球瓶,同时确保其他 15 个球瓶中止空中。现我们假设这位杂耍人很厉害,当一个球瓶空中突然体积改动时,他可以立即调解其他 15 个球瓶,来补偿这一改造。他可以顺应球瓶的恣意改造并举行调解,使通通 16 个球瓶都中止空中!

确实是禀赋,对吧?链式法则也是云云:从一个权重到最终预测有许众道径,链式法则调解这些道径,使它们全都是相对较直的道。我们示例中的神经收集比较小,终究上链式法则同样适用于包罗数百万以致数十亿权重的大型神经收集。

5.2.2 我们念要办理的题目:怎样调解 16 个权重

难点于T媚课你调解 16 个权重中的此中一个时,通通神经收集都会受到影响。怎样既思索到权重调解对预测偏向的影响,槐ボ盘算出每个权重的最佳调解值呢?这听起来很繁杂。

终究也确实云云。我们方才曾经运用 Python 代码和置信度举行了须要的盘算,可是为了掌握这个要点,我们需求从另一个角度再做一次:链式法则。

我们将应用坡度使 16 个球瓶同时待空中。而寻得坡度的秘诀便是导数。

5.2.3 链式法则和改造率

这一次,我们运用链式法则寻得改造率的坡度。

改造率是一个主要看法。3.2 节提到 syn0,1 为 3.66,那么要害题目来了:当我们添加或减小 syn0,1 的值时,这对 l2_error 的增减有众大影响?也便是说,将 l2_error 对 syn0,1 改造的反响看作「敏锐度」,或者改造率:即调解 syn0,1 的值后,l2_error 值的改造会与之成比例。这个比例是众大呢?l2_error 对 syn0,1 的敏锐度怎样呢?

记住:反向传达的目标是寻得每个权重需求调解的量,从而下一次迭代中尽可以地低沉 l2_error。可是挑衅于每个权重都会对其他 15 个权重发生影响,于是权重 1 调解的量依赖于权重 2 调解的量,权重 2 的调解量依赖于权重 3 调解的量,依此类推。怎样调解 16 个不时改造的保龄球瓶取决于某个瓶子有众大改造。

不过我有一个更好的类比:蝴蝶。

5.3 定义链式法则:它像蝴蝶效应

还记得我们试图办理的题目吗?「怎样调解 16 个权重,使每个瓶子都能与其他 15 个球瓶完美搭配,同时中止空中,而且最小化 l2_error,帮帮我抵达城堡,找到生命的原理。」

我们将这个大题目剖析一下。我们先看此中的一个权重 syn0 (1,1)(本文将其简写为 syn0,1)。我怎样故有序、依存的方法调解 syn0,1,才干使 16 个球瓶平常运转,同时槐ボ尽可以众地低沉 l2_error?

谜底便是链式法则,它和蝴蝶效应很像(一只新墨西哥州的蝴蝶扇动党羽,激起了一系列连锁事情,惹起中国飓风)。我们来看这个类比怎样运用到反向传达中必需盘算的改造率上:

而当我们将 syn0,1 的值举行增减时,新墨西哥州的蝴蝶开端扇动党羽。出于简明性思索,我们将 syn0,1 的值添加到 3.66,这一方法激起了一系列连锁反响——其他权重协力构成的「完美风暴」,从而低沉 l2_error。

接下来,我们将蝴蝶效应和另一个类比——连锁反响联合起来。

5.4 蝴蝶效应碰睹 5 个改造率:连锁反响

蝴蝶效应只是更广泛看法——连锁反响的一个实例。下图将蝴蝶效应和改造率改动带来的连锁反响联合了起来,图看起来很繁杂,但它实由以下三项构成:

Ripple 1,即对 syn0,1 举行调解后的第一个连锁反响,将导致 l1_LH 上升必定比率,这个比率便是改造率。这便是「内华达州的大风」(睹下图灰色箭头)。

因为 l1_LH 是 sigmoid 函数的输入,那么盘算 l1_LH 和 L1 之间的改造率就需求权衡 Ripple 2,即「洛杉矶的暴风」(睹下图紫色箭头)。

很分明,l2_LH 会受到 l1 改造及 l1 乘以 syn1,1 的影响(为了简化示例,syn1,1 及其他 14 个权重的值并未改动),于是 l2_LH 和 l2 之间的改造率带来了 Ripple 3——「夏威夷的雷暴」(睹下图黄色箭头)。

l2 的改造与 l2_LH 的改造成比例,于是 l2_LH 的坡度将带来 Ripple 4——「安宁洋的暴风雨」(睹下图绿色箭头)。

着末,y 值减去新的 l2 取得的余数——l2_error 将会改动,即 Ripple Effect #5——「中国的飓风」(睹下图蓝色箭头)。

我们的目标是盘算每次连锁反响带来的改造率,寻得 syn0,1 需求增减的量,以便下一次迭代中最小化 l2_error。当我们说神经收集「进修」的时分,我们实外达的是每一次迭代中低沉 l2_error,使得每一次迭代中收集的预测结果准确率都有晋升。

倒过来看,我们可以说「飓风 l2_error 的改造取决于 l2 的改造,l2 的改造取决于 l2_LH 的改造,l2_LH 的改造取决于 l1 的改造,l1 的改造取决于 l1_LH 的改造,而 l1_LH 的改造取决于蝴蝶 syn0,1 的改造」。该示例中所用的规矩即步长等于坡度。

另外,我还念让大师了解 Python 代码和这些是怎样同步的。接下来,我们就来看看哪些代码行对应链式法则函数中的改造率。

5.5 代码与链式法则的同步

5.5.1 移除中心变量

上图中呈现了代码行 66 到 115 中的代码,血色线连接代码与改造率。假如你认为这些连线不太对,这是因为原始代码将反向传达进程剖析成了众个中心步和众个分外的中心变量。下面我们将从代码中移除以下四个中心变量:l2_error、l2_delta、l1_error 和 l1_delta。

先从血色箭头连接的代码片断开端。假设四个中心变量曾经移除,还剩下什么呢?我们来看下图的最底下一行。将中心变量从代码中移除后,这行代码并没有改动。现这三行完美同步了。

5.6 实战演示

下面,我们看看改动 syn0 中一个权重的数学配景。出于简便,这里的变量和第 3 节相同:

l0= 1
syn0,1= 3.66
l1_LH= 3.82
l1= 0.98
syn1,1= 12.21
l2_LH= 0.00
l2= 0.50
y= 1 (This is a "Yes" answer to survey question 4, "Ever bought Litter Rip?" which corresponds to training example #1, i.e., row 1 of l0)
l2_error = y-l2 = 1-0.5 = 0.5

5.6.1 不要重蹈我的覆辙

办理改造率时,万万不要和我犯同样的过失。我最初是这么盘算改造率的(过失树模):

那么上图有什么题目呢?

5.6.2 不是为了盘算改造率,而是为了盘算改造率的改造:坡度

上图中,我遗忘了此时的目标是盘算相对改造。看到上图中每个变量前面的 d 了吗?我疏忽了它们,只写下了每个变量的目今值。

而那些 d 外示 delta,delta 十分主要,不行疏忽。

我们念预测未来。我们念晓得 syn0,1 改动众少会最终导致下一次迭代中 l2_error 减小。也便是说,我们不是要比照 syn0,1 中单个数值 3.66 对 l2_error(0.5)的影响,而是念晓得 syn0,1 中 3.66 应当怎样改造才干影响到 5 个连锁改造率,从而最终发生更好的 l2_error。我们不念要一堆改造率,我们念要的是能改动 delta 的改造率。

5.6.3 盘算改造率的公式:x_current 和 x_nearby

「current」外示每个变量的目今值,「nearby」外示我们念供应的与目今数字接近的数字。nearby 数字减去 current 数字,会取得一个很小的数字。假如两个点一条弧线上,这便当盘算出更准确的坡度值。接下来我们过一遍上述 5 个改造率,练习怎样寻找每个改造率的 nearby 数字。

下图展现了完备的反向传达:

5.6.4 示例

从后往前,我们要先盘算的 Ratio 1 是 Ripple 5:d l2_error / d l2。那么「current」和「nearby」从哪里来呢?

其他几步的盘算进程此处不再赘述,念了解更众,请阅读原文。

总结

课程到这里已接近尾声,现你们曾经掌握了梯度下降的中心东西——反向传达。着末,我将送给大师一份分手礼品:

Andrew Trask 教会我:记住这些 Python 代码才干醒目。出于以下两点启事我认同这个看法:

紧记这些代码帮帮我编了一个把所有看法串一同的荒谬故事,你也可以编制本人的故事。

期望你能享用深度进修路程!

原文链接:https://colab.research.google.com/drive/1VdwQq8JJsonfT4SV0pfXKZ1vsoNvvxcH

相关数据

深度进修技能

深度进修(deep learning)是板滞进修的分支,是一种试图运用包罗繁杂构造或由众重非线性变换构成的众个处理层对数据举行高层笼统的算法。 深度进修是板滞进修中一种基于对数据举行外征进修的算法,至今依鳌有种深度进修框架,如卷积神经收集和深度置信收集和递归神经收集等已被运用盘算机视觉、语音识别、自然言语处理、音频识别与生物新闻学等范畴并获取了极好的效果。

计划技能

人工智能范畴的「计划」一般是指智能体施行的义务/举措的主动计划和调治,其目标是举行资源的优化。常睹的计划方法包罗经典计划(Classical Planning)、分层义务收集(HTN)和 logistics 计划。

堆叠技能

堆叠泛化是一种用于最小化一个或众个泛化器的泛化偏向率的方法。它通过推导泛化器相关于所供应的进修集的偏向来发挥其感化。这个推导的进程包罗:第二层中将第一层的原始泛化器对部分进修集的猜念举行泛化,以及实验对进修集的盈余部分举行猜念,而且输出准确的结果。当与众个泛化器一同运用时,堆叠泛化可以被看作是一个交叉验证的繁杂版本,应用比交叉验证更为繁杂的计谋来组合各个泛化器。当与单个泛化器一同运用时,堆叠泛化是一种用于估量(然后改正)泛化器的过失的方法,该泛化器曾经特定进修集上举行了教练并被讯问了特定题目。

发外评论

用户评论

暂无评论
暂无评论~
评论 0
点赞
分享
请挑选分享平台
微博
Twitter
撤消分享