我在阅读了一些之前的问题后,遇到了这个错误,这可能与张量的维度差异有关,但由于这是我第一次尝试运行PyTorch,所以我来这里寻求帮助,因为我对这方面几乎没有直觉。我想在一个基本的MNIST设置上运行一个非标准数据集(我相当确定我加载得很好),来摆弄它,看看哪些部分会产生什么样的变化。
Traceback (most recent call last):File "C:/Users/Administrator/Desktop/pytong/proj/pytorch_cnnv2.py", line 110, in <module>loss = loss_func(output, b_y)File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\nn\modules\module.py", line 547, in __call__result = self.forward(*input, **kwargs)File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\nn\modules\loss.py", line 916, in forwardignore_index=self.ignore_index, reduction=self.reduction)File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\nn\functional.py", line 1995, in cross_entropyreturn nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\nn\functional.py", line 1316, in log_softmaxret = input.log_softmax(dim)IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
引起问题的是损失函数这一行:
loss = loss_func(output, b_y)
除了导入和加载之外的其余代码:
class CNNModel(nn.Module):def __init__(self): super(CNNModel, self).__init__() # 卷积层1 self.cnn1 = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=5, stride=1, padding=0) self.relu1 = nn.ReLU() # 最大池化层1 self.maxpool1 = nn.MaxPool2d(kernel_size=2) # 卷积层2 self.cnn2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=5, stride=1, padding=0) self.relu2 = nn.ReLU() # 最大池化层2 self.maxpool2 = nn.MaxPool2d(kernel_size=2) # 全连接层 self.fc1 = nn.Linear(338 * 4 * 4, 5)def forward(self, x): # 卷积层1 out = self.cnn1(x) print(out.shape) out = self.relu1(out) print(out.shape) # 最大池化层1 out = self.maxpool1(out) print(out.shape) # 卷积层2 out = self.cnn2(out) print(out.shape) out = self.relu2(out) print(out.shape) # 最大池化层2 out = self.maxpool2(out) print('++++++++++++++ out') print(out.shape) # out = out.reshape(-1, 169 * 4 * 4) out = out.view(out.size(0), -1) print(out.shape) print('-----------------------') # 线性函数(输出层) out = self.fc1(out) print(out.shape) print('=======================') return outif __name__ == '__main__':print("训练样本数量: ", len(train_data))print("测试样本数量: ", len(test_data))print("检测到的类别是: ", train_data.class_to_idx) # 类别通过文件夹结构检测model = CNNModel()optimizer = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE)loss_func = nn.CrossEntropyLoss()# 训练和测试for epoch in range(EPOCHS): print(enumerate(train_data_loader)) for step, (x, y) in enumerate(train_data_loader): b_x = Variable(x) # 批次x(图像) b_y = Variable(y) # 批次y(目标) # print('============ b_x') # print(len(b_x)) # print(b_x.data) # print('============ b_y') # print(len(b_y)) # print(b_y.data) output = model(b_x)[0] loss = loss_func(output, b_y) optimizer.zero_grad() loss.backward() optimizer.step() if step % 50 == 0: test_x = Variable(test_data_loader) test_output, last_layer = model(test_x) pred_y = torch.max(test_output, 1)[1].data.squeeze() accuracy = sum(pred_y == test_y) / float(test_y.size(0)) print('Epoch: ', epoch, '| 训练损失: %.4f' % loss.data[0], '| 测试准确率: %.2f' % accuracy)
还有我尝试用于诊断的打印输出:
torch.Size([100, 16, 60, 60])torch.Size([100, 16, 60, 60])torch.Size([100, 16, 30, 30])torch.Size([100, 32, 26, 26])torch.Size([100, 32, 26, 26])++++++++++++++ outtorch.Size([100, 32, 13, 13])torch.Size([100, 5408])-----------------------torch.Size([100, 5])=======================
回答:
问题出在这一行:
output = model(b_x)[0]
[0]
将形状从[100, 5]
变为[5]
,而损失函数期望的是相反的情况。只要删除它即可:
output = model(b_x)