ValueError: Target и input должны иметь одинаковое количество элементов. целевой элемент (50)! = входной элемент (100) - PullRequest
0 голосов
/ 14 апреля 2020

Я новичок в Pytorch, поэтому я попытался выучить его, создав простую классификацию собак против кошек. Код:

class DogCatClassifier(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 32, 5)
        self.conv2 = nn.Conv2d(32, 64, 5)
        self.conv3 = nn.Conv2d(64, 128, 5)

        self.fc1 = nn.Linear(512, 256)
        self.fc2 = nn.Linear(256, 2)

    def forward(self, x):
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        print("1-st: ", x.shape)

        x = F.max_pool2d(F.relu(self.conv2(x)), (2, 2))
        print("2-nd: ", x.shape)

        x = F.max_pool2d(F.relu(self.conv3(x)), (2, 2))
        print("3-rd: ", x.shape)

        x = torch.flatten(x, start_dim=1)

        x = F.relu(self.fc1(x))
        print("6-th: ", x.shape)

        x = self.fc2(x)  # bc this is our output layer. No activation here.
        print("7-th: ", x.shape)

        x = F.sigmoid(x)
        print("8-th: ", x.shape)

        return x

Я передаю одну порцию данных (форма данных (50, 1, 50, 50)

model = DogCatClassifier()

images, labels = next(iter(train_loader))

preds = model(images)
print(pred)

loss = F.binary_cross_entropy(preds, labels)

Моя форма прогноза (50, 2) Так что, насколько я понимаю, F.binary_cross_entropy (preds, label) проверяет оба прогноза по одному изображению, и поэтому я получаю 100 прогнозов против 50 меток. Исходя из тензорного потока, я подумал, что могу просто реализовать те же логики c, что и при использовании sigmoid как последняя активация и binary_cross_entropy как функция потерь. Чего я не понимаю, так это как заставить этот кусок кода работать.

1 Ответ

0 голосов
/ 14 апреля 2020

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

1- Измените на F.cross_entropy (preds, label) в качестве функции потерь.

2- Измените свой код, чтобы выбрать максимальное значение в качестве цели.

  pred = pred.argmax(dim=1, keepdim=True) # gets the max value

Дайте мне знать, если это работает, если это не так, пожалуйста, обновите с новой ошибкой.

...