我是Pytorch的新手,正在尝试实现一个简单的CNN来识别MNIST图像。
我在训练网络时使用了MSE Loss作为损失函数,SGD作为优化器。当我开始训练时,出现了以下
警告:” UserWarning: Using a target size (torch.Size([64])) that is different to the input size (torch.Size([64, 10])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.”
然后我得到了以下
错误:"RuntimeError: The size of tensor a (10) must match the size of tensor b (64) at non-singleton dimension 1".
我尝试了一些在其他问题中找到的解决方案,但似乎都不起作用。以下是我加载数据集的代码:
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,),(0.5,))])trainset = torchvision.datasets.MNIST(root='./data', train = True, transform = transform, download = True)trainloader = torch.utils.data.DataLoader(trainset, batch_size = 64, shuffle = True)testset = torchvision.datasets.MNIST(root='./data', train = False, transform = transform, download = True)testloader = torch.utils.data.DataLoader(testset, batch_size = 64, shuffle = False)
定义我的网络的代码如下:
class Net(nn.Module): def __init__(self): super(Net, self).__init__() #卷积层 self.conv1 = nn.Conv2d(1, 6, 5) self.conv2 = nn.Conv2d(6, 12, 5) #全连接层 self.fc1 = nn.Linear(12*4*4, 120) self.fc2 = nn.Linear(120, 60) self.out = nn.Linear(60,10) def forward(self, x): x = F.max_pool2d(F.relu(self.conv1(x)), (2,2)) x = F.max_pool2d(F.relu(self.conv2(x)), (2,2)) x = x.reshape(-1, 12*4*4) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.out(x) return x
这是训练代码:
net = Net()print(net)criterion = nn.MSELoss() optimizer = optim.SGD(net.parameters(), lr=0.001)epochs = 3for epoch in range(epochs): running_loss = 0; for images, labels in trainloader: optimizer.zero_grad() output = net(images) loss = criterion(output, labels) loss.backward() optimizer.step() running_loss += loss.item() else: print(f"Training loss: {running_loss/len(trainloader)}")print('Finished training')
谢谢!
回答:
您使用的损失函数(nn.MSELoss
)对于这个问题是不正确的。您应该使用nn.CrossEntropyLoss
。
均方误差损失测量输入x和目标y之间的均方误差。在这里,输入和目标自然应该具有相同的形状。
交叉熵损失计算每张图像在各个类别上的概率。输出将是一个N x C的矩阵,目标将是一个大小为N的向量。(N = 批量大小,C = 类别数量)
由于您的目标是分类图像,这就是您想要使用的损失函数。
在您的案例中,网络输出将是一个大小为64 x 10的矩阵,目标是一个大小为64的向量。输出矩阵的每一行(应用softmax函数后)表示该类别的概率,然后计算交叉熵损失。Pytorch的nn.CrossEntropyLoss
结合了softmax操作和损失计算。
您可以参考这里的文档,了解Pytorch如何计算损失的更多信息。