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

时间:2021-01-07 16:24:09

标签: python image-processing pytorch conv-neural-network

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 中工作。 任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

我假设您正在处理图像。在这种情况下,您的代码存在多个问题。同时阅读评论,我需要澄清一些事情。

  • 我认为最重要的是您已经将输入形状的轴调高了。与 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_classes logits 的输出。

  • 另外,我看了评论

    <块引用>

    如果你组织正确,我认为你必须将 Sequential() 中的第一层从 nn.Conv2d(256,80,1, stride=1) 更改为 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()
)
相关问题