【云驻共创】基于转移的语义Parser分享

举报
AnRFDev 发表于 2021/08/27 15:48:14 2021/08/27
6.6k+ 0 0
【摘要】 语义依存分析是NLP中十分经典的任务 。 它可以分析一个自然语言句子中的语言单位成分之间的依存关系 。 得到的依存关系可以应用在NLP下游的任务中 。 比如机器翻译 , 事件抽取 , 语义角色标注等等 。本文分为下面几个部分 :论文解读什么是语义分析 , 介绍常用方法 。代码复现拆分讲解代码关键点 。使用方法介绍在ModelArts上实操 。论文解读 论文基本信息《A Neural Tran...

语义依存分析是NLP中十分经典的任务 。 它可以分析一个自然语言句子中的语言单位成分之间的依存关系 。 得到的依存关系可以应用在NLP下游的任务中 。 比如机器翻译 , 事件抽取 , 语义角色标注等等 。

本文分为下面几个部分 :

  • 论文解读
    • 什么是语义分析 , 介绍常用方法 。
  • 代码复现
    • 拆分讲解代码关键点 。
  • 使用方法介绍
    • 在ModelArts上实操 。

论文解读

论文基本信息

《A Neural Transition-Based Approach for Semantic Dependency Graph Parsing》

AAAI-18 (The Association for the Advance of Artificial Intelligence)

作者

YuXuan Wangl yxwang@ir.hit.edu.cn

Wanxiang Che* car@ir.hit.edu.cn

哈尔滨工业大学SCIR实验室 http://ir.hit.edu.cn/

http://people.csail.mit.edu/jiang_guo/papers/aaai2018-nnsdp.pdf

研究背景

依存句法分析

关注句子的语法结构 。 比如主谓宾 , 定状补 。

依存语义分析

关注句子深层的语义信息 。 跨过语法结构 , 直接获取更深层次的语义信息 。

这个例子是一份分析结果 。 上面的是依存句法分析 , 下面是依存语义分析 。

依存句法分析 中 :

  • “在餐厅”和“用勺子”都是状语 。
  • “喝”是谓语 。
  • “我”是主语 。
  • “玉米汤”是宾语 。

句法parsing是要解析得到一个句法树 。 更关注句法结构 。 句法结构中有一个父节点 , 它是树结构 。

依存语义分析

“餐厅”、“勺子”都是“喝”的论元 。 “餐厅”指的是地点 , “勺子”指的是工具 。

需要关注的是 , 语义依存是图结构 , 而不是树结构 。 它的每个节点可能会有多个头 。 一个单词在句子中可能会作为多种成分 。

语义依存图

这个例子中 , 主要的英文数据集有DM、PAS、PSD、EDS、UCCA、AMR 。

DM和PSD比较类似 , 都以词为节点 。

EDS与UCCA比较像 , 都以语义片段为节点 。

AMR有一些抽象的语义表示 。

可以在这里看到详细说明 :http://mrp.nlpl.eu/2019/index.php?page=4#training

在本篇论文复现中,实验的中文数据集是SemEval-2016 Task 9中的TEXT和NEWS 。

这两个是中文数据集 。 参考 :https://github.com/HIT-SCIR/SemEval-2016

上面蓝色的是依存句法分析 , 下面紫色的是依存语义分析 。

我们看下面紫色的是依存语义分析 :

“小丽”同时作为“帮助”和“学习”这两个谓词的论元 。 导致“小丽”有两个头节点 。

转移系统

转移算法: List-based Arc-eager算法(Choi and McCallum 2013)

如上图所示 , 需要用 2 个栈 , Stack和Buffer 。 还有一个队列 。

有 7 种转移动作对栈和队列进行操作 , 来标记出一个完整的语义依存图 。

转移动作:

1) LEFT-REDUCE

2) RIGHT-SHIFT

3) NO-SHIFT

4) NO-REDUCE

5) LEFT-PASS

6) RIGHT-PASS

7) NO-PASS

转移动作中 , 横杠 「-」 前后表示的是不同的操作 。

前面指的是要产生什么样的弧 。

后面指的是如何操作栈和队列 。

前半部分有 :

LEFT: 从Stack栈顶和Buffer头部产生一个向左的弧

RIGHT: 从Stack栈顶和Buffer头部产生一个向右的弧

NO: 不产生弧

后半部分有 :

REDUCE: 销毁Stack栈顶数据

SHIFT: Buffer头部数据拿出来压入Stack栈顶

PASS: Stack拿出栈顶放入Deque中

词嵌入(Word Embedding)

词向量:100维+预训练词向量( 对模型性能提升很大 )

字向量:50维

词性:50维

lemma :50维

其它:词向量扩充词典;shuffle;dropout;随机初始化等调优操作

编码层

在转移系统中的对每一步进行编码 。

如下图 , 上部分图里Stack有 3 个词 , Buffer里有 2 个 。 模型需要知道现在的情况才能输出 。 对Stack 、 Deque和Buffer进行编码 。

编码层 : Buffer

上图是 Bi-LSTM Subtraction的编码过程

在论文中介绍了 Bi-LSTM Subtraction模块 。 Buffer中是一个连续的完整的单词串 , 先用Bi - LSTM编码整个句子 。

编码层 : Stack

RecNN 递归神经网络

在处理较深的子结构时可能会出现梯度消失问题 。

本篇论文提出用 Tree-LSTM 对子结构进行建模 。

Tree-LSTM 能合并节点和子节点 。

建模的子结构不一定是树 。 依存图中不存在环 , 我们能够使用LSTM 。

基于转移的依存分析中 , 我们可以一个个找到节点 ( 弧 )。

Tree-LSTM的编码过程

每当找到一个新的节点 , 把它们合并 。 如上图 (1), a+b来作为原来A的代表 。

Tree-LSTM用这种方法把标记出来的结构进行编码 。

编码层 : Deque和Action

Stack LSTM:拥有pop、push等栈操作,可以动态计算LSTM

参考论文

论文:Transition-Based Dependency Parsing with Stack Long Short-Term Memory

论文地址: https://aclanthology.org/P15-1033/

论文:Parallelizable Stack Long Short-Term Memory

论文地址:https://aclanthology.org/W19-1501/

总体结构

上图是模型的总体结构 。

左边是Stack ; buffer是右边 ; 下面是队列和转移动作 。

把它们的整个表示用向量进行拼接 。 把得到的全部表示用线性压缩增加激活函数 。 最后预测概率 。

但这种编码方式会有错误传播的问题 。 后文会提到 。

评价指标

有 4 种评价指标 。 先看F值的说明

以下是 4 种指标 :

LF(labeled F-score) 带标签的F值

UF(unlabeled F-score) 不带标签的F值

NLF(non-local dependencies LF) 多头结点的LF值

NUF(non-local dependencies UF) 多头结点的UF值

LF比UF更加严格 , 弧和标签都要预测对 。

实验

第一行都是baseline 。

+ BS行的结果能比baseline高零点几 。 在NUF项提升很大 。

+ IT的结果表现也比baseline好 。

+ BS & IT是两个模块都用 , 各个指标都有了不小的提升 。

我们认为是对模块提供了很多结构信息 , 多头结点的弧预测提高了很多 。

需要注意的是 , TEXT中 + IT的NUF项反而降低了 。

上表是解码速度 , 单位是 tokens/s, 可以和其他转移方法进行比较 。

可以看出 , 添加了BS或者IT后 , 解码速度会降低 。

其他 基于图方法

BiAffine Parser

图方法是一个端到端的方法 。 从输入层直接送到编码层 。 编码层可以是SelfAtt也可以是BiLSTM 。 输出的隐藏层直接送到MLP中压缩 。 再用 B iaffine进行打分 。

非常适合大矩阵运算 。 图方法适合深度学习时代 。

其它:Batch化困难

基于转移的语义分析 , 准确率比图方法稍差 。 难用上大规模矩阵操作 , 训练推理速度非常慢 。

原因:

1. 同一个batch中的各个转移动作不一致

2. 各个句子的转移动作序列长度不一致 ( 每个句子不能使用同样的矩阵操作 )

错误传播

错误产生后 , 离正确结果偏移的越来越远 。 一种解决方法是采用Dynamic oracle进行训练。

一般来说转移路径都是用static oracle ( 静态 ) 来训练 。 出现错误的话 , 得到的结果会偏离 。

用Dynamic oracle进行训练 。

在训练时加入一些模型同位的状态 , 让模型去适应真实场景 。 即训练过程中加入噪声 。

其它 栈指针方法

Transition-based Semantic Dependency Parsing with Pointer Networks.

2020 ACL.

代码复现

初始化

3 个依赖包

  • AllenNLP:数据载入
  • MoXing:与OBS存储交互
  • PyTorch:深度学习框架

依赖包的官网

  • AllenNLP: https://docs.allennlp.org/main/
  • MoXing: https://support.huaweicloud.com/moxing-devg-modelarts/modelarts_11_0002.html
  • PyTorch: https://pytorch.org/

AllenNLP不能直接加载 , 要用代码加载一下 , 可能涉及到权限问题 。

ModelArts上可能会遇到路径问题 。 按照ModelArts指定的目录来存放数据 。

/home/work/modelarts/inputs/SDP_data

/home/work/modelarts/outputs/SDP_output/

编码层

解码层

贪心解码


计算当前分值:

得到 4 个表示 :stack_emb, buffer_emb, action_emb, deque_emb

把它们用 torch.cat 进行拼接得到向量 p_t, 用 tanh 函数进行压缩

LOSS

基于ModelArts实操演示

首先在AiGallery上订阅算法 。

案例指导 : https://bbs.huaweicloud.com/forum/thread-92854-1-1.html

简要流程如下 :

  • 订阅算法后 , 可以在算法管理中找到已订阅的算法 。 可以创建训练作业 。 把OBS的路径进行设置 。
  • 开始训练 。 能看到运行成功的状态 。 在模型管理中 , 把刚才创建好的模型导入 。
  • TEXT训练时间比NEWS稍微多一些 , NEWS训练集比较小 。
  • 部署 。 搭建起一个服务 。

以下是几个步骤的截图 :

https://marketplace.huaweicloud.com/markets/aihub/modelhub/detail/?id=0e7f6c71-e289-4737-8709-d0af17e789f5

准备数据集

https://github.com/HIT-SCIR/SemEval-2016

安装OBS

https://support.huaweicloud.com/browsertg-obs/obs_03_1003.html

创建桶

订阅算法 , 图中是已订阅状态

在算法管理中找到语义分析

创建训练作业

部署

部署时 , 可以选择 「 在线服务 」 或者 「 批量服务 」。 实操演示完成 。

总结

语义依存分析是NLP中十分经典的任务 。 通过读论文 , 我们了解依存语法分析和依存语义分析的特点和不同点 ; 了解转移系统的原理 。 用代码进行了复现 。 最后在ModelArts上进行训练得到模型 , 并部署了在线服务 。

本文整理自华为云社区内容共创活动  基于转移的语义Parser分享  查看活动详情 https://bbs.huaweicloud.com/blogs/293957

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。