运行时错误:给定的输入大小:(40x256x1)。计算输出大小:(40x253x2)。输出大小太小

2024-04-23 20:04:52 发布

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

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from torch.autograd import Variable
from sklearn import preprocessing

batch_size = 32
num_classes = 8 
epochs = 10

img_rows, img_cols = 256, 256
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)

print('x_train shape:', x_train.shape)
print("Training samples: {}".format(x_train.shape[0]))
print("Test samples: {}".format
      (x_test.shape[0]))
x_train = torch.Tensor(x_train).float()
x_test = torch.Tensor(x_test).float()
y_train = torch.LongTensor(y_train)
y_test = torch.LongTensor(y_test)
#Define model
model = nn.Sequential(
        nn.Conv2d(256,80,1, stride=1),
        nn.ReLU(),
        nn.Conv2d(80,40,1, stride=1),
        nn.ReLU(),
        nn.MaxPool2d(4,stride=1),
        nn.Conv2d(40,30,1, stride=1),
        nn.ReLU(),
        nn.Conv2d(30,15,1, stride=1),
        nn.ReLU(),
        nn.Dropout(0.2),
        nn.Flatten(),
        nn.Linear(32, 32),
        nn.Dropout(0.1),
        nn.Linear(num_classes, 256),
        nn.ReLU()
        )
criterion = nn.CrossEntropyLoss()# cross entropy loss

optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

for epoch in range(100):
    optimizer.zero_grad()
    out = model(x_train)
    loss = criterion(out, y_train)
    loss.backward()
    optimizer.step()
    print(f"Epoch {epoch+1}, loss: {loss.item()}")

但是,当我运行这段代码时,它会在这一特定行产生错误

RuntimeError                              Traceback (most recent call last)
<ipython-input-10-96fa8b09f1ec> in <module>
     63 for epoch in range(100):
     64     optimizer.zero_grad()
---> 65     out = model(x_train)
     66     loss = criterion(out, y_train)
     67     loss.backward()

显示以下错误消息

运行时错误:给定的输入大小:(40x256x1)。计算输出大小:(40x253x-2)。输出大小太小

我不确定如何解决这个问题,因为我是pytorch的新手,并且最初的模型在tensorflow中工作过。 任何帮助都将不胜感激


Tags: fromtestimportimgmodelastrainnn
1条回答
网友
1楼 · 发布于 2024-04-23 20:04:52

我假设你正在处理图像。在这种情况下,代码有几个问题。从评论中也可以看出,有几件事我需要澄清

  • 我认为最重要的是你已经在输入形状上调高了轴。与Tensorflow不同,PyTorch多通道图的形状为(b, c, h, w)b:批量大小;c:通道数;hxw:特征图的高度和宽度

  • 您还将第一层定义为nn.Conv2d(256, 80, 1, stride=1),这意味着它有80个过滤器,并且需要256个通道输入!假设您遵循了我的第一点(即馈送(1,256,256)图像),那么这不是您想要的过滤器的数量可以保持在80,这取决于您和您的神经网络设计

  • 稍晚一点,在您的模型中,您用nn.MaxPool2d(4, stride=1)定义了一个最大池。只是要指出,您在这里使用的内核大小是4像素。这意味着,此时,生成的张量将具有(b, 40, 253, 253)的形状。从256x256253x253的变化是由于内核大小是4

  • 最后一次卷积后,将其展平为(b, 960135)。这就是253*253*15(特征图维度乘以特征图的数量)。最终,下一个密集层需要将该数字作为输入大小。相反,您将nn.Linear(32, 32)后跟nn.Linear(num_classes, 256)。它应该类似于nn.Linear(253*253*15, n)后跟nn.Linear(n, num_classes)。其中n是任意设置的,我假设您想要一个结尾带有num_classeslogits的输出

  • 还有,我在评论中读到了

    If you organize all correctly, I think you have to change the first layer in Sequential() from nn.Conv2d(256,80,1, stride=1) to nn.Conv2d(32,80,1, stride=1)

    批次大小与图层的大小参数无关。不要考虑批次轴,它是第一个轴。您的模型不依赖于批次大小

  • 我建议,增加内核大小,这将允许功能映射在通过网络时缩小尺寸,同时增加通道数量,直到到达平坦层并完全连接


以下是您的模型,其中有一些重要的修正,足以使其运行:

batch_size = 32
num_classes = 8

img_rows, img_cols = 256, 256
input_shape = (img_rows, img_cols, 1)

# dummy data, would broadcast your data with these shapes
x_train = torch.rand(batch_size, 1, img_rows, img_cols) 
y_train = torch.rand(batch_size, 256)

model = nn.Sequential(
    nn.Conv2d(1, 80, 1, stride=1),
    nn.ReLU(),
    nn.Conv2d(80, 40, 1, stride=1),
    nn.ReLU(),
    nn.MaxPool2d(4, stride=1),
    nn.Conv2d(40, 30, 1, stride=1),
    nn.ReLU(),
    nn.Conv2d(30, 15, 1, stride=1),
    nn.ReLU(),
    nn.Dropout(0.2),
    nn.Flatten(),
    nn.Linear(253*253*15, 256),
    nn.Dropout(0.1),
    nn.Linear(256, num_classes),
    nn.ReLU()
)

相关问题 更多 >