RuntimeError: Expected 4-dimensional input for 4-dimensional weight X, but got 3-dimensional input of size Y instead

RuntimeError: Expected 4-dimensional input for 4-dimensional weight X, but got 3-dimensional input of size Y instead

我正在构建一个 CNN 来对 EMNIST 数据集进行图像分类。

为此,我有以下数据集:

import scipy .io
emnist = scipy.io.loadmat(DIRECTORY + '/emnist-letters.mat')
data = emnist ['dataset']
X_train = data ['train'][0, 0]['images'][0, 0]
X_train = X_train.reshape((-1,28,28), order='F')

y_train = data ['train'][0, 0]['labels'][0, 0]

X_test = data ['test'][0, 0]['images'][0, 0]
X_test = X_test.reshape((-1,28,28), order = 'F')

y_test = data ['test'][0, 0]['labels'][0, 0]

形状:

  1. X_train = (124800, 28, 28)
  2. y_train = (124800, 1)
  3. X_test = (20800, 28, 28)
  4. y_test = (20800, 1)

注意图片是灰度的,所以颜色只用一个数字表示。

我进一步准备如下:

train_dataset = torch.utils.data.TensorDataset(torch.from_numpy(X_train), torch.from_numpy(y_train))
test_dataset = torch.utils.data.TensorDataset(torch.from_numpy(X_test), torch.from_numpy(y_test))

train_loader = torch.utils.data.DataLoader(dataset=train_dataset, 
                                           batch_size=batch_size, 
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset, 
                                          batch_size=batch_size, 
                                          shuffle=False)

我的模型如下所示:

class CNNModel(nn.Module):
    def __init__(self):
        super(CNNModel, self).__init__()

        self.cnn_layers = Sequential(
            # Defining a 2D convolution layer
            Conv2d(1, 4, kernel_size=3, stride=1, padding=1),
            BatchNorm2d(4),
            ReLU(inplace=True),
            MaxPool2d(kernel_size=2, stride=2),
            # Defining another 2D convolution layer
            Conv2d(4, 4, kernel_size=3, stride=1, padding=1),
            BatchNorm2d(4),
            ReLU(inplace=True),
            MaxPool2d(kernel_size=2, stride=2),
        )

        self.linear_layers = Sequential(
            Linear(4 * 7 * 7, 10)
        )

    # Defining the forward pass    
    def forward(self, x):
        x = self.cnn_layers(x)
        x = x.view(x.size(0), -1)
        x = self.linear_layers(x)
        return x

model = CNNModel()

下面的代码是我用来训练模型的部分代码:

for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):

    images = Variable(images)
    labels = Variable(labels)

    # Forward pass to get output/logits
    outputs = model(images)

但是,通过执行我的代码,我得到以下错误:

RuntimeError: Expected 4-dimensional input for 4-dimensional weight [4, 1, 3, 3], but got 3-dimensional input of size [100, 28, 28] instead

因此,当我的输入是 3D 时,需要 4D 输入。我该怎么做才能让 3D 模型而不是 4D 模型?

有人问了一个类似的问题,但是我不知道如何将其转换为我的代码

卷积期望输入的大小为 [batch_size、通道、高度、宽度],但您的图像大小为 [batch_size, height, width], channel 维度缺失。灰度由单个通道表示,并且您已将第一个卷积的 in_channels 正确设置为 1,但您的图像没有匹配的维度。

您可以使用 torch.unsqueeze 轻松添加奇异维度。

此外,请不要使用 Variable,它在 2 年前发布的 PyTorch 0.4.0 中已被弃用,它的所有功能都已合并到张量中。

for i, (images, labels) in enumerate(train_loader):
    # Add a single channel dimension
    # From: [batch_size, height, width]
    # To: [batch_size, 1, height, width]
    images = images.unsqueeze(1)

    # Forward pass to get output/logits
    outputs = model(images)