python-3.x - BERT 二进制文本分类每次运行都会得到不同的结果
问题描述
我使用Simpletransformer中的 BERT 进行二进制文本分类。
我在 Colab 中使用 GPU 运行时类型工作。
我已经使用 sklearn StratifiedKFold 方法生成了训练和测试集。我有两个文件,其中包含我的折叠字典。
我在以下 while 循环中运行我的分类:
from sklearn.metrics import matthews_corrcoef, f1_score
import sklearn
counter = 0
resultatos = []
while counter != len(trainfolds):
model = ClassificationModel('bert', 'bert-base-multilingual-cased',args={'num_train_epochs': 4, 'learning_rate': 1e-5, 'fp16': False,
'max_seq_length': 160, 'train_batch_size': 24,'eval_batch_size': 24 ,
'warmup_ratio': 0.0,'weight_decay': 0.00,
'overwrite_output_dir': True})
print("start with fold_{}".format(counter))
trainfolds["{}_fold".format(counter)].to_csv("/content/data/train.tsv", sep="\t", index = False, header=False)
print("{}_fold Train als train.tsv exportiert". format(counter))
testfolds["{}_fold".format(counter)].to_csv("/content/data/dev.tsv", sep="\t", index = False, header=False)
print("{}_fold test als train.tsv exportiert". format(counter))
train_df = pd.read_csv("/content/data/train.tsv", delimiter='\t', header=None)
eval_df = df = pd.read_csv("/content/data/dev.tsv", delimiter='\t', header=None)
train_df = pd.DataFrame({
'text': train_df[3].replace(r'\n', ' ', regex=True),
'label':train_df[1]})
eval_df = pd.DataFrame({
'text': eval_df[3].replace(r'\n', ' ', regex=True),
'label':eval_df[1]})
model.train_model(train_df)
result, model_outputs, wrong_predictions = model.eval_model(eval_df, f1 = sklearn.metrics.f1_score)
print(result)
resultatos.append(result)
shutil.rmtree("outputs")
shutil.rmtree("cache_dir")
#shutil.rmtree("runs")
counter += 1
我得到不同的结果运行此代码相同的折叠:
这里以两次运行的 F1 分数为例:
0.6237942122186495
0.6189111747851003
0.6172839506172839
0.632183908045977
0.6182965299684542
0.5942492012779553
0.6025641025641025
0.6153846153846154
0.6390532544378699
0.6627906976744187
The F1 Score is: 0.6224511646974427
0.6064516129032258
0.6282420749279539
0.6402439024390244
0.5971014492753622
0.6135693215339232
0.6191950464396285
0.6382978723404256
0.6388059701492537
0.6097560975609756
0.5956112852664576
The F1 Score is: 0.618727463283623
对于相同的褶皱,它们怎么会如此不同?
我已经尝试过的是在循环开始之前给出一个固定的随机种子:
random.seed(42)
np.random.seed(42)
torch.manual_seed(42)
torch.cuda.manual_seed_all(42)
我想出了在循环中初始化模型的方法,因为当它在循环之外时,它会以某种方式记住它所学到的东西——这意味着在第二次折叠之后我的 f1 分数几乎是 1——尽管我删除了缓存..
解决方案
我自己想出来了,只需设置所有种子加上 torch.backends.cudnn.deterministic = True 和 torch.backends.cudnn.benchmark = False 就像这篇文章中所示,我在所有运行中都得到相同的结果!
推荐阅读
- php - 通过 XMLHTTPRequest 加载 PHP 不共享相同的变量范围
- angularjs - chart.js 不同数据范围的工具提示
- javascript - AngularJS 标识符已声明错误(使用 `let` 语句)
- java - 运行具有固定语言环境的 Spring Boot 应用程序
- networking - skb_header_pointer() 总是以大端返回?
- python - TypeError:datetime.datetime 不是 JSON 可序列化的
- batch-file - 一次查找和替换 2 个不同字符串的批处理脚本
- typescript - 空值检查不识别可空值由条件语句处理
- spring - Spring Boot - 可配置的 bean
- c - C-决策函数用于交换结构数组内的字符串或数字