PyTorch 正向传播 returns 相同样本的不同 logits
PyTorch forward propagation returns different logits on same samples
考虑以下 MNIST 的 LeNet 模型
import torch
from torch import nn
import torch.nn.functional as F
class LeNet(nn.Module):
def __init__(self):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5, 1)
self.conv2 = nn.Conv2d(20, 50, 5, 1)
self.fc1 = nn.Linear(4*4*50, 500)
self.fc2 = nn.Linear(500, 10)
self.ceriation = nn.CrossEntropyLoss()
def forward(self, x):
x = self.conv1(x)
x = F.max_pool2d(x, 2, 2)
x = F.relu(x)
x = self.conv2(x)
x = F.max_pool2d(x, 2, 2)
x = F.relu(x)
x = x.view(-1, 4*4*50)
x = self.fc1(x)
x = self.fc2(x)
return x
现在,我使用这个模型对一批样本做一个向前的步骤,比如
network=LeNet()
optimizer = torch.optim.SGD(self.network.parameters(), lr=0.001, momentum=0.9)
device = torch.device("cpu")
network.to(device)
network.train()
optimizer.zero_grad()
# X_batch= ... some batch of 50 samples pulled from a train_loader defined as
# torch.manual_seed(42)
# training_set = datasets.MNIST('./mnist_data', train=True, download=False,
# transform=transforms.Compose([
# transforms.ToTensor(),
# transforms.Normalize((0.1307,), (0.3081,))]))
# train_loader = torch.utils.data.DataLoader(training_set,
# batch_size=50,
# shuffle=False)
logits = network(X_batch)
请注意,shuffle=False
和 download=False
用于加载程序,因为数据集已经下载,我不想洗牌。我的问题是,如果我 运行 这段代码两次,我将得到 logits
的不同值,我不明白为什么,因为其他一切似乎都没有改变。为了进行额外检查,我还将 X_batch
提取到 numpy
数组并验证这批样本与之前执行的样本完全相同。我用 numpy.array_equal()
函数做这个检查。
除非有精度问题,否则我真的不知道我在这里遗漏了什么。
原因是因为每次你运行你调用这段代码
network = LeNet()
并最终对网络权重进行不同的随机初始化。如果您在此之前设置了随机种子,例如像这样:
torch.manual_seed(42)
network = LeNet()
如果你使用相同的数据作为输入,那么你应该在第一步中得到相同的结果。
考虑以下 MNIST 的 LeNet 模型
import torch
from torch import nn
import torch.nn.functional as F
class LeNet(nn.Module):
def __init__(self):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5, 1)
self.conv2 = nn.Conv2d(20, 50, 5, 1)
self.fc1 = nn.Linear(4*4*50, 500)
self.fc2 = nn.Linear(500, 10)
self.ceriation = nn.CrossEntropyLoss()
def forward(self, x):
x = self.conv1(x)
x = F.max_pool2d(x, 2, 2)
x = F.relu(x)
x = self.conv2(x)
x = F.max_pool2d(x, 2, 2)
x = F.relu(x)
x = x.view(-1, 4*4*50)
x = self.fc1(x)
x = self.fc2(x)
return x
现在,我使用这个模型对一批样本做一个向前的步骤,比如
network=LeNet()
optimizer = torch.optim.SGD(self.network.parameters(), lr=0.001, momentum=0.9)
device = torch.device("cpu")
network.to(device)
network.train()
optimizer.zero_grad()
# X_batch= ... some batch of 50 samples pulled from a train_loader defined as
# torch.manual_seed(42)
# training_set = datasets.MNIST('./mnist_data', train=True, download=False,
# transform=transforms.Compose([
# transforms.ToTensor(),
# transforms.Normalize((0.1307,), (0.3081,))]))
# train_loader = torch.utils.data.DataLoader(training_set,
# batch_size=50,
# shuffle=False)
logits = network(X_batch)
请注意,shuffle=False
和 download=False
用于加载程序,因为数据集已经下载,我不想洗牌。我的问题是,如果我 运行 这段代码两次,我将得到 logits
的不同值,我不明白为什么,因为其他一切似乎都没有改变。为了进行额外检查,我还将 X_batch
提取到 numpy
数组并验证这批样本与之前执行的样本完全相同。我用 numpy.array_equal()
函数做这个检查。
除非有精度问题,否则我真的不知道我在这里遗漏了什么。
原因是因为每次你运行你调用这段代码
network = LeNet()
并最终对网络权重进行不同的随机初始化。如果您在此之前设置了随机种子,例如像这样:
torch.manual_seed(42)
network = LeNet()
如果你使用相同的数据作为输入,那么你应该在第一步中得到相同的结果。