项目名称:基于BERT架构的外卖评论情感分析系统

1.深入对比了传统RNN/LSTM 与Transformer 架构的优劣
1)RNN的缺陷:RNN是串行计算的,必须处理完上一个词才能处理下一个词,无法并行的计算,导致训练速度慢。其次存在严重的梯度消失/爆炸问题,导致很难捕捉长文本,有长距离依赖的问题
2)LSTM的优势与局限:引入了门控机制(遗忘门、输入门、输出门),缓解了RNN的长距离依赖的问题。但本质上还是串行的结构,计算效率依然不高
3)Self-attention(自注意力机制):自注意力机制就是让模型在处理一个词的时候,自动的去"环顾四周",看看周围的词和这个词本身的相关联程度,从而更好的理解语句。
高度并行化:矩阵运算一次性处理所有的词,极大提升训练速度
完美的全局感受野:文本中任意两个词之间的距离都是O(1),模型可以直接"看到"句子中相隔很远的两个词,彻底解决了长距离依赖的问题
2.Bert的原理是什么
原理:原理就是多层Transformer架构中的Encouder的堆叠,得益于Self-attention的机制,可以同时看到一个词左右两边所有上下文,做到"通读全文".
规模参数:12层Encoder,维数为768,参数量在1.1个亿左右
3.Bert为什么好用?
Bert在海量无标注文本上做了预训练任务,就是把句子中15%的词进行mask,让模型结合上下文去猜这些词是什么,类似"完形填空"。
4.并接入全连接层进行下游任务微调
全连接层:self.cls_head = nn.Linear(768, num_class)
BERT 的输出是什么: 当你把一句外卖评论(比如"这外卖太难吃了")输入给 BERT 后,BERT 会经过层层计算,最后在 [CLS] 这个标志位上输出一个 768 维的向量 (也就是你代码里的 pooler_out池化层,这个层也可以选择取平均值等等,128*768 -> 1*768(假设有128个token)这里取得是第一个token)。最后用全连接层得到二分类的结果
什么是下游任务?
上游任务就是bert去提取文本的特征,下游任务就是具体的任务,比如情感分类
微调?
同时,在训练的时候,我不仅训练了这个分类头,还让反向传播的梯度微微更新了 BERT 的底层参数,这就是微调,这样能让模型更贴合外卖评论的语境。
5.为什么使用AdamW
普通的 Adam 在引入 L2 正则化时,权重衰减会和梯度更新耦合在一起。AdamW 将权重衰减解耦,对于 Transformer 这种参数量巨大的模型,AdamW 能提供更好的泛化性能。
6.为什么epochs只有5
因为我们是基于 BERT 的预训练权重进行微调,模型已经具备了很好的特征提取能力,所以不需要从头开始收敛。通常微调任务在 3-5 个 epoch 左右就能达到最优效果,如果 epoch 设置过大,反而容易在训练集上过拟合
7.【重中之重】BERT 最后的输出有几种不同的方式?
BERT 处理输出主要有以下几种常用方式:
-
取 Pooler Output 池化输出层(你代码中使用的方式):
- 原理: BERT 在输入序列的最前面会强制加一个特殊的
[CLS]标志位。Pooler Output就是拿这个[CLS]token 在最后一层的隐藏状态(Hidden State),再经过一个线性层(Dense)和 Tanh 激活函数后得到的向量(维度通常是 768)。它被设计用来表示整个句子的全局语义。
- 原理: BERT 在输入序列的最前面会强制加一个特殊的
-
取 Last Hidden State 并做平均池化(Mean Pooling):
- 原理: 不只用
[CLS],而是把最后一层所有 token(字/词)的隐藏状态拿出来,按序列长度维度求平均值。
- 原理: 不只用
-
取 [CLS] 的 Last Hidden State(不经过 Tanh 层):
- 原理: 直接拿第一位的
[CLS]向量去接分类头,跳过官方预设的池化层。
- 原理: 直接拿第一位的
"在我的情感分类任务中,我主要使用的是 Pooler Output。通常情况下,对于简单的句级分类任务,直接用 [CLS] 的 Pooler Output 就能达到很好的效果(比如 90% 以上的准确率)。但在一些更复杂的文本相似度或长文本任务中,学术界研究表明,对所有 token 做 Mean Pooling 往往能保留更平滑的全局信息 ,准确率可能会比单独用 [CLS] 高出 1到2个百分点 。这也是我未来可以进一步优化和对比的方向。"