PyTorch Lightning中如何在模型微调前执行测试?
报错原因
你遇到的两个报错均为PyTorch Lightning 1.2.7版本的设计限制:
- 直接调用
trainer.test()触发AttributeError:1.2.x版本的trainer.test要求trainer.fit已执行完成内部状态初始化,未初始化时running_stage属性为空,就会触发该报错 - 空参数调用
trainer.fit()触发MisconfigurationException:trainer.fit必须传入训练数据,或者你的LightningModule实现了train_dataloader方法,空参数调用不符合接口要求
解决方案
以下两种方案都可以在不更新模型权重的前提下,完成微调前的效果测试:
方案1:手动执行测试逻辑(最稳定,不受PL版本限制)
不需要调用trainer相关接口,直接手动遍历测试集计算精度,完全不影响后续微调流程:
import torch from tqdm import tqdm ### (a) ### 模型实例化后的位置 model = BertForSequenceClassification_pl(...) # 保留你原来的模型实例化代码 model.eval() # 切换到评估模式 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model.to(device) correct_num = 0 total_num = 0 with torch.no_grad(): # 关闭梯度计算,降低显存占用 for batch in tqdm(dataloader_test): # 按你数据集的实际结构调整batch取值,和你test_step里的输入保持一致即可 input_ids = batch[0].to(device) attention_mask = batch[1].to(device) labels = batch[2].to(device) outputs = model(input_ids, attention_mask=attention_mask) pred = torch.argmax(outputs.logits, dim=1) correct_num += (pred == labels).sum().item() total_num += labels.size(0) pretrain_acc = correct_num / total_num print(f"微调前测试集精度:{pretrain_acc:.4f}")
方案2:复用现有test_step逻辑(适配PL 1.2.7接口)
如果你想复用已经写在LightningModule里的test_step、test_epoch_end逻辑,可以通过初始化一个跑0轮训练的trainer完成状态初始化,不会更新模型权重:
import pytorch_lightning as pl import torch ### (a) ### 模型实例化后的位置 model = BertForSequenceClassification_pl(...) # 保留你原来的模型实例化代码 # 初始化仅做状态初始化的trainer,max_epochs=0不会执行任何训练step pre_test_trainer = pl.Trainer( gpus=1 if torch.cuda.is_available() else 0, max_epochs=0, logger=False, checkpoint_callback=False ) # 传入训练、验证集dataloader执行fit,仅完成初始化,不会更新模型权重 pre_test_trainer.fit( model, train_dataloader=dataloader_train, val_dataloaders=dataloader_val ) # 调用test获取微调前结果,返回值的key和你现有test返回的key完全一致 pretrain_test_res = pre_test_trainer.test(test_dataloaders=dataloader_test) print(f"微调前测试集精度:{pretrain_test_res[0]['test_acc']:.4f}") # 后续正常执行你原来的微调流程即可 # trainer = pl.Trainer(你的原有参数) # trainer.fit(...) # trainer.test(...)
内容的提问来源于stack exchange,提问作者user15283025
相关产品推荐
相关产品推荐

