PyTorch:定义的层不参与正向传播,但影响损耗值

2024-04-24 01:29:39 发布

您现在位置:Python中文网/ 问答频道 /正文

最近,当我使用Pytork做逻辑回归的简单实验时,我遇到了一个令人困惑的现象

问题是当我修复随机种子时,如下所示:

def set_seed(seed, cuda=True):
    np.random.seed(seed)
    torch.manual_seed(seed)
    if cuda:
        torch.cuda.manual_seed(seed)

并定义了以下具有2层的模型:

class net(nn.Module):
    def __init__(self):
        super(net, self).__init__()
        self.hidden = nn.Linear(784, 100)
        self.output = nn.Linear(100, 10)

    def forward(self, x):
        x = self.hidden(x)
        x = self.output(x)
        return x

对网络进行以下培训:

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)

原始损失值为0.6422,可重复

但是,当我添加一个在转发过程中未涉及的附加层时,如下所示:

class net(nn.Module):
    def __init__(self):
        super(net, self).__init__()
        self.hidden = nn.Linear(784, 100)
        self.output = nn.Linear(100, 10)
        self.add = nn.Linear(10,10)

    def forward(self, x):
        x = self.hidden(x)
        x = self.output(x)
        return x

原始损失值更改为0.7431,与前一个值不相等,同时模型性能下降

我真想知道为什么会这样。谢谢大家!


Tags: 模型selfoutputnetinitdefnntorch
1条回答
网友
1楼 · 发布于 2024-04-24 01:29:39

如果在计算损失之前存在其他随机性来源(消耗RNG的东西),则这是完全可以预料的。由于您没有提供Minimal, Reproducible Example,我猜您使用的是带有shuffle=TrueDataLoader。在这种情况下,即使您不使用self.add层,当您初始化它时,它也会使用RNG;因此导致样品的顺序不同。如果随机性来自具有shuffle=True的数据加载器,则可以通过向数据加载器提供不同的RNG来控制该随机性。大概是这样的:

import numpy as np

import torch
from torch import nn

import torchvision
from torchvision.transforms import ToTensor

def set_seed(seed, cuda=True):
    np.random.seed(seed)
    torch.manual_seed(seed)
    if cuda:
        torch.cuda.manual_seed(seed)

class net(nn.Module):
    def __init__(self):
        super(net, self).__init__()
        self.hidden = nn.Linear(784, 100)
        self.output = nn.Linear(100, 10)
        # self.add = nn.Linear(10, 10)  # try with and without
    def forward(self, x):
        x = self.hidden(x)
        x = self.output(x)
        return x

set_seed(0)

m = net()

bs = 4
ds = torchvision.datasets.MNIST(root=".", train=True, transform=ToTensor(), download=True)
rng_dl = torch.Generator()
dl = torch.utils.data.DataLoader(ds, batch_size=bs, shuffle=True, num_workers=0, generator=rng_dl)

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(m.parameters(), lr=0.1)

for x, y in dl:
    y_hat = m(x.view(bs, -1))
    l = criterion(y_hat, y)
    print(l)
    exit()

请记住,可能还有其他一些事情,例如数据扩充和对依赖于随机操作的函数的其他调用。如果你能提供MRE,我可以试着给出一个更具体的答案

相关问题 更多 >