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

SimCSE如何实现两次独立dropout?BERT两次dropout输出相同如何解决

SimCSE两次独立dropout原理及代码问题修复

代码输出完全相同的根因

  • 从transformers库加载的预训练模型默认处于评估模式(eval mode),该模式下dropout层、BN层等仅训练阶段生效的组件会被完全关闭,相同输入多次调用模型必然得到完全一致的输出。
  • 你当前的代码没有手动开启模型训练模式,因此无法触发两次独立dropout计算。

正确实现代码

只需在调用模型前开启训练模式即可激活dropout层,修改后代码如下:

from transformers import AutoModel, AutoTokenizer
import torch

bert = AutoModel.from_pretrained('bert-base-cased')
tokenizer = AutoTokenizer.from_pretrained('bert-base-cased')
sent_dict = tokenizer('Some weights of the model checkpoint at bert-base-cased were not used when initializing BertModel', return_tensors='pt')

# 关键:手动开启训练模式,激活dropout
bert.train()

out1 = bert(**sent_dict).pooler_output
out2 = bert(**sent_dict).pooler_output
print(torch.allclose(out1, out2)) # 输出为False,代表两次输出存在差异

SimCSE两次独立dropout的核心原理

SimCSE的无监督训练逻辑完全依托BERT原生的dropout实现,核心逻辑如下:

  • 把BERT自带的dropout(包括embedding层dropout、transformer块内的attention dropout、全连接层dropout)作为天然的无监督数据增强方式,不需要额外构造正样本。
  • 同一句子输入模型两次,每次前向传播走独立的随机dropout掩码,得到两个存在轻微差异的表征,训练时让这两个表征的相似度尽可能高,和同批次其他句子的表征相似度尽可能低,从而让模型学到更鲁棒的语义向量。
  • 全程不需要修改BERT内部结构,仅需要保持模型在训练模式即可实现。

注意事项

  • 如果你的训练代码固定了全局随机种子,两次调用模型前需要重置随机种子才会得到不同的dropout结果,否则固定种子下两次dropout掩码完全一致,输出也会相同。
  • 推理阶段需要切换回bert.eval()模式关闭dropout,保证相同输入的输出稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:15:06