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
Code for CVPR 2018 paper --- Texture Mapping for 3D Reconstruction with RGB-D Sensor

G2LTex This repository contains the implementation of "Texture Mapping for 3D Reconstruction with RGB-D Sensor (CVPR2018)" based on mvs-texturing. Due

Fu Yanping(付燕平) 129 Dec 30, 2022
Lightweight stereo matching network based on MobileNetV1 and MobileNetV2

MobileStereoNet: Towards Lightweight Deep Networks for Stereo Matching

Cognitive Systems Research Group 139 Nov 30, 2022
Meta Learning Backpropagation And Improving It (VSML)

Meta Learning Backpropagation And Improving It (VSML) This is research code for the NeurIPS 2021 publication Kirsch & Schmidhuber 2021. Many concepts

Louis Kirsch 22 Dec 21, 2022
[ICCV 2021] Excavating the Potential Capacity of Self-Supervised Monocular Depth Estimation

EPCDepth EPCDepth is a self-supervised monocular depth estimation model, whose supervision is coming from the other image in a stereo pair. Details ar

Rui Peng 110 Dec 23, 2022
This repo holds the code of TransFuse: Fusing Transformers and CNNs for Medical Image Segmentation

TransFuse This repo holds the code of TransFuse: Fusing Transformers and CNNs for Medical Image Segmentation Requirements Pytorch=1.6.0, 1.9.0 (=1.

Rayicer 93 Dec 19, 2022
Augmented CLIP - Training simple models to predict CLIP image embeddings from text embeddings, and vice versa.

Train aug_clip against laion400m-embeddings found here: https://laion.ai/laion-400-open-dataset/ - note that this used the base ViT-B/32 CLIP model. S

Peter Baylies 55 Sep 13, 2022
An official reimplementation of the method described in the INTERSPEECH 2021 paper - Speech Resynthesis from Discrete Disentangled Self-Supervised Representations.

Speech Resynthesis from Discrete Disentangled Self-Supervised Representations Implementation of the method described in the Speech Resynthesis from Di

Facebook Research 253 Jan 06, 2023
Image-to-Image Translation in PyTorch

CycleGAN and pix2pix in PyTorch New: Please check out contrastive-unpaired-translation (CUT), our new unpaired image-to-image translation model that e

Jun-Yan Zhu 19k Jan 07, 2023
DuBE: Duple-balanced Ensemble Learning from Skewed Data

DuBE: Duple-balanced Ensemble Learning from Skewed Data "Towards Inter-class and Intra-class Imbalance in Class-imbalanced Learning" (IEEE ICDE 2022 S

6 Nov 12, 2022
RM Operation can equivalently convert ResNet to VGG, which is better for pruning; and can help RepVGG perform better when the depth is large.

RMNet: Equivalently Removing Residual Connection from Networks This repository is the official implementation of "RMNet: Equivalently Removing Residua

184 Jan 04, 2023
Experiments and code to generate the GINC small-scale in-context learning dataset from "An Explanation for In-context Learning as Implicit Bayesian Inference"

GINC small-scale in-context learning dataset GINC (Generative In-Context learning Dataset) is a small-scale synthetic dataset for studying in-context

P-Lambda 29 Dec 19, 2022
Generative Flow Networks for Discrete Probabilistic Modeling

Energy-based GFlowNets Code for Generative Flow Networks for Discrete Probabilistic Modeling by Dinghuai Zhang, Nikolay Malkin, Zhen Liu, Alexandra Vo

Narsil-Dinghuai Zhang 51 Dec 20, 2022
BMVC 2021: This is the github repository for "Few Shot Temporal Action Localization using Query Adaptive Transformers" accepted in British Machine Vision Conference (BMVC) 2021, Virtual

FS-QAT: Few Shot Temporal Action Localization using Query Adaptive Transformer Accepted as Poster in BMVC 2021 This is an official implementation in P

Sauradip Nag 14 Dec 09, 2022
Implementation based on Paper - Learning a Probabilistic Latent Space of Object Shapes via 3D Generative-Adversarial Modeling

Implementation based on Paper - Learning a Probabilistic Latent Space of Object Shapes via 3D Generative-Adversarial Modeling

HamasKhan 3 Jul 08, 2022
Informal Persian Universal Dependency Treebank

Informal Persian Universal Dependency Treebank (iPerUDT) Informal Persian Universal Dependency Treebank, consisting of 3000 sentences and 54,904 token

Roya Kabiri 0 Jan 05, 2022
利用python脚本实现微信、支付宝账单的合并,并保存到excel文件实现自动记账,可查看可视化图表。

KeepAccounts_v2.0 KeepAccounts.exe和其配套表格能够实现微信、支付宝官方导出账单的读取合并,为每笔帐标记类型,并按月份和类型生成可视化图表。再也不用消费一笔记一笔,每月仅需10分钟,记好所有的帐。 作者: MickLife Bilibili: https://spac

159 Jan 01, 2023
Add-on for importing and auto setup of character creator 3 character exports.

CC3 Blender Tools An add-on for importing and automatically setting up materials for Character Creator 3 character exports. Using Blender in the Chara

260 Jan 05, 2023
Learning to Predict Gradients for Semi-Supervised Continual Learning

Learning to Predict Gradients for Semi-Supervised Continual Learning Code for project: "Learning to Predict Gradients for Semi-Supervised Continual Le

Yan Luo 2 Mar 05, 2022
Attack classification models with transferability, black-box attack; unrestricted adversarial attacks on imagenet

Attack classification models with transferability, black-box attack; unrestricted adversarial attacks on imagenet, CVPR2021 安全AI挑战者计划第六期:ImageNet无限制对抗攻击 决赛第四名(team name: Advers)

51 Dec 01, 2022