拆解 BERT:Output 中的 Hidden States 到底藏了什么秘密?

动手写 bert 系列 解析 bertmodel 的output(last_hidden_state,pooler_output,hidden_state) 专栏第七个视频学习归纳总结。

在 NLP 开发中,transformers 库的 model(input) 调用是我们最熟悉的动作。通常情况下,我们只需要拿到结果做下游任务即可。你将配置参数 output_hidden_states 设置为 True 时,BERT 返回的 outputs 就不再是一个简单的 Tensor,而是一个包含了丰富内部信息的元组。我们基于一段真实的代码运行结果,来深入剖析 outputs[0]outputs[1]outputs[2] 之间的数学关系与逻辑含义。

0. 实验环境与数据设定

为了方便理解,我们先固定实验的维度参数(基于 bert-base-uncased):

  • Batch Size: 1

  • Sequence Length: 22("After stealing money..." 这句话 tokenize 后的长度)

  • Hidden Size: 768

  • 配置 : output_hidden_states=True

在此设定下,模型返回的 outputs 长度为 3。我们逐一拆解。

1. Outputs0:Last Hidden State(最终隐藏层)

  • 形状 : (1, 22, 768)

  • 代码验证 : outputs[0]

这是我们最常用的输出。它代表了BERT 最后一层(第 12 层)Transformer Encoder 的输出

在这个张量中,序列中的每一个 Token(共 22 个)都包含了基于整个句子上下文的深层语义信息。

  • 应用场景: 序列标注(NER)、问答系统(QA)、以及任何需要对每个 Token 进行细粒度分析的任务。

2. Outputs1:Pooler Output(池化层输出)

  • 形状 : (1, 768)

  • 代码验证 : outputs[1]

注意:这是新手最容易混淆的地方。 很多同学误以为 outputs[1] 只是简单的把 outputs[0] 的第一个 [CLS] 向量取出来。

事实并非如此。

outputs[1] 是专门为了句子分类任务设计的。它的计算逻辑如下:

  1. 取出最后一层隐藏状态的第一个 Token([CLS] 对应向量)。

  2. 将其输入到一个全连接层(Dense Layer)

  3. 经过 Tanh 激活函数处理。

所以,outputs[1] 是经过非线性加工的、代表整句语义的向量。

  • 应用场景: 文本分类(情感分析、意图识别)。

3. Outputs2:Hidden States(隐藏层全家桶)

  • 数据类型 : Tuple (元组)

  • 长度: 13

  • 形状 : 元组内每个元素均为 (1, 22, 768)

这部分是本文的重点。为什么 BERT Base 只有 12 层,这里却返回了 13 个 Tensor?

这是因为 outputs[2] 完整记录了数据流经模型的历史轨迹

  • 索引 0: Embedding 层的输出(输入层)。

  • 索引 1-12: 第 1 层到第 12 层 Transformer Block 的输出。

通过代码中的布尔值验证,来实锤它们之间的关系。

4. 核心解密:三者之间的数学关系

基于运行的代码验证结果,我们可以得出以下铁一般的结论:

结论 A:Outputs2-1 等于 Outputs0

代码证据 : outputs[0] == outputs[2][-1] 返回 True

这是一个恒等关系。

  • outputs[2] 是所有层的列表。

  • outputs[2] 的最后一个元素(索引 12),自然就是第 12 层的输出。

  • outputs[0] 的定义正是"最后一层的输出"。

理解 : 如果把 BERT 看作一栋 12 层的大楼,outputs[2][-1] 是你站在楼顶看到的风景,而 outputs[0] 是这张风景的照片。它们是完全一样的东西。

结论 B:Outputs20 等于 Model Embeddings

代码证据 : outputs[2][0] == model.embeddings(...) 返回 True

这个验证非常有意义。它证明了 outputs[2] 的第一个元素(索引 0)是纯粹的 Embedding 输出

  • 在这个阶段,数据仅仅完成了 Token Embedding + Position Embedding + Segment Embedding 的查表与相加。

  • 关键点: 此时数据还没有进入任何 Attention 层!也就是说,在这个阶段,句子里的单词之间还没有开始"交流"。

结论 C:Outputs1 与 Outputs2 的关系

虽然代码中没有直接画等号(因为涉及计算),但逻辑关系是:

它取的是 outputs[2] 最后一层的 [CLS] 向量,再加工得到的。

5. 总结

为了方便记忆,我们可以构建这样一个"BERT 楼层模型":

输出变量 楼层隐喻 物理含义 备注
outputs[2][0] 地基 Embedding 层输出 无 Attention 交互,纯静态向量
outputs[2][1...11] 中间楼层 第 1-11 层输出 语义逐渐加深
outputs[2][12] (即 outputs[0]) 顶楼 第 12 层输出 上下文理解最充分,Token 级任务首选
outputs[1] 物业报告 Pooler 输出 基于顶楼 [CLS] 加工,句子级任务首选

下次当你在 Debug 模型或者做特征融合(比如把最后四层拼接起来效果更好)时,千万别忘了 output_hidden_states=True 这个强大的参数,它能让你拥有透视 BERT 内部运作的"上帝视角"。

相关推荐
ZzT1 小时前
怎么做才不会被 AI 替代?
人工智能·程序员
道友可好1 小时前
从今天开始:你的第一个 Harness Engineering 实践
前端·人工智能·后端
小姜前线技术2 小时前
AI回答代码块高亮加一键复制
人工智能
洛阳泰山2 小时前
从 0 到 1.6K Star:一个 Java 开源项目的增长复盘
人工智能·后端·开源
米小虾3 小时前
Agent Skill 设计模式完全指南
人工智能·agent
饼干哥哥4 小时前
保姆级教程:用Image2 + Seedance2.0 做长视频,以品牌广告为例
人工智能
米小虾4 小时前
Agent Skill 规范与 Skill-Creator 核心思想
人工智能·agent
ZhengEnCi4 小时前
09e-斯坦福CS336作业四:大规模语言模型训练数据收集与处理
人工智能
oil欧哟4 小时前
Codex 最佳实践(超级长文):先搞懂 AI,再用好 AI
前端·人工智能·后端
甲维斯5 小时前
日本发布比肩Fable5的模型?Fugu Ultra初探!
人工智能·ai编程