使用 pytorch 闪电的不同测试结果

Posted

技术标签:

【中文标题】使用 pytorch 闪电的不同测试结果【英文标题】:Different test results with pytorch lightning 【发布时间】:2021-07-05 18:20:02 【问题描述】:

我使用 Pytorch Lightning 用膜翅目照片(灵感来自 here)训练一个小型 NN 迁移学习。

test_step 方法中,它打印真实类 (classes) 和预测 (preds)。 训练结束后,我做同样的事情(验证步骤),但得到不同的结果。

import torch
from torch import nn
from torch.optim import Adam,SGD
import pytorch_lightning as pl
from torchvision import  models
from torch.optim import lr_scheduler
from pytorch_lightning.metrics.functional import accuracy
from pytorch_lightning.loggers import TensorBoardLogger
from hymenoptereDataModule import HymenopteraDataModule


class LitHymenoptera(pl.LightningModule):

    def __init__(self, batch_size=4):
        super().__init__()
        torch.manual_seed(42)
        self.batch_size = batch_size
        self.dataModule = HymenopteraDataModule()
        self.dataModule.setup()
        self.criterion = nn.CrossEntropyLoss()
        self.logger = TensorBoardLogger('tb_logs', name=f'Model')
        # Define the model
        self.model = models.resnet18(pretrained=True)
        num_ftrs = self.model.fc.in_features
        self.model.fc = nn.Linear(num_ftrs, 2)

    def forward(self, x):
        return self.model(x)

    def training_step(self, batch, batch_idx):
        x, y = batch
        logits = self.model(x)
        # Compute loss
        loss = self.criterion(logits, y)
        # training metrics
        preds = torch.argmax(logits, dim=1)
        acc = accuracy(preds, y)
        num_correct = torch.eq(preds.view(-1), y.view(-1)).sum()
        return 'loss': loss,
                'acc': acc,
                'num_correct': num_correct

    def training_epoch_end(self, outputs):
        self.exp_lr_scheduler.step()

    def validation_step(self, batch, batch_idx):
        x, y = batch
        logits = self.model(x)
        loss = self.criterion(logits, y)
        # validation metrics
        preds = torch.argmax(logits, dim=1)
        acc = accuracy(preds, y)
        num_correct = torch.eq(preds.view(-1), y.view(-1)).sum()
        return 'loss': loss,
                'acc': acc,
                'num_correct': num_correct

    def test_step(self, batch, batch_idx):
        inputs, classes = batch
        logits = self(inputs)
        preds = torch.argmax(logits, dim=1)
        print('###############################')
        print('classes1 = ',classes)
        print('preds1 = ',preds)
        print(logits)

    def configure_optimizers(self):
        optimizer = SGD(self.parameters(), lr=0.001, momentum=0.9)
        # Decay LR by a factor of 0.1 every 7 epochs
        self.exp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)
        return optimizer


model = LitHymenoptera()
trainer = pl.Trainer(gpus=1, max_epochs=5, progress_bar_refresh_rate=100)
trainer.fit(model,model.dataModule)
trainer.test(model)

# Now, another test
for inputs, classes in model.dataModule.val_dataloader():
    print('###############################')
    logits = model(inputs.cuda())
    preds = torch.argmax(logits, dim=1)
    print('classes2 = ', classes)
    print('preds2 = ', preds)
    print(logits)

这是 test_step 方法的第一个输出:

classes1 =  tensor([0, 0, 0, 0], device='cuda:0') 
preds1 =  tensor([1, 0, 0, 0], device='cuda:0') tensor([[0.1626, 0.2195],
            [1.1437, 0.5745],
            [0.9351, 0.4271],
            [0.7365, 0.5342]], device='cuda:0')

现在是验证步骤的第一个输出:

classes2 =  tensor([0, 0, 0, 0])
preds2 =  tensor([1, 0, 1, 0], device='cuda:0')
tensor([[-0.0168,  0.0800],
        [ 0.6817,  0.2949],
        [-0.2205,  0.1009],
        [ 0.6126,  0.4924]], device='cuda:0', grad_fn=<AddmmBackward>)

两个 是相同的(我检查了图像,它们是相同的)但是 preds 是不同的。 它来自哪里?

【问题讨论】:

【参考方案1】:

我意识到我忘记添加了:

model.freeze()

在第二次使用该模型之前。 所以,现在,两个结果是一样的。

【讨论】:

以上是关于使用 pytorch 闪电的不同测试结果的主要内容,如果未能解决你的问题,请参考以下文章

pytorch闪电模型的输出预测

使用Pytorch实现手写数字识别

权重和偏差扫描无法使用 pytorch 闪电导入模块

用 pytorch 闪电组织张量板图

如何在忽略类中使用 pytorch 闪电精度?

使用 pytorch 闪电进行多 GPU 训练时出错