PowerLZY's Blog

本博客主要用于记录个人学习笔记(测试阶段)

安全知识图谱 | 绿盟

本文为安全知识图谱技术白皮书践行安全知识图谱,携手迈进认知智能》精华解读系列第四篇,介绍了如何利用知识图谱相关技术实现攻击路径调查,主要依据图表示学习与图谱推理实现攻击路径评估与路径修复。

三、知识图谱视角下的威胁评估

本文为安全知识图谱技术白皮书《践行安全知识图谱,携手迈进认知智能》精华解读系列第三篇——利用知识图谱助力攻击画像与威胁评估。主要利用知识图谱表示学习技术对攻击源或攻击行为进行威胁评估

3.1 攻击画像的痛点

攻击画像及风险评估是针对复杂的企业环境,利用采集到的日志或设备告警构建相关的威胁图谱,以图的形式来刻画攻击和攻击源,然后利用图的相关方法对攻击源和企业运行环境进行风险与威胁评估

企业为了应对网络威胁,通常会部署多个检测设备(如网络入侵检测系统IDS/IPS、全流量检测和网络应用防护系统WAF等)。由于检测设备规则的敏感性,企业安全运营每天需要面临大量威胁告警关联分析,海量告警远远超出了运营人员的事件排查能力。当前的攻击检测设备缺少对这种事件关联的分析能力,从而导致高误报问题,检测设备产生的告警日志通常是低级的、孤立的,安全运营人员需要丰富的安全知识和经验才能针对告警做出相关地研判,这进一步增加了企业安全运营的挑战。

因此,在安全大数据涌现与高级威胁对抗的大背景下,将安全知识图谱应用到企业智能安全运营中,对提升安全运营的自动化水平,减少对人力投入与专家经验的依赖,降低威胁分析与响应的周期等方面具有至关重要的作用。

3.2 知识图谱表示学习

在安全知识图谱的应用中,知识图谱表示学习具有关键作用。知识图谱表示学习通过让机器尽可能全面地学习知识,从而表现出类似于人类的行为,同时采用知识图谱表示方法来表示知识。知识图谱表示方法是研究计算机表示知识的可行性、有效性的一般方法,是把人类知识表示成机器能处理的数据结构和系统控制结构的策略。

安全知识图谱借鉴通用知识图谱的高效知识图谱表示方法,充分利用安全知识图谱中的知识,提升安全知识获取、融合和推理的性能。近年来,基于知识图谱表示学习方法主要分为两种:基于结构的知识图谱表示学习方法基于语义的表示学习方法

  • 基于结构的知识图谱表示学习方法大多采用三元组(head,relation,tail可简写为h,r,t)表示方法,具有一定的稀疏性,且无法进行语义层面的计算,主要方法有TransE[1]模型以及变体模型TransH[2],TransD[3],TransA[4]和KG2E[5]等。
  • 基于语义的表示学习方法往往存在参数多,处理大型知识图谱效率较差的问题,相对降低复杂度后仅能在部分场景中应用。基于语义的表示学习主要研究工作有RESCAL[6]以及其变体[7-9]。

随着知识图谱表示学习技术的不断发展,如何有效地获取全面的知识特征,更好地融合空间时间维度的知识图谱表示,同时避免知识的表示学习导致语义缺失的问题,成为此类研究的关键。

3.3 知识图谱助力企业威胁评估

img

在企业环境中,安全设备每日产生海量告警,这给安全分析带来了巨大挑战。为此,针对企业环境存在的问题,需要通过构建安全属性图模型来从不同维度对攻击源的威胁度进行评估。

威胁建模选用属性图对整个企业运行环境进行建模。这里以IP地址、端口、网段、告警、文件、日志等实体为图模型的节点边则表示实体之间的关系,关系通常分为显式关系与隐式关系。显式关系是通过对日志解析直接可以得到的关系,而隐式关系是通过数据挖掘方法得到的节点之间暗含的关联关系。

企业环境中,安全运营人员通常是基于告警信息识别攻击者与攻击行为。针对单一告警,很难做出预判,这就需要一种有效的关联告警上下文的评估方法来辅助安全分析和运维。为了挖掘告警之间的因果依赖关系,需要构建告警因果关联图,并利用图表示学习方法DeepWalk学习告警的向量表示,详细过程如图 2所示。

针对属性知识图谱模型,可以参考深度图神经网络的一些方法,如图自编码器等来实现威胁评估。图自编码器就是在编码过程中使用了图表示学习技术,这里采用TransE模型来学习图谱中节点与边的向量表示。TransE模型属于翻译模型:直观上,将每个三元组实例(head,relation,tail 简写为 h,r,t)中的关系relation看作从实体head到实体tail的transform,通过不断调整head、relation和tail的向量,使(h + r) 尽可能与 tail 相等,即 h + r = t,如图3所示。

参看文献

  • 安全知识图谱 - 知乎 :本文为安全知识图谱技术白皮书《践行安全知识图谱,携手迈进认知智能》精华解读系列

图神经网络:从入门到放弃:https://www.zhihu.com/column/c_1322582255018184704

图卷积:从GCN到GAT、GraphSAGE

图卷积:从GCN到GAT、GraphSAGE
image-20230311122935355

一、图卷积:从GCN到GAT、GraphSAGE

前言

图模型总体上可以分为两大类:一是random-walk游走类模型,另一类就是GCN、GAT等卷积模型了

下面就自己学习卷积图模型过程的一些模型GCN、GAT、GraphSAGE 及疑问总结一下,欢迎交流学习。

1.1 为什么出现GCN来处理图结构?

在图像领域,CNN被拿来自动提取图像特征的结构,但是CNN处理的图像或者视频数据中像素点(pixel)是排列成成很整齐的矩阵,虽然图结构不整齐(不同点具有不同数目neighbors),但是不是可以用同样的方法去抽取图的的特征呢?

于是就出现了两种方式来提取图的特征一是空间域卷积(spatial domain)二是频域卷积(spectral domain)。第一种方式由于每个顶点提取出来的neighbors不同,处理上比较麻烦,同时它的效果没有频域卷积效果好,没有做深究。因此,现在比较流行、工程上应用较多的为频域卷积

1.2 GCN的计算原理

GCN的卷积核心公式: [公式]

[公式] 分别是第l层、第l+1的节点,D为度矩阵,A为邻接矩阵,如下图。

img

GCN计算方式上很好理解,本质上跟CNN卷积过程一样,是一个加权求和的过程,就是将邻居点通过度矩阵及其邻接矩阵,计算出各边的权重,然后加权求和。 img

D负责提供权值的矩阵,邻接A矩阵控制应该融合哪些点, H表示上一层的embedding参数

结合上面两张图,动手算一算 [公式] ,能很清楚的看到,这个加权求和的卷积过程是怎么做的。

GCN 小结一下:

GCN首次提出了卷积的方式融合图结构特征,提供一个全新的视角

主要缺点

  • 问题1:融合时边权值是固定的,不够灵活。
  • 问题2:可扩展性差,因为它是全图卷积融合,全图做梯度更新,当图比较大时,这样的方式就太慢了,不合适。
  • 问题3:层数加深时,结果会极容易平滑,每个点的特征结果都十分相似

GAT就来解决问题1的,GraphSAGE就来解决这个问题2的,DeepGCN等一系列文章就来讨论问题3的。基本上,GCN提出之后,后续就是各路神仙打架了,都是针对GCN的各个不同点进行讨论改进了。

1.3 带attention的图注意网络GAT

attention这么流行,看完GCN就容易想到,GCN每次做卷积时,边上的权重每次融合都是固定的,那能不能灵活一点,加个attention,让模型自己去学,那GAT就来干这个事了。

img

结合下面这两各公式,看看这个attention是怎么定义的。 [公式]

img

[公式] 表示第i个点与第j个点之间的attention系数,是node feature,其他a、W的为模型参数。

[公式] 就是通过计算 [公式] ,在经过Normalize处理一下得到。

得到各条边的 [公式] 之后,第i个点的融合attention过后的node feature可以表示下面这个公式,实质上还是一个加权的feature求和过程,只是每次融合中的权重系数是随模型训练学习的,最后在经过一个非线性的激活函数去做对应的任务。

img

在这个基础上,文中还提到了,为了使attention机制更具扩展性,定义multi-head attention机制(K代表K个attention head),去做attention权重的计算,然后concat起来,得到node feature。

img

当在网络最后一层时,concat输出的维度就node feature太大,不太合理,就改用累加再平均,然后输出,做具体任务。

img

以上就是第一个图中右边示意的结构了。

GAT 小结一下

GAT中的attention机制还是很直观的,通过给每条边加了一个模型可学习的系数 [公式] ,进行带attention系数的node feature融合,使得在做卷积融合feature的过程,能够根据任务调整模型参数,变得自适应使得效果更好。

今年还出了一篇专门讨论GAT的工作的,讨论attention到底学到了的是什么,感兴趣的可以去看看How Attentive are Graph Attention Networks?

1.4 可扩展的图网络Graph-SAGE

前面说到,GCN中做卷积融合是全图的,梯度是基于全图更新,若是图比较大,每个点邻居节点也较多,这样的融合效率必然是很低的。于是GraphSAGE出现了。

在提GraphSAGE前,先解释下transductive learning、inductive learning的概念,这也是GraphSAGE与其他图模型的区别。

  1. transductive是说要预测的数据在训练时模型也能看到。进一步解释一下,就是说训练前,构建的图结构已经是固定的,你要预测的点或边关系结构都应该已经在这个图里了,训练跟预测时的图结构都是一样的。
  2. inductive是说要预测的数据在训练时模型不用看到,也就是我们平常做算法模型的样子,训练预测时的数据是分开的,也就是上面说的可以图结构不是固定的,加入新的节点。

GraphSAGE就是inductive的模式,GraphSAGE提出随机采子图的方式去采样,通过子图更新node embedding, 这样采出的子图结构本身就是变化,从而让模型学到的是一种采样及聚合的参数的方式,有效解决了unseen nodes问题,同时避免了训练中需要把整个图的node embedding一起更新的窘境,有效的增加了扩展性。

img

具体的思想就是分三步:

  1. 采子图:训练过程中,对于每一个节点采用切子图的方法,随机sample出部分的邻居点,作为聚合的feature点。如上图最左边,对于中心点,采两度,同时sample出部分邻居节点组成训练中的子图。
  2. 聚合:采出子图后,做feature聚合。这里与GCN的方式是一致的,从最外层往里聚合,从而聚合得到中心点的node embedding。聚合这里可操作的地方很多,比如你可以修改聚合函数(一般是用的mean、sum,pooling等),或增加边权值都是可以的。
  3. 任务预测 得到node embedding后,就可以接下游任务了,比如做node classification,node embedding后接一个linear层+softmax做分类即可。

具体到代码实现思路上,也是与上述思路高度一致。

img

也是针对每一个node采出子图,然后进行聚合,最后得到node embedding。

举例:假设中心点为v,采点v的K度子图

  1. 采出中心点v的K层子图中邻居点u,然后一层层聚合,聚合得到邻居节点node feature [公式]
  2. 中心点与它的邻居点通过concat方式聚合, [公式] ,在经过一个非线性函数处理。
  3. 最后再Normalize归一化处理一下,得到最后的node embedding
  4. 以上述这种方式,从最外层往里聚合,一直聚合到最初的中心点v,点v的node embedding 就更新完成了。

GraphSAGE小结一下:

GraphSAGE主要解决了两个问题:

  1. 解决了预测中unseen nodes的问题,原来的GCN训练时,需要看到所有nodes的图数据。
  2. 解决了图规模较大,全图进行梯度更新,内存消耗大,计算慢的问题

以上两点都是通过一个方式解决的,也就是采子图的方式,由于采取的子图是局部图且是随机的,从而大大增加模型的可扩展性,但这也有一个问题可以思考一下,这个随机采子图的方式是合理的吗?这种方式会不会损失掉部分这个图的node信息,欢迎交流学习。

对以上感兴趣的还可以看看Cluster-GCN,它通过图聚类的方式去划分子图分区,从而,进一步提高了计算效率。

  • DeepWalk【图神经网络论文精读】:https://www.bilibili.com/video/BV1o94y197vf/?spm_id_from=pageDriver&vd_source=29387dc08d18f642078183a6816e93e8
  • https://www.zhihu.com/column/c_1322582255018184704
  • 图神经网络—基于随机游走的早期研究(一):DeepWalk & Node2Vec:https://zhuanlan.zhihu.com/p/343041065

一、DeepWalk

image-20230311111100589

DeepWalk[1]是一篇14年的文章,它极大的受到word2vec[4]的启发。

在图机器学习的早期研究中,人们主要希望模型能够捕捉到节点之间的连接关系。那在word2vec中人们希望模型学习的是什么呢?没错,就是token与token之间的"连接性"。word2vec的skip-gram (with negative sampling) 模型本质上在回答:给定两个token,它们是否有在同一个context window中出现过?从图的角度来说,word2vec的任务目标可以翻译为:给定两个节点,判断它们是否有任意k阶的连接关系,其中k即为context window的大小。

因此,一个自然的想法就是,能不能利用word2vec训练模型,来捕捉图数据结构中节点之间的连接关系呢?出于此intuition,研究者们提出了DeepWalk。

1.1 Overview of the Model

DeepWalk非常简单粗暴,它基本上就是以下两个模块的结合,甚至各个模块都没有太大的改动:

  • 基于随机游走在图上进行游走采样,将节点邻接结构映射成序列结构。
  • 利用采样得到的序列,训练Skip-gram模型,使习得的表达能够捕捉节点间的连接性。

第一部分:原论文提出在进行随机游走时,每次从给定起点出发,不停的利用uniform sampling来采样邻居进行游走,直到该采样序列长度达到给定最大长度。因为每步游走仅需做一次uniform sampling,所以DeepWalk可以在不需要额外存储计算的情况下,在O(1)的时间内采样一步随机游走。

假设给定模型l的walk length,并且以每个节点为起点进行k次游走,那么总计会生成k|V|个长度为l的序列。最终完成整张图的随机游走的时间复杂度为O(lk|V|)。

第二部分:原论文提出基于Hierarchical Softmax (HS) 来训练一个Skip-gram模型。但从今天的眼光来看,HS已经逐步退出历史的舞台。人们现在往往直接在GPU上计算softmax,并不再特别需要HS加速softmax计算。并且,若softmax计算量难以接受,人们也往往利用Noise Contractive Estimation (NCE) or Negative Sampling (NS),来规避softmax的使用。因此,今天人们更常利用skip-gram with negative sampling训练DeepWalk/Node2Vec模型。

image-20230311113705926
image-20230311114014622

如何利用多杀软结果提取恶意软件标签

  • secrss.com/articles/33242
  • 通过多杀软结果挖掘得到更多关于样本的上下文信息是一个经久不衰的研究点

从杀软标签中自动提取标签是对大量样本进行分类和索引的有效方法。此前的 AVClass 和 Euphony 等工作已经能够从杀软标签中提取家族名称。而杀软标签包含有价值的信息不止是家族,还有类别(例如勒索软件、下载器、广告软件)和行为(例如垃圾邮件、DDoS、信息窃取)等。

恶意软件属性枚举和表征(MAEC)等标准定义了一种用于共享恶意软件分析结果的语言。然而,由于使用严格的受控词汇表(即预定义标签),这些词汇表可能并不总是符合分析师的需求,需要频繁更新,并且必然是不完整的,因此它们的采用率很低,例如,MAEC 中就不包括恶意软件家族

杀软引擎有一些通用标签,标明恶意软件的类别、家族、文件属性和动态行为。也有一个通用标签(malicious, application)和特定杀软引擎(deepscan, cloud)才有的,或者是恶意软件家族变种(aghr, bcx)标签。

工作设计

AVClass2 的目标是分辨提供有用信息的 Token,识别不同杀软引擎 Token 之间的关系,最后转换成分类法的标签。

AVClass2 是一个自动恶意软件标记工具,可为样本提取一组干净的标签。AVClass2 附带一个默认的开放分类法,可将杀软标签的名词分类到不同的类别,捕获标签之间关系的默认标记规则和扩展规则。AVClass2 有一个更新模块,使用标签共现来识别标签之间的关系,以在杀软厂商引入新标签时保持工具更新。

AVCalss2 基于 AVClass 进行了最少必要更改,继承了 AVClass 的主要特点:可扩展性好、杀软引擎独立性好、平台无关性好、不需要样本文件、开源。

基本架构如下所示:

img

主要是两大模块:Labeling 模块和 Update 模块。

  • Labeling 模块将多个杀软的标签结果作为输入,同时可以提供使用的杀软引擎列表,如果不提供默认使用所有杀软引擎的标签结果。给出一组标记规则、一个可选扩展规则以及可将标签分类合并的分类法。
  • Update 模块将共现统计、标记规则、扩展规则和分类法作为输入。识别标签之间的强关联,生成新的标记规则、扩展规则和分类法。

标签

Labeling 模块分为三部分:标记化(Tokenization)、标记(Tagging)、扩展(Expansion)。

  • 标记化(Tokenization)将每个杀软标签拆分为一个 Token 列表。标记化是与厂商无关的,VirusTotal 现在已经支持超过一百个引擎。每个厂商的格式也不完全一致,经常修改。如果尝试为引擎的标签定义格式或者自动推断格式,可能会得到数百个格式模板。不仅选择正确格式进行解析很困难,遇到未知格式的标签还可能出现错误。
  • 标记(Tagging)会用分类法中的一组 Tag 替换杀软标签中的 Token,即将杀软标签中的 Token 转换为分类法中概念明确的 Tag。大多数标记规则会映射到单个标记,例如 downldr、dloader 会被映射到 downloader 上;finloski 和 fynloski 会被映射到 darkkomet 上。也存在一对多的关系,比如 ircbot 会映射到 irc 和 bot。
  • 扩展(Expansion)用于处理未知的 Token,使用扩展规则定义一个标签隐含一组其他标签。例如有 95% 的标签在带有 virut 的同时也带有 virus,virut 就会是 virus 的扩展规则。扩展规则一共分为两类,一类是类内规则一类是类间规则,处理顺序是先类间规则再类内规则。类内规则由分类法中统一类别的父子关系隐式定义,例如 adware 是 grayware 的子类。类间规则由分类法中不同类别的隐式关系定义,例如 filemodify 行为归属于 virus 类。

整体流程如下所示:

img

分类法

行为、类型、文件属性和家族

分类法定义了标记规则使用的标签之间的父子关系。AVClass2 的分类法被构造为树型结构,默认包含四个类型(行为 BEH、类型 CLASS、文件属性 FILE、家族 FAM)。

img

标签是自上而下进行描述的,例如 CLASS:grayware:adware。

自带的默认分类法如下所示:

img
  • 行为:例如 infosteal(信息窃取)、sendssms(发送短信)、spam(垃圾邮件)、mining(挖矿)等
  • 类别:例如 worm(蠕虫)、virus(病毒)、ransomware(勒索)、downloader(下载)。Trojan 问题很大,原来特指某类,后来变成了默认类型,故而认为 Trojan 为通用 Token。
  • 文件属性:例如文件类型(例如 pdf、flash、msword)、操作系统(android、linux、windows)、壳类型(pecompact、themida、vmprotect)、编程语言(autoit、delphi、java)
  • 家族:默认分类家族不包括父子关系

Update

为了新的家族、新的行为都能够通过 AVClass2 自动更新,需要根据共现关系识别数据集中的强关系,迭代更新到规则中。基于 VAMO 引用的杀软标签共现关系,在 AVClass 和 Euphony 中也用于合并家族。(Roberto Perdisci and U. ManChon. 2012. VAMO: Towards a Fully Automated Malware Clustering Validity Analysis. In Annual Computer Security Applications Conference.)。共现的判断需要确定阈值,以AVClass的经验选择 𝑛 = 20 和 𝑇 = 0.94。

img

工作准备

使用 11 个数据集进行评估,数据集之间存在重复(例如 Drebin 是 MalGenome 的超集)但并未去重,为了便于单独映射结果。

img

工作评估

通过在 4200 万恶意样本中评估 AVClass2,并且与 AVClass 和 Euphony 进行了比较,测试其效果。

标记覆盖

标签覆盖率如下所示:

img
  • 选择至少四个杀软引擎标记为恶意的样本,最近的研究表明 2-14 个杀软引擎判定的筛选范围有利于平衡精度和召回率。

    Shuofei Zhu, Jianjun Shi, Limin Yang, Boqin Qin, Ziyi Zhang, Linhai Song, and Gang Wang. 2020. Measuring and Modeling the Label Dynamics of Online Anti-Malware Engines

  • AVClass2 可以为 89% 以上的样本提取至少一个标签,无法提取的基本都是检测结果较少的文件

  • 测试时可识别的 975 个标签已经超过了 VirusTotal 的 335 个标签,VirusTotal 的标签基本都对应于文件属性和样本行为。其中,与 VirusTotal 重合的共有 259 个标签

每个类别 TOP10 的标签如下所示:

img
  • 超过 10% 的样本对应了四个类别的标签。例如 CLASS:grayware:adware:multiplug 是通过浏览器插件进行广告推广的软件。
  • Trojan 如果不是通用Token被剔除的话,会被分配给 86% 的样本。
  • 最多的家族是 vobfus,占到了总数的十分一。
  • 除了恶意软件外,grayware 也是常见家族的大赢家(loadmoney、softpulse、installererex、domaiq、firseria)。

知识更新

使用 Andropup 数据集举例说明 update 模块的用法。首次测试观察到 65% 的样本包含一个未知标签,执行 update 模块后会下降到 16%。

img

共现关系共计 30107 个,有归属于 11 类的 968 个强关联。96% 的强关联涉及未知 Token,从中自动识别出了 486 个新类别实体、216 个新标记规则、461 个扩展规则。处理完成后只剩下 3 个强关联不能自动更新,需要手动处理。

手动检查了更新的内容,1163 个更新中只有 11 个(0.9%)是需要调整的、3 个是需要手动检查的。

执行速度

img
  • AVClass2 和 AVClass* 在四个数据集中获得了最好的 F1 成绩,而 AVClass 在 Malheur 上排名第一。
  • AVClass 最快,AVClass2 其次,Euphony 则比 AVClass 慢 7 到 34 倍。对特大的数据集 Euphony 会很慢或者因内存不足而崩溃。

工作思考

AVClass2 对通过多杀软结果处理实现提取 VirusTotal 类的 Tag 标签很有帮助,实际上没有必要合并成一个完整的分类法的语法树结构。通过多杀软结果挖掘得到更多关于样本的上下文信息是一个经久不衰的研究点,本文作者也在 AVClass 的基础上再进一步做出了 AVClass2,==两个工作分别发表在 RAID 2016 与 ACSAC 2020 都是很不错的成绩。==

像 AVClass++ 指出的那样,AVClass 在杀软引擎结果较少时效果较差,那些新提交到 VirusTotal 的样本会因此效果较差。另外就是杀软结果中也存在随机生成类的结果,这两点实际上都可能是未来在这条路上的研究进展,AVClass++ 的解决方法是否很优则见仁见智,但仍不失为一个极佳的参考。

深度学习PHP webshell查杀引擎demo

  • https://www.cdxy.me/?p=788
  • ==Webshell研究综述:检测与对抗技术的动态博弈进展==:https://zhuanlan.zhihu.com/p/259985000
传统webshell查杀思路
  • 规则系统
  • 旁路执行
  • 沙箱
基于机器学习/深度学习的webshell查杀引擎,通过专家知识提取特征训练分类器,其结果受样本、特征、结构等多种因素影响。
特征维度:
  • 统计特征 (信息熵/重合指数/最长词/可压缩比)
  • 历史数据特征 (计算单个文件的落盘时间/文件创建进程/文件类型/代码风格/权限和同目录下其他文件的"距离")
  • OP指令层特征 (指令/调用链/参数文本特征)
  • 动态特征 (文件读写/网络连接,可依靠沙箱或旁路执行能力解决编码混淆类case)
  • 文本语义 (n-gram/TF-IDF/word2vec/CNN/RNN)

恶意软件检测

一、论文

  • MALWARE综述
    • 论文分析:https://powerlzy.github.io/posts/2GBZRTM/
  • Deep Learning for Android Malware Defenses: a Systematic Literature Review
    • 项目地址:https://github.com/yueyueL/DL-based-Android-Malware-Defenses-review
    • 项目概述:ACM Computing Surveys.+安卓恶意软件检测;

二、开源项目

2.1 论文复现

  • TrustCom2021:Malware Classification by Learning Semantic and Structural Features of Control Flow Graphs
    • 项目地址:https://github.com/Bowen-n/MCBG
    • 项目概述:通过学习控制流图的语义和结构特征进行恶意软件分类的源代码
  • Windows-malware-detection
    • 项目地址:https://github.com/strugglingeagle/Windows-malware-detection
    • 项目概述:基于HIN的Windows恶意软件检测模型
  • Learning from Context: Exploiting and Interpreting File Path Information for Better Malware Detection
    • 项目概述:Sophos公司:(ember+路径上下文)
    • 论文分析:https://powerlzy.github.io/posts/2Z5SQWP/
  • Quo Vadis: Hybrid Machine Learning Meta-Model Based on Contextual and Behavioral Malware Representations
    • 项目地址:https://github.com/dtrizna/quo.vadis
    • 项目概述:基于Windows内核仿真的混合机器学习恶意软件检测模型(动态分析+ember+路径上下文)
    • 论文分析:https://powerlzy.github.io/posts/2Z5SQWP/
  • Malware Detection based on API Sequence Intrinsic Features
    • 项目地址:https://github.com/friendllcc/Malware-Detection-API-Sequence-Intrinsic-Features
    • 项目概述:沙箱API序列特征
  • Learning-Based-PE-Malware-Family-Classification-Methods
    • 项目地址:https://github.com/nikeluobinxiaoma/Learning-Based-PE-Malware-Family-Classification-Methods
    • 项目概述:天大同学实验代码,包含三类基于学习的PE恶意软件家族分类方法,分别是基于图像的、基于二进制的和基于反汇编的方法,还有一种检测恶意软件类间漂移的方法。
  • MalConv-Pytorch
    • 项目地址:https://github.com/PowerLZY/MalConv-Pytorch
    • 项目概述:基于字节序列的恶意软件检测研究
  • CADE: Detecting and Explaining Concept Drift Samples for Security Applications
    • 项目地址:https://github.com/whyisyoung/CADE
    • 项目概述:Code for our USENIX Security 2021 paper
  • Ember:Elastic Malware Benchmark for Empowering Researchers
    • 项目地址:https://github.com/elastic/ember
    • 项目概述:2038维,静态分析+LightGBM
  • When Malware is Packin’ Heat; Limits of Machine Learning Classifiers Based on Static Analysis Features
    • 项目地址:https://github.com/ucsb-seclab/packware
    • 项目概述:打包器对仅使用静态分析的基于机器学习的恶意软件分类器的影响
  • Dynamic Malware Analysis with Feature Engineering and Feature Learning
    • 项目地址:https://github.com/joddiy/DynamicMalwareAnalysis
    • 项目概述:服务器上有源码

2.2 开源工具

  • DeepMalwareDetector
    • 项目地址:https://github.com/islem-esi/DeepMalwareDetector
    • 项目概述:一个深度学习框架,用于分析Windows PE文件以检测恶意软件。
image
  • 恶意软件沙箱
    • CAPE: Malware Configuration And Payload Extraction
      • 项目地址:https://github.com/kevoreilly/CAPEv2
    • Bold-Falcon:https://github.com/PowerLZY/Bold-Falcon

三、算法比赛

  • DataCon2019大数据安全分析比赛冠军思路分享 - 杨航锋的文章
    • 知乎 https://zhuanlan.zhihu.com/p/64252076
  • DataCon2020大数据安全分析大赛,🏆【方向五】恶意代码分析冠军源码和方案。
    • 项目地址:
      • https://github.com/yuriufo/DataCon2020;
      • https://datacon.qianxin.com/#integral
  • 2021 CCF BDCI 数字安全公开赛 - 基于人工智能的恶意软件家族分类
    • 比赛官网:https://www.datafountain.cn/competitions/507
    • 项目地址:https://github.com/PowerLZY/malware_classification_bdci

四、工业界应用

  • McAfee: https://www.mcafee.com/enterprise/en-us/security-awareness/endpoint/what-is-next-gen-endpoint-protection.html

  • Vmware:https://www.carbonblack.com/resources/definitions/what-is-next-generation-antivirus/

  • CrowdStrike:https://www.crowdstrike.com/epp-101/next-generation-antivirus-ngav/

  • Avast:https://www.avast.com/technology/malware-detection-and-blocking

  • 卡巴斯基:https://media.kaspersky.com/en/enterprise-security/Kaspersky-Lab-Whitepaper-Machine-Learning.pdf

    • 论文分析:https://powerlzy.github.io/posts/3JVWT1D/
  • 火眼:https://www.fireeye.com/blog/threat-research/2019/03/clustering-and-associating-attacker-activity-at-scale.html

  • Linux沙箱 | 阿里云恶意文件检测平台开放Linux二进制文件检测:https://www.anquanke.com/post/id/276349#10006-weixin-1-52626-6b3bffd01fdde4900130bc5a2751b6d1

恶意软件逃逸攻击

一、论文

  • A survey on practical adversarial examples for malware classifiers
    • 论文分析:https://powerlzy.github.io/posts/17HFC4S/
    • 项目概述:恶意软件的对抗样本综述
  • Awesome Resources for Adversarial Attacks and Defenses for Windows PE Malware Detection
    • 项目地址:https://github.com/ryderling/adversarial-attacks-and-defenses-for-windows-pe-malware-detection
    • 项目概述:针对Windows PE恶意软件检测的对抗性攻击和防御的精心策划的资源列表。别人总结的到2021年之前。
  • Adversarial Training for Raw-Binary Malware Classifiers
    • 论文地址:https://www.usenix.org/conference/usenixsecurity23/presentation/lucas
    • 项目概述:2023 USENIX Security-原始二进制恶意软件分类器的对抗性训练
  • Adversarial Attacks and Defenses in Deep Learning: From a Perspective of Cybersecurity
    • 论文地址:https://dl.acm.org/doi/10.1145/3547330
    • 项目概述:ACM Computing Surveys-系统地理解对抗性攻击提供第一个分析框架
  • Black-Box Adversarial Attacks Against Deep Learning Based Malware Binaries Detection with GAN
    • 论文分析:https://powerlzy.github.io/posts/35K4AXJ/
    • 项目概述:GAPGAN
  • 深度学习赋能的恶意代码攻防研究进展 (2021 计算机学报)
  • Intriguing Properties of Adversarial ML Attacks in the Problem Space (2020 S&P)
    • 项目概述:重点理解问题空间定义和搜索策略
  • Functionality-Preserving Black-Box Optimization of Adversarial Windows Malware (2021 TIFS)
    • 论文分析:https://powerlzy.github.io/posts/3SMQYQP/
    • 项目概述:攻击被形式化为一个有约束的最小化问题,这也使得规避检测的概率和注入的有效负载的大小之间的权衡得到优化
  • Adversarial EXEmples: A Survey and Experimental Evaluation of Practical Attacks on Machine Learning for Windows Malware Detection

二、项目

2.1 开源论文

  • MALGAN: Generating Adversarial Malware Examples for Black-Box Attacks Based on GAN
    • 项目地址:https://github.com/PowerLZY/MalGAN
    • 项目概述:动态分析+逃逸攻击
  • Evading Machine Learning Malware Detection
    • 项目地址:https://github.com/drhyrum/gym-malware
    • 项目概述:blackhat 2017,强化学习
  • MAB-Malware
    • 项目地址:https://github.com/weisong-ucr/MAB-malware
    • 项目概述:MAB恶意软件是一个开源的强化学习框架,用于生成PE恶意软件的AE。
  • dversarial Deep Ensemble: Evasion Attacks and Defenses for Malware Detection
    • 项目地址:https://github.com/deqangss/adv-dnn-ens-malware
    • 项目概述:对抗性深度集成;Android恶意软件变体

2.2 开源工具

  • secml-malware
    • 项目地址:https://github.com/pralab/secml_malware
    • 项目概述:针对机器学习Windows恶意软件检测器创建对抗性攻击
  • CleverHans
    • 项目地址:https://github.com/cleverhans-lab/cleverhans
    • 项目概述:用于构建攻击、构建防御和基准测试的对抗性示例库

三、比赛

  • 2021 Machine Learning Security Evasion Competition
    • 比赛链接:
      • https://mlsec.io/;
      • https://cujo.com/announcing-the-winners-of-the-2021-machine-learning-security-evasion-competition/

Attention-注意力机制

注意力机制

如何理解attention中的Q,K,V? - 林亿的回答 - 知乎 https://www.zhihu.com/question/298810062/answer/2274132657

Self-attention中dot-product操作为什么要被缩放:https://www.zhihu.com/question/339723385/answer/782509914

一、注意力机制是什么

假设有一天热爱绘画的你决定去户外写生,你来到一片山坡上,极目远去,心旷神怡。头顶一片蔚蓝,脚踩一席草绿,远处山川连绵,眼前花草送香,暖阳含羞云后,轻风拂动衣襟,鸟啼虫鸣入耳,美景丹青共卷。

你集中精神,拿起画笔将蓝天、白云、青草等等这些元素,按照所思所想纷纷绘入画板。在绘画的过程中,你会持续地关注你构思到画板上的元素(比如蓝天,白云),而不会太多关注那些其他的元素,比如风,虫鸣,阳光等等。即你的精神是聚焦在你关心的那些事物上,这其实就是注意力的体现,这种有意识的聚焦被称为聚焦式注意力(Focus Attention)。

在深度学习领域,模型往往需要接收和处理大量的数据,然而在特定的某个时刻,往往只有少部分的某些数据是重要的,这种情况就非常适合Attention机制发光发热。

image-20220529190526010

举个例子,上图展示了一个机器翻译的结果,在这个例子中,我们想将”who are you”翻译为”你是谁”,传统的模型处理方式是一个seq-to-seq的模型,其包含一个encoder端和一个decoder端,其中encoder端对”who are you”进行编码,然后将整句话的信息传递给decoder端,由decoder解码出”我是谁”。在这个过程中,decoder是逐字解码的,在每次解码的过程中,如果接收信息过多,可能会导致模型的内部混乱,从而导致错误结果的出现。

我们可以使用Attention机制来解决这个问题,从图中可以看到,在生成”你”的时候和单词”you”关系比较大,和”who are”关系不大,所以我们更希望在这个过程中能够使用Attention机制,将更多注意力放到”you”上,而不要太多关注”who are”,从而提高整体模型的表现。

备注:在深度学习领域,无意识的显著性注意力更加常见。

Attention机制自提出以来,出现了很多不同Attention应用方式,但大道是共同的,均是将模型的注意力聚焦在重要的事情上。本文后续将选择一些经典或常用的Attention机制展开讨论。

二、经典注意力机制

2.1 用机器翻译任务带你看Attention机制的计算

单独地去讲Attention机制会有些抽象,也有些枯燥,所以我们不妨以机器翻译任务为例,通过讲解Attention机制在机器翻译任务中的应用方式,来了解Attention机制的使用。

什么是机器翻译任务?以中译英为例,机器翻译是将一串中文语句翻译为对应的英文语句,如图1所示。

image-20220529201640683

图1展示了一种经典的机器翻译结构Seq-to-Seq, 并且向其中添加了Attention计算。Seq-to-Seq结 构包含两个部分:Encoder和Decoder。其中Encoder用于将中文语句进行编码, 这些编码后续将提 供给Decoder进行使用; Decoder将根据Encoder的数据进行解码。我们还是以图1为例详细解释一 下Decoder的解码过程。 更明确的讲, 图1展示的是生成单词"machine"时的计算方式。首先将前一个时刻的输出状态 \(q_{2}\) 和 Encoder的输出 \(h=\left[h_{1}, h_{2}, h_{3}, h_{4}\right]\) 进行Attention计算, 得到一个当前时刻的 context, 用公式可 以这样组织: \[ \begin{aligned} {\left[a_{1}, a_{2}, a_{3}, a_{4}\right] } &=\operatorname{softmax}\left(\left[s\left(q_{2}, h_{1}\right), s\left(q_{2}, h_{2}\right), s\left(q_{2}, h_{3}\right), s\left(q_{2}, h_{4}\right)\right]\right) \\ \text { context } &=\sum_{i=1}^{4} a_{i} \cdot h_{i} \end{aligned} \] 我们来解释一下, 这里的 \(s\left(q_{i}, h_{j}\right)\) 表示注意力打分函数, 它是个标量, 其大小描述了当前时刻在这 些Encoder的结果上的关注程度, 这个函数在后边会展开讨论。然后用softmax对这个结果进行归一 化, 最后使用加权评价获得当前时刻的上下文向量 context。这个context 可以解释为:截止到当前 已经有了"I love", 在此基础上下一个时刻应该更加关注源中文语句的那些内容。这就是关于 Attention机制的一个完整计算。

最后, 将这个context和上个时刻的输出”love"进行融合作为当前时刻RNN单元的输入。图1中采用了继续融合上一步的输出结果, 例如上述描述中融合了"love", 在有些实现中, 并没 有融入这个上一步的输出, 默认 \(q_{2}\) 中已经携带了"love"的信息, 这也是合理的。

2.2 注意力机制的正式引入

前边我们通过机器翻译任务介绍了Attention机制的整体计算。但是还有点小尾巴没有展开,就是那个注意力打分函数的计算,现在我们将来讨论这个事情。但在讲这个函数之前,我们先来对上边的Attention机制的计算做个总结,图2详细地描述了Attention机制的计算原理。

image-20220529202937945

假设现在我们要对一组输入 \(H=\left[h_{1}, h_{2}, h_{3}, \ldots, h_{n}\right]\) 使用Attention机制计算重要的内容, 这里往 往需要一个查询向量 \(q\) (这个向量往往和你做的任务有关, 比如机器翻译中用到的那个 \(q_{2}\) ), 然后通 过一个打分函数计算查询向量 \(q\) 和每个输入 \(h_{i}\) 之间的相关性, 得出一个分数。接下来使用softmax 对这些分数进行归一化, 归一化后的结果便是查询向量 \(q\) 在各个输入 \(h_{i}\) 上的注意力分布\(a=\left[a_{1}, a_{2}, a_{3}, \ldots, a_{n}\right]\), 其中每一项数值和原始的输入\(H=\left[h_{1}, h_{2}, h_{3}, \ldots, h_{n}\right]\) 一一对应。以 \(a_{i}\) 为例, 相关计算公式如下: \[ a_{i}=\operatorname{softmax}\left(s\left(h_{i}, q\right)\right)=\frac{\exp \left(s\left(h_{i}, q\right)\right)}{\sum_{j=1}^{n} \exp \left(s\left(h_{j}, q\right)\right)} \] 最后根据这些注意力分布可以去有选择性的从输入信息 \(H\) 中提取信息, 这里比较常用的信息提取方式, 是一种”软性”的信息提取(图2展示的就是一种"软性"注意力), 即根据注意力分布对输入信 息进行加权求和,最终的这个结果 context 体现了模型当前应该关注的内容: \[ \text { context }=\sum_{i=1}^{n} a_{i} \cdot h_{i} \] 现在我们来解决之前一直没有展开的小尾巴-打分函数, 它可以使用以下几种方式来计算: - 加性模型: \(s(h, q)=v^{T} \tanh (W h+U q)\) - 点积模型: \(s(h, q)=h^{T} q\) - 缩放点积模型: \(s(h, q)=\frac{h^{T} q}{\sqrt{D}}\) - 双线性模型: \(s(h, q)=h^{T} W q\)

以上公式中的参数 \(W 、 U\)\(v\) 均是可学习的参数矩阵或向量, \(D\) 为输入向量的维度。下边我们来分 析一下这些分数计算方式的差别。

加性模型引入了可学习的参数, 将查询向量 \(q\) 和原始输入向量 \(h\) 映射到不同的向量空间后进行计算打分, 显然相较于加性模型, 点积模型具有更好的计算效率。

另外, 当输入向量的维度比较高的时候, 点积模型通常有比较大的方差, 从而导致Softmax函数的 梯度会比较小。因此缩放点积模型通过除以一个平方根项来平滑分数数值, 也相当于平滑最终的注意力分布, 缓解这个问题。

最后, 双线性模型可以重塑为 \(s\left(h_{i}, q\right)=h^{T} W q=h^{T}\left(U^{T} V\right) q=(U h)^{T}(V q)\), 即分别对查询向量 \(q\) 和原始输入向量 \(h\) 进行线性变换之后, 再计算点积。相比点积模型, 双线性模型在计算相似度时 引入了非对称性

 一、李宏毅-Self Attention自注意力机制 - p1

相关性查询(q, k)-softmax - 乘上v

视频链接:https://www.bilibili.com/video/BV1JK4y1D7Wb?p=26&vd_source=29387dc08d18f642078183a6816e93e8

跟自己计算关联性重要吗?

为什么用softmax?relu也行

到目前为止,我们的Network的Input都是一个向量,不管是在预测这个,YouTube观看人数的问题上啊,还是影像处理上啊,我们的输入都可以看作是一个向量,然后我们的输出,可能是一个数值,这个是Regression,可能是一个类别,这是Classification

1.1 What is the output?

我们刚才已经看说输入是一堆向量,它可以是文字,可以是语音,可以是Graph,那这个时候,我们有可能有什么样的输出呢,有三种可能性。

1.1.1 每一个向量都有一个对应的Label

当你的模型,看到输入是四个向量的时候,它就要输出四个Label,而每一个Label,它可能是一个数值,那就是Regression的问题,如果每个Label是一个Class,那就是一个Classification的问题。

image-20220612171420908

举例来说 在文字处理上,假设你今天要做的是==POS Tagging==,POS Tagging就是词性标註,你要让机器自动决定每一个词汇 它是什么样的词性,它是名词 还是动词 还是形容词等等。

这个任务啊,其实并没有很容易,举例来说,你现在看到一个句子,I saw a saw。这并不是打错,并不是“我看一个看”,而是“我看到一个锯子”,这个第二个saw当名词用的时候,它是锯子,那所以机器要知道,第一个saw是个动词,第二个saw虽然它也是个saw,但它是名词,但是每一个输入的词汇,都要有一个对应的输出的词性。

1.1.2 一整个Sequence,只需要输出一个Label

image-20220612171433616

举例来说,如果是文字的话,我们就说Sentiment Analysis。Sentiment Analysis就是给机器看一段话,它要决定说这段话是正面的还是负面的

那你可以想像说这种应用很有用,假设你的公司开发了一个产品,这个产品上线了,你想要知道网友的评价怎么样,但是你又不可能一则一则网友的留言都去分析,那也许你就可以用这种,Sentiment Analysis的技术,让机器自动去判读说,当一则贴文里面有提到某个产品的时候,它是正面的 还是负面的,那你就可以知道你的产品,在网友心中的评价怎么样,这个是Sentiment Analysis给一整个句子,只需要一个Label,那Positive或Negative,那这个就是第二类的输出。

那如果是语音的例子的话呢,在作业四里面我们会做语者辨认,机器要听一段声音,然后决定他是谁讲的。或者是如果是Graph的话呢,今天你可能想要给一个分子,然后要预测说这个分子,比如说它有没有毒性,或者是它的亲水性如何,那这就是给一个Graph 输出一个Label。

1.1.3 机器要自己决定,应该要输出多少个Label

我们不知道应该输出多少个Label,机器要自己决定,应该要输出多少个Label,可能你输入是N个向量,输出可能是N'个Label,为什么是N',机器自己决定。

image-20220612171446043

这种任务又叫做==sequence to sequence==的任务,那我们在作业五会有sequence to sequence的作业,所以这个之后我们还会再讲

  • 翻译就是sequence to sequence的任务,因为输入输出是不同的语言,它们的词汇的数目本来就不会一样多
  • 或者是语音辨识也是,真正的语音辨识也是一个sequence to sequence的任务,输入一句话,然后输出一段文字,这也是一个sequence to sequence的任务

第二种类型有作业四,感兴趣可以去看看作业四的程式,那因为上课时间有限,所以上课,我们今天就先只讲第一个类型,也就是输入跟输出数目一样多的状况。

1.2 Sequence Labeling

那这种输入跟输出数目一样多的状况又叫做Sequence Labeling,你要给Sequence里面的每一个向量,都给它一个Label,那要怎么解Sequence Labeling的问题呢?那直觉的想法就是我们就拿个Fully-Connected的Network

然后虽然这个输入是一个Sequence,但我们就各个击破,不要管它是不是一个Sequence,把每一个向量,分别输入到Fully-Connected的Network里面,然后Fully-Connected的Network就会给我们输出,那现在看看,你要做的是Regression还是Classification,产生正确的对应的输出,就结束了,

那这么做显然有非常大的瑕疵,假设今天是,词性标记的问题,你给机器一个句子,I saw a saw,对Fully-Connected Network来说,后面这一个saw跟前面这个saw完全一模一样,它们是同一个词汇啊。

方案一:Window

既然Fully-Connected的Network输入同一个词汇,它没有理由输出不同的东西。但实际上,你期待第一个saw要输出动词,第二个saw要输出名词,但对Network来说它不可能做到,因为这两个saw 明明是一模一样的,你叫它一个要输出动词,一个要输出名词,它会非常地困惑,完全不知道要怎么处理。所以怎么办,有没有可能让Fully-Connected的Network,考虑更多的,比如说上下文的Context的资讯呢。这是有可能的,你就把前后几个向量都串起来,一起丢到Fully-Connected的Network就结束了

所以我们可以给Fully-Connected的Network,一整个Window的资讯,让它可以考虑一些上下文的,跟我现在要考虑的这个向量,相邻的其他向量的资讯。把Window开大一点啊,大到可以把整个Sequence盖住就结束了。

如果你今天说我真的要开一个Window,把整个Sequence盖住,那你可能要统计一下你的训练资料,然后看看你的训练资料里面,最长的Sequence有多长,然后开一个Window比最长的Sequence还要长,你才有可能把整个Sequence盖住但是你开一个这么大的Window,意味著说你的Fully-Connected的Network,它需要非常多的参数,那可能不只运算量很大,可能还容易Overfitting

方案二:self-attention

Self-Attention的运作方式就是,Self-Attention会吃一整个Sequence的资讯

image-20220613211233215

然后你Input几个Vector,它就输出几个Vector,比如说你这边Input一个深蓝色的Vector,这边就给你一个另外一个Vector。这边给个浅蓝色,它就给你另外一个Vector,这边输入4个Vector,它就Output 4个Vector。那这4个Vector有什么特别的地方呢,这4个Vector,他们都是考虑一整个Sequence以后才得到的,那等一下我会讲说Self-Attention,怎么考虑一整个Sequence的资讯。

如此一来你这个Fully-Connected的Network,它就不是只考虑一个非常小的范围,或一个小的Window,而是考虑整个Sequence的资讯,再来决定现在应该要输出什么样的结果,这个就是Self-AttentionSelf-Attention不是只能用一次,你可以叠加很多次

image-20220613211415203

可以Self-Attention的输出,通过Fully-Connected Network以后,再做一次Self-Attention,Fully-Connected的Network,再过一次Self-Attention,再重新考虑一次整个Input Sequence的资讯,再丢到另外一个Fully-Connected的Network,最后再得到最终的结果。

所以可以把Fully-Connected的Network,跟Self-Attention交替使用

  • Self-Attention处理整个Sequence的资讯
  • Fully-Connected的Network,专注于处理某一个位置的资讯
  • 再用Self-Attention,再把整个Sequence资讯再处理一次
  • 然后交替使用Self-Attention跟Fully-Connected

有关Self-Attention,最知名的相关的文章,就是《Attention is all you need》.那在这篇Paper里面呢,Google提出了==Transformer==这样的Network架构,那Transformer就是变形金刚,所以提到这个Network的时候呢,我们就会有变形金刚这个形象。

image-20220613211500443

Transformer我们今天还不会讲到,但我们之后会讲到,Transformer里面一个最重要的Module就是Self-Attention,它就是变形金刚的火种源。那这篇Paper最厉害的地方,就是它有一个霸气的名字Attention is all you need.

那其实像Self-Attention这样的架构,最早我并不会说它是出现在《Attention is all you need》这样的Paper,因为其实很多更早的Paper,就有提出过类似的架构,只是不见得叫做Self-Attention,比如说叫做Self-Matching,或者是叫别的名字,不过呢是Attention is all you need.这篇Paper,把Self-Attention这个Module,把它发扬光大。

1.3 Self-Attention过程

Self-Attention的Input,它就是一串的Vector,那这个Vector可能是你整个Network的Input,它也可能是某个Hidden Layer的Output,所以我们这边不是用\(x\)来表示它,用\(a\)来表示它。

image-20220613211620957

我们用\(a\)来表示它,代表它有可能是前面已经做过一些处理,它是某个Hidden Layer的Output,那Input一排a这个向量以后,Self-Attention要Output另外一排b这个向量。那这每一个b都是考虑了所有的a以后才生成出来的,所以这边刻意画了非常非常多的箭头,告诉你$b^1 \(考虑了\)a1\(到\)a4\(产生的,\)b2\(考虑\)a1\(到\)a4\(产生的,\)b3 b^4$也是一样,考虑整个input的sequence,才产生出来的。

那接下来呢就是要跟大家说明,怎么产生\(b^1\)这个向量,那你知道怎么产生\(b^1\)这个向量以后,你就知道怎么产生剩下\(b^1 b^2 b^3 b^4\)剩下的向量。

这里有一个特别的机制,这个机制是根据\(a^1\)这个向量,找出整个很长的sequence里面,到底哪些部分是重要的,哪些部分跟判断\(a^1\)是哪一个label是有关系的,哪些部分是我们要决定\(a^1\)的class,决定\(a^1\)的regression数值的时候,所需要用到的资讯

image-20220613212112611

每一个向量跟\(a^1\)的关联的程度,用一个数值叫α来表示,这个self-attention的module,怎么自动决定两个向量之间的关联性呢,你给它两个向量\(a^1\)\(a^4\),它怎么决定\(a^1\)\(a^4\)有多相关,然后给它一个数值α呢,那这边呢你就需要一个计算attention的模组

image-20220613212206065

这个计算attention的模组,就是拿两个向量作为输入,然后它就直接输出α那个数值,计算这个α的数值有各种不同的做法:

  • ==dot product==:输入的这两个向量分别乘上两个不同的矩阵,左边这个向量乘上\(W^q\)这个矩阵得到矩阵\(q\),右边这个向量乘上\(W^k\)这个矩阵得到矩阵\(k\)

    再把\(q\)\(k\)做dot product,就是把他们做element-wise 的相乘,再全部加起来以后就得到一个 scalar,这个scalar就是α,这是一种计算α的方式

  • ==Additive==:把同样这两个向量通过\(W^q\) \(W^k\),得到\(q\)\(k\),那我们不是把它做Dot-Product,是把它这个串起来,然后丢到这个过一个Activation Function,然后再通过一个Transform,然后得到α。

总之有非常多不同的方法,可以计算Attention,可以计算这个α的数值,可以计算这个关联的程度,但是在接下来的讨论里面,我们都只用左边这个方法,这也是今日最常用的方法,也是用在Transformer里面的方法。那你就要把这边的\(a^1\)去跟这边的\(a^2 a^3 a^4\),分别都去计算他们之间的关联性,也就是计算他们之间的α。

image-20220613212357947

你把\(a^1\)乘上$W^q \(得到\)q^1$,那这个q有一个名字,我们叫做==Query==,它就像是你搜寻引擎的时候,去搜寻相关文章的问题,就像搜寻相关文章的关键字,所以这边叫做Query。

然后接下来呢,\(a^2 a^3 a^4\)你都要去把它乘上\(W^k\),得到\(k\)这个Vector,\(k\)这个Vector叫做==Key==,那你把这个 Query q1,跟这个Key k2,算 Inner-Product就得到 α‘ (注意力矩阵)我们这边用\(α_{1,2}\)来代表说,Query是1提供的,Key是2提供的时候,这个1跟2他们之间的关联性,这个α这个关联性叫做==Attention的Score==,叫做Attention的分数。

接下来也要跟\(a^3 a^4\)来计算,把\(a_3\)乘上\(W^k\),得到另外一个Key也就是\(k^3\),\(a^4\)乘上\(W^k\)得到\(k^4\),然后你再把\(k^3\)这个Key,跟\(q^1\)这个Query做Inner-Product,得到1跟3之间的关联性,得到1跟3的Attention,你把\(k^4\)\(q^1\)做Dot-Product,得到\(α_{1,4}\),得到1跟4之间的关联性。

image-20220613212536289

其实一般在实作时候,\(q^1\)也会跟自己算关联性,自己跟自己计算关联性这件事情有多重要。计算出,a1跟每一个向量的关联性以后,接下来这边会接入一个Soft-Max

image-20220613221201944

这个Soft-Max跟分类的时候的那个Soft-Max是一模一样的 ,所以Soft-Max的输出就是一排α,所以本来有一排α,通过Soft-Max就得到\(α'\)

这边你不一定要用Soft-Max,用别的替代也没问题,比如说有人尝试过说做个ReLU,这边通通做个ReLU,那结果发现还比Soft-Max好一点,所以这边你不一定要用Soft-Max,这边你要用什么Activation Function都行,你高兴就好,你可以试试看,那Soft-Max是最常见的,那你可以自己试试看,看能不能试出比Soft-Max更好的结果。

接下来得到这个\(α'\)以后,我们就要根据这个\(α'\)去抽取出这个Sequence里面重要的资讯,根据这个α我们已经知道说,哪些向量跟\(a^1\)是最有关系的,怎么抽取重要的资讯呢?

image-20220613221501080

  • 首先把\(a^1\)\(a^4\)这边每一个向量,乘上$W^v \(得到新的向量,这边分别就是用\)v^1 v^2 v^3 v^4$来表示

  • 接下来把这边的\(v^1\)\(v^4\),每一个向量都去乘上Attention的分数,都去乘上\(α'\)

  • 然后再把它加起来,得到\(b^1\)

\[ b^1=\sum_i\alpha'_{1,i}v^i \]

如果某一个向量它得到的分数越高,比如说如果\(a^1\)\(a^2\)的关联性很强,这个\(α'\)得到的值很大,那我们今天在做Weighted Sum以后,得到的\(b^1\)的值,就可能会比较接近\(v^2\),所以谁的那个Attention的分数最大,谁的那个\(v\)就会Dominant你抽出来的结果

 二、李宏毅-Self Attention自注意力机制 - p2

image-20220613221835154

从这一排 vector 得到 \(b^1\),跟从这一排 vector 得到 \(b^2\),它的操作是一模一样的.要强调一点是,这边的 \(b^1\)\(b^4\),它们并不需要依序产生,它们是一次同时被计算出来的。

怎么计算这个 \(b^2\)?我们现在的主角,就变成 \(a^2\)

image-20220613221854934

  • \(a^2\) 乘上一个 matrix,变成 \(q^2\)

  • 然后接下来根据 \(q^2\),去对\(a^1\)\(a^4\) 这四个位置,都去计算 attention 的 score

    • \(q^2\)\(k^1\) 做个这个 dot product
    • \(q^2\)\(k^2\) 也做个 dot product
    • \(q^2\)\(k^3\) 也做 dot product
    • \(q^2\)\(k^4\) 也做 dot product,得到四个分数
  • 得到这四个分数以后,可能还会做一个 normalization softmax,然后得到最后的 attention 的 score,\(α'_{2,1} \space α'_{2,2} \space α'_{2,3} \space α'_{2,4}\)那我们这边用 \(α'\)表示经过 normalization 以后的attention score

  • 接下来拿这四个数值,分别乘上 \(v^1 \space v^2 \space v^3 \space v^4\)

    image-20220613221952411

    • \(α'_{2,1}\)乘上 \(v^1\)
    • \(α'_{2,2}\) 乘上 \(v^2\)
    • \(α'_{2,3}\) 乘上 \(v^3\)
    • \(α'_{2,4}\) 乘上 \(v^4\),然后全部加起来就是 $ b^2$

    \[ b^2=\sum_iα'_{2,i}v^i \]

同理就可以,由 \(a^3\) 乘一个 transform 得到 \(q^3\),然后就计算 \(b^3\),从 \(a^4\) 乘一个 transform 得到 \(q^4\),就计算 \(b^4\),以上说的是 Self-attention 它运作的过程。

2.2 矩阵的角度

接下来我们从矩阵乘法的角度,再重新讲一次我们刚才讲的,Self-attention 是怎么运作的,我们现在已经知道每一个 a 都产生 q k v。

image-20220613222115187

如果要用矩阵运算表示这个操作的话,是什么样子呢

我们每一个 a,都乘上一个矩阵,我们这边用 \(W^q\) 来表示它,得到 \(q^i\),每一个 a 都要乘上 \(W^q\),得到\(q^i\),这些不同的 a 你可以把它合起来,当作一个矩阵来看待

image-20220613222137478

一样$a2a3a^4 $也都乘上 \(W^q\) 得到$q^2 q^3 $跟 \(q^4\),那你可以把 a1 到 a4 拼起来,看作是一个矩阵,这个矩阵我们用 I 来表示,这个矩阵的四个 column 就是 \(a^1\)\(a^4\)

\(I\) 乘上 \(W^q\) 就得到另外一个矩阵,我们用 \(Q\) 来表示它,这个 \(Q\) 就是把 \(q^1\)\(q^4\) 这四个 vector 拼起来,就是 \(Q\) 的四个 column。

所以我们从 \(a^1\)\(a^4\),得到 \(q^1\)\(q^4\)这个操作,其实就是把 I 这个矩阵,乘上另外一个矩阵 \(W^q\),得到矩阵\(Q\)\(I\) 这个矩阵它里面的 column就是我们 Self-attention 的 input是 \(a^1\)\(a^4\)\(W^q\)其实是 network 的参数,它是等一下会被learn出来的\(Q\) 的四个 column,就是 \(q^1\)\(q^4\)。接下来产生 k 跟 v 的操作跟 q 是一模一样的。

image-20220613222206939

所以每一个 a 得到 q k v ,其实就是把输入的这个,vector sequence 乘上三个不同的矩阵,你就得到了 q,得到了 k,跟得到了 v。下一步是,每一个 q 都会去跟每一个 k,去计算这个 inner product,去得到这个 attention 的分数。那得到 attention 分数这一件事情,如果从矩阵操作的角度来看,它在做什么样的事情呢?

image-20220613222251046

你就是把 \(q^1\)\(k^1\) 做 inner product,得到 \(α_{1,1}\),所以 \(α_{1,1}\)就是 \(q^1\)\(k^1\) 的 inner product,那这边我就把这个,\(k^1\)它背后的这个向量,把它画成比较宽一点代表说它是 transpose。同理 \(α_{1,2}\) 就是 \(q^1\)\(k^2\),做 inner product, \(α_{1,3}\) 就是 \(q^1\)\(k^3\) 做 inner product,这个 \(α_{1,4}\) 就是 \(q^1\)\(k^4\) 做 inner product。那这个四个步骤的操作,你其实可以把它拼起来,看作是矩阵跟向量相乘

image-20220613222335546

这四个动作,你可以看作是我们\(k^1\)\(k^4\) 拼起来,当作是一个矩阵的四个 row。那我们刚才讲过说,我们不只是 \(q^1\),要对\(k^1\)\(k^4\) 计算 attention,\(q^2,q^3,q^4\)也要对 \(k^1\)\(k^4\) 计算 attention,操作其实都是一模一样的。

image-20220613222430034

所以这些 attention 的分数可以看作是两个矩阵的相乘,一个矩阵它的 row,就是 \(k^1\)\(k^4\),另外一个矩阵它的 column 。我们会在 attention 的分数,做一下 normalization,比如说你会做 softmax,你会对这边的每一个 column,每一个 column 做 softmax,让每一个 column 里面的值相加是 1。

之前有讲过说 其实这边做 softmax不是唯一的选项,你完全可以选择其他的操作,比如说 ReLU 之类的,那其实得到的结果也不会比较差,通过了 softmax 以后,它得到的值有点不一样了,所以我们用 \(A'\),来表示通过 softmax 以后的结果。

我们已经计算出 $A' \(,那我们把这个\)v^1$ 到 \(v^4\)乘上这边的 α 以后,就可以得到 b。

image-20220613223101872

你就把\(v^1\)\(v^4\) 拼起来,你\(v^1\)\(v^4\)当成是V 这个矩阵的四个 column,把它拼起来,然后接下来你把 v 乘上,\(A'\) 的第一个 column 以后,你得到的结果就是 \(b^1\)

如果你熟悉线性代数的话,你知道说把这个 \(A'\) 乘上 V,就是把 \(A'\)的第一个 column,乘上 V 这一个矩阵,你会得到你 output 矩阵的第一个 column。而把 A 的第一个 column乘上 V 这个矩阵做的事情,其实就是把 V 这个矩阵里面的每一个 column,根据第 \(A'\) 这个矩阵里面的每一个 column 里面每一个 element,做 weighted sum,那就得到 \(b^1\)

那就是这边的操作,把 \(v^1\)\(v^4\) 乘上 weight,全部加起来得到 \(b^1\),如果你是用矩阵操作的角度来看它,就是把$ A'$ 的第一个 column 乘上 V,就得到 \(b^1\),然后接下来就是以此类推。

image-20220613223143878

就是以此类推,把 \(A'\) 的第二个 column 乘上 V,就得到 \(b^2\),\(A'\) 的第三个 column 乘上 V 就得到 \(b^3\),\(A'\) 的最后一个 column 乘上 V,就得到 \(b^4\)。所以我们等于就是把 \(A'\) 这个矩阵,乘上 V 这个矩阵,得到 O 这个矩阵,O 这个矩阵里面的每一个 column,就是 Self-attention 的输出,也就是 \(b^1\)\(b^4\),

所以其实整个 Self-attention,我们在讲操作的时候,我们在最开始的时候 跟你讲的时候我们讲说,我们先产生了 q k v,然后再根据这个 q 去找出相关的位置,然后再对 v 做 weighted sum,其实这一串操作,就是一连串矩阵的乘法而已

2.3 Self-attention 流程

我们再复习一下我们刚才看到的矩阵乘法:

image-20220613223238727

  • I 是 Self-attention 的 input,Self-attention 的 input 是一排的vector,这排 vector 拼起来当作矩阵的 column,就是 I;

  • 这个 input 分别乘上三个矩阵,\(W^q\) \(W^k\) 跟$ W^v$,得到 Q K V ;

  • 这三个矩阵,接下来 Q 乘上 K 的 transpose,得到 A 这个矩阵,A 的矩阵你可能会做一些处理,得到 \(A'\),那有时候我们会把这个 \(A'\),叫做 Attention Matrix生成Q矩阵就是为了得到Attention的score

  • 然后接下来你把 \(A'\) 再乘上 V,就得到 O,O 就是 Self-attention 这个 layer 的输出,生成V是为了计算最后的b,也就是矩阵O;

所以 Self-attention 输入是 I,输出是 O,那你会发现说虽然是叫 attention,但是其实 Self-attention layer 里面,唯一需要学的参数,就只有 \(W^q\) \(W^k\) 跟$ W^v$ 而已,只有\(W^q\) \(W^k\) 跟$ W^v$是未知的,是需要透过我们的训练资料把它找出来的。但是其他的操作都没有未知的参数,都是我们人为设定好的,都不需要透过 training data 找出来,那这整个就是 Self-attention 的操作,从 I 到 O 就是做了 Self-attention。

2.4 Multi-head Self-attention

Self-attention 有一个进阶的版本,叫做 ==Multi-head Self-attention==, Multi-head Self-attention,其实今天的使用是非常地广泛的。在作业 4 里面,助教原来的 code 4 有,Multi-head Self-attention,它的 head 的数目是设成 2,那刚才助教有给你提示说,把 head 的数目改少一点 改成 1,其实就可以过medium baseline。

但并不代表所有的任务,都适合用比较少的 head,有一些任务,比如说翻译,比如说语音辨识,其实用比较多的 head,你反而可以得到比较好的结果。至于需要用多少的 head,这个又是另外一个 hyperparameter,也是你需要调的。

那为什么我们会需要比较多的 head 呢,你可以想成说相关这件事情?

我们在做这个 Self-attention 的时候,我们就是用 q 去找相关的 k,但是==相关==这件事情有很多种不同的形式,有很多种不同的定义,所以也许我们不能只有一个 q,我们应该要有多个 q,不同的 q 负责不同种类的相关性

所以假设你要做 Multi-head Self-attention 的话,你会怎么操作呢?

image-20220613223634261

  • 先把 a 乘上一个矩阵得到 q
  • 再把 q 乘上另外两个矩阵,分别得到 \(q^1\)\(q^2\),那这边还有 这边是用两个上标,i 代表的是位置,然后这个 1 跟 2 代表是,这个位置的第几个 q,所以这边有 \(q^{i,1}\)\(q^{i,2}\),代表说我们有两个 head

我们认为这个问题,里面有两种不同的相关性,是我们需要产生两种不同的 head,来找两种不同的相关性。既然 q 有两个,那 k 也就要有两个,那 v 也就要有两个,从 q 得到 \(q^1 q^2\),从 k 得到 \(k^1 k^2\),从 v 得到 \(v^1 v^2\),那其实就是把 q 把 k 把 v,分别乘上两个矩阵,得到这个不同的 head,就这样子而已,对另外一个位置,也做一样的事情只是现在\(q^1\),它在算这个 attention 的分数的时候,它就不要管那个 \(k^2\) 了。

image-20220613223730387

  • 所以 \(q_{i,1}\) 就跟 \(k^{i,1}\) 算 attention

  • \(q_{i,1}\) 就跟 \(k^{j,1}\) 算 attention,也就是算这个 dot product,然后得到这个 attention 的分数

  • 然后今天在做 weighted sum 的时候,也不要管 \(v^2\) 了,看 \(V^{i,1}\)\(v^{j,1}\) 就好,所以你把 attention 的分数乘 \(v^{i,1}\),把 attention 的分数乘 \(v^{j,1}\)

  • 然后接下来就得到 \(b^{i,1}\)

这边只用了其中一个 head,那你会用另外一个 head,也做一模一样的事情。

image-20220613223749217

所以 \(q^2\) 只对 \(k^2\) 做 attention,它们在做 weighted sum 的时候,只对 \(v^2\) 做 weighted sum,然后接下来你就得到 \(b^{i,2}\)

如果你有多个 head,有 8 个 head 有 16 个 head,那也是一样的操作,那这边是用两个 head 来当作例子,来给你看看有两个 head 的时候,是怎么操作的,现在得到 \(b^{i,1}\)\(b^{i,2}\)然后接下来你可能会把 \(b^{i,1}\)\(b^{i,2}\),把它接起来,然后再通过一个 transform。

image-20220613223832789

也就是再乘上一个矩阵,然后得到 bi,然后再送到下一层去,那这个就是 Multi-head attention,一个这个 Self-attention 的变形。

2.5 Positional Encoding

No position information in self-attention

那讲到目前为止,你会发现说 Self-attention 的这个 layer,它少了一个也许很重要的资讯,这个资讯是位置的资讯。对一个 Self-attention layer 而言,每一个 input,它是出现在 sequence 的最前面,还是最后面,它是完全没有这个资讯的。

对 Self-attention 而言,位置 1 跟位置 2 跟位置 3 跟位置 4,完全没有任何差别,这四个位置的操作其实是一模一样,对它来说 q1 到跟 q4 的距离,并没有特别远,1 跟 4 的距离并没有特别远,2 跟 3 的距离也没有特别近。

对它来说就是天涯若比邻,所有的位置之间的距离都是一样的,没有任何一个位置距离比较远,也没有任何位置距离比较近,也没有谁在整个 sequence 的最前面,也没有谁在整个 sequence 的最后面。但是这样子设计可能会有一些问题,因为有时候位置的资讯也许很重要,举例来说,我们在做这个 POS tagging,就是词性标记的时候,也许你知道说动词比较不容易出现在句首,所以如果我们知道说,某一个词汇它是放在句首的,那它是动词的可能性可能就比较低,这样子的位置的资讯往往也是有用的。

Each positon has a unique positional vector \(e^i\)

可是在我们到目前为止,讲的 Self-attention 的操作里面,根本就没有位置的资讯,所以怎么办呢,所以你做 Self-attention 的时候,如果你觉得位置的资讯是一个重要的事情,那你可以把位置的资讯把它塞进去,怎么把位置的资讯塞进去呢,这边就要用到一个叫做,==positional encoding== 的技术。

image-20220613224025472

你为每一个位置设定一个 vector,叫做 positional vector,这边\(e^i\) 来表示,上标 i 代表是位置,每一个不同的位置,就有不同的 vector,就是 \(e^1\) 是一个 vector,\(e^2\) 是一个vector,\(e^{128}\) 是一个vector,不同的位置都有一个它专属的 e,然后把这个 e 加到 \(a^i\) 上面,就结束了。就是告诉你的 Self-attention,位置的资讯,如果它看到说 \(a^i\) 好像有被加上 $ e^i$,它就知道说现在出现的位置,应该是在 i 这个位置。

最早的这个 transformer,就 Attention Is All You Need 那篇 paper 里面,它用的 $ e^i$长的是这个样子

image-20220613224248928

Hand-crafted or Learned from data

这样子的 positional vector,它是 handcrafted 的,也就是它是人设的,那人设的这个 vector 有很多问题,就假设我现在在定这个 vector 的时候,只定到 128,那我现在 sequence 的长度,如果是 129 怎么办呢?不过在最早的那个,Attention Is All You Need paper里面,没有这个问题,它 vector 是透过某一个规则所产生的,透过一个很神奇的sin和cos 的 function 所产生的。

其实你不一定要这么产生, positional encoding仍然是一个尚待研究的问题,你可以创造自己新的方法,或甚至 positional encoding,是可以根据资料学出来的。那有关 positional encoding,你可以再参考一下文献,这个是一个尚待研究的问题,比如说我这边引用了一篇,这个是去年放在 arxiv 上的论文,所以可以想见这其实都是很新的论文。

image-20220613224538933

里面就是比较了跟提出了,新的 positional encoding

  • 比如说这个是最早的 positional encoding,它是用一个神奇的 sin function 所产生的
  • 那如果你的 positional encoding,你把 positional encoding 里面的数值,当作 network 参数的一部分,直接 learn 出来,看起来是这个样子的,这个图是那个横著看的,它是横著看的,它是每一个 row,代表一个 position,好 所以这个是这个最原始的,用 sin function 产生的,这个是 learn 出来的
  • 它里面又有神奇的做法,比如说这个,这个是用 RNN 生出来的,positional encording 是用 RNN 出来的,这篇 paper 提出来的叫做 FLOATER,是用个神奇的 network 生出来的,

总之你有各式各样不同的方法,来产生 positional encoding,那目前我们还不知道哪一种方法最好,这是一个尚待研究中的问题,所以你不用纠结说,为什么 Sinusoidal 最好,你永远可以提出新的做法

2.6 Applications …

Self-attention 当然是用得很广,我们已经提过很多次 transformer 这个东西

image-20220613224644049

那我们大家也都知道说,在 NLP 的领域有一个东西叫做 BERT,BERT 里面也用到 Self-attention,所以 Self-attention 在 NLP 上面的应用,是大家都耳熟能详的。但 Self-attention,不是只能用在 NLP 相关的应用上,它还可以用在很多其他的问题上

Self-attention for Speech

比如说在做语音的时候,你也可以用 Self-attention,不过在做语音的时候,你可能会对 Self-attention,做一些小小的改动。因为一般语音的,如果你要把一段声音讯号,表示成一排向量的话,这排向量可能会非常地长

image-20220613224723147

而每一个向量,其实只代表了 10 millisecond 的长度而已,所以如果今天是 1 秒鐘的声音讯号,它就有 100 个向量了,5 秒鐘的声音讯号,就 500 个向量了,你随便讲一句话,都是上千个向量了。所以一段声音讯号,你要描述它的时候,那个像这个 vector 的 sequence 它的长度是非常可观的,那可观的 sequence,可观的长度,会造成什么问题呢?

你想想看,我们今天在计算这个 attention matrix 的时候,它的计算complexity 是长度的平方。

image-20220613224807917

计算这个 attention matrix A′你需要做 L 乘以 L 次的 inner product,那如果这个 L 的值很大的话,它的计算量就很可观,你也需要很大的这个 memory,才能够把这个矩阵存下来。

所以今天如果在做语音辨识的时候,一句话所产生的这个 attention matrix,可能会太大,大到你根本就不容易处理,不容易训练,所以怎么办呢?在做语音的时候,有一招叫做 ==Truncated Self-attention==

image-20220613224906348

Truncated Self-attention 做的事情就是,我们今天在做 Self-attention 的时候,不要看一整句话,就我们就只看一个小的范围就好,那至于这个范围应该要多大,那个是人设定的。

那为什么我们知道说,今天在做语音辨识的时候,也许只需要看一个小的范围就好,那就是取决于你对这个问题的理解,也许我们要辨识这个位置有什么样的phoneme,这个位置有什么样的内容,我们并不需要看整句话,只要看这句话,跟它前后一定范围之内的资讯,其实就可以判断。

所以如果在做 Self-attention 的时候,也许没有必要看过一整个句子,也许没有必要让 Self-attention 考虑一整个句子,也许只需要考虑一个小范围就好,这样就可以加快运算的速度,这个是 Truncated Self-attention。

Self-attention for Image

那其实 Self-attention ,还可以被用在影像上,Self-attention那到目前为止,我们在讲 Self-attention 的时候,我们都说 Self-attention 适用的范围是:输入是一个 vector set 的时候,一张图片啊,我们把它看作是一个很长的向量,那其实一张图片,我们也可以换一个观点,把它看作是一个 vector 的 set。

image-20220613225206980

这个是一个解析度 5 乘以 10 的图片,那这一张图片呢,可以看作是一个 tensor,这个 tensor 的大小是 5 乘以 10 乘以 3,3 代表 RGB 这 3 个 channel。你可以把每一个位置的 pixel,看作是一个三维的向量,所以每一个 pixel,其实就是一个三维的向量,那整张图片,其实就是 5 乘以 10 个向量的set

所以我们其实可以换一个角度,影像这个东西,其实也是一个 vector set,它既然也是一个 vector set 的话,你完全可以用 Self-attention 来处理一张图片,那有没有人用 Self-attention 来处理一张图片呢,是有的。那这边就举了两个例子,来给大家参考,那现在把 Self-attention 用在影像处理上,也不算是一个非常石破天惊的事情。

image-20220613225244115

==Self-attention v.s. CNN==

我们可以来比较一下,Self-attention 跟 CNN 之间,有什么样的差异或者是关联性。如果我们今天,是用 Self-attention 来处理一张图片,代表说,假设这个是你要考虑的 pixel,那它产生 query,其他 pixel 产生 key。

image-20220613225357976

你今天在做 inner product 的时候,你考虑的不是一个小的receptive field的信息,而是整张影像的资讯,但是今天在做 CNN 的时候,,会画出一个 receptive field,每一个 filter,每一个 neural,只考虑 receptive field 范围里面的资讯。

image-20220613225442244

  • 所以如果我们比较 CNN 跟 Self-attention 的话,CNN 可以看作是一种简化版的 Self-attention ,因为在做CNN的时候,我们只考虑 receptive field 里面的资讯,而在做 Self-attention 的时候,我们是考虑整张图片的资讯,所以 CNN,是简化版的 Self-attention。或者是你可以反过来说, Self-attention 是一个复杂化的 CNN
  • 在 CNN 里面,我们要划定 receptive field,每一个 neural,只考虑 receptive field 里面的资讯,而 receptive field 的范围跟大小,是人决定的。而对 Self-attention 而言,我们用 attention,去找出相关的 pixel,就好像是 receptive field 是自动被学出的,network 自己决定说,receptive field 的形状长什么样子,network 自己决定说,以这个 pixel 为中心,哪些 pixel 是我们真正需要考虑的,那些 pixel 是相关的所以 receptive field 的范围,不再是人工划定,而是让机器自己学出来

其实你可以读一篇 paper,叫做 On the Relationship,between Self-attention and Convolutional Layers。

image-20220613230146104

在这篇 paper 里面,会用数学的方式严谨的告诉你说,其实这个 CNN就是 Self-attention 的特例,Self-attention 只要设定合适的参数,它可以做到跟 CNN 一模一样的事情。所以 self attention,是更 flexible 的 CNN,而 CNN 是有受限制的 Self-attention,Self-attention 只要透过某些设计,某些限制,它就会变成 CNN。

image-20220613230212397

那这也不是很旧的 paper,你发现它放到网路上的时间呢,是 19 年的 11 月,所以你知道这些,我们今天上课里面讲的东西,其实都是很新的资讯。 既然Self-attention 比较 flexible,之前有讲说比较 flexible 的 model,比较需要更多的 data,如果你 data 不够,就有可能 overfitting。

如果你今天用不同的 data 量,来训练 CNN 跟 Self-attention,你确实可以看到我刚才讲的现象。

image-20220613230309663

那这个实验结果,来自于 An image is worth 16 乘以 16 的 words,这个是 Google 的 paper,它就是把这个 Self-attention,apply 在影像上面。那其实把一张影像呢,拆成 16 乘以 16 个 patch,它把每一个 patch想像成是一个 word,因为一般我们这个 Self-attention,比较常用在 NLP 上面,所以他就说,想像每一个 patch 其实就是一个 word,所以他就取了一个很 fancy 的 title,叫做一张图值 16 乘以 16 个文字

横轴是训练的影像的量,那你发现说,对 Google 来说 用的,所谓的资料量比较少,也是你没有办法用的资料量啦这边有 10 个 million 就是,1000 万张图,是资料量比较小的 setting,然后资料量比较大的 setting 呢,有 3 亿张图片,在这个实验里面呢,比较了 Self-attention 是浅蓝色的这一条线,跟 CNN 是深灰色的这条线。

就会发现说,随著资料量越来越多,那 Self-attention 的结果就越来越好,最终在资料量最多的时候,Self-attention 可以超过 CNN,但在资料量少的时候,CNN 它是可以比 Self-attention,得到更好的结果的。

那为什么会这样,你就可以从 CNN 跟 Self-attention,它们的弹性来加以解释:

  • Self-attention 它弹性比较大,所以需要比较多的训练资料,训练资料少的时候,就会 overfitting。
  • CNN 它弹性比较小,在训练资料少的时候,结果比较好,但训练资料多的时候,它没有办法从更大量的训练资料得到好处。

所以这个就是 Self-attention 跟 CNN 的比较,那 Self-attention 跟 CNN,谁比较好呢,我应该选哪一个呢,事实上你也可以都用,在我们作业四里面,如果你要做 strong baseline 的话,就特别给你一个提示,就是用 conformer,里面就是有用到 Self-attention,也有用到 CNN。

Self-attention v.s. RNN

我们来比较一下,Self-attention 跟 RNN,RNN就是 recurrent neural network,这门课里面现在就不会讲recurrent neural network,因为 recurrent neural network 的角色,很大一部分都可以用 Self-attention 来取代了,但是 RNN 是什么呢,假设你想知道的话,那这边很快地三言两语把它带过去,RNN 跟 Self-attention 一样,都是要处理 input 是一个 sequence 的状况。

image-20220613230659968

在 RNN 里面呢

  • 左边是你的 input sequence,你有一个 memory 的 vector
  • 然后你有一个 RNN 的 block,这个 RNN 的 block 呢,它吃 memory 的 vector,吃第一个 input 的 vector
  • 然后 output 一个东西,然后根据这个 output 的东西,我们通常叫做这个 hidden,这个 hidden 的 layer 的 output
  • 然后通过这个 fully connected network,然后再去做你想要的 prediction

接下来当sequence 里面,第二个 vector 作为 input 的时候,也会把前一个时间点吐出来的东西,当做下一个时间点的输入,再丢进 RNN 里面,然后再产生新的 vector,再拿去给 fully connected network。然后第三个 vector 进来的时候,你把第三个 vector 跟前一个时间点的输出,一起丢进 RNN,再产生新的输出,然后在第四个时间点。第四个 vector 输入的时候,把第四个 vector 跟前一个时间点,产生出来的输出,再一起做处理,得到新的输出,再通过 fully connected network 的 layer,这个就是 RNN。

Recurrent Neural Network跟 Self-attention 做的事情其实也非常像,它们的 input 都是一个 vector sequence,Self-attention output 是另外一个 vector sequence,这里面的每一个 vector,都考虑了整个 input sequence 以后,再给 fully connected network 去做处理。

那 RNN 呢,它也会 output 另外一群 vector,这另外一排 vector 也会给,fully connected network 做进一步的处理,那 Self-attention 跟 RNN 有什么不同呢。

image-20220613230944896

当然一个非常显而易见的不同,你可能会说,这边的每一个 vector,它都考虑了整个 input 的 sequence,而 RNN 每一个 vector,只考虑了左边已经输入的 vector,它没有考虑右边的 vector,那这是一个很好的观察。

但是 RNN 其实也可以是双向的,所以如果你 RNN 用双向的 RNN 的话,其实这边的每一个 hidden 的 output,每一个 memory 的 output,其实也可以看作是考虑了整个 input 的 sequence。但是假设我们把 RNN 的 output,跟 Self-attention 的 output 拿来做对比的话,就算你用 bidirectional 的 RNN,还是有一些差别的。

  • 对RNN 来说,假设最右边这个黄色的 vector,要考虑最左边的这个输入,那它必须要把最左边的输入存在 memory 里面,然后接下来都不能够忘掉,一路带到最右边,才能够在最后一个时间点被考虑。

  • 对 Self-attention 来说没有这个问题,它只要这边输出一个 query,这边输出一个 key,只要它们 match 得起来,天涯若比邻,你可以从非常远的 vector,在整个 sequence 上非常远的 vector,轻易地抽取资讯,所以这是 RNN 跟 Self-attention,一个不一样的地方。

  • RNN 今天在处理的时候, input 一排 sequence,output 一排 sequence 的时候, RNN 是没有办法平行化的。RNN 它今天 input 一排是 vector,output 另外一排 vector 的时候,它没有办法一次处理,没有办法平行处理所有的 output。但 Self-attention 有一个优势,是它可以平行处理所有的输出,你今天 input 一排 vector,再 output 这四个 vector 的时候,这四个 vector 是平行产生的,并不需要等谁先运算完才把其他运算出来,output 的这个 vector,里面的 output 这个 vector sequence 里面,每一个 vector 都是同时产生出来的。 所以在运算速度上,Self-attention 会比 RNN 更有效率。

image-20220613231148500

那你今天发现说,很多的应用都往往把 RNN 的架构,逐渐改成 Self-attention 的架构了,如果你想要更进一步了解,RNN 跟 Self-attention 的关係的话,你可以看下面这篇文章,Transformers are RNNs,里面会告诉你说,Self-attention 你加上了什么东西以后,其实它就变成了 RNN,发现说这也不是很旧的 paper,这个是去年的六月放到 arXiv 上。

Self-attention for Graph

Graph 也可以看作是一堆 vector,那如果是一堆 vector,就可以用 Self-attention 来处理,所以 Self-attention 也可以用在 Graph 上面,但是当我们把 Self-attention,用在Graph 上面的时候,有什么样特别的地方呢?

 Graph 往往是人为根据某些 domain knowledge 建出来的,那 domain knowledge 告诉我们说,这两个向量彼此之间没有关联,我们就没有必要再用机器去学习这件事情。

image-20220613231411144

在 Graph 上面,每一个 node 可以表示成一个向量,但不只有 node 的资讯,还有 edge 的资讯,我们知道哪些 node 之间是有相连的,也就是哪些 node 是有关联的。

我们知道哪些向量间是有关联,那之前我们在做 Self-attention 的时候,所谓的关联性是 network 自己找出来的,但是现在既然有了 Graph 的资讯,有了 edge 的资讯,那关联性也许就不需要透过机器自动找出来,这个图上面的 edge 已经暗示了我们,node 跟 node 之间的关联性

所以今天当你把 Self-attention,用在 Graph 上面的时候,你有一个选择是你在做这个,Attention Matrix 计算的时候,你可以只计算有 edge 相连的 node 就好。那如果两个 node 之间没有相连,那其实很有可能就暗示我们,这两个 node 之间没有关係,既然没有关係,我们就不需要再去计算它的 attention score,直接把它设为 0 就好了

2.7 More

其实Self-attention 有非常非常多的变形,你可以看一篇 paper 叫做,Long Range Arena,里面比较了各种不同的 Self-attention 的变形。

image-20220613231703000

Self-attention 它最大的问题就是,它的运算量非常地大,所以怎么样减少 Self-attention 的运算量,是一个未来的重点,可以看到这边有,各种各式各样 Self-attention 的变形。

Self-attention 最早是,用在 Transformer 上面,所以很多人讲 Transformer 的时候,其实它指的就是这个 Self-attention,有人说广义的 Transformer,指的就是 Self-attention。那所以后来各式各样的,Self-attention 的变形都这样做,都叫做是什么 former,比如说 Linformer Performer Reformer 等等,所以 Self-attention 的变形,现在都叫做 xxformer。

那可以看到,往右代表它运算的速度,所以有很多各式各样新的 xxformer,它们的速度会比原来的 Transformer 快,但是快的速度带来的就是 performance 变差。这个纵轴代表是 performance,所以它们往往比原来的 Transformer,performance 差一点,但是速度会比较快。那到底什么样的 Self-attention,才能够真的又快又好,这仍然是一个尚待研究的问题,如果你对 Self-attention,想要进一步研究的话,你还可以看一下,Efficient Transformers: A Survey 这篇 paper,里面会跟你介绍,各式各样 Self-attention 的变形。

三、注意力机制 Q&A

3.1 Self-Attention、CNN、RNN对比?

Self-Attention vs CNN

  • CNN 可以看作是一种简化版的 Self-attention ,因为在做CNN的时候,我们只考虑 receptive field 里面的资讯,而在做 Self-attention 的时候,我们是考虑整张图片的资讯。
  • 在 CNN 里面 receptive field 的范围跟大小,是人决定的。而对 Self-attention ,不再是人工划定,而是让机器自己学出来
  • Self-attention 比较 flexible,之前有讲说比较 flexible 的 model,比较需要更多的 data,如果你 data 不够,就有可能 overfitting

Self-Attention vs RNN

  • RNN 右边的 vector,要考虑最左边的这个输入,那它必须要把最左边的输入存在 memory 里面,然后接下来都不能够忘掉,一路带到最右边,才能够在最后一个时间点被考虑。 Self-attention 只要a1输出一个 query,a4输出一个 key,只要它们 match 得起来,天涯若比邻,你可以从非常远的 vector,在整个 sequence 上非常远的 vector,轻易地抽取资讯,所以这是 RNN 跟 Self-attention一个不一样的地方。
  • RNN 是没有办法平行化的。所以在运算速度上,Self-attention 会比 RNN 更有效率。

3.2 Self-Attention、CNN、RNN时间复杂度对比?

##### 计算效率: 一个形状为 [公式] 的矩阵,与另一个形状为 [公式] 的矩阵相乘,其运算复杂度来源于乘法操作的次数,时间复杂度为 [公式]

Self-Attention

[公式]
  • [公式]
  • 相似度计算 [公式][公式][公式] 运算,得到 [公式] 矩阵,复杂度为 [公式]
  • softmax计算:对每行做softmax,复杂度为 [公式] ,则n行的复杂度为 [公式]
  • 加权和: [公式][公式] 运算,得到 [公式] 矩阵,复杂度为 [公式]

故最后self-attention的时间复杂度为 [公式]

对于受限的self-attention,每个元素仅能和周围 [公式] 个元素进行交互,即和 [公式][公式] 维向量做内积运算,复杂度为 [公式] ,则 [公式] 个元素的总时间复杂度为 [公式]

Multi-Head Attention

[公式]

对于multi-head attention,假设有 [公式] 个head,这里 [公式] 是一个常数,对于每个head,首先需要把三个矩阵分别映射到 [公式] 维度。这里考虑一种简化情况: [公式] 。(对于dot-attention计算方式, [公式][公式] 可以不同)。

  • 输入线性映射的复杂度: [公式][公式] 运算,忽略常系数,复杂度为 [公式]
  • Attention操作复杂度:主要在相似度计算及加权和的开销上, [公式][公式] 运算,复杂度为 [公式][公式]
  • 输出线性映射的复杂度:concat操作拼起来形成 [公式] 的矩阵,然后经过输出线性映射,保证输入输出相同,所以是 [公式][公式] 计算,复杂度为 [公式]

故最后的复杂度为: [公式]

注意:多头的计算并不是通过循环完成的,而是通过 transposes and reshapes,用矩阵乘法来完成的。假设有 [公式] 个head,则新的representation dimension: [公式] 。因为,我们将 [公式] 的矩阵拆为 [公式] 的张量,再利用转置操作转为 [公式] 的张量。故 [公式] 的计算为: [公式][公式] 做计算,得到 [公式] 的张量,复杂度为 [公式] ,即 [公式] 。注意,此处 [公式] 实际是一个常数,故 [公式] 复杂度为 [公式]

Recurrent

[公式]
  • [公式][公式][公式] 运算,复杂度为 [公式][公式] 为input size
  • [公式][公式][公式] 运算,复杂度为 [公式]

故一次操作的时间复杂度为 [公式][公式] 次序列操作后的总时间复杂度为 [公式]

Convolution

注: 这里保证输入输出都是一样的,即均是 [公式]

  • 为了保证输入和输出在第一个维度都相同,故需要对输入进行padding操作,因为这里kernel size为 [公式] ,(实际kernel的形状为 [公式] )如果不padding的话,那么输出的第一个维度为 [公式] ,因为这里stride是为1的。为了保证输入输出相同,则需要对序列的前后分别padding长度为 [公式]
  • 大小为 [公式] 的卷积核一次运算的复杂度为: [公式] ,一共做了 [公式] 次,故复杂度为 [公式]
  • 为了保证第二个维度在第二个维度都相同,故需要 [公式] 个卷积核,所以卷积操作总的时间复杂度为 [公式]

一、Seq2Seq

CS224n笔记[7]:整理了12小时,只为让你20分钟搞懂Seq2seq - 蝈蝈的文章 - 知乎 https://zhuanlan.zhihu.com/p/147310766

目录:

  • 机器翻译

    • 传统机器翻译,SMT
    • 神经机器翻译,NMT
  • Seq2seq

    • Seq2seq结构详解
    • 为什么训练和预测时的Decoder不一样?
    • Seq2seq的损失函数
    • Decoding和Beam Search
  • 总结

    • NMT的优缺点
    • 机器翻译的评价指标

1.1 seq2seq结构详解

CS224n笔记[7]:整理了12小时,只为让你20分钟搞懂Seq2seq

这张图,展示了在「训练时」,seq2seq内部的详细结构。

在Encoder端,我们将source文本的词序列先经过embedding层转化成向量,然后输入到一个RNN结构(可以是普通RNN,LSTM,GRU等等)中。另外,这里的RNN也可以是多层、双向的。经过了RNN的一系列计算,最终隐层的输入,就作为源文本整体的一个表示向量,称为「context vector」

Decoder端的操作就稍微复杂一些了。首先,Decoder的输入是什么呢?Decoder的输入,训练和测试时是不一样的! 「在训练时,我们使用真实的目标文本,即“标准答案”作为输入」(注意第一步使用一个特殊的<start>字符,表示句子的开头)。每一步根据当前正确的输出词、上一步的隐状态来预测下一步的输出词。

下图则展示了在「预测时」,seq2seq的内部结构:

img

预测时,Encoder端没什么变化,在Decoder端,由于此时没有所谓的“真实输出”或“标准答案”了,所以只能「自产自销:每一步的预测结果,都送给下一步作为输入」,直至输出<end>就结束。如果你对我之前写的笔记很熟悉的话,会发现,「这时的Decoder就是一个语言模型」。由于这个语言模型是根据context vector来进行文本的生成的,因此这种类型的语言模型,被称为“条件语言模型”:Conditional LM。正因为如此,在训练过程中,我们可以使用一些预训练好的语言模型来对Decoder的参数进行初始化,从而加快迭代过程。

1.2 为什么训练和预测时的Decoder不一样?

很多人可能跟我一样,对此感到疑惑:为什么在训练的时候,不能直接使用这种语言模型的模式,使用上一步的预测来作为下一步的输入呢?

img

我们称这两种模式,根据标准答案来decode的方式为「teacher forcing」,而根据上一步的输出作为下一步输入的decode方式为「free running」

其实,free running的模式真的不能在训练时使用吗?——当然是可以的!从理论上没有任何的问题,又不是不能跑。但是,在实践中人们发现,这样训练太南了。因为没有任何的引导,一开始会完全是瞎预测,正所谓“一步错,步步错”,而且越错越离谱,这样会导致训练时的累积损失太大(「误差爆炸」问题,exposure bias),训练起来就很费劲。这个时候,如果我们能够在每一步的预测时,让老师来指导一下,即提示一下上一个词的正确答案,decoder就可以快速步入正轨,训练过程也可以更快收敛。因此大家把这种方法称为teacher forcing。所以,这种操作的目的就是为了使得训练过程更容易。

所以,更好的办法,更常用的办法,是老师只给适量的引导,学生也积极学习。即我们设置一个概率p,每一步,以概率p靠自己上一步的输入来预测,以概率1-p根据老师的提示来预测,这种方法称为「计划采样」(scheduled sampling):

img

另外有一个小细节:在seq2seq的训练过程中,decoder即使遇到了<end>标识也不会结束,因为训练的时候并不是一个生成的过程 ,我们需要等到“标准答案”都输入完才结束。

1.3 Seq2Seq的损失函数

在上面的图中,我们看到decoder的每一步产生隐状态后,会通过一个projection层映射到对应的词。那怎么去计算每一步的损失呢?实际上,这个projection层,通常是一个softmax神经网络层,假设词汇量是V,则会输出一个V维度的向量,每一维代表是某个词的概率。映射的过程就是把最大概率的那个词找出来作为预测出的词。

在计算损失的时候,我们使用交叉熵作为损失函数,所以我们要找出这个V维向量中,正确预测对应的词的那一维的概率大小[公式],则这一步的损失就是它的负导数[公式],将每一步的损失求和,即得到总体的损失函数:

[公式]

其中T代表Decoder有多少步,[EOS]代表‘end of sentence’这个特殊标记.

1.4 Decoding和Beam search

前面画的几个图展示的预测过程,其实就是最简单的decoding方式——「Greedy Decoding」,即每一步,都预测出概率最大的那个词,然后输入给下一步。

img

这种Greedy的方式,简单快速,但是既然叫“贪心”,肯定会有问题,那就是「每一步最优,不一定全局最优」,这种方式很可能“捡了芝麻,丢了西瓜”。

改进的方法,就是使用「Beam Search」方法:每一步,多选几个作为候选,最后综合考虑,选出最优的组合。

下面我们来具体看看Beam Search的操作步骤:

  • 首先,我们需要设定一个候选集的大小beam size=k;
  • 每一步的开始,我们从每个当前输入对应的所有可能输出,计算每一条路的“序列得分”;
  • 保留“序列得分”最大的k个作为下一步的输入;
  • 不断重复上述过程,直至结束,选择“序列得分”最大的那个序列作为最终结果。

这里的重点就在于这个“序列得分”的计算。

我们使用如下的score函数来定义「序列得分」

[公式]

这个score代表了当前到第t步的输出序列的一个综合得分,越高越好。其中[公式]类似于前面我们写的第t步的交叉熵损失的负数。所以这个score越到,就意味着到当前这一步为止,输出序列的累积损失越小。

再多描述不如一张图直观,我用下图描绘一个极简的案例(只有3个词的语料,k=2):

img

最后还有一个问题:由于会有多个分支,所以很有可能我们会遇到多个<end>标识,由于分支较多,如果等每一个分支都遇到<end>才停的话,可能耗时太久,因此一般我们会设定一些规则,比如已经走了T步,或者已经积累了N条已完成的句子,就终止beam search过程。

在search结束之后,我们需要对已完成的N个序列做一个抉择,挑选出最好的那个,那不就是通过前面定义的score函数来比较吗?确实可以,但是如果直接使用score来挑选的话,会导致那些很短的句子更容易被选出。因为score函数的每一项都是负的,序列越长,score往往就越小。因此我们可以使用长度来对score函数进行细微的调整:对每个序列的得分,除以序列的长度。根据调整后的结果来选择best one。

Beam Search的使用,往往可以得到比Greedy Search更好的结果,道理很容易理解,高手下棋想三步,深思熟虑才能走得远。

1.5 NMT的优缺点

NMT相比于SMT,最大的优点当然就如前面所说的——简洁。我们不需要什么人工的特征工程,不需要各种复杂的前后组件,就是一个端到端的神经网络,整个结构一起进行优化

另外,由于使用了深度学习的方法,我们可以引入很多语义特征,比如利用文本的相似度,利用文本内隐含的多层次特征,这些都是统计学方法没有的。

但是,没有什么东西是绝对好或绝对差的,NMT也有其不足。它的不足也是跟深度学习的黑箱本质息息相关。NMT的解释性差,难以调试,难以控制,我们谁也不敢保证遇到一个新的文本它会翻译出什么奇怪的玩意儿,所以NMT在重要场合使用是有明显风险的。

1.6 NMT的评价

机器翻译的效果如何评价呢?——「BLEU」指标。BLEU,全称是Bilingual Evaluation Understudy,它的主要思想是基于N-gram等特征来比较人工翻译和机器翻译结果的相似程度。