- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
1、前言 。
随着 ChatGPT 的横空出世,全世界的目光都聚焦在了生成式 AI 上。本次将介绍 Transformer 的发展历史、基本原理,也是记录总结自己在学习路上的所得.
首先我想聊聊 NLP 的发展路线,这样对于后面的 transformer 可能会有更好的理解。自从计算机诞生之初,让计算机理解人类的语言,一直是计算机科学研究的前沿方向。早在1950年,A.M. Turing 就已经开创性的发表过一篇文章 。
Computing Machinery and Intelligence. 。
在文章中他提出了一个模仿游戏,一共有 a,b,c 三个玩家,让 c 来根据 a,b 的回答,来猜测他们相应的性别。a 的工作是用来迷惑,让 c 做出错误的判断,而 b 的工作是配合 c,让 c 尽可能的猜对。这时我们把 c 换成一台计算机,如果这次能和上次保持一样的结果,那么就说机器通过了图灵测试。这个问题还有一个变种,那就是让参与者同时对计算机还有人类来进行提问,基于他们的回答,让他们判断对方到底是计算机还是人类,如果参与者的平均误判超过了30%,同样我就指出计算机通过了图灵测试。虽然现在的 openai 一直没有公布 ChatGPT 是否通过了图灵测试,但是我相信应该是通过测试了的。 。
图灵提出了一个影响深远的问题: Can Machine Think?
所以这里引发了一个哲学的问题,What is thinking? 你首先需要定义什么是思考🤔?但是这问题太抽象了,这个问题慢慢简化总结为,机器能不能做到我们人类,我们思考者所做的事情?要解答这个问题,为了让计算机可以模仿我们人类,最大程度的接近人类的行为,理解我们人类的自然语言就是第一步。所以 NLP 自然语言处理,无疑是人工智能发展中至关重要的一环.
在1980到1990年代,人们提出了一个比较通用的语言模型的构想,可以服务于各行各业。这里的模型主要基于统计方法,基于马尔可夫假设,一个词语的出现概率,只和前面的 n 个词语有关,而与更早的词语或者说往后的词语无关。那么自然而然的就产生了二元模型(bigram模型) 。
其中产生的一个新的词语,只和它的现在的词语和前一个词语有关,和 ngram 模型跟它前 n-1 个词语有关系。但是随着 n 的增大,你所需要记录的 n 的概率就成指数上升了。所以为了应对这个问题,人们发明了CNN, RNN 这一类的卷积神经网络,通过层数的迭代,而可以学习到更多参数,让模型达到更好的效果.
。
2、Attention机制 。
Attention 这里如果用神经网络来解释的话,就是我们如果要识别人类语言,那么最开始的工作非常容易想到,那就是把目标语言和输入语言一对一的进行转化翻译,也就是 one input -> one output.
每个全连接网络负责1对1的输出,把每一个向量输入 fully-connected network 里面,其实这里也就是单纯的词向量转化比如 word2vec 模型。它可以把每次词语一一对应的进行翻译,把中文的“我”变成“me”,“你”变成“you”.
但是这样子只是解决了词义的转换,而语义的理解和解析,这种模型架构里还没有很好的解决。比如我输入 "i saw a saw" ,我期待的是机器能把第一个 saw 翻译成动词,而第二个 saw 翻译成名词。但是对于这种全连接网络来说是不可能做到的,因为 FC 接收的是同一个输入“saw”,它怎么可能会翻译成动词“看见”,和名词“锯子”呢?所以这里人们的解决方案是上面提到的 bigram 模型。也就是把它相相关联的词语向量都作为输入,进入 FC 中.
。
这里的输入是3个词向量,我们也就称其为 n=3 的的一个 sequnece window,显而易见的是如果 n 越大,那么这个模型的关联输入也就越大,那么它的输出也就是越准确,语义的理解自然也就越好了。但是如果某个任务的 n 需要膨胀到等于整个输入的 seq,也就是说需要把整个输入的话作为输入的 window,它才能表现的比较好的时候,那么势必会造成运算量的成倍增加,FC需要学习的参数可能就会非常多,而且这是一个不确定的值.
所以有没有一个更好的方法来考虑整个 FC 的 input 信息呢?所以这里的解决方式就是自注意力的机制 。
self-attention 专门处理所有的关联咨询,也就是 attention 层会考虑所有输入 input 并把他变成一个输出 ouput 给到 FC ,FC 负责处理某一个位置的资讯,并且将其进行转化为输出。所以 attention 机制是怎么运作的呢?
实际上在 attention 中主要是计算与每个输入之间的关联程度,比如 a1 分别和 a2, a3, a4 求 dotproduct 点积。如下 。
两个输入向量分别乘以两个不同的矩阵 Wq 和 Wk 得到 q 和 k 的新向量,然后再进行 dotproduct 得到新向量 α,这个向量就表示了输入的两个 a1 和 a2 向量的关联程度。在 attention 层内的计算关联方式则如下图 。
每个输入的向量都和 Wk 矩阵相乘然后计算出 k1 ~ k4 的关联向量,用输入的 a1 向量和 Wq 向量相乘,获取 q1 输入向量,这样 q1 分别和 k1 ~ k4 做 dotproduct 就可以获取到当前 a1 输入和每一个其他输入之间的联系了,最后在经过一层 soft-max 函数就可以让结果分布靠近 0 或者 1的值了,这样就可以准确的描述是否关联这样子的显式表达.
。
我个人的理解是这里的注意层,实际上可以分层很多层的,比如词性,积极词,消极词,语气词这些可以靠训练集去获取划分不同的注意层,然后通过训练集训练处每一个层的 Wk 和 Wq 矩阵,所以说 Wk 和 Wq 是可以让机器学出来的。接下来就是 b1 ~ b4 整个 attention 的输出是怎么获取到的 。
。
3、Attention计算流程 。
这里先看 b2 的输出计算流程,a2 会和其他的输入向量 a1,a3,a4 做关联计算,得到 a'21 , a'22,a'23,a'24 向量,然后再分别和向对应的 vn 向量做点积,这里的v是每个a向量乘以矩阵 Wv 得到的。 。
所有的计算都可以看成矩阵的计算,我们可以把整个输入 a1~a4 作为一个输入矩阵 I,得到同样长度的举证 Q 。
同样的道理。矩阵 K 和 V 可以这样子获取 。
而 a'nm 的计算可以看成是矩阵和向量的相乘,也就是 k1-4 组成一个只有一列的矩阵然后和 q1 向量相乘 。
所有的 a' 都可以组成一个新的矩阵,如下,这个矩阵里面存的就是每个 q 和 k 的 attention 分布 。
再对矩阵中的每一个做一下 soft-max 。
接着在根据 v 向量做矩阵相乘,就可以得到最终的输出 b1~b4 。
。
4、Multi-Head多头注意力的计算 。
多头注意力(Multi-head Attention)是一种在深度学习中用于处理序列数据的机制,最常见于自然语言处理(NLP)任务中,特别是在序列到序列(Sequence-to-Sequence)模型中。它是由"Transformer"模型中引入的一项关键技术.
在传统的注意力机制中,模型会对输入序列中的每个位置都计算一个权重,以便在编码阶段关注不同位置的信息。然而,对于长序列来说,单一的注意力可能不足以捕捉到不同位置之间的复杂依赖关系。为了更好地处理这种情况,多头注意力被提出.
多头注意力通过在注意力机制中引入多个独立的注意力头(Attention Head)来扩展模型的能力。每个注意力头都会学习到不同的注意力权重,从而使模型能够在不同的表示空间中进行关注。具体而言,它通过执行多次自注意力(Self-Attention)操作,每个自注意力操作都产生一个输出,而这些输出最终会被拼接在一起形成多头注意力的最终输出.
如下图也表示了在多头注意力中的计算:
这里使用 2 head 的方式,来计算两个头的注意力,方法是把三个向量 q、k、v 分别计算成两个 head 的注意力向量。然后在去做 attention 计算得到 bi,1。同样的道理我们通过第二个头的向量,可以计算出 bi,2。两者再乘以一个矩阵参数Wo就变成这一层的注意力 bi 了.
在注意力机制中,所有的关联计算都是矩阵进行的,也就是说可以并发的计算其关联性,但是并发也由此带来一些问题,就是没办法知道输入的位置信息。因为有可能输入的位置信息对于整个任务来说会比较重要,比如知道位置信息可以让机器知道某个产生的动词不宜出现在句首.
为了将位置信息引入到模型中,通常会使用位置编码(Positional Encoding)。位置编码是一种特殊的向量表示,用于表示输入序列中每个位置的相对位置信息。位置编码的目的是为了让模型在处理序列数据时能够区分不同位置的单词或标记,因为注意力机制本身并没有显式地包含序列中的位置信息.
在Transformer模型中,位置编码是通过添加一个位置嵌入向量(Positional Embedding Vector)来实现的。这个向量会与输入的词嵌入向量(Word Embedding Vector)相加,从而将位置信息融合到输入的表示中.
在《Attention is all you need》这个篇论文里使用的是正弦余弦编码(Sine and Cosine Positional Encoding):这是Transformer模型中使用的默认方法。它基于正弦和余弦函数的周期性特征来编码位置信息。位置编码向量的每个维度对应不同频率的正弦或余弦函数,根据位置索引的奇偶性来确定使用正弦函数还是余弦函数。这种编码方式能够让模型学习到序列中不同位置之间的相对距离.
不过 positional encode 也还是一个尚待研究的问题,就是你可以自定义位置表示函数.
上面的计算注意力过程可以用一张图来表示:
操作包括:
这里每一层 layer 中都会进行无数次"多头注意"的合并,并且通过累加 layer 层数,来提供更多的注意力方向的学习.
总的公式概括如下:
根据公式,在结合上面的操作来解释的话,那么其中第1步的线性变换参数为 , , ,第4步的线性变化参数为 ,第3步计算的次数为 h 。
。
5、Encoder 和 Decoder 。
大部分的序列处理模型都采用encoder-decoder结构,其中encoder将输入序列 (x1,x2,...,xn-1,xn) 映射到连续表示 z→=(z1,z2,...,zn-1,zn) ,然后decoder生成一个输出序列 (y1,y2,...,yn-1,yn) ,每个时刻输出一个结果。Transformer模型延续了这个模型,整体架构如上图所示。 。
Encoder有N=6层,每层包括两个 sub-layers
在每个 sub-layer 中都模拟了残差网络,每个 sub-layer 的输出都是大部分的序列处理模型都采用 encoder-decoder 结构,其中 encoder 将输入序列 (x1,x2,...,xn-1,xn) 映射到连续表示 z→=(z1,z2,...,zn-1,zn) ,然后 decoder 生成一个输出序列 (y1,y2,...,yn-1,yn) ,每个时刻输出一个结果:
其中Sublayer(x) 表示Sub-layer对输入 x 做的映射,为了确保连接,所有的sub-layers和embedding layer输出的维数都相同,也就是 self-attention 层的 layer 层数为,d-model=512。在图中的 Add 标识的是对每一层都会做残差计算,也就是:
在 encoder 之前的输入,其实还需要对属于的词做 embedding。单词的 Embedding 有很多种方式可以获取,例如可以采用 Word2Vec、Glove 等算法预训练得到,也可以在 Transformer 中训练得到。 。
Transformer 中除了单词的 Embedding,还需要使用位置 Embedding 表示单词出现在句子中的位置。像上面提到的,位置 Embedding 用 PE表示,PE 的维度与单词 Embedding 是一样的。PE 可以通过训练得到,也可以使用某种公式计算得到。在 Transformer 中采用了后者,公式的计算方式也很多,论文中使用的计算公式如下:
其中,pos 表示单词在句子中的位置,d 表示 PE的维度 (与词 Embedding 一样),2i 表示偶数的维度,2i+1 表示奇数维度 (即 2i≤d, 2i+1≤d)。使用这种公式计算 PE 有以下的好处:
将单词的词 Embedding 和位置 Embedding 相加,就可以得到单词的表示向量 x,x 就是 Transformer 的输入.
。
而在 Decoder 层,其实你发现图中的的过程和 encoder 的过程都差不多,只是多了个 Masked Multi-Head Attention 的机制.
在 Decoder 中也是N=6层,每层包括3个 sub-layers:
同时 Decoder 中的 self-attention 层需要进行修改,因为只能获取到当前时刻之前的输入,因此只对时刻之前的时刻输入进行attention计算,这也称为Mask操作.
。
。
6、Add & Norm 。
在看这部分的时候,我是非常懵逼的。完全看不懂这一层是个什么东西。所以读者在理解这一层的内容的时候可能需要参考其他的一些资料.
Add & Norm 层由 Add 和 Norm 两部分组成,其计算公式如下:
Add 指 X+MultiHeadAttention( X),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分,在 ResNet 中经常用到。因为在残差网络没有被应用之前,人们会发现一个训练的怪异现象,就是训练的次数少的模型比训练次数多的模型效果更好。因为其实每一层求解的梯度,随着层数越多,它会越来越小,如果深度较深,容易出现很多个小于1的数连乘,梯度消失(梯度趋近0)。而把输入加入到输出再经过一个 F(x) 中的话, 无论连乘是否会造成梯度消失,都有一个1作为保底,保证梯度不会消失。在做梯度后向传播时,即使长路梯度消失造成靠前的神经元参数得不到优化, 也可以通过 identity=X 抄近路优化。所以能使较深的网络训练起来.
Norm指 Layer Normalization,通常用于 RNN 结构,Layer Normalization 会将每一层神经元的输入都转成均值方差都一样的,这样可以加快收敛.
。
7、总结 。
Transformer 与 RNN 不同,可以比较好地并行训练。 Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding,否则 Transformer 就是一个词袋模型了.
Transformer 的重点是 Self-Attention 结构,其中用到的 Q, K, V矩阵通过输出进行线性变换得到.
Transformer 中 Multi-Head Attention 中有多个 Self-Attention,可以捕获单词之间多种维度上的相关系数 attention score.
。
。
Reference 。
[1] https://github.com/Kyubyong/transformer 。
[2] https://baijiahao.baidu.com/s?id=1651219987457222196&wfr=spider&for=pc 。
[3] https://arxiv.org/abs/1706.03762 。
[4] https://www.bilibili.com/video/BV1v3411r78R?p=3&vd_source=122a8013b3ca1b80a99d763a78a2bc50 。
[5] https://www.bilibili.com/video/BV1bV41177ap/?spm_id_from=333.880.my_history.page.click 。
[6] https://mp.weixin.qq.com/s?__biz=MzU1NTU3Njg4Mw==&mid=2247484435&idx=1&sn=64db5d053b967600546cecb8e22bf23a&chksm=fbd37f4fcca4f659ff16bfe04012bf3d59dae2c600502fa3b76db1f2ac7fd48f339ed7480008&scene=21#wechat_redirect 。
最后此篇关于机器学习从入门到放弃:Transfomer-现代大模型的基石的文章就讲到这里了,如果你想了解更多关于机器学习从入门到放弃:Transfomer-现代大模型的基石的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
Hive —— 入门 Hive介绍 Apache Hive是一款建立在Hadoop之上的开源数据仓库系统,可以将存储在Hadoop文件中的结构化、半结构化数据文件映射为一张数据库表,基于表提供了一
HBase —— 入门 HBase介绍 HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”
零:前端目前形势 前端的发展史 HTML(5)、CSS(3)、JavaScript(ES5、ES6):编写一个个的页面 -> 给后端(PHP、Python、Go、Java) ->
在本教程中,您将了解在计算机上运行 JavaScript 的不同方法。 JavaScript 是一种流行的编程语言,具有广泛的应用程序。 JavaScript 以前主要用于使网页具有交
我曾经是一个对编程一窍不通的小白,但因为对互联网世界的好奇心和求知欲的驱使,我踏入了编程的殿堂。在学习的过程中,我发现了一门神奇的编程语言——Python。Python有着简洁、易读的语法,让初学者能
嗨,亲爱的读者们! 今天我要给大家分享一些关于Python爬虫的小案例。你是否曾为了获取特定网页上的数据而烦恼过?或者是否好奇如何从网页中提取信息以供自己使用?那么,这篇文章将会给你一些启示和灵感。
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 8 年前。 Improv
我想创建一个像https://apprtc.appspot.com/?r=04188292这样的应用程序。我对 webrtc 了解一点,但无法掌握 google app-engine。如何为 java
我刚刚开始使用 Python 并编写了一个简单的周边程序。但是,每当我在终端中键入 python perimeter.py 时,都会收到以下错误,我不知道如何解决。 >>> python perime
Redis有5个基本数据结构,string、list、hash、set和zset。它们是日常开发中使用频率非常高应用最为广泛的数据结构,把这5个数据结构都吃透了,你就掌握了Redis应用知识的一半了
创建发布web项目 具体步骤: 1.在开发工具中创建一个dynamic web project helloword 2.在webContent中创建index.html文件 3.发布web应用到
如果你在 Ubuntu 上使用终端的时间很长,你可能会希望调整终端的字体和大小以获取一种良好的体验。 更改字体是一种最简单但最直观的 Linux 的终端自定义 的方法。让我
1. 前言 ADODB 是 Active Data Objects Data Base 的简称,它是一种 PHP 存取数据库的函式组件。现在 SFS3 系统 (校园自由软件交流网学务系统) 计划的
我对 neo4j 完全陌生,我很抱歉提出这样一个基本问题。我已经安装了neo4j,我正在使用shell“localhost:7474/webadmin/#/console/” 我正在寻找一个很好的例子
我正在阅读 ios 4 的核心音频,目的是构建一个小测试应用程序。 在这一点上,我对所有 api 的研究感到非常困惑。理想情况下,我想知道如何从两个 mp3 中提取一些样本到数组中。 然后在回调循环中
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是无关紧要的,因
我下载了 GNUStep并安装了它,但是我不确定在哪里可以找到 IDE。有谁知道什么程序可以用作 GNUStep IDE/从哪里获取它们?否则,有没有人知道有关如何创建和编译基本 GNUStep 程序
我正在尝试开始使用 Apache Solr,但有些事情我不清楚。通读tutorial ,我已经设置了一个正在运行的 Solr 实例。我感到困惑的是 Solr 的所有配置(架构等)都是 XML 格式的。
请问有没有关于如何开始使用 BruTile 的文档? 我目前正在使用 SharpMap,我需要预缓存切片以加快进程 最佳答案 我今天正在研究这个:)Mapsui项目site严重依赖 SharpMap
尽我所能,我无法让 CEDET 做任何事情。 Emacs 24.3。我下载了最新的 CEDET 快照。我从他的底部(不是这样)Gentle Introduction 中获取了 Alex Ott 的设置
我是一名优秀的程序员,十分优秀!