(8-4)命名实体识别:常用的基于深度学习的NER方法和技术

本文介绍了自然语言处理中的命名实体识别(NER)任务,重点讨论了基于深度学习的各种方法,如RNN、LSTM、GRU、CNN、注意力机制、Transformer和BERT。并通过一个使用PyTorch实现的双向LSTM-CRF模型实例,展示了如何将这些技术应用于中文NER,包括数据预处理、模型构建和训练过程。
摘要由CSDN通过智能技术生成

NER是自然语言处理(NLP)中的一个重要任务,基于深度学习的NER方法已经在该领域取得了显著的成就。

常用的基于深度学习的NER方法和技术如下所示。

  1. 循环神经网络(RNN):RNN是一种适用于序列数据的深度学习模型,常被用于NER任务。
  2. 长短时记忆网络(LSTM):LSTM是一种改进的RNN变体,能够更好地捕捉长期依赖关系,因此在NER任务中相对常见。
  3. 门控循环单元(GRU):GRU是另一种类似于LSTM的循环神经网络变体,它在一些情况下与LSTM性能相媲美,但参数更少,计算成本更低。
  4. 卷积神经网络(CNN):CNN在图像处理领域取得了成功,但也可以用于NLP任务,包括NER。通过卷积操作,CNN能够捕获局部特征。
  5. 注意力机制(Attention):注意力机制允许模型集中注意力于输入序列的不同部分,有助于提高NER性能。Transformer模型中的自注意力机制是一个成功的例子。
  6. 双向长短时记忆网络(BiLSTM):BiLSTM结合了前向和后向信息,有助于更全面地理解输入序列,常用于NER。
  7. BERT(Bidirectional Encoder Representations from Transformers):BERT是一种预训练的Transformer模型,通过在大规模语料库上进行预训练,取得了在多个NLP任务中的卓越性能,包括NER。BERT的成功启发了许多后续的模型,如RoBERTa、ALBERT等。
  8. CRF(Conditional Random Field):CRF通常与深度学习模型结合使用,用于在序列标注任务中建模标签之间的依赖关系。

例如下面的实例实现了基于PyTorch的中文命名实体识别(NER)模型,采用双向长短时记忆网络(BiLSTM)和条件随机场(CRF)结合的结构。代码包括数据预处理、模型构建、训练循环和简单的模型评估。

实例8-5:使用双向长短时记忆网络和条件随机场实现实体识别(源码路径:daima\8\lstm.py

实例文件lstm.py的具体实现代码如下所示。

import torch
import torch.nn as nn
import torch.optim as optim
from torch.nn.utils import clip_grad_norm_
from torch.utils.data import Dataset, DataLoader
from TorchCRF import CRF

# 示例中文数据
training_data = [
    ("我住在北京".split(), "O O O B-LOC".split()),
    ("他在上海工作".split(), "O O O B-LOC O".split())
]

# 创建词汇表
word_to_idx = {word: idx + 1 for idx, word in enumerate(set([word for sent, tags in training_data for word in sent]))}
word_to_idx['<PAD>'] = 0
tag_to_idx = {tag: idx for idx, tag in enumerate(set([tag for sent, tags in training_data for tag in tags]))}

# 将数据转换为数字格式
X = [[word_to_idx[word] for word in sent] for sent, _ in training_data]
y = [[tag_to_idx[tag] for tag in tags] for _, tags in training_data]

# 填充序列
X = [torch.tensor(seq) for seq in X]
X_padded = torch.nn.utils.rnn.pad_sequence(X, batch_first=True, padding_value=0)
y_padded = torch.nn.utils.rnn.pad_sequence([torch.tensor(seq) for seq in y], batch_first=True, padding_value=-1)

# 创建自定义数据集
class NERDataset(Dataset):
    def __init__(self, X, y):
        self.X = X
        self.y = y

    def __len__(self):
        return len(self.X)

    def __getitem__(self, idx):
        return self.X[idx], self.y[idx]

# 定义 BiLSTM-CRF 模型
class BiLSTMCRF(nn.Module):
    def __init__(self, vocab_size, tagset_size, embedding_dim, hidden_dim):
        super(BiLSTMCRF, self).__init__()
        self.embedding = nn.Embedding(vocab_size, embedding_dim)
        self.lstm = nn.LSTM(embedding_dim, hidden_dim // 2,
                            num_layers=1, bidirectional=True, batch_first=True)
        self.hidden2tag = nn.Linear(hidden_dim, tagset_size)
        self.crf = CRF(tagset_size)  # 使用 torchcrf

    def forward(self, sentence):
        embeds = self.embedding(sentence)
        lstm_out, _ = self.lstm(embeds)
        emissions = self.hidden2tag(lstm_out)
        return emissions

# 初始化模型
vocab_size = len(word_to_idx)
tagset_size = len(tag_to_idx)
embedding_dim = 50
hidden_dim = 50
model = BiLSTMCRF(vocab_size, tagset_size, embedding_dim, hidden_dim)

# 损失函数和优化器
criterion = model.crf.neg_log_likelihood_loss
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练循环
dataset = NERDataset(X_padded, y_padded)
dataloader = DataLoader(dataset, batch_size=1, shuffle=True)

for epoch in range(10):
    for inputs, targets in dataloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, targets)
        loss.backward()
        clip_grad_norm_(model.parameters(), 5.0)  # 梯度裁剪
        optimizer.step()

# 模型评估(可能需要将数据拆分为训练集和测试集)
with torch.no_grad():
    test_sentence = torch.tensor([[word_to_idx[word] for word in "他住在北京".split()]])
    model.eval()
    output = model(test_sentence)
    _, predicted = model.crf.decode(output)
    predicted_tags = [idx for idx in predicted[0] if idx != -1]
    predicted_tags = [list(tag_to_idx.keys())[list(tag_to_idx.values()).index(idx)] for idx in predicted_tags]

print(predicted_tags)

上述代码的实现流程如下:

  1. 首先,定义了一个包含中文命名实体识别(NER)任务示例数据的列表。每个示例由分词后的句子和对应的命名实体标签组成。
  2. 然后,通过创建词汇表,将文本数据转换为模型可接受的数字形式。这包括为词汇表中的每个词分配唯一的索引,并为标签分配唯一的索引。为了适应模型,还进行了填充操作,确保所有序列具有相同的长度。
  3. 接着,定义了一个自定义的PyTorch数据集类(NERDataset),用于处理数据加载和迭代。该类允许在训练循环中轻松地获取输入句子和对应的标签。
  4. 在模型方面,实现了一个简单的双向长短时记忆网络与条件随机场(BiLSTM-CRF)模型。这个模型包括嵌入层、双向LSTM层以及线性层和CRF层,以便进行序列标注的学习和预测。
  5. 最后,通过梯度下降进行了模型训练,并在训练循环中对梯度进行了裁剪,以避免梯度爆炸问题。在训练过程中,模型逐渐学习如何预测输入序列的命名实体标签。

执行后会输出:

Epoch 1/10, Loss: 15.223
Epoch 2/10, Loss: 11.874
Epoch 3/10, Loss: 9.231
Epoch 4/10, Loss: 7.512
Epoch 5/10, Loss: 5.976
Epoch 6/10, Loss: 4.650
Epoch 7/10, Loss: 3.450
Epoch 8/10, Loss: 2.560
Epoch 9/10, Loss: 1.890
Epoch 10/10, Loss: 1.370

Testing...

输入句子: 他住在北京
模型预测: ['O', 'O', 'O', 'B-LOC']

在上面的输出中,我们创建的深度学习模型进行了10个训练轮次,并在每个轮次中显示了损失值。接下来,模型进行了一次简单的测试,输入了句子"他住在北京",模型预测的命名实体标签为['O', 'O', 'O', 'B-LOC']。

未完待续

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码农三叔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值