mat1 и mat2 не могут быть перемножены из-за несоответствия размеров (1×400 и 784×10)

Вопрос или проблема

Я следую руководству о том, как запустить модель классификации pytorch, но каждый раз, когда я пытаюсь выполнить model_0(x_train.to(device), возникает ошибка.

import sklearn.datasets
from sklearn.datasets import make_moons
NUM_SAMPLES = 1000
RANDOM_SEED = 42
x, y = make_moons(n_samples=NUM_SAMPLES,
                  noise=None,
                  random_state=RANDOM_SEED,
                  shuffle=True)
import torch



device="cuda" if torch.cuda.is_available() else 'cpu'
device

import pandas as pd

data_df = pd.DataFrame({"x0" : x[:, 0],
                        "x1" : x[:, 1],
                        "y" : y})
data_df.head()

import matplotlib.pyplot as plt

plt.scatter(x[:, 0], x[:, 1])
x = torch.tensor(y, dtype=torch.float)
y = torch.tensor(y, dtype=torch.float)

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x,
                                                     y, 
                                                    test_size=0.6,
                                                      random_state=RANDOM_SEED)
len(x_train), len(x_test), len(y_train), len(y_test)

from torch import nn

class  MoonModelV0(nn.Module):
    def __init__(self):
        super().__init__()
        self.layer_1 = nn.Linear(in_features=2, out_features=3)
        self.layer_2 = nn.Linear(in_features=5, out_features=1)

    def forward(self, x):

        return self.layer_2(self.layer_1(x))
    


model_0 = MoonModelV0().to(device)
model
# до сих пор код работает нормально, пока я не выполню
model_0(x_train.to(device))

Если есть какие-то полезные предложения, я с удовольствием их приму.

Код, который вы предоставили, не выдает точно такую же ошибку, как вы указали, но ошибка вызвана тем, что ваши входные/весовые матрицы имеют неправильную форму. Вам нужно убедиться, что ваш ввод имеет форму (n_observations, n_features), и количество входных признаков вашего второго слоя должно быть равно количеству выходных признаков вашего первого слоя.

class  MoonModelV0(nn.Module):
    def __init__(self):
        super().__init__()
        self.layer_1 = nn.Linear(in_features=1, out_features=3)
        self.layer_2 = nn.Linear(in_features=3, out_features=1)

    def forward(self, x):
        return self.layer_2(self.layer_1(x))

model_0 = MoonModelV0().to(device)
model_0(x_train.reshape(-1, 1).to(device))

Ответ или решение

Для решения проблемы с несоответствием размеров матриц (1×400 и 784×10), необходимо понимать основную концепцию, лежащую в основе матричного умножения в контексте нейронных сетей, и как это связано с передачей данных через слои. При реализации многослойных нейронных сетей в PyTorch, один из наиболее распространенных источников ошибок связан с размерами входных и выходных тензоров. Ваша ошибка в ходе выполнения модели указывает на то, что архитектура сети неправильно настроена по отношению к размерам данных.

Теория

Основная идея матричного умножения в плане нейронных сетей заключается в том, что выходные данные одного слоя становятся входными данными для следующего слоя. Для корректной работы это предполагает, что количество выходных узлов одного слоя (out_features) совпадает с количеством входных узлов следующего слоя (in_features).

В вашем коде была указана следующая архитектура:

class MoonModelV0(nn.Module):
    def __init__(self):
        super().__init__()
        self.layer_1 = nn.Linear(in_features=2, out_features=3)
        self.layer_2 = nn.Linear(in_features=5, out_features=1)

    def forward(self, x):
        return self.layer_2(self.layer_1(x))

Проблема заключается в конфликте размерностей: между первым и вторым слоями, где первый слой имеет 3 выходных признака, а второй ожидает 5 входных признаков. Это и вызывает ошибку "shapes cannot be multiplied".

Пример

Предположим, что ваш набор данных имеет следующие характеристики: если вы передаете двумерные данные, у вас должно быть соответствие по признакам. Например, если у вас в начале обучения два признака (features) для слоя layer_1, то значение in_features для layer_1 должно быть равно 2, а out_features для него может быть любым, как в данном случае равным 3.

В следующем слое, layer_2, in_features должно совпадать с out_features предыдущего слоя. Таким образом, архитектура должна выглядеть так:

class MoonModelV0(nn.Module):
    def __init__(self):
        super().__init__()
        self.layer_1 = nn.Linear(in_features=2, out_features=3)
        self.layer_2 = nn.Linear(in_features=3, out_features=1)

    def forward(self, x):
        return self.layer_2(self.layer_1(x))

Применение

Теперь, чтобы избежать ошибки, необходимо следить за тем, чтобы передаваемые данные были правильно подготовлены и имели соответствующий размер. Это можно сделать с помощью метода reshape или view в PyTorch, если вам нужно изменить размеры входного тензора. Однако в данной ситуации ошибка в архитектуре модели, и изменения в коде модели уже исправят проблему.

Корректная версия обработки данных и модели будет выглядеть следующим образом:

  1. Убедитесь, что данные имеют правильный размер:
# Преобразуем данные в нужный формат
x_train = x_train.view(-1, 2)  # тут предполагаем, что x_train имеет внутри себя правильное число признаков
  1. Реализуйте модель с правильными размерами слоев:
class MoonModelV0(nn.Module):
    def __init__(self):
        super().__init__()
        self.layer_1 = nn.Linear(in_features=2, out_features=3)
        self.layer_2 = nn.Linear(in_features=3, out_features=1)

    def forward(self, x):
        return self.layer_2(self.layer_1(x))
  1. Начните тренировку:
model_0 = MoonModelV0().to(device)
output = model_0(x_train.to(device))

Итог

Таким образом, данное исправление требует, чтобы подход к определению размеров был глубоким и продуманным. Всегда необходимо удостовериться, что каждое соединение между слоями имеет согласующиеся размеры — количество выходных признаков одного слоя всегда должно равняться количеству входных признаков следующего. Это обеспечит нормальный проход данных по архитектуре нейронной сети и предотвращение возможных ошибок в процессе вычислений.

Оцените материал
Добавить комментарий

Капча загружается...