2021 CCF BDCI 全国信息检索挑战杯(CCIR-Cup)智能人机交互自然语言理解赛道第二名参赛解决方案

Overview

2021 CCF BDCI 全国信息检索挑战杯(CCIR-Cup) 智能人机交互自然语言理解赛道第二名解决方案

比赛网址: CCIR-Cup-智能人机交互自然语言理解

1.依赖环境:

  • python==3.8
  • torch==1.7.1+cu110
  • numpy==1.19.2
  • transformers==4.5.1
  • scikit_learn==1.0
  • seqeval==1.2.2
  • tqdm==4.50.2
  • CUDA==11.0

2.解决方案

1.数据预处理部分

1.首先对任务进行明确,赛题任务是意图识别与槽填充,在观察训练数据之后,发现槽填充任务可分解为两类任务来做:一类是标准槽填充任务,即槽值可在当前对话句子当中完全匹配到;另一类是非标准槽填充(自拟的名字),即槽值不可在当前对话句子中找到或者完全匹配。对于非标准槽填充任务,把它当作另一种分类任务来解决。所以,我就把比赛任务当作三个子任务来进行,分别是意图识别、标准槽填充和非标准槽填充(分类任务)。

2.对于标准槽填充而言,有些槽标签在大部分训练数据中都是可完全匹配的,但是仍然存在少量不完全匹配槽标签,例如:句中出现的是港片、韩剧、美剧、内地、英文、中文等词汇时,对应的槽值标注却是香港、韩国、美国、大陆、英语、华语等。对于这一类数据,若将其当作非标准槽填充任务显得不太合理,解决方案是:提前准备好一个特殊词汇的映射字典 region_dic.json,在处理训练数据的时候,如果碰到了有的槽值出现在特殊词汇字典中,则对其进行槽标注的时候需要先进行转换。

3.然后用 ernie 的 Tokenizer 将对话句子按字切分,可能存在 ##后缀 和 [UNK] 的情况,将切分好的句子作为原始输入,对于标准槽填充任务,按 BIO 的方式进行标注。观察训练数据后发现,标准槽填充任务中存在少量的嵌套命名实体,例如:

{
"NLU07301": {
    "text": "西安WE比赛的视频帮我找一下",
    "intent": "Video-Play",
    "slots": {
      "name": "西安WE比赛的视频",
      "region": "西安"
    }
  }
}

对于这种少量嵌套的例子,我并没有涉及特殊的网络结构来解决,而是使用了一种简单的方式:首先将每条训练数据的 slots 下的所有槽值的长度按从大到小排列,然后在对其进行序列标注的时候按槽的先后顺序进行标注,比如上面的例子的标注方式为:

首先是 "name" 这个槽标签:

B-name I-name I-name I-name I-name I-name I-name I-name I-name O O O O O

然后是 "region" 这个槽标签:

B-region I-region I-name I-name I-name I-name I-name I-name I-name O O O O O

"region" 标注完成后将 B-name I-name 这两个tag给覆盖掉了。

最后,对于这种嵌套实体,模型就按照这种标注方式去训练;在解码的时候,按照一定的匹配规则识别出"name" 和 "region"这两个槽标签,后面的实验中表明使用这种标注方式能够有效的识别出测试集数据中存在的嵌套实体。

4.手动纠正部分,训练数据中存在一些数据有着明显的标注错误。例如:NLU00400 的 "artist": "银临,河图",正确的标注应该为 "artist": ["银临",""河图"];"query_type":"汽车票查询" 和 "query_type":"汽车票",这两个明显就是一样的,故将其统一,再比如:

{
  "NLU04386": {
    "text": "明天早上7:20你会不会通知我带洗衣液",
    "intent": "Alarm-Update",
    "slots": {
      "datetime_date": "明天",
      "notes": "带洗衣液",
      "datetime_time": "早上7"
    }
  }
}

"datetime_time":"早上7" 标注错误,正确标注应该为"datetime_time": "早上7:20",且类似这种的错误在"Alarm-Update"这个意图中大量存在。如果不进行纠正,则对模型的训练会造成很大的影响。

5.对于非标准槽填充部分,统计出了四种槽标签:command、index、play_mode 和 query_type,将这四类槽标签的槽值当作类别,一共有29种类别,如:

音量调节
查询状态
汽车票查询
穿衣指数
紫外线指数
...
None

None表示不存在这一类值。然后对其进行类似意图识别那样做分类。

6.对于域外检测任务:在 a 榜阶段,我在 LCQMC 数据集中选择了1000条左右数据作为 Other 数据的来源;在 b 榜阶段,我把 a 榜阶段预测出的 intent 为 Other 的数据加上 LCQMC数据集中选择出500条数据一起作为训练集的 intent 为 Other 类进行训练。

7.对于小样本检测任务:发现意图为 Audio-Play 和 TVProgram_Play 的这两个意图是小样本数据,在原始训练集中分别为50条。解决方法:对小样本意图数据进行数据增强,使其数量接近基本任务数据的1000条左右,具体做法:分别对 Audio-Play 和TVProgram_Play这两个意图进行增强,举例来说,对于 Audio-Play 而言,其可能的槽标签有

8.在模型输出后,进行一步后处理操作:对模型预测结果进行纠正,即把不属于某一类intent的槽值删除,首先统计出训练数据中的意图和槽标签之间的关系:

{
  "FilmTele-Play": ["name", "tag", "artist", "region", "play_setting", "age"],
  "Audio-Play": ["language", "artist", "tag", "name", "play_setting"],
  "Radio-Listen": ["name", "channel", "frequency", "artist"],
  "TVProgram-Play": ["name", "channel", "datetime_date", "datetime_time"],
  "Travel-Query": ["query_type", "datetime_date", "departure", "destination", "datetime_time"],
  "Music-Play": ["language", "artist", "album", "instrument", "song", "play_mode", "age"],
  "HomeAppliance-Control": ["command", "appliance", "details"],
  "Calendar-Query": ["datetime_date"],
  "Alarm-Update": ["notes", "datetime_date", "datetime_time"],
  "Video-Play": ["name", "datetime_date", "region", "datetime_time"],
  "Weather-Query": ["datetime_date", "type", "city", "index", "datetime_time"],
  "Other": []
}

就可以发现意图只能包含特定的标签,某些标签不可能出现在其它意图中
举例来说:比如我在一条测试数据中预测出其intent = FilmTele-Play, 然后其槽值预测中出现了"notes"这个槽标签,这与我之前统计的哪些槽标签只出现在哪些意图中不符合(即训练数据中FileTele-Play这个意图不可能出现"notes"这个槽标签),所以该函数就把"notes"这个槽位和槽值删除掉。

"Audio-Play": ["language", "artist", "tag", "name", "play_setting"], 一共五类,分别在训练数据中统计出各个槽标签可能出现的槽值有哪些,比如 "language": ["日语", "英语", "法语", "俄语", "西班牙语", "华语", "韩语", "德语", "藏语"] ,language 有这些可选项,当然也可以自己随便添加几个合适的选项。得到了一个这种字典后,对于每一条原训练数据中意图为 Audio-Play 的数据进行扩充,每一条扩充20条新数据,具体扩充方式:对于原数据而言,如果某一个槽标签出现,则在该槽标签对应的标签候选项中随机选择一个替换它,对原数据存在的每一个槽标签都进行这种操作,这样就增加了一条”新数据“,经过实验验证,小样本数据扩充前后,线上得分提升了两个点,证明这种方式还是效果不错的。
9.在a榜阶段,训练数据包括三部分:原始训练数据 + 小样本意图扩充数据 + LCQMC数据集(1000条)当作域外数据;在b榜阶段,训练数据除了和a榜相同的部分外,还把模型在a榜测试集上的输出当作a榜测试集的标注,再将这些数据也添加到训练数据中进行训练,然后再去预测b榜测试集,所以b榜阶段的最终使用的训练集有13119条。

2.模型算法部分

此次比赛我一共使用了三个模型进行训练,最后的结果 result.json 由三个模型的投票表决产生。

1.JointErine 模型

思路参照:BERT for Joint Intent Classification and Slot Filling

预训练模型并没有使用中文版 bert base,而是使用的是百度的中文版 ernie-1.0 base,三个任务进行联合训练。意图识别和非标准槽填充使用 erine 模型的输出分别连接一个全连接层进行分类;标准槽填充得到 erine 的输出后,再将其输入到 CRF 层,erine预训练模型与CRF层采用不同的学习率,erine 的学习率是5e-5,CRF层的学习率是5e-2

2.InteractModel_1 模型

思路参照:A CO-INTERACTIVE TRANSFORMER FOR JOINT SLOT FILLING AND INTENT DETECTION

仍然是三个任务联合训练,不同的是,意图识别和标准槽填充部分进行了一层交互,非标准槽填充未与上述二个任务进行交互,而是把预训练模型的输出 pooled_output 直接输入到全连接层中进行分类。

交互层部分:

首先使用中文版 ernie-1.0 base 预训练模型作为主体部分: $$ 对于输入的序列{x_1,x_2,...,x_n}(n是token的数量),输入到中文版ernie-1.0模型之后得到输出H = {h_1, h_2, ..., h_n} $$ 然后是意图和标准槽填充的交互层,这个模型中使用了一层交互层:

标签注意力层

image-20210929212611984

协同交互注意力层

image-20210929212740433

前馈神经网络层

image-20210929212830068

解码器层部分

image-20210929213002909

3.InteractModel_3模型

InteractModel_3 模型结构类似于上述讲解的 InteractModel_1 ,唯一的区别就是 InteractModel_3 的意图识别和标准槽填充部分使用了三层的交互。
镜像复现说明请查看 ccir/image/README.md

3.项目目录结构

ccir
|-- data                                                —— 数据文件夹
|   |-- code                                            —— 包含所有代码文件夹
|   |   |-- __init__.py
|   |   |-- model                                       —— 与网络模型相关文件夹
|   |   |   |-- __init__.py
|   |   |   |-- InteractModel_1.py                      —— InteractModel_1 网络模型
|   |   |   |-- InteractModel_3.py                      —— InteractModel_3 网络模型
|   |   |   |-- JointBertModel.py                       —— JointBertModel 网络模型
|   |   |   |-- __pycache__
|   |   |   |   |-- __init__.cpython-38.pyc
|   |   |   |   |-- InteractModel_1.cpython-38.pyc
|   |   |   |   |-- InteractModel_3.cpython-38.pyc
|   |   |   |   |-- JointBertModel.cpython-38.pyc
|   |   |   |   `-- torchcrf.cpython-38.pyc
|   |   |   `-- torchcrf.py                             —— CRF层网络模型
|   |   |-- predict                                     —— 包含推理代码的文件夹
|   |   |   |-- __init__.py     
|   |   |   |-- integration.py                          —— 负责将三个模型的结果进行投票输出成最后的结果result.json
|   |   |   |-- post_process.py                         —— 对模型的结果进行后处理的代码
|   |   |   |-- __pycache__
|   |   |   |   |-- __init__.cpython-38.pyc
|   |   |   |   |-- post_process.cpython-38.pyc
|   |   |   |   |-- test_dataset.cpython-38.pyc
|   |   |   |   `-- test_utils.cpython-38.pyc
|   |   |   |-- run_interact1.py                        —— 对线上训练的InteractModel_1模型进行推理
|   |   |   |-- run_interact3.py                        —— 对线上训练的InteractModel_3模型进行推理
|   |   |   |-- run_JointBert.py                        —— 对线上训练的JointBert模型进行推理
|   |   |   |-- run_trained_interact1.py                —— 对本地训练的InteractModel_1模型进行推理
|   |   |   |-- run_trained_interact3.py                —— 对本地训练的InteractModel_3模型进行推理
|   |   |   |-- run_trained_JointBert.py                —— 对本地训练的JointBert模型进行推理
|   |   |   |-- test_dataset.py                         —— 构建测试集dataset
|   |   |   `-- test_utils.py                           —— 测试集的工具类函数
|   |   |-- __pycache__
|   |   |   `-- __init__.cpython-38.pyc
|   |   |-- preprocess                                  —— 数据预处理代码
|   |   |   |-- __init__.py     
|   |   |   |-- analysis.py                             —— 分析训练数据,哪些意图包含哪些标签
|   |   |   |-- extend_audio_sample.py                  —— 用于扩充意图为”Audio-Play“的小样本数据
|   |   |   |-- extend_tv_sample.py                     —— 用于扩充意图为”TVProgram-Play“的小样本数据
|   |   |   |-- extract_intent_sample.py                —— 在训练数据中提取特定意图的数据
|   |   |   |-- generate_intent.py                      —— 对训练数据和验证集数据提取意图
|   |   |   |-- process_other.py                        —— 处理域外数据
|   |   |   |-- process_rawdata.py                      —— 处理原始训练数据和验证集数据
|   |   |   |-- rectify.py                              —— 对意图为”Alarm-Update“的训练数据进行纠正
|   |   |   |-- slot_sorted.py                          —— 对槽填充的标注按槽值从大到小进行排序
|   |   |   |-- split_train_dev.py                      —— 将原始训练数据按8: 2划分
|   |   `-- scripts
|   |       |-- build_vocab.py                          —— 构建词典,加载词汇表
|   |       |-- config_Interact1.py                     —— InteractModel_1的配置文件(参数设置)
|   |       |-- config_Interact3.py                     —— InteractModel_3的配置文件(参数设置)
|   |       |-- config_jointBert.py                     —— JointBert的配置文件(参数设置)
|   |       |-- dataset.py                              —— 构建训练集dataset
|   |       |-- __init__.py
|   |       |-- __pycache__
|   |       |   |-- build_vocab.cpython-38.pyc
|   |       |   |-- config_Interact1.cpython-38.pyc
|   |       |   |-- config_Interact3.cpython-38.pyc
|   |       |   |-- config_jointBert.cpython-38.pyc
|   |       |   |-- dataset.cpython-38.pyc
|   |       |   |-- __init__.cpython-38.pyc
|   |       |   `-- utils.cpython-38.pyc
|   |       |-- train_interact1.py                      —— InteractModel_1的主函数训练代码
|   |       |-- train_interact3.py                      —— InteractModel_3的主函数训练代码
|   |       |-- train_jointBert.py                      —— JointBert的主函数训练代码
|   |       `-- utils.py                                —— 训练阶段的工具类函数(train、valid等)
|   |-- __init__.py
|   |-- prediction_result                               —— 模型推理结果result.json的保存文件夹
|   |-- __pycache__
|   |   `-- __init__.cpython-38.pyc
|   |-- raw_data                                        —— 原始训练集文件夹
|   `-- user_data                                       —— 用户数据文件夹
|       |-- common_data                                 —— 训练和验证时使用的公共文件夹
|       |   |-- intent_label.txt                        —— 包含11类意图的txt文件
|       |   |-- intent_slot_mapping.json                —— 意图与槽标签对应关系的字典
|       |   |-- region_dic.json                         —— 用于帮助训练集槽标注的映射字典
|       |   |-- slot_label.txt                          —— 标准槽标签
|       |   `-- slot_none_vocab.txt                     —— 非标准槽标签
|       |-- dev_data
|       |   |-- dev_intent_label.txt                    —— 验证集数据的意图
|       |   |-- dev_seq_in.txt                          —— 验证集数据的原始句子分词输入
|       |   |-- dev_seq_out.txt                         —— 验证集数据的序列标注
|       |   `-- dev_slot_none.txt                       —— 验证集数据的非标准槽填充分类标签
|       |-- output_model                                —— 保存训练过程中间的模型文件夹
|       |   |-- InteractModel_1                         —— InteractModel_1文件夹(线上训练的模型保存在该文件夹下)
|       |   |   `-- trained_model                       —— 保存本地训练好的模型的文件夹
|       |   |       `-- Interact1_model_best.pth.tar    —— 本地训练好的InteractModel_1模型
|       |   |-- InteractModel_3                         —— InteractModel_3文件夹(线上训练的模型保存在该文件夹下)
|       |   |   `-- trained_model
|       |   |       `-- Interact3_model_best.pth.tar    —— 本地训练好的InteractModel_3模型
|       |   `-- JointBert                               —— JointBert文件夹(线上训练的模型保存在该文件夹下)
|       |       `-- trained_model
|       |           `-- bert_model_best.pth.tar         —— 本地训练好的JointBert模型
|       |-- pretrained_model                            —— 预训练模型文件夹
|       |   `-- ernie                                   —— ernie
|       |       |-- config.json
|       |       |-- pytorch_model.bin
|       |       |-- special_tokens_map.json
|       |       |-- tokenizer_config.json
|       |       `-- vocab.txt
|       |-- test_data                                   —— 测试集文件夹
|       |   |-- test_B_final_text.json                  —— 测试集原始json文件
|       |   `-- test_seq_in_B.txt                       —— 经过Tokenizer分词后的测试集文件
|       |-- tmp_result                                  —— 保存单个模型输出结果
|       `-- train_data                                  —— 训练集文件夹
|           |-- train_intent_label.txt                  —— 训练集数据的意图
|           |-- train_seq_in.txt                        —— 验证集数据的原始句子分词输入
|           |-- train_seq_out.txt                       —— 验证集数据的序列标注
|           `-- train_slot_none.txt                     —— 验证集数据的非标准槽填充分类标签
|-- image                                               —— 镜像相关文件夹
|   |-- readme_images                                   —— 存放赛题解决方案和算法介绍的README文档的图片
|   |-- ccir-image.tar                                  —— 镜像文件
|   |-- README.md                                       —— 关于复现具体操作的REDAME文档
|   |-- run_infer.sh                                    —— 使用本地训练的模型进行线上推理的脚本
|   `-- run.sh                                          —— 进行线上训练和推理的脚本
`-- README.md                                           —— 赛题整体的解决方案和算法介绍的README文档
Owner
JinXiang
自然语言处理
JinXiang
PyMatting: A Python Library for Alpha Matting

Given an input image and a hand-drawn trimap (top row), alpha matting estimates the alpha channel of a foreground object which can then be composed onto a different background (bottom row).

PyMatting 1.4k Dec 30, 2022
Lenia - Mathematical Life Forms

For full version list, see Timeline in Lenia portal [2020-10-13] Update Python version with multi-kernel and multi-channel extensions (v3.4 LeniaNDK.p

Bert Chan 3.1k Dec 28, 2022
ESTDepth: Multi-view Depth Estimation using Epipolar Spatio-Temporal Networks (CVPR 2021)

ESTDepth: Multi-view Depth Estimation using Epipolar Spatio-Temporal Networks (CVPR 2021) Project Page | Video | Paper | Data We present a novel metho

65 Nov 28, 2022
TensorFlow-based implementation of "ICNet for Real-Time Semantic Segmentation on High-Resolution Images".

ICNet_tensorflow This repo provides a TensorFlow-based implementation of paper "ICNet for Real-Time Semantic Segmentation on High-Resolution Images,"

HsuanKung Yang 406 Nov 27, 2022
A tool to estimate time varying instantaneous reproduction number during epidemics

EpiEstim A tool to estimate time varying instantaneous reproduction number during epidemics. It is described in the following paper: @article{Cori2013

MRC Centre for Global Infectious Disease Analysis 78 Dec 19, 2022
Article Reranking by Memory-enhanced Key Sentence Matching for Detecting Previously Fact-checked Claims.

MTM This is the official repository of the paper: Article Reranking by Memory-enhanced Key Sentence Matching for Detecting Previously Fact-checked Cla

ICTMCG 13 Sep 17, 2022
Deep learning library featuring a higher-level API for TensorFlow.

TFLearn: Deep learning library featuring a higher-level API for TensorFlow. TFlearn is a modular and transparent deep learning library built on top of

TFLearn 9.6k Jan 02, 2023
A simple root calculater for python

Root A simple root calculater Usage/Examples python3 root.py 9 3 4 # Order: number - grid - number of decimals # Output: 2.08

Reza Hosseinzadeh 5 Feb 10, 2022
RATCHET is a Medical Transformer for Chest X-ray Diagnosis and Reporting

RATCHET: RAdiological Text Captioning for Human Examined Thoraxes RATCHET is a Medical Transformer for Chest X-ray Diagnosis and Reporting. Based on t

26 Nov 14, 2022
MPLP: Metapath-Based Label Propagation for Heterogenous Graphs

MPLP: Metapath-Based Label Propagation for Heterogenous Graphs Results on MAG240M Here, we demonstrate the following performance on the MAG240M datase

Qiuying Peng 10 Jun 28, 2022
Official Pytorch Implementation for Splicing ViT Features for Semantic Appearance Transfer presenting Splice

Splicing ViT Features for Semantic Appearance Transfer [Project Page] Splice is a method for semantic appearance transfer, as described in Splicing Vi

Omer Bar Tal 253 Jan 06, 2023
Yolact-keras实例分割模型在keras当中的实现

Yolact-keras实例分割模型在keras当中的实现 目录 性能情况 Performance 所需环境 Environment 文件下载 Download 训练步骤 How2train 预测步骤 How2predict 评估步骤 How2eval 参考资料 Reference 性能情况 训练数

Bubbliiiing 11 Dec 26, 2022
The Surprising Effectiveness of Visual Odometry Techniques for Embodied PointGoal Navigation

PointNav-VO The Surprising Effectiveness of Visual Odometry Techniques for Embodied PointGoal Navigation Project Page | Paper Table of Contents Setup

Xiaoming Zhao 41 Dec 15, 2022
Jigsaw Rate Severity of Toxic Comments

Jigsaw Rate Severity of Toxic Comments

Guanshuo Xu 66 Nov 30, 2022
[peer review] An Arbitrary Scale Super-Resolution Approach for 3D MR Images using Implicit Neural Representation

ArSSR This repository is the pytorch implementation of our manuscript "An Arbitrary Scale Super-Resolution Approach for 3-Dimensional Magnetic Resonan

Qing Wu 19 Dec 12, 2022
Pytorch implementation for Semantic Segmentation/Scene Parsing on MIT ADE20K dataset

Semantic Segmentation on MIT ADE20K dataset in PyTorch This is a PyTorch implementation of semantic segmentation models on MIT ADE20K scene parsing da

MIT CSAIL Computer Vision 4.5k Jan 08, 2023
[CVPR 2022] Official Pytorch code for OW-DETR: Open-world Detection Transformer

OW-DETR: Open-world Detection Transformer (CVPR 2022) [Paper] Akshita Gupta*, Sanath Narayan*, K J Joseph, Salman Khan, Fahad Shahbaz Khan, Mubarak Sh

Akshita Gupta 127 Dec 27, 2022
Neural Dynamic Policies for End-to-End Sensorimotor Learning

This is a PyTorch based implementation for our NeurIPS 2020 paper on Neural Dynamic Policies for end-to-end sensorimotor learning.

Shikhar Bahl 47 Dec 11, 2022
An open-source Deep Learning Engine for Healthcare that aims to treat & prevent major diseases

AlphaCare Background AlphaCare is a work-in-progress, open-source Deep Learning Engine for Healthcare that aims to treat and prevent major diseases. T

Siraj Raval 44 Nov 05, 2022
PyTorch implementation of our ICCV 2021 paper, Interpretation of Emergent Communication in Heterogeneous Collaborative Embodied Agents.

PyTorch implementation of our ICCV 2021 paper, Interpretation of Emergent Communication in Heterogeneous Collaborative Embodied Agents.

Saim Wani 4 May 08, 2022