You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

摩洛哥方言NER任务:BERT+BiGRU+Softmax网络过拟合问题求助

摩洛哥方言NER系统过拟合问题求助

我正在基于BERT+BiGRU+Softmax架构构建摩洛哥方言命名实体识别(NER)系统,目前遭遇严重过拟合:训练集F1约98%,验证集F1仅约78%。使用的数据集规模较小(共65,905个token),希望在无需数据增强的前提下解决过拟合并提升验证集性能。

我尝试过多种正则化手段,但效果不理想:要么无法缓解过拟合,要么导致整体性能下滑。比如我设置BERT的hidden_dropout_prob为0.3,在BERT与BiGRU之间添加p=0.1的Dropout层,BiGRU与全连接层之间添加p=0.4的Dropout层,同时设置权重衰减为0.01;还把BiGRU的hidden_state增大到512来抵消Dropout带来的性能损失。这么做确实降低了过拟合,但训练集和验证集的F1都下降了(分别为83%和74%)。

我也试过更简单的模型架构(BERT+全连接层+Softmax),但同样存在程度相当的过拟合问题。

以下是我的PyTorch模型代码,目前正在用Weights and Biases Sweeps做超参数调优:

class NER_GRU_Model(nn.Module): 
    def __init__(self, hidden_size, num_layers, bert_dropout, p1, p2, num_classes=len(tag2idx)): 
        super().__init__() 
        config = transformers.BertConfig.from_pretrained(lm, hidden_dropout_prob=bert_dropout) 
        self.bert = transformers.BertModel.from_pretrained(lm, config = config, add_pooling_layer = False) 
        input_size = self.bert.config.to_dict()['hidden_size'] 
        self.gru = nn.GRU(hidden_size = hidden_size, input_size = input_size, bidirectional = True, num_layers = num_layers, batch_first = True) 
        self.fc = nn.Linear(hidden_size*2, num_classes) 
        self.drop1 = nn.Dropout(p1) 
        self.drop2 = nn.Dropout(p2) 
        if freeze_bert == False:  
            for param in self.bert.parameters():  
                param.requires_grad = False 
        else:  
            for param in self.bert.parameters():  
                param.requires_grad = True 
                
    def forward(self, input_ids, attention_mask = None): 
        s = self.bert(input_ids = input_ids, attention_mask=attention_mask) 
        s = s['last_hidden_state'] 
        s = self.drop1(s) 
        s, _ = self.gru(s) 
        s = self.drop2(s) 
        s = self.fc(s) 
        return F.log_softmax(s)

可行的优化方向

1. 修正BERT冻结逻辑

你当前的冻结判断逻辑写反了:if freeze_bert == False时冻结BERT参数,这会导致预训练的BERT权重无法适配摩洛哥方言的特征。正确的写法应该是:

if freeze_bert:  # 需要冻结时才禁用梯度更新
    for param in self.bert.parameters():
        param.requires_grad = False
else:
    for param in self.bert.parameters():
        param.requires_grad = True

另外建议采用分层冻结:先冻结BERT的前8层,只训练顶层和下游网络;待验证集性能稳定后,再逐步解冻低层微调,避免小数据量下预训练特征被破坏。

2. 优化正则化策略

  • 降低Dropout强度:当前Dropout参数设置过高,尤其是BERT的hidden_dropout_prob=0.3会过度破坏预训练特征。建议把BERT的dropout降到0.10.2,BERT与BiGRU间的Dropout设为0.1,BiGRU与全连接层间的Dropout设为0.20.3。
  • 调整权重衰减:权重衰减0.01对小数据场景来说过大,建议尝试1e-4~1e-3的范围;可以给BERT参数单独设置更小的衰减系数(比如5e-5),下游网络用1e-4,避免预训练权重被过度正则化。
  • 添加标签平滑:在交叉熵损失中加入标签平滑(epsilon=0.1),比如用torch.nn.CrossEntropyLoss(label_smoothing=0.1),避免模型对训练标签过于自信,缓解过拟合。

3. 限制模型容量

你之前增大BiGRU的hidden_size到512反而导致性能下滑,说明小数据量下模型容量超出需求。建议把BiGRU的hidden_size调回256甚至128,同时将num_layers设为1,降低模型复杂度,减少过拟合空间。

4. 优化训练流程

  • 早停机制:监控验证集F1,当连续3~5个epoch验证集性能没有提升时停止训练,避免模型在训练集上过度拟合。
  • 精细化学习率:给BERT和下游网络设置不同的学习率,比如BERT用5e-5,BiGRU和全连接层用1e-4;配合余弦退火学习率衰减(CosineAnnealingLR),避免训练后期权重震荡。
  • 调整批量大小:如果硬件允许,适当增大batch size(比如从16调到32),提升梯度估计的稳定性,减少训练噪声。

5. 数据层面的小调整(非增强)

  • 重新划分数据集:检查训练/验证集的实体类型分布,确保两者一致,避免验证集中出现训练集没有见过的实体类别。
  • 清理低质量样本:排查数据集中的错误标注样本(比如标签错位、实体标注错误),移除或修正这些样本,减少模型学习到的噪声。

内容的提问来源于stack exchange,提问作者hananour

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 03:13:25