深度学习:自注意力机制详细笔记(嘎嘎通俗易懂,草履虫都直呼简单)

本文介绍了自注意力机制如何解决词向量表示中同词不同义的问题,通过计算词向量之间的相关度并赋予权重,实现对文本序列的深入理解和处理,如词性标注、情绪分析和翻译任务。作者还用通俗的例子和数学公式详细阐述了Q、K、V矩阵的操作过程。

自注意力机制(self-attention)

介绍

  • 当我们需要对一段文字进行处理的时候,我们需要将文字转变成一种可以放进神经网络里的形态

  • 主流的有两种方法可以完成这个,就是以下两种方法

    • one-hot编码

    • image-20211223102022382
    • word embedding

    • image-20211223103326484
  • 当我们将我们的词汇转变成了一个个的向量的时候,我们就可以将向量作为输入放入神经网络中进行训练了

  • 那么我们会有什么样的输出呢?

  • 有大概以下三种情况:

    • 输入多少个向量就输出多少个标签,也就是输入和输出的长度是一样的
      • image-20211223105203795
      • 举例来说,词性标注:
      • image-20211223105446168
      • 可以看到每个单词都有对应着它的词性,也就是输入输出长度是一样的
    • 无论输入多少向量,都只输出一个标签
      • image-20211223105819212
      • 例如:情绪分析,也就是判断一句话是积极还是消极的
      • image-20211223110011518
    • 无论输入的向量有多少类,由机器来自行判别输出多少标签
      • image-20211223110149137
      • 例如:翻译任务
      • 因为输入输出是不同的语言,所以他们之间的词汇肯定也不一样的
  • 假如我们要做一个词性标注任务的时候,我们通过上述方法获取到了我们所要标注的序列的词向量表示,然后我们可以直接将这些词向量逐个放到全连接层去训练,最后神经网络会给出一个个的输出

  • image-20211223113406815
  • 但是这样有一个非常大的弊端,就是对于上图所示,可以看出第一个saw是动词,而第二个saw是名词,但是由于他俩长得一样,所以他俩的词向量按道理来说就应该是一样的,从而导致他俩的输出就是一样的,但是实际上,我们想要第一个saw输出动词,第二个saw输出名词

  • 为了解决上述问题,所以这就要引出我们的注意力机制

  • 注意力机制在做什么呢?可以通过下图进行解释

  • image-20211223114750228
  • 当我们输入了一个向量,他会在考虑整个序列的情况下输出一个相对应的向量

  • 就像我们读书一样,我们在阅读的时候,读完全篇和只读到一半的时候对这本书的理解是不一样的,同理,我们也可以添加多个注意力机制的层,类比我们一本书读多遍一样,如下图所示

  • image-20211223115501559
  • 那么注意力机制这一层到底干了啥事捏?

具体运算

  • 如下所示
  • image-20211223172749850
  • 其中的a1,a2,a3,a4为我们的输入,b1是a1所对应的输出,也就是考虑了整个序列a1-a4才输出的对应a1的向量
  • 假如我们要找出a1所对应的向量b1,那么我们就先得看a1-a4里哪些和a1相关,也就是哪些部分对a1来讲重要,哪些不重要,这个相关度用α\alphaα来表示
  • alpha有几种计算方法,举最常用的一种计算方法:Dot - product
    • image-20211223174225715
    • 假如要计算两个向量的关联程度,那么就用该向量乘上一个Wq矩阵得出q,用另一个向量乘上wk矩阵得出k,再将q和k做一个内积运算,最后就能得出alpha
    • 这里的wq和wk均为训练中得出的参数
  • 用上述方法进行计算a1和其他所有向量的相关度,可得到下图
  • image-20211223175236133
  • 当求得a1对所有向量的相关度后,我们对它用一个softmax激活函数,用softmax激活函数的目的是为了表现出他们相关度的权重比例,也可以使用一些其他的激活函数,比如relu
  • 当我们做完上面步骤后,我们就可以知道哪些向量对a1相关性高,然后我们就可以通过alpha来抽取出重要的信息了
  • 我们对每一个向量a1-a4创建出v1-v4向量,v1=Wva1,v2=Wva2,v3=Wva3,v4=Wva4v_1=W^va^1,v_2=W^va^2,v_3=W^va^3,v_4=W^va^4v1=Wva1,v2=Wva2,v3=Wva3,v4=Wva4
  • 然后将每一个v乘上alpha撇再全部进行相加,就能得出b1,也就是b1=∑iα1,i′vib^1=\sum\limits_i\alpha_{1,i}'v^ib1=iα1,ivi
  • image-20211223204645334
  • 同理可得b2、b3、b4
  • image-20211223212742824

self-attention向量化

  • 首先我们有三个需要训练的矩阵Wq,Wk,WvW_q,W_k,W_vWq,Wk,Wv
  • 而且每个输入进来的词向量都有q, k, v
  • 可以看到每一个q1-q4都是是由a1-a4分别乘上Wq矩阵得来的
  • 于是我们可以将a1-a4放进一个矩阵I当中,然后用Wq*I就可以得到大矩阵Q,如下图所示
    • image-20211223215153805
  • 每个k和每个v同理
  • image-20211223215328905
  • 怎样一步计算出每个alpha呢
  • 通过之前的方法求是这样子的
    • image-20211223215837016
  • 可以看到α1,1−α1,4\alpha_{1,1}-\alpha_{1,4}α1,1α1,4都是用q1乘上k1-k4,于是我们直接将K.T乘q1,于是就可以一步求出所有的α1,1−α1,4\alpha_{1,1}-\alpha_{1,4}α1,1α1,4
  • image-20211223215916530
  • 同理可得,如果用q2乘上k1-k4这个向量,最终会得到α2,1−α2,4\alpha_{2,1}-\alpha_{2,4}α2,1α2,4
  • 于是我们可以直接用K.T和Q做乘法,就得到了所有α\alphaα矩阵,称它为A矩阵
  • 由于一般算出来的A矩阵内的值会变的比较大,这样在后续计算过程中容易形成梯度消失,所以在这里会让A矩阵除上一个dk\sqrt{d_k}dk,其中的dk是词向量的维度
  • 再将该矩阵套入softmax激活函数当中,就能得到所有的代表相关度的权重比A′A'A矩阵了
  • image-20211224101757385
  • 最后我们再将A′A'A和V乘起来就能得到我们I矩阵所对应的O,也就是a1-a4经过对整体序列进行学习后所输出的b1-b4
  • image-20211224144231065

整体流程

  1. image-20211224144559512
  2. image-20211224144617675
  3. image-20211224144636924

对Q、K、V的通俗解释:

  • 假如一个男生A,面对许多个潜在交往对象B1,B2,B3…,他想知道自己谁跟自己最匹配,应该把最多的注意力放在哪一个上。那么他需要这么做:
    1. 他要把自己的实际条件用某种方法表示出来,这就是Value
    2. 他要定一个自己期望对象的标准,就是Query
    3. 别人也有期望对象标准的,他要给出一个供别人参考的数据,当然不能直接用自己真实的条件,总要包装一下,这就是Key
    4. 他用自己的标准去跟每一个人的Key比对一下(Q*K),当然也可以跟自己比对,然后用softmax求出权重,就知道自己的注意力应该放在谁身上了

参考链接

  • https://www.bilibili.com/video/BV1v3411r78R/?spm_id_from=333.337.search-card.all.click&vd_source=97163a4e6e2704667559fdbd58743862
<think>我们被要求详细解释PHP封装协议,从基础到精通,使用简单易懂的语言。根据引用[1]和[3],我们知道PHP在Web开发中用于处理动态内容,并且经常需要与文件系统或网络资源交互。封装协议(Wrapper)是PHP中一个重要的特性,它允许我们像操作普通文件一样操作各种资源(如HTTP、FTP、压缩文件等)。计划回答结构:1.什么是封装协议?(基础)2.内置的封装协议有哪些?(列举并简要说明)3.如何使用封装协议?(包括示例)4.自定义封装协议(进阶)5.封装协议的应用场景注意:引用中并没有直接提到封装协议,但提到了PHP处理数据、存储和读取,封装协议正是处理这些资源访问的一种机制。我们将按照上述结构进行解释,并尽量使用简单易懂的语言和示例。</think>### PHP封装协议详解:从入门到精通 #### 一、基础概念(什么是封装协议?) 封装协议(Wrapper)是PHP中用于**统一访问不同资源**的抽象层。它允许开发者使用标准文件函数(如`fopen()`, `file_get_contents()`)处理各种资源类型,包括: - 本地文件系统(`file://`) - HTTP/HTTPS网页(`http://`) - FTP服务器(`ftp://`) - 压缩文件(`zip://`) - 数据流(`php://`)等 核心原理:通过**协议前缀**(如`http://`)告诉PHP使用对应的协议处理器解析资源路径,实现**统一操作接口**[^1]。 --- #### 二、常用内置封装协议详解 1. **`file://` (默认协议)** 访问本地文件系统: ```php $content = file_get_contents('file:///var/www/data.txt'); // 等效于(默认省略协议): $content = file_get_contents('/var/www/data.txt'); ``` 2. **`http://` & `https://`** 获取网络资源: ```php $html = file_get_contents('https://www.example.com/api'); // 发送带参数的GET请求: $data = file_get_contents('http://api.com?user=john&page=2'); ``` 3. **`php://` (PHP流协议)** - `php://input`:读取原始POST数据 ```php $rawData = file_get_contents('php://input'); ``` - `php://output`:直接写入输出缓冲 ```php fwrite(fopen('php://output', 'w'), 'Hello World'); ``` - `php://temp`:临时数据存储(内存不足时转存磁盘) ```php $temp = fopen('php://temp', 'r+'); fwrite($temp, 'Temporary data'); ``` 4. **`zip://`** 直接读取压缩包内文件: ```php // 读取 archive.zip 中 config.ini 的内容 $content = file_get_contents('zip://archive.zip#config.ini'); ``` 5. **`data://`** 嵌入Base64或URL编码数据: ```php $img = file_get_contents('data:image/png;base64,iVBORw0KGgo...'); ``` --- #### 三、高级应用:自定义封装协议 通过`stream_wrapper_register()`创建自定义协议处理器: ```php class MyWrapper { public function stream_open($path, $mode, $options, &$opened_path) { // 解析路径并建立连接 $this->position = 0; return true; } public function stream_read($count) { // 返回自定义数据 $data = "Custom data chunk"; $this->position += strlen($data); return $data; } } // 注册 myproto:// 协议 stream_wrapper_register('myproto', 'MyWrapper'); // 使用自定义协议 $data = file_get_contents('myproto://example-data'); ``` **关键方法**: - `stream_open()`:打开资源 - `stream_read()`/`stream_write()`:读写数据 - `stream_close()`:关闭资源 - `stream_seek()`:随机访问 --- #### 四、封装协议的应用场景 1. **统一资源访问** 用相同代码处理本地文件和网络资源: ```php function getContent($path) { return file_get_contents($path); // 自动识别协议 } ``` 2. **安全控制** 通过`allow_url_fopen`和`allow_url_include`配置限制危险协议访问。 3. **数据处理管道** 结合`stream_filter_append()`实现实时数据转换: ```php $stream = fopen('http://example.com/data.csv', 'r'); stream_filter_append($stream, 'convert.iconv.UTF-8/ASCII'); // 字符编码转换 ``` --- #### 五、安全注意事项 1. **禁用危险协议** 在`php.ini`中设置: ```ini allow_url_include = Off // 禁止直接包含远程代码 allow_url_fopen = On // 按需开启网络访问 ``` 2. **验证用户输入路径** 防止路径注入攻击: ```php $userPath = $_GET['path']; if (!preg_match('/^[a-z0-9:\/\.\-]+$/i', $userPath)) { die('Invalid path!'); } ``` > **最佳实践**:优先使用PHP内置协议(如`php://input`),避免直接操作`$_POST`处理二进制数据[^3]。 --- ### 相关问题 1. PHP封装协议与cURL在处理HTTP请求时有何性能差异? 2. 如何通过`php://filter`实现文件内容实时加密? 3. 自定义封装协议时如何实现目录遍历功能? 4. 为什么`allow_url_include`默认关闭?它可能引发哪些安全问题? [^1]: PHP封装协议允许统一访问不同资源类型,简化开发流程。 [^3]: PHP内置协议如`php://input`能安全处理原始数据流。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值