Flat-Lattice-Transformer模型源码测试


论文地址:
FLAT: Chinese NER Using Flat-Lattice Transformer
原github项目地址:
Flat-Lattice-Transformer

1. 下载embedding

Character and Bigram embeddings (gigaword_chn.all.a2b.{‘uni’ or ‘bi’}.ite50.vec) :

下载地址

Word(Lattice) embeddings:yj, (ctb.50d.vec)

下载地址

Word(Lattice) embeddings:ls, (sgns.merge.word.bz2)

下载地址

在项目根目录下新建文件夹embeddings,将所有embedding文件都放入embeddings/文件夹下面。

2. 下载数据集

2.1. OntoNotes

需要注册申请,暂无法获取

2.2. MSRA

下载地址

MSRA数据需要进行预处理,原始数据为bio标注,需要转成bmes。

2.2.1. 数据预处理
  • 新建py脚本文件util/prepro_data.py,内容如下:
#!usr/bin/env python
# encoding: utf-8

from const.paths import msra_ner_cn_path
import os
import sys

def BIO2BMES(input_file, output_file):
    print("Convert BIO -> BMES for file:", input_file)
    with open(input_file,'r') as in_file:
        fins = in_file.readlines()
    fout = open(output_file,'w')
    words = []
    labels = []
    for line in fins:
        if len(line) < 3:
            sent_len = len(words)
            for idx in range(sent_len):
                if "-" not in labels[idx]:
                    fout.write(words[idx]+" "+labels[idx]+"\n")
                else:
                    label_type = labels[idx].split('-')[-1]
                    if "B-" in labels[idx]:
                        if (idx == sent_len - 1) or ("I-" not in labels[idx+1]):
                            fout.write(words[idx]+" S-"+label_type+"\n")
                        else:
                            fout.write(words[idx]+" B-"+label_type+"\n")
                    elif "I-" in labels[idx]:
                        if (idx == sent_len - 1) or ("I-" not in labels[idx+1]):
                            fout.write(words[idx]+" E-"+label_type+"\n")
                        else:
                            fout.write(words[idx]+" M-"+label_type+"\n")
            fout.write('\n')
            words = []
            labels = []
        else:
            if line == '0\t\n':
                words.append('0')
                labels.append('O')
            else:
                pair = line.strip('\n').split()
                words.append(pair[0])
                labels.append(pair[-1].upper())
    fout.close()
    print("BMES file generated:", output_file)

def msra_bio2bmes(msrapath):
    train_dev_path = os.path.join(msrapath, 'msra_train_bio.txt')
    train_dev_path_out = os.path.join(msrapath, 'train_dev.char.bmes')
    test_path = os.path.join(msrapath, 'msra_test_bio.txt')
    test_path_out = os.path.join(msrapath, 'test.char.bmes')

    BIO2BMES(train_dev_path, train_dev_path_out)
    BIO2BMES(test_path, test_path_out)

if __name__ == '__main__':
    msra_bio2bmes(msra_ner_cn_path)
    print('- Done!')

按照配置paths.py文件,配置好路径以后,直接运行脚本:

cd util
python prepro_data.py

如果要使用clip(限制句子长度,将长句子进行拆分)的MSRA数据训练模型还需要*_clip1文件,可以在项目根目录运行下面命令生成:

python preprocess.py --clip_msra

2.3. Weibo

下载地址

weibo数据需要进行预处理,将原始数据中的seg信息去掉。

2.3.1. 数据预处理
  • 在py脚本文件util/prepro_data.py中添加如下内容:
#!usr/bin/env python
# encoding: utf-8

from const.paths import weibo_ner_path
import os

def deseg_weibo(weibopath):
    train_path = os.path.join(weibopath, 'weiboNER_2nd_conll.train')
    dev_path = os.path.join(weibopath, 'weiboNER_2nd_conll.dev')
    test_path = os.path.join(weibopath, 'weiboNER_2nd_conll.test')

    for data_file in [train_path, dev_path, test_path]:
        output_file = data_file + "_deseg"
        f_out = open(output_file, "w", encoding='utf8')
        with open(data_file, "r", encoding='utf8') as f:
            for line in f.readlines():
                line = line.strip()
                if line != "":
                    span_list = line.split('\t')
                    raw_char = ''.join(list(span_list[0])[:-1])
                    tag = span_list[-1]
                    f_out.write(' '.join([raw_char, tag]) + '\n')
                else:
                    f_out.write('\n')

if __name__ == '__main__':
    deseg_weibo(weibo_ner_path)
    print('- Done!')

可以先直接运行脚本,生成数据文件,这样就没必要修改load_data.py文件了。

2.4. ResumeNER

下载地址

ResumeNER数据可直接使用。

将所有数据集文件都放入data/文件夹下面,文件夹结构如下:

-data
--Resume
---dev.char.bmes
---test.char.bmes
---train.char.bmes
--MSRA
---msra_test_bio.txt
---msra_train_bio.txt
---test.char.bmes
---train_dev.char.bmes
---test.char.bmes_clip1
---train_dev.char.bmes_clip1
--Weibo
---weiboNER_2nd_conll.dev
---weiboNER_2nd_conll.test
---weiboNER_2nd_conll.train
---weiboNER_2nd_conll.dev_deseg
---weiboNER_2nd_conll.test_deseg
---weiboNER_2nd_conll.train_deseg

3. 配置环境

conda create -n FLAT python=3.7.3
# gpu
conda install pytorch==1.2.0 torchvision==0.4.0 cudatoolkit=10.0 -c pytorch
# cpu
conda install pytorch==1.2.0 torchvision==0.4.0 cpuonly -c pytorch
pip install FastNLP==0.5.0 -i https://pypi.doubanio.com/simple
pip install Numpy==1.16.4 -i https://pypi.doubanio.com/simple
pip install fitlog -i https://pypi.doubanio.com/simple
pip install pytz -i https://pypi.doubanio.com/simple

其中FastNLP和fitlog都是复旦大学计算机科学技术学院自然语言处理与深度学习组的fastNLP团队开发的。

可直接运行conda env create -f environment.yml命令,从environment.yml或者environment-gpu.yml文件中创建名为FLAT的conda环境。

4. 配置paths.py文件

修改paths.py文件为如下内容,然后只用配置PROJECT_DIR(项目根目录)即可。

PROJECT_DIR = '/home/appendDisk/PycharmProjects/NER/Flat-Lattice-Transformer'

yangjie_rich_pretrain_unigram_path = PROJECT_DIR + '/embeddings/gigaword_chn.all.a2b.uni.ite50.vec'
yangjie_rich_pretrain_bigram_path = PROJECT_DIR + '/embeddings/gigaword_chn.all.a2b.bi.ite50.vec'
yangjie_rich_pretrain_word_path = PROJECT_DIR + '/embeddings/ctb.50d.vec'
yangjie_rich_pretrain_char_and_word_path = PROJECT_DIR + '/embeddings/yangjie_word_char_mix.txt'
# lk_word_path = '/remote-home/xnli/data/pretrain/chinese/sgns.merge.word'
lk_word_path_2 = PROJECT_DIR + '/embeddings/sgns.merge.word_2'



# ontonote4ner_cn_path = PROJECT_DIR + '/data/OntoNote4'
msra_ner_cn_path = PROJECT_DIR + '/data/MSRA'
resume_ner_path = PROJECT_DIR + '/data/Resume'
weibo_ner_path = PROJECT_DIR + '/data/Weibo'

5. 配置日志文件

5.1. 使用V0中的flat_main.py

fitlog init V0
cd V0
# fitlog log logs

修改V0/flat_main.py文件:

import fitlog
# use_fitlog = False
use_fitlog = True

5.2. 使用V1中的flat_main.py

fitlog init V1
cd V1
# fitlog log logs

6. embedding文件预处理

运行下面脚本:

python preprocess.py

7. 训练模型

7.1. GPU设备

python flat_main.py --dataset resume
# 如果默认device报gpu OOM错误,可以通过nvidia-smi命令查看闲置的编号(如2),然后运行下面命令
python flat_main.py --dataset resume --device 2

目前可用的数据文件只有resume

MSRA和weibo数据好像都要做预处理,项目中没有给出详细的预处理信息

OntoNotes数据暂时无法获取

7.2. CPU设备

python flat_main.py --dataset resume --device cpu还是会报找不到gpu未指定cpu的错误,参数未生效。

报错内容如下:

ValueError: There is no usable gpu. set `device` as `cpu` or `None`.

修改V0/flat_main.py文件:

if args.device!='cpu':
    if args.device == 'None':# 添加内容
        device = None# 添加内容
    else:# 添加内容
        assert args.device.isdigit()
        device = torch.device('cuda:{}'.format(args.device))
else:
    device = torch.device('cpu')

refresh_data = True

运行下面命令即可:

python flat_main.py --dataset resume --device None

8. 查看模型结果

以下是在gpu服务器上运行的结果
仅输出了模型相关参数,没有输出训练好的模型。

8.1. MSRA

目前的只用了一个device,一直报CUDA out of memory,目前跑不了了,看看后面能不能找到支持多GPU运行的办法。

github issue的类似问题里,作者说”吃的显存应该和训练数据中的最长句子的长度相关,对10g显存来说,一般支持长度200的句子“。
也有可能是数据预处理的问题,看看后面作者会不会公开预处理的脚本吧。

8.2. Weibo

8.2.1. V0结果摘要

时间信息:/V0/logs/log_20201202_110755/other.log

{"other": {"cost_time": "0h20m18s"}}

评价指标:/V0/logs/log_20201202_110755/metric.log

Step:6750	{"metric": {"SpanFPreRecMetric": {"f": 0.626109, "pre": 0.6175, "rec": 0.634961}, "label_acc": {"acc": 0.961509}}, "step": 6750, "epoch": 50}
Step:6750	{"metric": {"data_test": {"SpanFPreRecMetric": {"f": 0.592593, "pre": 0.591885, "rec": 0.593301}, "label_acc": {"acc": 0.956756}}}, "step": 6750, "epoch": 50}

其中最大的F1值为:0.635538

8.2.2. V1结果摘要

时间信息:/V1/logs/log_20201202_114132/other.log

{"other": {"cost_time": "0h40m55s"}}

评价指标:/V1/logs/log_20201202_114132/metric.log

Step:7695	{"metric": {"SpanFPreRecMetric": {"f": 0.685786, "pre": 0.66586, "rec": 0.706941}, "label_acc": {"acc": 0.964555}}, "step": 7695, "epoch": 57}
Step:7695	{"metric": {"data_test": {"SpanFPreRecMetric": {"f": 0.689017, "pre": 0.666667, "rec": 0.712919}, "label_acc": {"acc": 0.964987}}}, "step": 7695, "epoch": 57}

其中最大的F1值为:0.708763

8.3. ResumeNER

8.3.1. V0结果摘要

时间信息:/V0/logs/log_20201201_162830/other.log

{"other": {"cost_time": "0h35m50s"}}

评价指标:/V0/logs/log_20201201_162830/metric.log

Step:19150	{"metric": {"SpanFPreRecMetric": {"f": 0.949153, "pre": 0.944444, "rec": 0.953908}, "label_acc": {"acc": 0.975378}}, "step": 19150, "epoch": 50}
Step:19150	{"metric": {"data_test": {"SpanFPreRecMetric": {"f": 0.944887, "pre": 0.943154, "rec": 0.946626}, "label_acc": {"acc": 0.96543}}}, "step": 19150, "epoch": 50}

其中最大的F1值为:0.951855

8.3.2. V1结果摘要

时间信息:/V1/logs/log_20201201_173707/other.log

{"other": {"cost_time": "1h25m38s"}}

评价指标:/V1/logs/log_20201201_173707/metric.log

Step:19916	{"metric": {"SpanFPreRecMetric": {"f": 0.893802, "pre": 0.896505, "rec": 0.891116}, "label_acc": {"acc": 0.947228}}, "step": 19916, "epoch": 52}
Step:19916	{"metric": {"data_test": {"SpanFPreRecMetric": {"f": 0.894314, "pre": 0.900996, "rec": 0.88773}, "label_acc": {"acc": 0.94298}}}, "step": 19916, "epoch": 52}

其中最大的F1值为:0.951859


接下来打算做的事情:

  1. 跑通MSRA和weibo数据
  2. 调用训练好的模型对输入字符串进行NER抽取任务
  3. 如何支持在多GPU运行
  • 19
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 41
    评论
### 回答1: 平面格变换器(Flat Lattice Transformer)是一种用于自然语言处理的神经网络模型,它是基于Transformer模型的改进版本。与传统的Transformer模型不同,平面格变换器使用平面格结构来表示输入和输出序列,这种结构可以更好地捕捉序列中的局部依赖关系。平面格变换器在机器翻译、文本分类、问答系统等任务中取得了很好的效果。 ### 回答2: Flat-lattice-transformer 是一种新型的序列建模技术,它是基于已有的transformer模型而进行改良升级所得到的。Flat-lattice-transformer在序列任务中具有极强的建模能力,在各种语言模型、机器翻译、文本分类等自然语言处理任务中表现优异。 Flat-lattice-transformer的主要思想是将传统的句子表示构建转换成一种扁平化的结构,从而解决了原来transformer模型中无法处理较长句子的问题。Flat-lattice-transformer将输入序列转换成一个图,将每个单词作为结点,并根据它们之间的依赖关系建立边,得到一个扁平的表示。这样做的好处是可以在不损失重要信息的前提下,缩小模型的空间复杂度,使其能够处理更长的序列。 构建这样一个扁平的图结构需要进行一系列的预处理和转换,其中最重要的是将输入的序列转换成一个有限状态自动机(Finite State Machine,FSM),然后将该自动状态转换成一个有向图。在构建图结构之后,Flat-lattice-transformer还会对其进行一定的拓扑排序和优化,以便在后续处理中更加高效地搜索图的信息。 最终的输出是一个矩阵,其中每个元素代表了一个状态下输出的结果概率,然后根据这个矩阵来计算输入序列的概率。 Flat-lattice-transformer在一些自然语言处理任务中已经取得了优异的成果,而且其对于长句建模和处理的能力更为突出,成为了自然语言处理领域中一个备受关注的技术。 ### 回答3: Flat-lattice-transformer是指一种基于transformer模型的语音识别系统。它是由研究人员提出的一种新型语音识别架构,用于解决传统语音识别系统中困扰人们已久的问题。 传统的语音识别系统通常采用深度神经网络(DNN)或循环神经网络(RNN)进行声学建模。这些模型通常使用帧级别的信息来预测每个音素的输出结果。然而,由于音素之间存在连续性和上下文依赖性,这种方法往往会导致误识别率较高。 Flat-lattice-transformer采用transformer作为声学建模器,从而利用transformer的自注意力机制学习多级别上下文信息,并能够直接预测音素序列,而无需使用基于帧的分类器。另外,该模型引入统一的flat lattice生成机制,将声学特征和语言学知识进行融合,使得模型具备更好的能力来解决上下文依赖性和连续性的问题,从而实现了更高的识别精度。 Flat-lattice-transformer还具有许多其他优点。例如,与传统的基于标注的端到端语音识别系统相比,它不需要任何语言标注信息,因此可以避免标注数据的稀缺性和昂贵的标注成本。此外,该系统还可以在训练数据较少的情况下实现较高的识别性能,这为许多实际应用提供了便利和可能性。 总的来说,Flat-lattice-transformer是一种比传统语音识别系统更优秀的语音识别架构。它的出现为语音识别领域带来了新的思路和技术,同时也为我们提供了更多解决语音识别问题的可能性。
评论 41
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值