0%

认知图谱学习笔记

今天阅读一篇来自清华和阿里巴巴团队的关于机器阅读理解方面的论文,Cognitive Graph for Multi-Hop Reading Comprehension at Scale。这篇论文同样中了ACL2019,但我没有将其放进ACL2019论文阅读的博文里,因为感觉这篇值得专门讲讲,虽然没有拿到优秀论文或者杰出论文,甚至提名都没有,但这篇论文的思路、方法论都非常好,用一种最简单的方式实现联结主义+知识推理。

mClGgH.png

任务

  • 作者提出的框架叫CogQA,也就是用基于认知图谱的框架来解决机器阅读理解里的问答,包括一般性问答(选择实体),以及比较性问答(两个实体之间的关系)。先抛开认知图谱不说,看看这个任务是什么。
  • 这个问答任务特殊的地方在于延伸到了多跳,multi-hop。多跳其实不应该是任务类型,而是指完成实体类问答任务的一种方式,即找到问题中的实体,根据这些实体在其对应介绍上下文中找到线索(clues),在这些线索里接着找实体作为下一跳(hop),下一跳的实体用于跳转到对应的介绍上下文,并在其中接着找线索,如此往复,直到多跳之后在正确的描述中找到正确的实体作为答案。一个问答,你可以用一跳的思路解决,也可以用多跳的思路解决。实际上大多数基于信息检索的问答模型就是基于一跳的,这类模型就只是比较问题和上下文,找出最相关的句子,再从这些句子中找出实体。这样做本质上是一种模式匹配,其问题在于,加入问题本身是多跳的,那么基于一跳的模式匹配可能根本找不出正确的实体,因为答案都不在候选的句子里。
  • 这和人类回答问题的方式其实很类似,比方我们问发表于ACL2019的认知图谱的作者是谁,我们会先找到ACL2019和认知图谱这两个实体,再分别到其线索中找到ACL2019所有论文对应作者和认知图谱的多种含义(可能有神经科学,可能有教育学,可能有自然语言处理),再找到更多的实体和描述(不同论文作者、不同含义的解释),最终找到一个或者多个答案。人类的思路可能会直接在ACL2019的所有论文标题里找认知图谱四个字,而计算机处理起来可能是ACL2019和认知图谱两部分延伸多跳之后在某一节点合并到一个实体,即作者的名字,然后作为答案输出。
  • 以上多个实体的多跳以及它们之间的拓扑关系就组成了认知图谱,一个有向图。这个有向图是可推理可解释的,不同于黑箱模型,有清晰的推理路线。那么问题就归结为:
    • 如何构造图?
    • 有了图,如何推理?
  • 作者首先提出了用认知科学里的双过程解释他们的做法。

双过程模型

  • 认知科学里的双过程是指,人类解决问题时会分两个步骤:
    • 系统一:先通过一个隐式的、无意识的、符合直觉的过程来分配注意力,检索相关信息
    • 系统二:再通过另一个显式的、有意识的、可控的过程来完成推理
    • 系统一给系统二提供资源,系统二指导系统一的检索,两者迭代进行
  • 这上面两个过程,其实可以对应到人工智能里的两大流派,联结主义和符号主义。第一个过程虽然是难以解释的、通过直觉完成的,但直觉不是天生的,实际上是通过生活经验得到的隐藏知识。这部分可以对应现在用深度学习完成的黑箱模型,通过对大量数据学习得到不可解释,但是能完成目的的模型。而第二个过程需要因果关系,或者需要显式的结构来帮助推理。
  • 具体到机器问答中,作者很自然的用了现有的神经网络模型来完成这两项工作:
    • 第一项需要分配注意力来检索相关信息,那么我就直接用自注意力模型,来完成实体的检索。
    • 第二项需要显式的结构,那么我就构造有向认知图谱,在认知图谱上完成推理。

如何构造图

  • 作者使用BERT来完成系统一的工作。BERT本身就可以用作一跳机器阅读理解,在这里作者沿用了一跳的做法,输入的句子对是问题和待标记实体的句子,输出是标记概率,即每个词是实体开始位置或者结束位置的概率。但是为了实现多跳,作者做了一点改动:
    • 输入的句子对不是以问题为基本单位,而是以每个问题中的每个实体为基本单位,具体而言,每个输入句子对的A句子由问题和问题中某一实体的线索(clue)拼接而成,而句子B是关于该实体的描述上下文中的所有句子。即
      • sentence A:\([CLS]Question[SEP]clues(x,G)[SEP]\)
      • sentence B:\(Para(x)\)
    • 那么某一实体的线索究竟是什么?线索是该实体在认知图谱里的所有父节点的介绍上下文中,提取出该实体的那一句话。可能有些拗口,但是这个设计是贯穿了整个系统,是其认知推理断的精髓所在,用论文给出的例子就是:
      • 问题:“谁在2003年拍了部电影,其中有一幕是在洛杉矶quality cafe拍的?”
      • 我们找到实体quality cafe,找到其介绍上下文:“......这是洛杉矶的一家咖啡店。这家店因其作为多部电影的取景地而出名,包括old school, gone in 60s等等。......”
      • 我们接着遍历这些电影名实体,接着找电影的介绍上下文,例如“old school是一部美国喜剧电影,拍于2003年,导演是todd phillips”,并且通过其他认知推理得到这个“todd phillips”就是正确答案,那么,这个导演实体的线索是什么?我们需要什么样的线索作为补充输入来得到“old school是一部美国喜剧电影,拍于2003年,导演是todd phillips”这句话中“todd phillips”就是我们想要的答案?
      • 答案就是“这家店因其作为多部电影的取景地而出名,包括old school, gone in 60s等等。”这句话。对应成BERT里的输入格式就是
      • sentence A:
        • Question:“谁在2003年拍了部电影,其中有一幕是在洛杉矶quality cafe拍的?”
        • clues(x,G):“这家店因其作为多部电影的取景地而出名,包括old school, gone in 60s等等。”
      • sentence B:“old school是一部美国喜剧电影,拍于2003年,导演是todd phillips”
      • 其中实体x是“old school”
    • 这个设计完成了系统一和系统二中的迭代部分,将两个系统连接了起来。这部分是让系统二利用图结构来指导系统一检索。并且通过循环往复,可能系统二更新了某一实体的父节点的特征,或者添加了新的父节点,这些都可能会导致有新的线索获得,系统一可以再次把这些线索拿来预测,找出之前没有找出的新的答案实体或者下一跳实体。
    • 那么系统二如何依赖系统一的结果呢?这里也分为两个部分
      • 做两个span prediction:系统一的BERT将答案实体和下一跳实体的预测起始结束位置分开,用四个参数向量来分别结合BERT输出的词特征向量来预测答案实体、下一跳实体的预测开始、结束位置共四个量。获得了答案和下一跳实体之后,将其加入认知图谱当中,作为当前实体的子节点,连上边。
      • 单单连上边当然不够,还需要节点特征。刚好BERT的位置0是提取整个句子对的特征,作者就将其作为节点特征\(sem(x,Q,clues)\)补充到图中。
    • 这样系统一就为图的扩展提供了拓扑关系和节点特征,从而为系统二提供了资源。

如何在图上推理

  • 这一部分就直接使用了GNN,在有向图上进行谱变换提取一层节点特征 \[ \Delta = \sigma ((AD^{-1})^T) \sigma (XW_1)) \\ X^1 = \sigma (XW_2 + \Delta) \\ \]
  • 之后的预测也只需要在变换后的节点特征上接一层简单网络来做回归或者分类就好了。
  • 注意虽然模型一提取了答案的span,但是答案span和下一跳实体span都作为节点加入到认知图谱当中,因为可能有多个答案节点,需要经过系统二来判断置信度,而需要BERT分别预测答案和下一跳的理由是:
    • 两者通过BERT得到的特征应该不同,需要独立的参数向量来辅助更新
    • 两者虽然是同等的加入认知图谱当中,但是只有下一跳节点会接着输入系统一来继续预测
  • 模型的损失包含两部分,分别是系统一的span prediction(answer & next hop) loss和系统二的answer prediction loss,都比较简单,可以直接看论文。

数据

  • 作者使用了HotpotQA的full-wiki部分来做训练测试,84%的数据需要多跳推理。训练集中每个问题提供了两个有用的实体,以及多个描述上下文和8个不相关描述上下文用于负采样。验证和测试时只有问题,需要给出答案和相关的描述上下文。
  • 为了构造gold-only认知图谱,即初始化的总的认知图谱,作者将所有的实体y和某一实体x的描述上下文中每一句做模糊匹配,匹配上了就将(x,y)作为一条边加入初始化的图谱中

总体流程

  • 输入:系统一、系统二、问题、预测网络、维基数据集
  • 用问题里的实体初始化构造gold-only图谱,并把这些实体标记为父节点,把初始化中模糊匹配找到的实体加入边界队列(待处理队列)
  • 重复以下过程
    • 从边界队列中弹出一个实体x
    • 从x的所有父节点那收集线索
    • 将该实体的线索、问题、该实体的描述上下文输入系统一,得到认知图谱节点表示\(sem(x^1,Q,clues)\)
    • 假如实体x是下一跳节点,那么:
      • 生成答案和下一跳的实体span
      • 对于下一跳实体span,假如其在维基数据库当中,就在图中创建新的下一跳节点并建立边;假如已经在图中,但是没有和当前实体x建立边,那就添加一条边,并把该节点加入边界队列
      • 对于答案实体span,直接加节点和边,而不需要经过维基数据库的判断,因为答案有可能不在数据库中
    • 通过系统二更新节点特征
  • 直到边界队列中没有节点,或者认知图谱足够大
  • 通过预测网络返回结果。
  • 通过以上流程可以看到,对每一条训练数据,在使用预测网络预测结果之前,需要两个系统交互迭代多次直到特征提取完全。迭代的条件是边界队列为空时停止,那么什么样的节点会加入边界队列?已经在图中且建立了新的边的下一跳节点,这一类节点可能带来新的线索,因此必须把这类节点都处理完,让系统二看到所有线索,之后才能做预测。

其他细节

  • 在系统一当中可能没有sentence B,即没有某个实体的描述上下文,这时我们可以仅仅通过BERT得到节点特征\(sem(x^1,Q,clues)\),而不预测答案和下一跳实体,即这个节点就作为有向图中的叶子节点,不再扩展。
  • 在初始化认知图谱时,不需要得到节点特征,仅仅预测span来构建边
  • 作者发现使用BERT的最后一层的位置0的特征作为节点特征不太好,因为高层的特征被转换成适用于span prediction,因此作者试验之后取BERT的倒数第三层来构建节点特征
  • 在做span prediction的时候,实际上是规定了一个span maximum length,然后预测top k个begin position,然后在span maximum length内预测end position
  • 作者还做了负采样来防止在无关句子上做span prediction,具体做法是先负采样出不相关的样本,将这些样本的[CLS]位置概率设为0,而正样本的该位置概率设为1。这样BERT就能在[CLS]位置学到这个sentence B是正样本的概率。之前选出的topk个span,只有begin position probability大于[CLS]位置概率才会被保留下来
  • 在伪算法描述的流程里,每次系统一更新了认知图谱结构,系统二就运行一次,实际上作者发现让系统一先把所有的边界节点遍历完,等图不再改变,再让系统二运行多次是一样的效果,而且效率更高。实际实现上也是采用这种算法。
  • HotpotQA包含特殊问题、非传统问题和传统问题,作者分别构建了预测网络,其中特殊问题是回归模型,其余两类是分类模型。
  • 初始化认知图谱的时候,不仅仅需要建立实体与下一跳实体之间的边,下一跳实体的begin和end位置也要标出来,feed给BERT模型
  • 作者还做了ablation study,主要是初始化的实体集不同,可以通过实验结果看出该模型还是比较依赖初始化的实体质量

结果

  • 在今年4月份以前一直霸榜HotpotQA几个月,直到最近被一个新的BERT模型打破,但至少该模型能够提供一个很好的解释性,例如下图所示的三种认知图谱推理情况 mClr8g.png

结论

  • 这个模型可以简单的看成是GNN在NLP的扩展,只不过用了强大的BERT做节点特征提取,但是GNN用于NLP的难点在于边关系的定义。本文对于关系的定义非常自然,和人类完成问答任务的直觉保持一致,并且BERT也不仅仅是提取节点特征,还完成了边的构建。这样的框架我感觉是很好的将黑盒模型和可解释模型结合起来,而不是一定要解释黑盒模型。黑盒将让他做黑盒擅长的部分,包括自然语言和推理网络的特征提取,而人类可以设计显式的边关系添加规则,两者合作,互补而不是互斥。