RuntimeError: ожидается 4-мерный ввод для 4-мерного веса X, но вместо этого получен 3-мерный ввод размера Y - PullRequest
0 голосов
/ 17 июня 2020

Я создаю 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

Таким образом, ожидается ввод 4D, в то время как мой ввод - 3D. Что я могу сделать, чтобы ожидалась 3D-модель, а не 4D-модель?

Здесь задается аналогичный вопрос, однако я не понимаю, как я могу перевести это в свой код

1 Ответ

1 голос
/ 17 июня 2020

Свертка ожидает, что вход будет иметь размер [размер_пакета, каналы, высота, ширина] , но ваши изображения имеют размер [размер_пакета, высота, ширина] , канал отсутствует размер. Оттенки серого представлены одним каналом, и вы правильно установили in_channels первых сверток на 1, но ваши изображения не имеют соответствующего измерения.

Вы можете легко добавить единственное измерение с помощью torch.unsqueeze.

Также, пожалуйста, не используйте Variable, он устарел в PyTorch 0.4.0, который был выпущен более 2 лет go , и все его функции были объединены в тензоры.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...