想象你刚调入警局情报科,老刑警丢给你一摞报案记录,让你圈出里面的人名、地名和组织名。你一眼扫过“小明在北京上学”,立刻标出“小明”是人物、“北京”是地点。可让计算机做这件事,就没这么简单了——它需要一套完整的侦探系统:一位侦探从左往右逐字读卷宗,另一位从右往左倒着读,两人各自记下“记忆笔记”;最后还有一位总警司负责检查整条标签链是否合逻辑。这套组合拳,就是今天的主角——BiLSTM-CRF 命名实体识别模型。它会先通过双向 LSTM 充分吸收上下文线索,再靠 CRF 层保证输出的标签序列前后呼应、不闹笑话。读完这篇文章,你会发现原来复杂的 NLP 模型,底层逻辑和警局破案如此相似。

岗位关联

对 AI 从业者来说,掌握 BiLSTM-CRF 是踏入高精度序列标注的必修课,无论做信息抽取、知识图谱构建还是对话系统实体识别,这套“特征提取+标签约束”的双层架构都是你简历和项目里的硬通货。

目录
  1. 可视化演示
  2. 任务与标签体系
  3. 序列标注本质
  4. BiLSTM特征提取
  5. CRF标签建模
  6. 模型联合训练
  7. 维特比解码
  8. 工程实践要点
  9. 模型优劣选型
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

对比FCFS、SJF和RR三种CPU调度算法的执行顺序,通过甘特图展示进程切换时间与平均等待时间差异。

本节配有交互动效(进入视口后自动加载,约 3KB)。

FCFS调度 按进程到达顺序依次执行,非抢占式 实现简单但平均等待时间可能较长 FCFS对短进程不友好

任务与标签体系

你跟着老刑警来到档案室,他指着屏幕说:“我们要搞清楚一句话里谁出现了、在哪、属于哪个组织,这就是命名实体识别(Named Entity Recognition,NER)。”计算机没有直觉,它必须把“圈出人名地名”这件看似简单的事,翻译成一道道明确的指令。于是有了 BIO 标注体系——B 代表实体开头(Begin),I 代表实体中间(Inside),O 代表无关内容(Outside)。再给 B 和 I 挂上实体类型后缀:PER 表示人名,LOC 表示地名,ORG 表示组织名。“小明在北京上学”逐字打徽章,就是 B-PER、I-PER、O、B-LOC、I-LOC、O、O。

有了标签体系,NER 就成了“给句子中每个字分配一个标签”的序列标注问题。模型输出的不是单个标签,而是一条完整的标签序列,y 的每一个分量都对应句子中的一个字位。

y=(y1,y2,…,yT),yt∈Yy = (y_1, y_2, \ldots, y_T), \quad y_t \in \mathcal{Y}
这个式子把一个“圈实体”的任务,变成了一条长度与句子相等的标签项链。
  1. 标签序列下标 t 从 1 到 T 表示句子里的每个字位,y_t 就是该字位最终被贴上的徽章。
    y=(y1,y2,…,yT)y = (y_1, y_2, \ldots, y_T)
  2. 标签集合每个 y_t 都必须从有限集合 Y 中取值,集合里放着 O、B-PER、I-PER、B-LOC、I-LOC 等所有可能徽章。
    yt∈Y={O,B-PER,I-PER,B-LOC,I-LOC,… }y_t \in \mathcal{Y} = \{\text{O}, \text{B-PER}, \text{I-PER}, \text{B-LOC}, \text{I-LOC}, \dots\}
  3. 序列目标模型要一口气输出整条标签序列,而不是孤立地预测每个字,这正是后面 CRF 登场的伏笔。
    x=(x1,x2,…,xT)→yx = (x_1, x_2, \ldots, x_T) \rightarrow y

序列标注本质

老刑警提醒你:“别小看 '京' 这个字,在 '北京' 里它是地名的一部分,在 '京剧' 里就只是普通字。”单看一个字往往拿不准,这正是序列标注和普通分类最大的区别——每个位置的标签都需要参考整句话。比如“小明”后面的“在”字,如果只看它本身,既像人名一部分又像介词;但结合前后文,模型才能自信地给它贴上 O 徽章。

这种“牵一发而动全身”的任务,让模型必须建立全局视野。理想情况下,每个位置的预测概率都要以整个句子为条件:

P(yt∣x1,x2,…,xT)P(y_t \mid x_1, x_2, \ldots, x_T)
意思是:给“京”贴标签时,要看完整句“小明在北京上学”,而不是只看邻近两个字。
  1. 整句条件竖线后面的 \(x_1, x_2, \ldots, x_T\) 表示模型做判断前通读了整句话,这是序列标注对“全局信息”的基本要求。
    x=(x1,x2,…,xT)x = (x_1, x_2, \ldots, x_T)
  2. 单点概率模型输出的是位置 t 取某种标签的概率,这个概率不是独立的,而是来自全句证据的综合判断。
    P(yt∣x1,x2,…,xT)P(y_t \mid x_1, x_2, \ldots, x_T)

BiLSTM特征提取

要让“全局视野”落地,就得请出两位侦探:正向侦探小正从卷宗第一页读到最后一页,反向侦探小反从最后一页倒着往前读。LSTM(长短期记忆网络)就是侦探手里的“记忆笔记本”——通过遗忘门、输入门和输出门,决定哪些线索该记住、哪些该丢。单个 LSTM 只能积累单向信息,好比只从一头读卷宗,容易错过藏在后文的关键证据。

BiLSTM 让两位侦探同时开工:正向隐藏状态 \(\overrightarrow{h_t}\) 携带“从开头到当前字”的线索,反向隐藏状态 \(\overleftarrow{h_t}\) 携带“从结尾到当前字”的线索。每个字位的最终特征,是两位侦探笔记的拼接:

ht=[h→t  ;  h←t]\mathbf{h}_t = \left[ \overrightarrow{\mathbf{h}}_t \; ; \; \overleftarrow{\mathbf{h}}_t \right]
拼接后的特征向量同时含有“过去”和“未来”的信息,这就是 BiLSTM 对每个字的“上下文画像”。
  1. 正向记忆\(\overrightarrow{\mathbf{h}}_t\) 是正方向 LSTM 读完前 t 个字后留下的记忆摘要,相当于小正侦探看完前半段卷宗的笔记。
    h→t=LSTM→(x1,x2,…,xt)\overrightarrow{\mathbf{h}}_t = \overrightarrow{\text{LSTM}}(x_1, x_2, \ldots, x_t)
  2. 反向记忆\(\overleftarrow{\mathbf{h}}_t\) 是反方向 LSTM 从末尾读到第 t 个字时的记忆摘要,相当于小反侦探倒着看完后半段卷宗的笔记。
    h←t=LSTM←(xT,xT−1,…,xt)\overleftarrow{\mathbf{h}}_t = \overleftarrow{\text{LSTM}}(x_T, x_{T-1}, \ldots, x_t)
  3. 向量拼接分号表示把两个向量首尾相连成一个大向量,让“左边线索”和“右边线索”并排进入下一步。
    ht=[h→t;h←t]\mathbf{h}_t = [\overrightarrow{\mathbf{h}}_t ; \overleftarrow{\mathbf{h}}_t]

CRF标签建模

两位侦探交上笔记,但总警司发现还差一道工序。侦探笔记只是“这个字本身像哪种徽章”的初步打分,可徽章之间的搭配也有规矩——B-PER 后面跟 I-PER 顺理成章,B-LOC 后面直接跟 B-PER 却像“前面说是人名、马上又跳成地名”,逻辑上说不通。CRF(条件随机场)就是这位总警司,手里揣着一本“标签转移规则手册”。

手册的精华是一个转移矩阵 \(T\),记录任意两个相邻标签之间的配合得分。BiLSTM 提供的“初步打分”叫发射分数 \(E_{t,y_t}\),表示位置 t 贴标签 \(y_t\) 的合适程度。一整条标签序列的合理性,就是把每个位置的发射分数和相邻标签的转移分数累加:

s(x,y)=∑t=1T(Et,yt+Tyt−1,yt)s(x, y) = \sum_{t=1}^{T} \left( E_{t, y_t} + T_{y_{t-1}, y_t} \right)
路径得分越高,说明这条标签链越“像话”:每个字贴对了徽章,相邻徽章之间也不打架。
  1. 发射分数\(E_{t, y_t}\) 由 BiLSTM 输出,表示“看到这个字,我认为它该贴 y_t 徽章”的原始评分。
    Et,ytE_{t, y_t}
  2. 转移分数\(T_{y_{t-1}, y_t}\) 来自 CRF 转移矩阵,表示“上一标签 y_{t-1} 后面接当前标签 y_t”这件事有多顺。
    Tyt−1,ytT_{y_{t-1}, y_t}
  3. 逐位累加从 \(t=1\) 扫到 \(T\),把每个位置的发射分与相邻转移分全部加总,得到整条路径的总分。
    ∑t=1T(⋅)\sum_{t=1}^{T}(\cdot)

模型联合训练

总警司立下规矩:训练的目标是让“正确答案”这条路得分最高。可得分只是个数字,怎么把它变成训练用的损失?办法是把所有路径的得分都取指数(把负数变正、拉开差距),再归一化成概率。正确路径的得分占总分的比重越高,概率就越接近 1。为了训练方便,我们取概率的负对数作为损失——概率越大,损失越小:

L=−log⁡e s(x,y)∑y′e s(x,y′)\mathcal{L} = -\log \frac{e^{\,s(x, y)}}{\sum_{y'} e^{\,s(x, y')}}
这个损失同时激励了 BiLSTM(把字面特征学得更准)和 CRF 转移矩阵(把标签搭配学得更合理)。梯度沿着损失反向传播,整个系统联合优化。
  1. 分子对正确路径的得分取指数 \(e^{s(x,y)}\),让“对的路”获得正数且可比较的权重。
    e s(x,y)e^{\,s(x, y)}
  2. 分母对“所有可能标签序列”的得分分别取指数再求和,这个归一化项叫配分函数,计算时通常用前向算法高效完成。
    ∑y′e s(x,y′)\sum_{y'} e^{\,s(x, y')}
  3. 负对数似然比值就是正确路径的相对概率,取负对数后,“最大化正确概率”变成了“最小化损失”,符合深度学习的梯度下降框架。
    −log⁡es(x,y)∑y′es(x,y′)-\log \frac{e^{s(x,y)}}{\sum_{y'} e^{s(x,y')}}

维特比解码

训练结束时,总警司要真正接手一个案子:给“张三去杭州出差”这句话贴标签。理论上可以枚举所有标签组合挑得分最高的,但标签种类有 K 种、句子长 T,组合数是 \(K^T\),指数爆炸。总警司改用动态规划的思路——维特比算法:走到每个新字时,只保留“以各种标签结尾的前缀路径”中的最优者,其余的一律淘汰。

维特比的核心递推式非常优雅:位置 t 选标签 j 的最优分数,等于“上一位置某个标签 i 的最优分 + 从 i 跳到 j 的转移分”的最大值,再加上当前字的发射分:

δt(j)=max⁡i[δt−1(i)+Ti,j]+Et,j\delta_t(j) = \max_{i} \left[ \delta_{t-1}(i) + T_{i, j} \right] + E_{t, j}
从第一个字推到最后一个字,再沿着记录倒推回去,就能得到全局最优的标签序列。复杂度从指数级降到 \(O(TK^2)\),这也是 CRF 能在工业界落地的关键。
  1. 初始化第一个字没有上一标签,它的最优分就是自己的发射分数。
    δ1(j)=E1,j\delta_1(j) = E_{1, j}
  2. 递推式\(\delta_{t-1}(i) + T_{i,j}\) 表示“从上一最优前缀 + 跳到 j 的转移分”,对所有候选 i 取最大,再加上当前发射分。
    δt(j)=max⁡i[δt−1(i)+Ti,j]+Et,j\delta_t(j) = \max_i [\delta_{t-1}(i) + T_{i,j}] + E_{t,j}
  3. 回溯过程每步记下最优分来自哪个前一标签,最后从最后位置倒推,还原整条标签项链。
    backt(j)=arg⁡max⁡i[δt−1(i)+Ti,j]\text{back}_t(j) = \arg\max_i [\delta_{t-1}(i) + T_{i,j}]

工程实践要点

理论成熟之后,真正的战场在工程。训练一个能落地的 NER 模型,并不只是把数据丢进 PyTorch 就行。首先是数据标注:BIO 的口径必须统一,同一实体在不同句子里的边界要保持一致,否则模型会被互相矛盾的标注搞糊涂。其次是文本预处理:中文 NER 常用“字符级”输入,直接按字切分,配合预训练词向量或 BERT 动态向量。

训练阶段有大量细节需要打磨:学习率太大模型震荡,太小收敛缓慢;LSTM 容易过拟合,配上 dropout 和早停更稳妥;标签类别不均衡时,O 标签占绝大多数,需要关注每类实体的单独表现。评估时不能只看准确率,业界标准是 F1 值,它综合了精确率和召回率:

F1=2×P×RP+RF_1 = \frac{2 \times P \times R}{P + R}
精确率看“找到的实体里多少是对的”,召回率看“真实实体里找回了多少”,F1 是两者的调和平均,两者都高才算真本事。
  1. 精确率 P预测出的所有实体片段中,预测正确的比例,代表“找得准不准”。
    P=TPTP+FPP = \frac{TP}{TP + FP}
  2. 召回率 R真实存在的实体片段中,模型成功找出的比例,代表“找得全不全”。
    R=TPTP+FNR = \frac{TP}{TP + FN}
  3. 调和平均对 P 和 R 取调和平均,只有当两者都高时 F1 才高,避免为了凑全把整句标成实体的偏科做法。
    F1=2×P×RP+RF_1 = \frac{2 \times P \times R}{P + R}

模型优劣选型

这套“双侦探 + 总警司”的组合拳,优点非常突出:BiLSTM 能捕捉长距离的上下文线索,CRF 能保证输出标签链的全局合理性,两者结合让 NER 效果远超“每个字独立分类”的朴素方案。而且整个模型可以端到端训练,不需要手工设计特征。几十年前需要语言学家制定规则才能提取的实体,现在用这套架构配合标注数据就能实现。

但它也有短板:训练数据需求量较大,标注成本不低;转移矩阵只建模了相邻标签的关系,无法表达更复杂的标签约束;标准的 BiLSTM 没有预训练语义知识,遇到少见词容易表现不佳。因此工业界逐渐用 BERT 等预训练模型替代 BiLSTM,形成 BERT-BiLSTM-CRF 或 BERT-CRF 的升级组合。选型时要在效果、算力、数据之间做平衡——小数据集用 BiLSTM-CRF 轻量高效,大数据集上预训练模型的优势更明显。

AI 应用场景

医疗病历实体抽取

阶段:模型训练与推理部署

解决的问题:电子病历里充满“患者于三年前出现咳嗽、发热”这样的描述,传统规则系统每换一个科室就要重写规则,难以扩展。BiLSTM-CRF 可以自动抽取“咳嗽”“发热”等症状实体、“三年”等时间实体,并借助 CRF 保证“症状后面跟时间”这类标签链不出错。

具体案例:某三甲医院对 10 万份出院小结做实体抽取,用 BiLSTM-CRF 识别疾病、症状、药物、检验指标四类实体,将医生手工录入时间从每份 8 分钟缩短到 1 分钟,并沉淀出结构化的临床数据库。

金融舆情事件主体识别

阶段:数据标注与模型微调

解决的问题:券商研报和财经新闻中频繁出现公司名、人名、金额,需要把它们识别出来构建知识图谱。传统关键词匹配无法处理“平安银行”与“平安保险”的边界歧义,BiLSTM 的双向上下文正好能区分这类易混实体。

具体案例:某金融科技公司每天抓取 2 万条财经新闻,用 BiLSTM-CRF 识别公司、人物、行业、金额四类实体,再配合关系抽取搭建产业链知识图谱,辅助分析师快速定位“某条消息影响了哪些公司”。

Python 演示

python97 行
import torchimport torch.nn as nnimport torch.optim as optim # 玩具语料:中文句子 + BIO 标签sentences = [    list("小明在北京上学"),    list("小红在上海工作"),    list("小李去广州出差"),]tags = [    ["B-PER", "I-PER", "O", "B-LOC", "I-LOC", "O", "O"],    ["B-PER", "I-PER", "O", "B-LOC", "I-LOC", "O", "O"],    ["B-PER", "I-PER", "O", "B-LOC", "I-LOC", "O", "O"],] tag_list = ["O", "B-PER", "I-PER", "B-LOC", "I-LOC"]tag2idx = {t: i for i, t in enumerate(tag_list)}idx2tag = {i: t for t, i in tag2idx.items()}word2idx = {"<UNK>": 0}for s in sentences:    for ch in s:        if ch not in word2idx:            word2idx[ch] = len(word2idx)  def encode(text, tag):    x = torch.tensor([word2idx.get(c, 0) for c in text]).unsqueeze(0)    y = torch.tensor([tag2idx[t] for t in tag]).unsqueeze(0)    return x, y  class BiLSTMCRF(nn.Module):    def __init__(self, vocab_size, tag_size):        super().__init__()        self.embed = nn.Embedding(vocab_size, 16)        self.lstm = nn.LSTM(16, 16, batch_first=True, bidirectional=True)        self.fc = nn.Linear(32, tag_size)        self.trans = nn.Parameter(torch.randn(tag_size, tag_size))     def emissions(self, x):        h, _ = self.lstm(self.embed(x))        return self.fc(h)     def score_path(self, em, y):        score = em[0, 0, y[0, 0]]        for t in range(1, em.size(1)):            score = score + em[0, t, y[0, t]] + self.trans[y[0, t-1], y[0, t]]        return score     def log_partition(self, em):        alpha = em[:, 0]        for t in range(1, em.size(1)):            alpha = em[:, t] + torch.logsumexp(                alpha.unsqueeze(2) + self.trans.unsqueeze(0), dim=1            )        return torch.logsumexp(alpha, dim=1)     def loss(self, x, y):        em = self.emissions(x)        return (self.log_partition(em) - self.score_path(em, y)).mean()     def decode(self, x):        em = self.emissions(x)        T, K = em.size(1), em.size(2)        back = torch.zeros(T, K, dtype=torch.long)        delta = em[0, 0]        for t in range(1, T):            val, idx = (delta.unsqueeze(1) + self.trans).max(dim=0)            back[t] = idx            delta = val + em[0, t]        best = delta.argmax().item()        path = [int(best)]        for t in range(T - 1, 0, -1):            best = int(back[t, best])            path.append(best)        return [idx2tag[i] for i in reversed(path)]  model = BiLSTMCRF(len(word2idx), len(tag_list))opt = optim.Adam(model.parameters(), lr=0.02)for epoch in range(30):    total = 0.0    for s, t in zip(sentences, tags):        x, y = encode(s, t)        opt.zero_grad()        l = model.loss(x, y)        l.backward()        opt.step()        total += l.item()    if epoch % 10 == 0:        print("epoch", epoch, "loss", round(total / len(sentences), 4)) test_text = list("张三去杭州出差")x = torch.tensor([[word2idx.get(c, 0) for c in test_text]])print("中文句子:", "".join(test_text))print("预测标签:", model.decode(x))
目的:用 PyTorch 实现一个可训练的 BiLSTM-CRF 最小模型,演示发射分数、转移矩阵、负对数似然损失和维特比解码的完整流程。
  1. self.lstm = nn.LSTM(16, 16, batch_first=True, bidirectional=True)双向 LSTM 核心定义,bidirectional=True 让模型同时读取正反两个方向的信息
  2. em = self.fc(self.lstm(self.embed(x))[0])词嵌入经过双向 LSTM 后再经线性层,输出每个字位对各类标签的发射分数
  3. self.trans = nn.Parameter(torch.randn(tag_size, tag_size))CRF 转移矩阵,记录任意两个标签之间切换的配合得分
  4. score = score + em[0, t, y[0, t]] + self.trans[y[0, t-1], y[0, t]]将每个位置的发射分数与相邻标签的转移分数累加,得到一条标签路径的总得分
  5. torch.logsumexp(alpha.unsqueeze(2) + self.trans.unsqueeze(0), dim=1)前向算法高效计算配分函数,避免遍历指数级标签序列
  6. loss = (self.log_partition(em) - self.score_path(em, y)).mean()配分函数减正确路径得分,等价于负对数似然损失
  7. best = delta.argmax().item(); path = [...]维特比解码最后一步:沿回溯表还原全局最优标签路径

常见误区

误区“BiLSTM 已经能输出每个字的标签概率,直接在每个位置取概率最高的标签不就行了?CRF 层麻烦又没用。”

正解独立分类忽略了标签之间的依赖关系。BiLSTM 的输出只代表“这个字本身像什么”,但它管不住“B-PER 后面直接跟 B-LOC”这类不合逻辑的切换。CRF 的转移矩阵本质上是一道“质检关卡”,专门拦截这种前后矛盾的标签序列,让输出在整体上更合理。比如 “I-PER 必须跟在 B-PER 后面” 的约束,单点分类完全学不到。

为何常见:初学者先接触 Softmax 分类,惯性思维是“每个位置各自取最大值”,没有意识到序列标注的标签之间存在着强依赖关系。

误区“既然维特比是找最优路径,那每到一个字就选当前概率最大的标签,一步步走下去不就是最优路径吗?”

正解贪心只做局部最优,而维特比是全局最优。它保存的是“以每个标签结尾的前缀路径得分”,做完当前字的转移后,下一字选择会反过来影响前面路径的取舍,最后统一回溯。一个局部概率稍低的标签,可能会因为在后续几步中转移分更高而成为全局赢家。贪心算法会在“局部高分”与“全局连贯”之间迷失,维特比则用动态规划保证了整体路径得分最高。

为何常见:人天然容易理解“一步一步选最大的”这种直觉,缺少对动态规划“保留多条候选路径再回溯”的认识。

误区“BIO 和 BIOES 都是主流标注法,我在数据集里一半用 BIO、一半用 BIOES,只要标签名字差不多就行。”

正解标注体系必须全量统一。BIOES 比 BIO 多出 E(结尾)和 S(单字实体),两类标签集合完全不同。模型训练时看到同样的字一会儿被标成 I-LOC 一会儿被标成 E-LOC,学到的发射分数和转移矩阵都会被搅乱。实践中,跨数据源合并时必须先把标注体系转换到同一套。

为何常见:初学者看到“都是标注实体范围”就误以为差别不大,忽略了标签集合本身也是模型要学习的对象,口径不一致等于喂给模型自相矛盾的答案。

误区“模型效果不好?那就把 BiLSTM 堆成三层,隐藏单元从 128 加到 512,参数越多表达能力越强,效果肯定涨。”

正解序列标注是强监督任务,模型容量上升会带来过拟合风险。层数加深后梯度在长序列中容易衰减甚至消失,训练时间和显存开销也直线上升。在中小规模 NER 数据集上,单层 BiLSTM + CRF 往往已经够用;真正的性能瓶颈通常不在层数,而在数据质量、预训练表示和标签约束设计。

为何常见:深度学习“大力出奇迹”的印象让初学者迷信堆参数,忽略了数据量和正则化对泛化能力的决定性影响。

面试题

Q1. 命名实体识别(NER)的核心任务是什么?

单选题 · easy

  • A.把文本翻译成另一门语言
  • B.从文本中找出有意义的实体← 正确答案
  • C.判断整段文本的情感色彩
  • D.为每个字标注拼音发音

答案:B。NER 的目标是从自然语言文本中识别出人名、地名、组织名等实体并标注类型。翻译、情感分析、拼音标注是其他 NLP 任务,不属于 NER 范畴。

Q2. BIO 标注中,字母 B 的含义是什么?

单选题 · easy

  • A.实体的中间位置
  • B.实体的开始位置← 正确答案
  • C.实体的结束位置
  • D.不属于任何实体

答案:B。B 是 Begin 的缩写,表示一个实体的起始字。中间部分用 I(Inside)表示,与实体无关的内容用 O(Outside)表示。B 不是“中间”也不是“结束”。

Q3. BiLSTM 相比单向 LSTM 的独特优势是什么?

单选题 · mid

  • A.参数总量大幅减少
  • B.无需训练即可使用
  • C.能同时利用两侧上下文信息← 正确答案
  • D.只能依赖未来信息做判断

答案:C。BiLSTM 由正向和反向两个 LSTM 组成,每个位置的隐藏状态拼接了两条方向的输出,因此能同时看到“过去”和“未来”的信息。单向 LSTM 只能看到一侧,参数不会减少,也不能免训练。

Q4. 在 BiLSTM 之后加 CRF 层的主要目的是什么?

单选题 · mid

  • A.加速模型收敛速度
  • B.让标签序列前后更合理← 正确答案
  • C.替代词嵌入的编码
  • D.减少模型的参数量

答案:B。CRF 通过转移矩阵建模相邻标签之间的依赖关系,能拦截“B-PER 后接 I-LOC”这类不合逻辑的标签组合,保证整条标签序列的合理性。它不负责加速训练,也不替代词嵌入。

Q5. CRF 中的转移矩阵记录的是什么信息?

单选题 · mid

  • A.两个词之间的相似程度
  • B.两个句子之间的语义相关性
  • C.相邻标签之间切换的得分← 正确答案
  • D.两个向量之间的点积结果

答案:C。转移矩阵 \(T\) 中的每一项 \(T_{i,j}\) 表示从标签 i 跳转到标签 j 的配合得分,刻画了“上一标签对下一标签”的约束关系。它作用在标签上,与词、句子的相似度无关。

Q6. CRF 训练时使用的损失函数是什么?

单选题 · mid

  • A.均方误差损失函数
  • B.负对数似然损失函数← 正确答案
  • C.逐位置交叉熵损失函数
  • D.支持向量机合页损失函数

答案:B。CRF 把正确路径得分用 softmax 归一化为概率后取负对数,得到负对数似然损失。逐位置交叉熵只对单点做分类、不考虑标签转移;均方误差和合页损失不属于序列标注的概率框架。

Q7. 维特比算法本质上属于哪一类方法?

单选题 · easy

  • A.动态规划算法← 正确答案
  • B.无监督聚类算法
  • C.数据降维的算法
  • D.随机采样算法

答案:A。维特比通过“保留每个位置的最优前缀、逐步递推、最终回溯”的方式寻找全局最优路径,是经典的动态规划算法。它不是聚类、降维,也不是随机采样。

Q8. 下列哪些说法符合 BIO 标注规则?

多选题 · mid

  • A.I 标签必须紧跟同类型 B 标签← 正确答案
  • B.B 标签可以出现在句中任意位置
  • C.O 标签表示不属于任何实体← 正确答案
  • D.I-LOC 可以紧跟 B-PER 出现

答案:AC。I(Inside)表示实体中间,必须跟在同类型 B 之后;O 表示与实体无关。B 是实体起点,通常出现在实体第一个字,但“任意位置”的说法不严谨;I-LOC 紧跟 B-PER 属于跨类型错误标签链,违反转移约束。

Q9. BiLSTM-CRF 训练过程中,下列哪些模块的参数会参与更新?

多选题 · mid

  • A.词嵌入矩阵的向量← 正确答案
  • B.LSTM 的权重参数← 正确答案
  • C.全连接层的权重参数← 正确答案
  • D.CRF 的转移矩阵参数← 正确答案

答案:ABCD。整个模型端到端联合训练,损失函数的梯度会从输出层一路回传到全连接层、双向 LSTM 和词嵌入层;CRF 的转移矩阵也作为可训练参数参与梯度更新。四个模块共同优化才能让发射分数和转移约束协同配合。

Q10. 关于 CRF 路径得分与配分函数,下列正确的有?

多选题 · hard

  • A.路径得分由发射分加转移分求和得到← 正确答案
  • B.配分函数需要对全部标签序列求指数和← 正确答案
  • C.路径得分等于发射分乘以转移分
  • D.正确路径只需发射分数最优即可

答案:AB。一条路径的得分是各位置发射分数与相邻标签转移分数之和,配分函数则要遍历所有可能标签序列把各自指数相加,工程上用前向算法高效计算。路径得分不是乘积关系,正确路径还要在转移分数上同时占优,因此 C、D 错误。