命名实体审核任务:BERT中文预训练模型

日萌社

 

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)


智能对话系统:Unit对话API

在线聊天的总体架构与工具介绍:Flask web、Redis、Gunicorn服务组件、Supervisor服务监控器、Neo4j图数据库

linux 安装 neo4jlinux 安装 Redissupervisor 安装

neo4j图数据库:Cypher

neo4j图数据库:结构化数据流水线、非结构化数据流水线

命名实体审核任务:BERT中文预训练模型

命名实体审核任务:构建RNN模型

命名实体审核任务:模型训练

命名实体识别任务:BiLSTM+CRF part1

命名实体识别任务:BiLSTM+CRF part2

命名实体识别任务:BiLSTM+CRF part3

在线部分:werobot服务、主要逻辑服务、句子相关模型服务、BERT中文预训练模型+微调模型(目的:比较两句话text1和text2之间是否有关联)、模型在Flask部署

系统联调测试与部署

离线部分+在线部分:命名实体审核任务RNN模型、命名实体识别任务BiLSTM+CRF模型、BERT中文预训练+微调模型、werobot服务+flask


5.1 任务介绍与模型选用

  • 学习目标:
    • 了解命名实体审核任务的相关知识.
    • 了解选用的模型及其原因.

  • NE审核任务:
    • 一般在实体进入数据库存储前, 中间都会有一道必不可少的工序, 就是对识别出来的实体进行合法性的检验, 即命名实体(NE)审核任务. 它的检验过程不使用上下文信息, 更关注于字符本身的组合方式来进行判断, 本质上,它是一项短文本二分类问题.

  • 选用的模型及其原因:
    • 针对短文本任务, 无须捕捉长距离的关系, 因此我们使用了传统的RNN模型来解决, 性能和效果可以达到很好的均衡.
    • 短文本任务往往适合使用字嵌入的方式, 但是如果你的训练集不是很大,涉及的字数有限, 那么可以直接使用预训练模型的字向量进行表示即可. 我们这里使用了bert-chinese预训练模型来获得中文汉字的向量表示.

5.2 训练数据集

  • 学习目标:
    • 了解训练数据集的样式及其相关解释.
    • 掌握将数据集加载到内存中的过程.

  • 训练数据集的样式:
1   手内肌萎缩
0   缩萎肌内手
1   尿黑酸
0   酸黑尿
1   单眼眼前黑影
0   影黑前眼眼单
1   忧郁
0   郁忧
1   红细胞寿命缩短
0   短缩命寿胞细红
1   皮肤黏蛋白沉积
0   积沉白蛋黏肤皮
1   眼神异常
0   常异神眼
1   阴囊坠胀痛
0   痛胀坠囊阴
1   动脉血氧饱和度降低
0   低降度和饱氧血脉动

  • 数据集的相关解释:
    • 这些训练集中的正样本往往是基于人工审核的标准命名实体.
    • 数据集中的第一列代表标签, 1为正标签, 代表后面的文字是命名实体. 0为负标签, 代表后面的文字不是命名实体.
    • 数据集中的第二列中的命名实体来源于数据库中的症状实体名字, 它是结构化爬虫抓取的数据. 而非命名实体则是它的字符串反转.
    • 正负样本的比例是1:1.

  • 将数据集加载到内存:
import pandas as pd 
from collections import Counter

# 读取数据
train_data_path = "./train_data.csv"
train_data= pd.read_csv(train_data_path, header=None, sep="\t")

# 打印正负标签比例
print(dict(Counter(train_data[0].values)))

# 转换数据到列表形式
train_data = train_data.values.tolist()
print(train_data[:10])

  • 代码位置: /data/doctor_offline/review_model/train.py

  • 输出效果:
# 正负标签比例
{1: 5740, 0: 5740}

# 取出10条训练数据查看
[[1, '枕部疼痛'], [0, '痛疼部枕'], [1, '陶瑟征阳性'], [0, '性阳征瑟陶'], [1, '恋兽型性变态'], [0, '态变性型兽恋'], [1, '进食困难'], [0, '难困食进'], [1, '会阴瘘管或窦道形成'], [0, '成形道窦或管瘘阴会']]


  • 小节总结:
    • 学习了训练数据集的样式及其相关解释.
    • 学习了将数据集加载到内存中的过程.

5.3 BERT中文预训练模型

  • 学习目标:
    • 了解BERT中文预训练模型的有关知识和作用.
    • 掌握使用BERT中文预训练模型对句子编码的过程.

  • BERT中文预训练模型:
    • BERT模型整体架构基于Transformer模型架构, BERT中文预训练模型的解码器和编码器具有12层, 输出层中的线性层具有768个节点, 即输出张量最后一维的维度是768. 它使用的多头注意力机制结构中, 头的数量为12, 模型总参数量为110M. 同时, 它在中文简体和繁体上进行训练, 因此适合中文简体和繁体任务.

  • BERT中文预训练模型作用:
    • 在实际的文本任务处理中, 有些训练语料很难获得, 他们的总体数量和包含的词汇总数都非常少, 不适合用于训练带有Embedding层的模型, 但这些数据中却又蕴含这一些有价值的规律可以被模型挖掘, 在这种情况下,使用预训练模型对原始文本进行编码是非常不错的选择, 因为预训练模型来自大型语料, 能够使得当前文本具有意义, 虽然这些意义可能并不针对某个特定领域, 但是这种缺陷可以使用微调模型来进行弥补.

  • 使用BERT中文预训练模型对句子编码:
import torch
import torch.nn as nn


# 通过torch.hub(pytorch中专注于迁移学的工具)获得已经训练好的bert-base-chinese模型
model =  torch.hub.load('huggingface/pytorch-transformers', 'model', 'bert-base-chinese')


# 获得对应的字符映射器, 它将把中文的每个字映射成一个数字
tokenizer = torch.hub.load('huggingface/pytorch-transformers', 'tokenizer', 'bert-base-chinese')


def get_bert_encode_for_single(text):
    """
    description: 使用bert-chinese编码中文文本
    :param text: 要进行编码的文本
    :return: 使用bert编码后的文本张量表示
    """
    # 首先使用字符映射器对每个汉字进行映射
    # 这里需要注意, bert的tokenizer映射后会为结果前后添加开始和结束标记即101和102 
    # 这对于多段文本的编码是有意义的, 但在我们这里没有意义, 因此使用[1:-1]对头和尾进行切片
    indexed_tokens = tokenizer.encode(text)[1:-1]
    # 之后将列表结构转化为tensor
    tokens_tensor = torch.tensor([indexed_tokens])
    print(tokens_tensor)
    # 使模型不自动计算梯度
    with torch.no_grad():
        # 调用模型获得隐层输出
        encoded_layers, _ = model(tokens_tensor)
    # 输出的隐层是一个三维张量, 最外层一维是1, 我们使用[0]降去它.
    print(encoded_layers.shape)
    encoded_layers = encoded_layers[0]
    return encoded_layers

  • 输入参数:
text = "你好, 周杰伦"

  • 调用:
outputs = get_bert_encode_for_single(text)
print(outputs)
print(outputs.shape)

  • 输出效果:
tensor([[ 3.2731e-01, -1.4832e-01, -9.1618e-01,  ..., -4.4088e-01,
         -4.1074e-01, -7.5570e-01],
        [-1.1287e-01, -7.6269e-01, -6.4861e-01,  ..., -8.0478e-01,
         -5.3600e-01, -3.1953e-01],
        [-9.3012e-02, -4.4381e-01, -1.1985e+00,  ..., -3.6624e-01,
         -4.7467e-01, -2.6408e-01],
        [-1.6896e-02, -4.3753e-01, -3.6060e-01,  ..., -3.2451e-01,
         -3.4204e-02, -1.7930e-01],
        [-1.3159e-01, -3.0048e-01, -2.4193e-01,  ..., -4.5756e-02,
         -2.0958e-01, -1.0649e-01],
        [-4.0006e-01, -3.4410e-01, -3.8532e-05,  ...,  1.9081e-01,
          1.7006e-01, -3.6221e-01]])

torch.Size([6, 768])

  • 小节总结:

    • 学习了BERT中文预训练模型的有关知识:
      • BERT模型整体架构基于Transformer模型架构, BERT中文预训练模型的解码器和编码器具有12层, 输出层中的线性层具有768个节点, 即输出张量最后一维的维度是768. 它使用的多头注意力机制结构中, 头的数量为12, 模型总参数量为110M. 同时, 它在中文简体和繁体上进行训练, 因此适合中文简体和繁体任务.

    • 学习了BERT中文预训练模型的作用:
      • 在实际的文本任务处理中, 有些训练语料很难获得, 他们的总体数量和包含的词汇总数都非常少, 不适合用于训练带有Embedding层的模型, 但这些数据中却又蕴含这一些有价值的规律可以被模型挖掘, 在这种情况下, 使用预训练模型对原始文本进行编码是非常不错的选择, 因为预训练模型来自大型语料, 能够使得当前文本具有意义, 虽然这些意义可能并不针对某个特定领域, 但是这种缺陷可以使用微调模型来进行弥补.

    • 学习了使用BERT中文预训练模型对句子编码的函数: get_bert_encode_for_single(text)

import pandas as pd
from collections import Counter

# 读取数据
train_data_path = "./train_data.csv"
train_data= pd.read_csv(train_data_path, header=None, sep="\t")

# 打印正负标签比例
print(dict(Counter(train_data[0].values)))

# 转换数据到列表形式
train_data = train_data.values.tolist()
print(train_data[:10])

import torch
import torch.nn as nn

"""
如果每次运行都重新下载“bert-base-chinese”的话,执行如下操作
    window:cd C:/Users/Administrator/.cache/torch/hub/huggingface_pytorch-transformers_master
    linux:cd /root/.cache/torch/hub/huggingface_pytorch-transformers_master
    activate pytorch
    pip install .
"""
# 通过torch.hub(pytorch中专注于迁移学的工具)获得已经训练好的bert-base-chinese模型
model =  torch.hub.load('huggingface/pytorch-transformers', 'model', 'bert-base-chinese')
# 获得对应的字符映射器, 它将把中文的每个字映射成一个数字
tokenizer = torch.hub.load('huggingface/pytorch-transformers', 'tokenizer', 'bert-base-chinese')

def get_bert_encode_for_single(text):
    """
    description: 使用bert-chinese编码中文文本
    :param text: 要进行编码的文本
    :return: 使用bert编码后的文本张量表示
    """
    # 首先使用字符映射器对每个汉字进行映射
    # 这里需要注意, bert的tokenizer映射后会为结果前后添加开始和结束标记即101和102
    # 这对于多段文本的编码是有意义的, 但在我们这里没有意义, 因此使用[1:-1]对头和尾进行切片
    indexed_tokens = tokenizer.encode(text)[1:-1]
    # 之后将列表结构转化为tensor
    tokens_tensor = torch.tensor([indexed_tokens])
    print(tokens_tensor)
    # 使模型不自动计算梯度
    with torch.no_grad():
        # 调用模型获得隐层输出
        encoded_layers, _ = model(tokens_tensor)
    # 输出的隐层是一个三维张量, 最外层一维是1, 我们使用[0]降去它.
    print(encoded_layers.shape)
    encoded_layers = encoded_layers[0]
    return encoded_layers

text = "你好, 周杰伦"
outputs = get_bert_encode_for_single(text)
print(outputs)
print(outputs.shape)
"""
tensor([[ 872, 1962,  117, 1453, 3345,  840]])
torch.Size([1, 6, 768])
tensor([[ 3.2732e-01, -1.4832e-01, -9.1618e-01,  ..., -4.4089e-01,
         -4.1074e-01, -7.5569e-01],
        [-1.1287e-01, -7.6269e-01, -6.4861e-01,  ..., -8.0478e-01,
         -5.3600e-01, -3.1953e-01],
        [-9.3011e-02, -4.4381e-01, -1.1985e+00,  ..., -3.6624e-01,
         -4.7467e-01, -2.6408e-01],
        [-1.6894e-02, -4.3753e-01, -3.6060e-01,  ..., -3.2451e-01,
         -3.4203e-02, -1.7930e-01],
        [-1.3159e-01, -3.0048e-01, -2.4193e-01,  ..., -4.5757e-02,
         -2.0958e-01, -1.0649e-01],
        [-4.0006e-01, -3.4410e-01, -3.5733e-05,  ...,  1.9081e-01,
          1.7006e-01, -3.6221e-01]])
torch.Size([6, 768])
"""

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

あずにゃん

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值