这是一篇私人文章,用来解读徐凤娇学姐的医疗命名实体识别代码。
CBMA文件夹
里面有bam.py , cbam.py , model_resnet.py三个文件,是CNNradical.py的import CBAM需要的一个额外包。但据学姐所说后面这东西效果不好,没有使用了
data文件夹
bert文件夹
这个文件夹里存的是google发布的bert_base_chinese模型,是一个基于中文文本的预训练模型,直接导入使用的
dataset文件夹
放的是数据集,只有NER是本次实验的数据集,其他的是原LEBERT模型自带的。NER文件里有chip,cck,resume数据集。
embedding文件夹
最重量级的文件夹,里面放了21G大小的embedding.txt文件
log文件夹
用来存放tensorboard日志文件,还有一个label_result文件夹,用来存放在验证集和测试集上的结果(包括准确率,召回率和f1值)
result文件夹
用来存放验证集和测试集的预测标签的结果。还有一个best_model用来存放模型
feature文件夹
task_dataset.py
该文件 `task_dataset.py` 是一个 PyTorch 数据集类,用于处理和加载特定格式的数据。以下是对文件内容的详细解读:该文件主要用于定义一个自定义的数据集类 `TaskDataset`,它可以从指定的文件加载数据,并进行必要的预处理,以便在模型训练中使用。
主要组成部分
1. 导入模块
– 导入了必要的库,如 `os`, `json`, `random`, `torch`, `numpy` 等。
– 从 `function.preprocess` 导入了 `sent_to_matched_words_boundaries` 函数,用于处理文本数据。
2. 类 `TaskDataset`
– 继承自 `torch.utils.data.Dataset`,允许该类与 PyTorch 的数据加载器兼容。
3. 构造函数 `__init__`
– 接受文件路径 `file` 和一些参数 `params`。
– 初始化一些属性,如最大单词数、tokenizer、词汇表、标签等。
– 根据给定的参数构建一个保存的 NumPy 文件路径,尝试加载已存在的 NumPy 数据集以提高读取速度。
4. 数据集初始化 `init_np_dataset`
– 检查是否存在预处理后的 NumPy 文件:
– 如果存在,直接加载数据。
– 如果不存在,读取原始文件,进行数据预处理,包括:
– 文本和标签的截断。
– 使用 tokenizer 转换文本为 ID。
– 生成必要的数组(输入 ID、段 ID、注意力掩码、匹配单词 ID 等)。
– 该过程还会将处理后的数据保存为 NumPy 格式,供后续使用。
5. 方法 `__len__` 和 `__getitem__`
– `__len__` 方法返回数据集的大小。
– `__getitem__` 方法根据给定索引返回相应的数据项,数据项以张量形式返回,方便模型训练。
6. 辅助函数 `get_head_tail_label`
– 用于从标签中提取头部和尾部信息,返回两个列表指示每个标签是头部还是尾部。
该文件的作用是提供一个高效的数据加载和预处理机制,支持从 JSON 文件中读取数据,进行必要的预处理,并支持 PyTorch 数据加载器的使用。通过将处理后的数据保存为 NumPy 格式,可以显著提高数据加载速度,适用于需要频繁读取相同数据的训练过程。
vacab.py
是一个用于构建和管理词汇表的 Python 模块,主要用于将词或标签映射到对应的 ID,以及反向映射。
BIO2BIOES.py文件:
这个脚本实现了BIO格式转BMES格式的功能:
– BIO2BMES函数实现了具体的转换逻辑:
– 读取BIO格式文件每行词汇和标签
– 根据标签类型(B、I等)判断词汇属于开始、中间、结束等状态
– 输出对应的BMES格式标签
– Trans函数实现了保留换行不进行转换的功能:
– 读取原文件每行
– 如果是换行,直接写入结果文件
– 否则进行词汇标签提取,并写入结果文件
主要流程是:
1. 读取BIO格式输入文件每行
2. 提取词汇和标签
3. 根据标签类型判断词汇在实体中的位置(开始、中间、结束)
4. 输出对应的BMES格式标签替换原标签
5. 添加换行输出到结果文件
它实现了BIO转BMES的核心逻辑,同时支持不对换行进行转换,方便针对不同格式文件的处理。
整体实现清晰,功能完整,可以很好地实现NER标注文件的格式转换工作。
conlleval.py
这个conlleval.py文件实现了命名体识别(NER)模型评估的功能。
整体流程为:
1. 解析模型预测结果和ground truth文件,提取标签信息。
2. 对预测结果和ground truth进行対比,统计 true positive、false positive、false negative 等数值。
3. 根据这些指标计算常用的NER指标 Precision、Recall、F1 score。
4. 给出整体和每个类型的评估指标结果。
具体模块功能:
– evaluate():主要对比函数,遍历文件对预测结果和ground truth进行匹配,记录指标数据。
– metrics():根据记录的指标数据计算Precision、Recall、F1等指标。
– report():输出评估结果,包括整体和每个类型的指标 numerically 和文本描述形式。
– report_notprint():只返回结果不输出,用于其他处理。
– utils函数:解析输入文件、计算指标、统计类型等工具函数。
所以这个py文件实现了NER模型常见的CoNLL格式评估任务,可以对模型在测试集上进行自动化评估,并给出每个类型和整体的评价指标,是NER模型开发和比较的重要工具。
data_transfer.py
这个python文件主要目的是将不同来源和格式的命名实体识别数据集,转换为统一的数据格式。
总体来说,这个py文件主要完成以下工作:
1. 将不同来源的数据集,如人民日报数据集、微软数据集等,转换为项目统一数据格式。
2. 处理不同标注样式的数据集,如BIO、BMES等标注转换为统一样式。
3. 提取标注文本中的实体信息,生成标准数据结构。
4. 输出转换后的数据集到指定文件。
5. 统计转换数据集中实体类型和数量。
主要模块功能:
1. transfer_dataX函数:实现不同数据集的转换,处理不同来源和格式的数据集。
2. 分词、词性标注、实体提取:处理原始文本,识别并提取句子和实体信息。
3. 实体类型统一:如地址->地址实体等给实体类型赋予统一命名。
4. 输出:将转换后数据按行写入文件。
5. 统计:统计转换数据集中实体类型和数量。
通过这个py文件,可以方便地对不同格式和来源的NER数据集进行预处理,输出到统一格式的文件中,为后续模型训练和测试提供便利。它实现了NER不同数据集的自动转换处理。
demo.py
这个Python文件主要实现了基于Transformer的自注意力机制模型。
总体来说,这个py文件完成以下工作:
1. 定义了Star-Transformer网络中的编码器层结构StarEncoderLayer,实现了星型结构中的节点更新。
2. 实现了位置编码PositionalEncoding,为模型输入文本添加位置信息。
3. 实现基于self-attention计算注意力权重的网络层Self_Attention。
4. 使用正弦位置编码实现了内置式位置编码。
各个模块功能:
1. StarEncoderLayer:定义星型Transformer编码器层,实现卫星节点和中继节点的更新。
2. PositionalEncoding:为模型输入添加位置编码,注入位置信息。
3. Self_Attention:采用查询 key value 计算注意力,输出weighted sum结果。
4. 正弦位置编码:生成内置式位置编码矩阵,作为参数学习。
5. 相关计算模块:定义查询、键值项目、归一化等计算模块。
通过定义这些组件,实现了基于自注意力的Transformer编码器结构。它对Transformer模型进行了扩展,实现了星型结构模型的关键层StarEncoderLayer。能对Transformer有更深入的了解。
entitylenth.py
这个Python文件主要是统计和可视化不同来源NER数据集中的实体长度和类别分布情况。
总体来说,这个py文件实现了以下功能:
1. 统计weibo数据集中实体长度的分布,统计数量。
2. 统计resume数据集中不同实体类型的长度分布,统计数量。
3. 统计labels中各个实体类型的计数。
4. 绘制柱状图可视化实体长度分布。
5. 绘制柱状图可视化不同实体类型的数量分布。
具体实现:
1. 读取数据,统计实体长度,统计小于5、5-10、大于10的数量。
2. 读取数据,统计不同实体类型的实体长度,统计长度小于7和大于等于7的数量。
3. 使用Counter从labels中统计各个实体类型的计数。
4. 使用matplotlib定义画布大小,绘制不同情况下的柱状图。
5. 设置 titles、labels、xticks对齐标签,设置横纵轴名称。
6. 保存图片,提供可视化结果。
7. 绘制不同实体类别数量分布的柱状图。
通过统计NER数据集的长度和类别分布,可以更好地了解和处理数据集的特点,为后续模型训练和预测提供参考。它实现了NER数据集分析的自动化。
focalloss.py
这个Python文件实现了一种损失函数-Focal Loss,用于解决分类问题中的不平衡数据问题。
总体来说,这个py文件完成以下工作:
1. 定义了一个FocalLoss类,用于计算Focal Loss。
2. 实现了Focal Loss的前向计算过程。
具体来说:
1. FocalLoss类继承了nn.Module,实现了一个可以作为模型损失函数的Module。
2. 在构造函数__init__()中,定义两个超参数gamma和weight。
3. 前向计算forward函数:
– 首先使用nn.CrossEntropyLoss计算交叉熵损失ce_loss,其中可以输入权重weight。
– 计算predicted probabilities pt,利用target和预测结果计算pt。
– 根据公式计算focal loss两部分:
– (1-pt)**gamma实现下调易分类样例的影响
– ce_loss作为基础损失
– 分别对这两部分进行权重乘法
– 输出focal loss作为最终损失值
通过这几步,实现了Focal Loss这个新的损失函数。解决了分类任务中正负样本不平衡问题,给予难易样本不同程度的惩罚,有助于增强模型的鲁棒性。
在医疗命名实体识别这样的任务中,使用Focal Loss相比常用的交叉熵损失函数有以下几点优势:
1. 数据不平衡问题更为明显。医疗实体作为负样本的数量远大于正样本。这会导致模型更倾向于识别负样本。
2. 医疗实体的边界非常难确定,包括一些小实体和易被忽视的实体。这类样例正是focal loss设计用来加强的重点。
3. Focal Loss通过调整难易样本的损失权重,弱化对易分类样本的学习,强化对难分类样本的学习能力。这在医疗实体识别中至关重要。
4. 它可以利用预测值中的置信程度来自动调整样本loss之间的平衡,不需要人工设置类样本权重。
5. 与交叉熵相比,focal loss收敛速度更快,对样本学习更有针对性,对神经网络友好些。
所以,在医疗实体识别中:
– 数据本身就存在不平衡,难易样本明显。
– 利用难易样本的识别能力对模型更关键。
– Focal Loss天然解决上述问题,更适合这类任务。
因此使用Focal Loss可以帮助模型更好地学习医疗实体,防止被大量负样本掩盖,提升识别效果。
GAU.py
这个Python文件实现了一种自注意力机制-Gate Attention Unit(GAU)。
总体来说,这个py文件完成以下工作:
1. 定义了GAU模块,可以作为Transformer的一种模块使用。
2. 实现了GAU注意力计算的前向过程。
详细功能如下:
1. GateAttentionUnit类继承nn.Module,重写forward()方法。
2. 初始化参数,如注意力尺寸、学习率等。
3. 对输入特征提取query、key、value、position信息。
4. 根据query、key计算注意力得分,加入位置编码优化。
5. 对注意力矩阵进行L2正则化,从而实现非局部注意。
6. 注意力得分作为权重对value进行加权求和。
7. 对输出特征进行线性变换后加成原特征,得到最终输出。
8. 定义辅助函数如rope()实现相对位置编码等。
通过这些步骤,实现了一种新型的自注意力机制-GAU。相比一般Transformer,它加入了非局部关注能力,适用于一些序列模型任务。
本文件从原理到实现都很清晰地规范化了GAU这一注意力变体。
getlabel.py
这个Python文件主要用于从命名实体识别(NER)数据集中提取和统计实体标签,实现NER任务中的预处理步骤。
总体来说,这个py文件实现了如下功能:
1. 读取NER数据集文件并按行解析数据。
2. 提取每行中目标列(标签列)的元素并保存到列表中。
3. 去重,只存储唯一的标签。
4. 打印所有唯一标签。
5. 输出标签到新的文本文件(实现注释)。
具体步骤:
1. open()打开数据集文件,readline()逐行读取。
2. split()按空格分割每行,取标签列元素保存列表。
3. append()将每次读取的标签添加到列表中,set()转换为集合实现去重。
4. for循环遍历唯一标签列表,打印每个标签。
5. with open写文件模式打开新文件,for循环遍历唯一标签列表逐个输出。
该py文件实现了NER数据集标签的提取、统计和清洗工作。提取了有效标签,为后续任务提供了参考标准。
通过简洁有效地处理了数据集,为提取特征、统计统计量、训练模型等提供了便利,起到了重要的预处理作用。
idcnn.py
这个Python文件实现了一种卷积神经网络模型-Interactive Dilated Convolutional Network(IDCNN),用于序列标注任务。
总体来说,这个py文件完成以下工作:
1. 定义一个IDCNN模型类,实现模型的前向计算过程。
2. 实现必要的模型参数初始化和保存功能。
详细功能如下:
1. IDCNN类继承nn.Module,重写forward()实现前向计算。
2. 初始化Embedding层、卷积层数目、层数、核大小等参数。
3. 定义Embedding层对输入进行嵌入处理。
4. 定义卷积层和残差块,以不同程度的膨胀实现交互注意。
5. 在每个残差块内进行多次卷积操作和非线性激活。
6. 将所有残差块的输出通过拼接结合成输出。
7. 定义全连接层将输出映射成标签空间进行预测。
本模型通过交互式膨胀卷积实现了对上下文特征的深度结合,并堆叠多块残差结构增强代表能力,适用于序列标注任务。
modules.py
这个Python文件定义了一些常用的模块,用于序列标注模型的构建。
总体来说,该文件实现了:
1. 定义了MultiHeadAttention模块,实现多头注意力机制。
2. 定义了FeedForward模块,实现前向投影和残差连接。
3. 定义了CRF模块,用于条件随机场解码。
详细功能:
1. MultiHeadAttention定义了多头注意力结构,包括线性映射、头结合等操作。
2. FeedForward定义了两层全连接网络,实现前向传播加残差。
3. CRF模块包含了CRF损失计算和解码功能:
– 实现CRF损失计算(_score,_log_partition)
– CRF解码实现Viterbi算法,返回最优路径和概率(_viterbi_decode)
– 定义转移矩阵和辅助函数如attenion_padding_mask
这些模块提供了序列标注模型中的重要组成部分,如多头注意力机制、残差连接和CRF解码。
能清晰定义这些通用模块接口和算法细节,方便后续直接调用进行模型构建,起到重要的复用作用。
MutiheadedAttention.py
这个Python文件定义了一些注意力机制相关的模块,用于序列标注模型的构建。
总体来说,该文件实现了:
1. 定义了ScaledDotProductAttention模块,实现缩放点积注意力机制。
2. 定义了MultiHeadAttention模块,实现多头注意力机制。
3. 定义了MultiHeadSelfAttention模块,实现多头自注意力。
4. 定义了CrossAttention模块,实现交叉注意力。
详细功能:
1. ScaledDotProductAttention实现点积注意力计算及Masked操作。
2. MultiHeadAttention定义线性映射、头合成等多头注意力结构。
3. MultiHeadSelfAttention继承SelfAttention,实现多头自注意力计算。
4. CrossAttention实现了输入与记忆间的交叉注意力计算:
– 对输入和记忆分别应用线性映射
– 计算注意力得分并归一化
– 应用注意力得分与值计算加权和
5. 还定义了旋转式位置编码方式计算键值向量位置表示。
这些模块提供了注意力算法的基本结构,如多头机制、自注意力、交叉注意力等,为序列模型构建奠定重要基础。清晰定义接口有助于模块化的模型开发。
readme .md
# 基于BERT适配器的中性序列标注任务利用词汇表增强
本仓库包含了论文《基于BERT适配器的中性序列标注任务利用词汇表增强》(Lexicon Enhanced Chinese Sequence Labelling Using BERT Adapter)的代码和权重文件。
论文链接:https://aclanthology.org/2021.acl-long.454.pdf
如果有任何问题,请联系邮箱:willie1206@163.com
# 依赖项
– Python 3.7.0
– Transformers 3.4.0
– Numpy 1.18.5
– Packaging 17.1
– skicit-learn 0.23.2
– torch 1.6.0+cu92
– tqdm 4.50.2
– multiprocess 0.70.10
– tensorflow 2.3.1
– tensorboardX 2.1
– seqeval 1.2.1
# 输入格式
采用CoNLL格式(优先采用BIOES标注方案),每个字与其标签在一行。句子用空行隔开。
“`cpp
美 B-LOC
国 E-LOC
的 O
华 B-PER
莱 I-PER
士 E-PER
我 O
跟 O
他 O
谈 O
笑 O
风 O
生 O
“`
# 中文BERT、中文词向量和权重文件
### 中文BERT
中文BERT: https://huggingface.co/bert-base-chinese/tree/main
### 中文词向量
中文词向量:https://ai.tencent.com/ailab/nlp/en/data/tencent-ailab-embedding-zh-d200-v0.2.0.tar.gz
更多信息参考:https://ai.tencent.com/ailab/nlp/en/embedding.html
### 权重文件和Shell脚本
– 微博NER
– 智能社NER
– MSRA NER
– 简历NER
– CTB5 POS
– CTB6 POS
– UD1 POS
– UD2 POS
– CTB6 CWS
– MSR CWS
– PKU CWS
# 数据目录结构
– berts: BERT权重文件
– dataset: 数据集
– vocab: 词向量词表
– embedding: 预训练词向量文件
– result: 预测结果
– log: 日志文件
# 运行过程
1. 将.char.bmes文件转换为.json格式的数据
2. 运行shell脚本训练
#### 如果需要加载我的预训练权重,需要修改transformers
我的模型采用分布式训练,无法直接加载单机版transformers。您可以按以下步骤修订transformers:
1. 进入transformers源码目录
2. 找到modeling_util.py文件
3. 修改约在995行的代码
4. 编译安装修改后的transformers
# 引用方式
“`
@inproceedings{liu-etal-2021-lexicon,
title = “Lexicon Enhanced {C}hinese Sequence Labeling Using {BERT} Adapter”,
author = “Liu, Wei and Fu, Xiyan and Zhang, Yue and Xiao, Wenming”,
booktitle = “ACL”,
year = “2021”
}
“`
repo.py
这个Python文件定义了基于BERT的序列标注模型Rope模型。
总体来说,这个文件实现了:
1. 定义Rope模块,实现Rope模型整体结构
2. 定义每层Ropeblock模块,构成Rope的网络结构
3. 构建Rope网络模型
详细功能如下:
1. Rope模块:
– 保存全局变量,如层数、head数等
– 调用Ropeblock搭建网络结构
2. Ropeblock模块:
– 输入:上一层输出
– 输出:多头注意力
– 包含主要结构:
– 多头自注意力
– 前馈网络
– 残差连接和层归一化
3. 构建网络:
– 定义配置参数
– 应用Rope模块
– 输入与输出尺寸设定
– 构建训练和预测模型
该文件定义了Rope作为序列标注Baseline的网络结构,采用模块化设计简洁明了,实现了依赖注入。
定义了标准的多头网络结构单元Ropeblock,通过堆叠搭建成整体模型结构。设计合理可扩展,有利于模型研发。
to_json.py
此py文件主要用于将序列标注数据集从字符级序列格式转换为json格式,具体功能如下:
1. 文件通过convert函数实现指定任务下不同模式(train/dev/test)下的数据集转换。
2. 具体转换流程:
– 读取原始.char.bmes文件
– 调用dele函数删除文件中的偶数行
– 将剩余奇数行写入新文件
3. 此外文件还定义了一些其他功能:
– BMES_to_json函数:将BMES标签转换为json格式
– get_all_labels_from_corpus:获取数据集所有标注类型
– bioes2span:BMES标签转换为开始结束型表示
– bio2span:BIO标签转换为开始结束型表示
4. 各功能模块功能:
– dele函数:删除文件中的偶数行
– BMES_to_json:标签转换
– bioes2span:BMES到开始结束表示转换
– bio2span:BIO到开始结束表示转换
5. 文件主要实现了数据集预处理工作:
– 格式转换
– 标签表达方式转换
– 提供更便于后续模块开发的json格式数据集
通过定义明确的转换模块,实现了数据集从原始格式到标准json格式的转换,为后续模型开发和应用提供了干净整洁的输入格式。
wcbert_modeling.py
这个wcbert_modeling.py文件实现了一个基于BERT的中文模型,主要功能包括:
1. 实现bert模型各个组成模块,包括词嵌入 Embedding、编码器 Encoder、池化器 Pooler等。
2. Embedding模块新增了词边界信息的嵌入。
3. Encoder模块的BertLayer新增了基于匹配词信息的注意力,能够将匹配词特征融入字向量表示。
4. 定义了WCBertModel,继承BertPreTrainedModel,整合Embedding、Encoder和Pooler模块。
5. 定义了WCBertCRFForTokenClassification,实现一个基于BERT-CRF的命名实体识别模型。
6. Encoder模块的BertLayer新增匹配词注意力机制,可以利用匹配词语义信息来改进字向量表示。
7. WCBertCRFForTokenClassification模型在BERT输出基础上,通过多头自注意力、GRU等对特征进行增强,然后经过CRF解码得到实体标签。
8. 实现了前向计算流程,支持训练和预测两个模式,训练模式加入CRF损失函数优化。
具体来说:
1. Embedding模块实现词、位置、类型嵌入的计算;
2. BertLayer实现了标准的Transformer编码层,并新增匹配词注意力来利用匹配词信息;
3. Encoder通过BertLayer堆叠得出最终编码;
4. Pooler对最后一层编码进行池化;
5. WCBertModel整合以上模块,定义BERT模型;
6. WCBertCRFForTokenClassification在BERT基础上利用匹配词信息等进行特征增强,最后CRF解码用于命名实体识别任务。
总体来说这个py文件实现了一个基于BERT的中文序列标注模型,利用匹配词增加上下文信息,接着利用CRF为每一个字或词进行实体类型预测。
wcbert_parser.py
这个wcbert_parser.py文件的主要作用是定义了训练与评估BERT模型的参数。
整体来说,它实现了一个命令行参数解析器,用于加载运行模型训练和预测所需要的各种参数。
具体来说:
1. 定义get_argparse函数,用于返回一个ArgumentParser对象。
2. 在ArgumentParser中添加各种参数,包括:
– 数据路径、模型路径等文件路径参数
– 模型结构相关参数,如模型类别、词典路径等
– 训练配置,如batch size、学习率、优化器等
– 训练过程控制,如epoch数、检查点间隔等
– 设备配置,如是否使用GPU、分布式训练节点数等
3. 数据路径参数主要用于控制加载数据的路径。
4. 模型结构参数用于指定加载的预训练模型和词典。
5. 训练配置参数细致地定义了训练的超参数设置。
6. 训练过程控制参数控制模型训练的过程,如评估间隔等。
7. 设备配置参数支持GPU和分布训练。
8. 解析出的参数后可以用于初始化模型和训练器,统一控制训练评估流程。
总体来说,这个脚本解析命令行,提取各种需要的训练和评估参数,为后续模型和训练器的初始化提供了方便。统一管理了BERT模型各模块的运行需要的参数。
trainer.py
这是一个NER任务的训练和评估脚本。
大致作用:
1. 数据加载:读取数据文件,构建词汇表、标签表等;构建预训练词向量;
2. 模型定义:选择WCBertCRF或BertWordLSTMCRF模型;
3. 训练过程:获取训练器、优化器等;循环训练每个epoch;记录loss、评估过程;
4. 评估过程:在验证集和测试集上评估模型性能,计算指标如F1分数等。
详细模块功能:
1. 数据加载:
– 构建词汇库、标签库
– 通过匹配词典构建输入数据词向量
– 构建Dataset类加载数据
2. 模型定义:
– 使用预训练的BERT配置
– 从BERT模型加载,添加CRF输出层
3. 训练:
– 获取优化器和学习率衰减规则
– 循环每个epoch训练
– 每步计算loss并反向传播
– 记录loss和学习率
– 每隔步评估在验证集效果
4. 评估:
– 在验证/测试集计算预测结果
– 构建词序列对比真实标签
– 计算F1/P/R指标
5. 保存结果:
– 保存最优模型
– 记录指标变化图谱
总体实现了NER任务的完整流程,从数据预处理、模型定义到训练评估而且记录了训练详细过程。
Comments NOTHING