Skip to content

Latest commit

 

History

History
175 lines (88 loc) · 16.4 KB

please-stop-drawing-neural-networks-wrong-ffd02b67ad77.md

File metadata and controls

175 lines (88 loc) · 16.4 KB

请停止错误绘制神经网络

原文:towardsdatascience.com/please-stop-drawing-neural-networks-wrong-ffd02b67ad77?source=collection_archive---------0-----------------------#2023-03-21

优质图表的案例

亚伦·马斯特数据科学 亚伦·马斯特

·

关注 发表在 Towards Data Science ·12 分钟阅读·2023 年 3 月 21 日

--

图片由作者提供,改编自 tikz.net/neural_networks/ (CC BY-SA 4.0)

作者:亚伦·马斯特和多龙·伯格曼

如果你是数百万尝试学习神经网络的人之一,那么你可能见过类似上述的图像。

这个图表只有一个问题:那就是毫无意义。

这意味着困惑、不完整,且可能是错误的。这个图表受到了某个著名在线深度学习课程中的图表的启发,排除了所有的偏差系数,并将数据展示成好像它是一个函数或节点。它“可能”错误地显示了输入。我们之所以说“可能”,是因为即使其中一位我们获得了完成这类课程的证书,还是很难确定它试图展示的内容。¹

其他神经网络图表有不同的缺陷。以下是一个受某个来自山景城——基于广告公司的 TensorFlow 课程图示启发的插图:

图片由作者提供,改编自之前的图片。

这个图比第一个图更清晰地展示了输入,这是一个进步。但它也做了其他奇怪的事情:它按名称展示了偏差,但没有用视觉图示显示它,还将数量以不同于它们使用或创建的顺序展示出来。

为什么?

很难猜测这些图表是如何形成的。第一个图在表面上看起来类似于流网络图表,这些图表在图论中使用。但它违反了这种流图的核心规则,即流入节点的量等于流出节点的量(这里没有适用的例外)。第二个图看起来可能起初是第一个图,但随后被编辑成展示参数数据,结果顺序错乱。² 这些图表都没有视觉上展示偏差(我们看到的大多数图表也没有),但这种选择并没有节省多少空间,如下所示。

我们没有挑选这些图表。对“神经网络图表”的互联网图片搜索显示,上述图表是常态,而非例外。

糟糕的图表对学生不好

上述图表如果仅在经验丰富的专业人士之间使用,可能会还不错。但遗憾的是,它们被用于教学目的,给无辜的机器学习学生带来了困扰。

遇到这种奇怪情况的学习者必须做出书面或心理笔记,例如“这里有偏差,但他们没有显示出来”或“他们画在圆圈内部的东西实际上是处理输出,而这个圆圈两张幻灯片前就显示过”或“输入实际上并不像图中显示的那样工作。” 上述提到的著名(且通常很优秀的)课程包含讲师耐心地多次重复某个网络的实际工作方式与图示方式不符的讲座。在课程的第三周,他勇敢地尝试折衷,交替使用特殊的、准确的图示来展示节点内部发生的情况,以及更典型的图示来展示其他内容。(如果你想看到那些更好的节点图示,可以参考这篇博客文章。)

一种更好的方法

学习神经网络不应该是解码误导性图表的练习。 我们提出了一种建设性的、新颖的方法来教授和学习神经网络:使用好的图表。我们希望图表能够简洁而忠实地表示数学内容——如费曼图、文氏图、数字滤波器图和电路图中所示。

制作 GOOD 图

那么,我们究竟提出了什么?让我们从基础开始。神经网络涉及许多简单的操作,这些操作已经在电气工程师使用了几十年的流程图中有表示。具体来说,我们可以描绘数据复制、数据相乘、数据相加和将数据输入函数以输出数据。然后,我们可以将这些符号的缩略版本组装成一个准确的整体,我们将其称为一般目标可观察描绘图,简称 GOOD 图。(抱歉,反缩写者。)

让我们看看这些构建块。首先,这里是如何展示来自单一数据源的三个数据副本的。很直观。

这里是显示缩放输入的方法。它就是一个三角形。

三角形表示输入值x₁进入它后被某个数w₁缩放,产生结果w₁乘x₁。例如,w₁可以是 0.5 或 1.2。稍后如果我们将这个三角形移到图的右端(与箭头合并)并将其缩小,会更方便,所以我们就这样画吧。

好吧,我们承认:这只是一个带实心三角形尖端的箭头。关键是,三角形尖端乘以箭头上的数据。

接下来,这是一种显示将两个或更多东西加在一起的方法。我们称和为z。也很简单。

现在,我们用一些标准符号展示了加法和乘法。但如果我们有一个更通用的函数,它接受一个输入并产生一个输出呢?更具体地说,当我们制作神经网络时,我们会使用一个激活函数,它通常是 Sigmoid 或 ReLU。无论哪种方式,都不成问题;我们只需将其表示为一个框。例如,假设我们函数的输入叫做z,函数z的结果叫做g(z),产生一个输出a。它看起来是这样的:

可选地,我们可以指出*g(z)具有给定的输入—输出特性,这可以放在函数框附近。这是一个包括 ReLU 的g(z)*图以及函数框的图。在实际应用中,通常只有少数几种激活函数,因此在图层附近注明函数名称(例如 ReLU)也足够了。

或者,我们可以进一步缩略,因为在典型的神经网络中将有许多,通常是相同的激活函数。我们建议在函数框内使用单个风格化的脚本字母来表示特定激活,例如R表示 ReLU:

同样,Sigmoid 可以用风格化的S表示,其他函数可以用另一指定字母表示。

在继续之前,让我们注意一个简单但关键的事实:我们将数据(及其传输方向)表示为箭头,将操作(如乘法、加法、一般函数)表示为形状(如三角形、圆形、方形)。这是电气工程流程图中的标准做法。 但由于某些原因,也许是受到早期计算机科学研究的启发,该研究物理上将记忆和操作结合在一起,当绘制神经网络时,这一惯例被忽视或甚至被颠倒。³ 尽管如此,这一区分仍然很重要,因为我们确实训练函数参数,但我们训练数据,每个数据实例都是不可变的。

好的,回到我们的故事。由于我们很快会构建神经网络图,因此需要描绘大量的“求和然后函数”处理。为了使我们的图示更加紧凑,我们将创建一个缩略符号来结合这两个功能。首先,让我们将它们绘制在一起,假设*g(z)*是 ReLU。

既然我们要缩略符号,那么我们来看一下它们放得非常近时的样子。我们还将从图中删除内部变量和函数符号,并添加一些虚线以提示建议的形状:

基于此,我们引入一个新的总结符号来表示“求和然后函数”:

它特殊的形状提醒我们它的作用。它也故意看起来与其他符号不同,以帮助我们记住它是特别的。⁴

一个好事

现在,让我们通过一个简单的逻辑回归示例,将上述所有图示操作整合在一起。我们的示例从二维输入开始,将每个输入维度的值乘以一个唯一的常数,然后将结果与常数b(我们称之为偏置)相加,并将和通过 Sigmoid 激活函数。由于稍后会讲解的原因,我们将偏置表示为 1 乘以值b。为了完整性(并作前瞻),我们为所有这些值指定名称,并在图示中显示出来。输入为x₁和x₂,乘法因子包括权重w₁和w₂以及偏置b。加权输入和偏置的总和为z,函数*g(z)*的输出为 a。

关于图表左下角显示的那个数字“1”。这个数字 1 不是输入值,但通过显示这个数字而不仅仅是输入,我们明确了这些值中的每一个都乘以一个参与求和的参数。这样我们可以在同一个图表中展示* w*(输入权重)和值* b*(偏置)。不好的图表通常省略偏置,但好的图表不会。特别是在网络可能故意省略偏置的情况下,省略偏置尤其危险;如果未显示偏置,观众就不得不猜测它是否是网络的一部分。因此,请在图表中故意包括或排除偏置。

现在通过使用上面定义的“求和然后函数”符号来稍微清理一下。我们还在图表下方显示了变量名称。请注意,我们用“求和然后函数”符号中的* S*来表示 Sigmoid 函数。

这看起来很简单。这是件好事。

现在,让我们构建一些更有趣的东西:一个具有三个单位的隐藏层(使用 ReLU 激活)和一个使用 Sigmoid 激活的输出层的实际神经网络(NN)。 (如果你不熟悉,隐藏层是除了输入层或输出层以外的任何层。)请注意,这是上面 Mountain View 网络图中使用的相同架构。在这种情况下,每个输入维度和输入层偏置连接到隐藏层中的每个节点,然后隐藏层输出(加上偏置值)连接到输出节点。每个函数的输出仍然称为a,但我们使用带括号的上标和下标分别表示我们从哪个层和节点输出。类似地,我们使用带括号的上标来表示* w b*值指向的层。使用之前示例中的风格,它看起来像这样:

现在我们有了进展。此时,我们还可以看到每层的* W b的维度由输入的维度和每层的节点数指定。让我们通过不单独标记每个 w b*值来清理上述图表。

本文所有图片均由作者提供。

哒哒!我们有了一个很好的神经网络图表,同时也是好的。可学习的参数在图表上(作为三角形)和图表下方的总结中都显示出来,而数据直接在图表上以标记的箭头显示。网络的架构和激活函数,通常称为超参数,可以通过检查图表本身的布局和节点来查看。

一切都很棒

让我们考虑一下好的图表的好处,不考虑坏图表:

  • 很容易看出每层的操作顺序。先进行乘法运算,然后是求和,然后是激活函数。

  • 容易将(不可变的)数据流经网络与属于网络的(可训练的)参数区分开来。

  • 容易看出每层的w矩阵和b向量的维度。对于一个有N节点的层,很明显我们需要b的形状为[N,1]。对于一个在有M节点(或输入)的层之后的有N节点的层,很明显w的形状为[N,M]。 (然而,仍然需要记住形状是[输出,输入]而不是[输入,输出]。)

  • 相关的,我们可以看到权重和偏差确切存在的位置,即层与层之间。传统上,它们被命名为属于它们输出到的层,但使用优秀图示的学生会被提醒,这只是一个命名惯例。

让我们还来回顾一下优秀图示与差的图示的区别:

  • 它们显示了每一层的偏差。它们不会遗漏偏差。

  • 它们将数据视为数据,将函数视为函数。它们不会混淆两者。

  • 它们显示了数据何时被复制并发送到函数。它们不会跳过这一步。

  • 它们按照正确的顺序显示所有步骤。它们不会错误地重新排序或遗漏步骤。

  • 它们相对简洁明了。好吧,不好的那一些稍显简洁。

做一些好事

本文详细讨论了差的图示存在的问题,并为优秀图示提供了理由。但如果你是机器学习讲师,我们鼓励你直接开始使用优秀图示,而不需要额外的宣传。优秀图示比其他选项更具自解释性。反正你在课程中会讲解神经网络,所以在那个时候引入优秀图示是个好主意。

当然,为了服务你的学生,展示一些差的图示也是个好主意。了解外界是如何绘制图示的,即使它们毫无意义,也很重要。我们认为,从准确的东西中学习,然后考虑混乱的东西,比反过来要容易得多。

更多精彩内容在前面

这篇文章完成了系列中的第一篇,如果它受到欢迎的话。特别是,我们关注的是简化网络图示,它们紧凑地表示了上面展示的全连接网络类型,并且也有改进的空间。卷积网络图示值得单独讨论。我们也在开发一个软件包,用于自动绘制优秀图示。

致谢

作者感谢 Jeremy Schiff 和 Mikiko Bazeley 对本篇文章的协助。

参考文献和附注

  1. 基于其他层,可能第一个图示正在将输入传递给非平凡的激活函数,从中得到的值可能与输入不同。但在相关课程中没有这样工作的例子,因此将这样的图示作为备忘单上唯一的全连接图示是不合适的。或者,第一个层中显示的“a”值可能与输入相同,在这种情况下,激活函数是恒等函数,这会引起平凡且不必要的处理。无论哪种情况,图示都是模糊的,因此不佳。

  2. 前两个图示中的任意一个看起来都可能是更好、更旧的图示的一个不幸缩略,例如 Duda、Hart 和 Stork 第二版《模式分类》第六章中的图示(其中一位我们还保留着 2002 年 CS229 时的纸质版)。那本书将激活函数显示为圆形单元(比将其输出放在单元内要好),并正确地显示输出在制作副本并分离到下一层之前离开单元。(虽然它也奇怪地显示了输入和偏置。)

  3. 如果你的学习已经进展到包括卷积网络(CNs),你会发现 CN 图示通常将数据显示为块,将处理过程显示为标注的箭头。不要担心。现在,只需记住数据和处理过程之间有本质的区别,对于全连接神经网络,一个好的(或优秀的)图示会清晰地表明它们的不同。

  4. 对于那些将“和再函数”符号视为反向操作的与门的逻辑爱好者,请记住,与门不可逆的。因此,这个新符号必然有其他含义,我们在这里定义。