简单易懂的变压器 (3):前馈层部分
编者按:随着人工智能技术的不断发展Transformer架构已经成为了当今最为热门的话题之一。前馈层作为Transformer架构中的重要组成部分,其作用和特点备受关注。本文通过浅显易懂的语言和生活中的例子,帮助读者逐步理解Transformers中的前馈层。
本文是Transformers系列的第三篇。作者的观点是:前馈层在Transformer架构中扮演着至关重要的角色,它能够有效地提高计算效率,同时也是集体智慧的体现。
文章作者首先介绍了前馈层的基本结构,它由全连接层组成,进行线性变换和线性计算。但也存在局限性,不能进行复杂的非线性变换。所以前馈层需要激活函数(如ReLU)进行非线性转换,增强网络的表达能力。为防止模型仅记忆数据特征而不具备推理能力,需要使用正则化技术如dropout。相信通过本文的阅读,读者将对Transformer中的前馈层有更深入的理解。
随着深度学习在语音、图像、自然语言处理等领域取得突破,人工智能或许正向着真正的通用人工智能迈进。但要培养通用人工智能,我们还需不断深入理解其中的原理和相关机制。
以下是译文,enjoy!
作者 | Chen Margalit
https://www.linkedin.com/in/chen-margalit/
编译 | 岳扬
本文经原作者授权,由Baihai IDP编译。如需转载译文,请联系获取授权。
原文链接:https://towardsdatascience.com/simplifying-transformers-state-of-the-art-nlp-using-words-you-understand-part-4-feed-foward-264bfee06d9
本节将介绍前馈层(Feed-Forward layer),这是大多数深度学习架构中的基础元素。在有关深度学习的常见话题交流时,一般都会强调它们在构造 Transformer 架构中的重要作用。
原论文中的图片[1]
前馈全连接层(feed-forward linear layer)基本上就是一堆神经元,每个神经元都与其他神经元相连接。请看下图,其中a、b、c和d是神经元。这些神经元包含了一些 input(即一些我们想要理解的数据(像素值(pixels)、词嵌入(word embeddings)等))。它们与编号为1的神经元相连。每两个神经元之间的连接都有不同的连接权重值(connection strength)。例如,a-1是0.12,b-1是-0.3,等等。实际上,左列中的所有神经元都与右列中的所有神经元相连。但是为了清晰起见,我没有在图像中展示全部的连接,你需要了解这一情况。就像图中有a-1一样,还应该有a-2、b-2、c-2、d-3等。两个神经元之间的每个连接都有不同的“连接权重”。
该图由原文作者绘制
该架构有两点值得注意:
- 如前所述,每个节点(神经元)都与其他节点相连。所有的a、b、c、d都与其他神经元(1、2、3)相连。可以将这幅图像看作是一条军队指挥链。1、2、3是指挥官。他们从士兵a、b、c、d那里得到情报。a知道某件事情的一些细节,但它的情报不够全面。1知道的就更多了,因为它能够从a、b、c和d那里同时得到情报。2和3也是指挥官,同样从a、b、c、d那里获取情报。这些指挥官(1、2、3)也会向更高级的指挥官传递报告。在他们之后的指挥官既从a、b、c、d那里得到情报,也从1、2、3那里得到情报,因为下一层(每列神经元为一层)也是以完全相同的方式进行全连接的。因此,首先要明白的是, 1 的情报比 a 更全面,而下一层指挥官的情报也比 1 更全面。
- 第二点需要注意的是,每个节点与下一层的每个其他节点之间的连接权重是不同的。a-1是0.12,b-1是-0.3。我在这里给出的数字显然是虚构的,但它们也是在合理的范围内,并且它们都是自动学习调整的参数(learned parameters)(例如,它们在训练过程中会发生变化)。把这些数字看作是 1 对 a、b 等的影响程度。从1号指挥官的角度来看,a的情报有一定的可信度。但不应该想当然地相信他说的每一句话,可以选择性地相信他说的某些话。b则截然不同。这个节点通常会低估它接收到的输入(情报)的重要性,就像一个悠闲的人一样。“这是一只tiger吗?不,只是一只big cat。” 这是对发生的事情的过度简化,但重要的是要注意这一点:每个神经元都掌握着一些input(无论是原始输入还是经过处理的input)并进行处理后将其传递下去。
你知道“传话游戏”吗?你和其他 10 个人坐成一排,然后你向下一个人耳语一个词,比如说“Pizza”。第 2 个人听成了类似“Pazza”的词,于是他们把“Pazza”传给了第 3 个人。第 3 个人听成了 “Lassa”(毕竟是耳语),于是他把 “Lassa”传给了第 4 个人。第 4 个人听成了 “Batata”,于是他又转述了 “Batata”,以此类推。当你问第 10 个人他听到了什么?结果他回答“Shambala”,我们是怎么从“Pizza”到“Shambala”的?这个游戏与神经网络的区别在于,每个人都会对信息进行处理。第二个人不会说 “Pazza”,他会说“Pazza 是意大利菜,很好吃”。第三个人会说:“Lassa是一道意大利菜,在全世界都很常见”,等等。每个人(层)都会补充一些他们希望有用的东西。
基本情况就是这样。每个神经元获得输入,处理输入,然后继续传递。 为了与全连接层(fully connected layer)相匹配,我建议对这个游戏进行升级:从现在开始,在游戏中引入多行人,每个人都可以对每一行中的其他人说悄悄话。从每一行的第 2 位开始,每个人都会收到很多人的悄悄话,他们需要了解每个人说的话语的“权重”(重要性),这就是前馈层(Feed Forward Layer)。
为什么我们要使用前馈层?因为它们使我们的计算能够更加有效,可以将其类比为集体智慧的体现。 讲一个关于“猜测一头牛重量”的故事吧!1906年,在英国的某个地方,有人把一头牛带到一个展览会上。主持人随机挑选了 787 名观览者,请他们猜测这头牛的重量。你认为他们猜测的结果会是多少?这头牛的实际体重是多少呢?
他们猜测的平均值是 1197 磅(542 公斤)。这些都是随机抽取的群众对牛体重的估计。这个平均猜测值离真实重量相差多远呢?只有1磅差距,也就是450克。这头牛的重量是1198磅。这个故事来自这里[2],我不确定细节是否准确,但回到本文的主题,我们可以把线性层 (译者 注:此处即本文所说的前馈层) 看作是在做类似的事情。通过增加更多的参数、更多的计算(更多的猜测),就可以得到更准确的结果。
照片由 Larry Costales[3] 在 Unsplash[4] 上发布
让我们试着想象一个真实的使用场景。给神经网络输入一张图片,让它判断图片里的是苹果还是橙子。这种架构基于卷积神经网络(CNN)层,本文不会深入讨论这个知识点,因为其超出了本系列文章的范围。但该层是一个能够学习和识别图像中特定模式(specific patterns)的计算层。 (译者注:这些特定模式的识别有助于网络进行更准确的分类和判断,例如判断图像中是苹果还是橙子。) 每一层都能识别更复杂的模式。例如,第一层几乎不能识别出任何东西,该层只是传递原始像素,第二层就能够识别出垂直线条。如果下一层同时接收到有垂直线条的信息,并从其他神经元那里听说还有非常接近的垂直线条。它会将两者综合起来进行计算、分析,然后思考:不错!这是一个角落。这就是从多个来源获取输入信息的好处。
我们可能会认为,进行计算的次数越多,得到的结果就越好。但事实上,并非完全是这样,但确实有一定的道理。如果我们做更多的计算,咨询更多人(神经元)的意见,通常就能得出更好的结果。
01 激活函数 Activation Function
接下来将介绍深度学习中另一个非常重要的基本概念的关键组成部分——激活函数,并探讨它与Transformer的关系,以便更好地理解两者之间的关联。
尽管全连接层(Fully connected layers)的使用非常广泛,但也存在一个很大的缺点——它们是线性层(linear layers),只能进行线性变换和线性计算。全连接层可以进行加法和乘法运算,但无法以“创造性”的方式转换输入(input)。有时候,仅仅增加计算量是不够的,需要以完全不同的思考方式来解决问题。
如果我每天工作10个小时,每天赚10美元,如果我想更快地存下1万美元,我可以每周工作更多天,或者每天工作更多小时。但是肯定还有其他解决方案,对吧?有很多人不需要他们拥有的钱(我可以更好地利用它),或者我可以找到更高薪的工作等等。解决办法并不总是千篇一律。
同理,在本文的情况下,激活函数可以来提供帮助。激活函数能够帮助我们进行非线性变换(non-linear transformation)。例如,将一个数字列表[1, 4, -3, 5.6]转换为概率分布,就是Softmax激活函数的作用。该激活函数能够将这些数字转换为[8.29268754e-03, 1.66563082e-01, 1.51885870e-04, 8.24992345e-01]这样的输出。这5个数字相加等于1。虽然这些数字看起来有些混乱,但 e-03 表示第一个数字(8)在小数点后3个零开始(例如0.00,然后是82926。实际上该数字是0.00829268754)。这个Softmax激活函数将整数转换为0到1之间的浮点数,转换后的浮点数仍然保持了原始整数之间的相对大小关系。这种保持相对大小关系的特性在统计学中非常有用。
还有其他类型的激活函数,其中最常用的之一是ReLU(修正线性单元)。这是一种非常简单(同时也非常有用)的激活函数,它能够将任何负数转化为0,而非负数保持不变。非常简单且实用。如果我将列表[1, -3, 2]输入ReLU函数,会得到[1, 0, 2]。
在介绍完复杂的Softmax之后,你可能会期望一些更复杂的东西,但有人曾经告诉我“Luck is useful”。有了激活函数后,我们就走运了。
我们之所以需要这些激活函数,是因为非线性关系(nonlinear relationship)无法通过线性计算(全连接层)来表示。如果我每工作一小时就能得到 10 美元,那么收入就是线性关系。如果我每连续工作 5 个小时,接下来的 5 个小时就能增加 10%,那么这种关系就不再是线性的了。我的工资不再是工作小时数乘以固定的小时工资。在文本生成等更复杂的任务中使用深度学习,就是因为我们要建模的关系高度非线性。 在“我喜欢”之后能出现的词并不是固定的。
ReLU 的一大优势,也许可以解释它为何被广泛使用,就是对大量数据进行计算的成本非常低。 当神经元数量较少时(比方说几万个),计算量并不重要。但是当像大语言模型那样使用数千亿个神经元时,一种更高效的计算方式会带来巨大差异。
02 正则化 Regularization
在解释Transformer中如何实现正则化(非常简单)之前,我们将介绍最后一个概念——dropout,这是一种正则化技术。由于算法是基于数据的,并且它们的任务是尽可能逼近训练目标,所以对于一个大脑聪明的人来说,有时仅仅记住一点点东西就足够了。正如我们在学校中所受到的教育,学习复杂的逻辑并不总是有用的,我们有时只需记住我们所见过的,或者记住与之接近的东西。第二次世界大战是什么时候发生的?嗯...它受到了第一次世界大战、经济危机、人民愤怒等等因素的影响...大约是1917年左右...所以我们就说是1928年吧。记住确切的日期可能更好。
可以想象,这对机器学习来说并不是好事。如果我们需要的是已经有答案的问题的答案,我们就不需要这些复杂的技术了。我们需要一个聪明的算法,因为我们无法记住所有的东西。我们需要它进行实时推理,进行思考。正则化(Regularization)是让算法仅学习不记忆的一系列技术的总称。在这些正则化技术中,一种常用的技术就是dropout。
03 Dropout
dropout可以说是一种相当简单的技术。还记得我们说过全连接层(fully connected layers)是完全连接的吗?dropout打破了这种逻辑。dropout技术将“连接权重(connection strength)”设置为0,这意味着该连接不会产生任何影响。对于1号指挥官来说,连接到士兵“a”的输入变为 0 时,“a”传递的情报会变得完全无用。不回答,不肯定,也不否定。我们在每一层中使用dropout技术时,会随机选择一定数量的神经元(由开发者配置),并将它们与其他神经元的连接权重设为0。 每次指挥官会*忽略不同的士兵,因此无法记住其中任何一个士兵,因为下次可能不会再遇到它们传递情报。
04 回到Transformer!
现在我们已经掌握了理解Transformer中前馈层工作原理所需的所有基础知识。接下来解释实现过程就会非常简单了。It will now be very simple.
图片来自 Vaswani, A. 等人的论文[5]
在原论文中的架构图中,前馈线性层只做了四件事情:
- 对文本中的每个位置(用向量表示),进行逐位置的线性计算。
- 对线性运算的输出应用ReLU函数。
- 对上一步骤ReLU运算的输出进行再一次线性运算。
- 最后,将其添加到第 3 层的输出中。
就是这样。如果你有深度学习领域的相关经验,那么理解这一部分对你来说可能很容易。如果你没有经验,可能稍显吃力,但你已经理解了深度学习中一个极为重要的组成部分。
在下一部分,我们将介绍Transformer中的解码器(Decoder)部分相关知识!
END
参考资料
[1]https://proceedings.neurips.cc/paper_files/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf
[2]https://www.wondriumdaily.com/the-wisdom-of-crowds/#:~:text=An%20Astonishing%20Example%20of%20the%20Wisdom%20of%20Crowds&text=The%20actual%20weight%20of%20the,that%20weight%20was%201%2C197%20pounds.
[3]https://unsplash.com/@larry3?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]https://unsplash.com/photos/Ahf1ZmcKzgE?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[5]https://proceedings.neurips.cc/paper_files/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf
推荐阅读
-
简单易懂的变压器 (3):前馈层部分
-
纯干货分享 | 研发效能提升——敏捷需求篇-而敏捷需求是提升效能的方式中不可或缺的模块之一。 云智慧的敏捷教练——Iris Xu近期在公司做了一场分享,主题为「敏捷需求挖掘和组织方法,交付更高业务价值的产品」。Iris具有丰富的团队敏捷转型实施经验,完成了企业多个团队从传统模式到敏捷转型的落地和实施,积淀了很多的经验。 这次分享主要包含以下2个部分: 第一部分是用户影响地图 第二部分是事件驱动的业务分析Event driven business analysis(以下简称EDBA) 用户影响地图,是一种从业务目标到产品需求映射的需求挖掘和组织的方法。 在软件开发过程中可能会遇到一些问题,比如大家使用不同的业务语言、技术语言,造成角色间的沟通阻碍,还会导致一些问题,比如需求误解、需求传递错误等;这会直接导致产品的功能需求和要实现的业务目标不是映射关系。 但在交付期间,研发人员必须要将这些需求实现交付,他们实则并不清楚这些功能需求产生的原因是什么、要解决客户的哪些痛点。研发人员往往只是拿到了解决方案,需要把它实现,但没有和业务侧一起去思考解决方案是否正确,能否真正的帮助客户解决问题。而用户影响地图通常是能够连接业务目标和产品功能的一种手段。 我们在每次迭代里加入的假设,也就是功能需求。首先把它先实现,再逐步去验证我们每一个小目标是否已经实现,再看下一个目标要是什么。那影响地图就是在这个过程中帮我们不断地去梳理目标和功能之间的关系。 我们在软件开发中可能存在的一些问题 针对这些问题,我们如何避免?先简单介绍做敏捷转型的常规思路: 先做团队级的敏捷,首先把产品、开发、测试人员,还有一些更后端的人员比如交互运维的同学放在一起,组成一个特训团队做交付。这个团队要包含交付过程中所涉及的所有角色。 接着业务敏捷要打通整个业务环节和研发侧的一个交付。上图中可以看到在敏捷中需求是分层管理的,第一层是业务需求,在这个层级是以用户目标和业务目标作为输入进行规划,同时需要去考虑客户的诉求。业务人员通过获取到的业务需求,进一步的和团队一起将其分解为产品需求。所以业务需求其实是我们真正去发布和运营的单元,它可以被独立发布到我们的生产环境上。我们的产品需求其实就是产品的具体功能,它是我们集成和测试的对象,也就是我们最终去部署到系统上的一个基本单元。产品需求再到了我们的开发团队,映射到迭代计划会上要把它分解为相应的技术任务,包括我们平时所说的比如一些前端的开发、后端的开发、测试都是相应的技术任务。所以业务敏捷要达到的目标是需要去持续顺畅高质量的交付业务价值。 将这几个点串起来,形成金字塔结构。最上层我们会把业务目标放在整个金字塔的塔尖。这个业务目标是通过用户的目标以及北极星指标确立的。确认业务目标后再去梳理相应的业务流程,最后生产。另外产品需求包含了操作流程和业务规则,具需求交付时间、工程时间以及我们的一些质量标准的要求。 谈到用户影响的地图,在敏捷江湖上其实有一个传说,大家都有一个说法叫做敏捷需求的“任督二脉”。用户影响地图其实就是任脉,在黑客马拉松上用过的用户故事地图其实叫督脉。所以说用户影响地图是在用户故事地图之前,先帮我们去梳理出我们要做哪些东西。当我们真正识别出我们要实现的业务活动之后,用户故事地图才去梳理我们整个的业务工作流,以及每个工作流节点下所要包含的具体功能和用户故事。所以说用户影响地图需要解决的问题,我们包括以下这些: 首先是范围蔓延,我们在整张地图上,功能和对应的业务目标是要去有一个映射的。这就避免了一些在我们比如有很多干系人参与的会议上,那大家都有不同想法些立场,会提出很多需求(正确以及错误的需求)。这个时候我们会依据目标去看这些需求是否真的是会影响我们的目标。 这里提到的错误需求,比如是利益相关的人提出的、客户认为产品应该有的、某个产品经理需求分析师认为可以有的....但是这些功能在用户影响地图中匹配不到对应目标的话,就需要降低优先级或弃掉。另外,通常我们去制定解决方案的时候,会考虑较完美的实现,导致解决方案括很多的功能。这个时候关键目标至关重要,会帮助我们梳理筛选、确定优先级。 看一下用户影响到地图概貌 总共分为一个三层的结构: 第一层why,你的业务目标哪个是最重要的,为什么?涉及到的角色有哪些? 第二层how ,怎样产生影响?影响用户角色什么样的行为? (不需要去列出所有的影响,基于业务目标) 第三层what,最关键的是在梳理需求时不需一次把所有细节想全,这通常团队中经常遇到的问题。 我们用这个例子来看一下 这是一个客服中心的影响地图,业务目标是 3个月内不增加客服人数的前提下能支持1.5倍的用户数。此业务目标设定是符合 smart 原则的,specific非常的具体,miserable 是可以衡量的,action reoriented是面向活动的, real list 也是很实际的。 量化的目标会指引我们接下来的行动,梳理一个业务目标,尽量去量化,比如 :我们通过打造一条什么样的流水线,能够提高整个部署的效率,时间是原来的 1/2 。这样才是一个能量化的有意义的目标。 回到这幅图, how 层级识别出来的内容,客服角色:想要对它施加的影响,把客户引导到论坛上,帮助客户更容易的跟踪问题,更快速的去定位问题。初级用户:方论坛上找到问题。高级用户:在论坛上回答问题。通过我们这些用户角色,进行活动,完成在不增加客户客服人数的前提下支持更多的用户数量。 最后一个层级,才是我们日常接触比较多的真正的功能的特性和需求,比如引导到客户到论坛上,其实这个产品就需要有一个常见问题的论坛的链接。这个层次需要我们团队进一步地在交付,在每个迭代之前做进一步的梳理,细化成相应的用户故事。 这个是云智慧团队中,自己做的影响地图的范例,可以看下整个的层级结构。序号表示优先级。 那我们用户影响地图可以总结为:
-
简单易懂!详解软件系统架构:C/S、B/S与三层架构的区别与介绍(第二部分:三层架构深入)
-
三分钟带你了解手机内部硬件-主要影响手机性能的有以下几点 CPU - *处理器(手机中的大脑) CPU 是计算思考以及处理事物的。 比如:我们日常玩手机,什么最重要?毫无疑问是手机打开软件很流畅,使用各种功能不卡。 这就是CPU的性能,那什么影响 CPU 的因素有哪些? 架构 架构是 CPU 的基础,对于处理器的整体性能起到了决定性的作用,不同架构的处理器同主频下,性能差距可以达到2-5倍。可见架构的重要性。 那么什么是架构呢? 打个比方,架构就是一栋楼的框架。至于最终楼什么样子,就由处理器的厂商决定了,但是有一点,如果说这栋楼房的结构设计出来容纳多少人,那么最后建好的房子也要在这个范围内。同理,如果使用相同架构的处理器,那么本质上不会有太大的区别。 看一下主流手机的架构 处理器对比.jpg 从上图可见:高通 和 苹果都是自主设计,所以说它们牛还是有一定的道理的。不同的架构, 性能和功耗也是不同的。架构决定了 主频、核心数、带宽等和运算量直接相关的东西。目前很多手机打广告都是说 多少核的机器。但是并不是说核越多性能就越强,你没看见,苹果双核就能吊打高通和联发科吗? 制程 制程 专指:事物运作程序的处理过程。常指手机芯片框架的运算速度量。 简单的说就是电路板中电路与电路之间的距离,目前已经发展到纳米级别。 制程越小,可以向芯片中塞入更多的晶体管,随之而来的好处还有:降低电量和成本、散热。 制程数的确定 这里有人要问,为什么制程的数字是这些,而不是别的数字,比如有28nm,为什么没有29nm? 这其实是有一定规律的。根据早期国际半导体蓝图规划,由五个在相关领域较为发达的国家共同制定,约定下一代制程要在上一代基础上做到晶体管数量不变,芯片面积缩小一半。由这一关系可以算出前一代制程要比后一代大√2倍,所以能算出后一代大概数值。纵观整个处理器制程变化,除了少部分特殊的外,都遵循着这一规则。 近代制程的发展 2014 年底,三星宣布了世界首个 14nm FinFET 3D 晶体管进入量产,标志着半导体晶体管进入 3D 时代。发展到今天,三星拥有了四代 14nm 工艺,第一代是苹果 A9 上面的 FinFET LPE(Low Power Early),第二代则是用在猎户座 骁龙 820 和骁龙 625 上面的 FinFET LPP(Low Power Plus)。第三代是 FinFET LPC,第四代则是目前的 FinFET LPU。至于 10nm 工艺,三星则更新到了第三代(LPE/LPP/LPC)。 目前为止,三星已经将 70000 多颗第一代 LPE(低功耗早期)硅晶片交付给客户。三星自家的猎户座 8895,以及高通的骁龙 835,都采用这种工艺制造,而 10nm 第二代 LPP 版和第三代 LPU 版将分别在年底和明年进入批量生产。 手机芯片市场上已经进入了 10nm、7nm 处理器的白热化竞争阶段,而 14/16nm 制程的争夺也不过是一两年前的事。 总线位宽 总线位宽决定输入/输出设备之间一次数据传输的信息量,用位(bit)表示,如总线宽度为8位、16位、32位和64位。