Ошибка измерения функции потерь классификатора вне допустимого диапазона - PullRequest
0 голосов
/ 16 июня 2020
import torch.nn as nn

class MyModel(nn.Module):

    def __init__(self):
        super(MyModel, self).__init__()

        self.conv1 = nn.Conv2d(1, 32, kernel_size=5, stride=2, padding=2)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=5,stride=2)

        self.fc = nn.Linear(884736, 1000)
        self.fc1 = nn.Linear(1000, 600)
        self.fc2 = nn.Linear(600, 200)
        self.fc3 = nn.Linear(200, 6)

        self.pooling = nn.MaxPool2d(2, 2)



    def forward(self, x):

        x = self.conv1(x)
        x = nn.functional.relu(x)
        x= self.pooling(x)

        x= self.conv2(x)

        x = torch.flatten(nn.functional.relu(x))

        x= self.fc(x)
        x = nn.functional.relu(x)
        # import pdb; pdb.set_trace()

        x= self.fc1(x)
        x= self.fc2(x)
        x= self.fc3(x)

        # x = torch.softmax(x)



        return x

# model = torch.nn.Sequential(
# )

model = MyModel()

#Training

dataiter = iter(trainloader)
total_epochs = 5
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters())

for epoch in tqdm(range(total_epochs)):

  #initialize batch
  gc.collect()
  input_, label_ = dataiter.next()

  #forwardd
  out = model.forward(input_)

  #backwardd     
  print (out,out.shape,)

  print (label_, label_.shape)
  # out = out.unsqueeze(dim=0)

  # label_ =label_.type_as(out)
  loss = criterion(out, label_)
  loss.backward()

  optimizer.zero_grad()
  optimizer.step()

  print('batch_loss:', str(loss.item()))

  print('Epochs completed:', epoch+1,'\n')
  print('epoch_loss:' + loop_loss/float(batch_size))

У меня есть набор данных о разных породах собак (120 классов) http://vision.stanford.edu/aditya86/ImageNetDogs/images.tar

Метки представляют собой значения int в диапазоне от 1 до 120

Мне нужно создать классификатор

Получение ошибки при вычислении потерь Размер вне допустимого диапазона (ожидается, что он находится в диапазоне [-1, 0], но получил 1)

Что может быть не так ?

1 Ответ

0 голосов
/ 16 июня 2020

Выход модели имеет только одно измерение, он имеет размер [6] , но nn.CrossEntropyLoss ожидает размер [batch_size, num_classes ] .

В модели вы сглаживаете вывод сверток. Вы должны сохранить размер партии, так как они независимы друг от друга, и их полное выравнивание объединит их в один. torch.flatten принимает аргумент start_dim (второй аргумент), который определяет, с какого измерения начинается сглаживание. Если установить для него значение 1, он начнется со второго измерения, а первое измерение (пакетное измерение) останется без изменений.

# Flatten everything but the first dimension
# From: [batch_size, channels, height, width] (4D)
# To: [batch_size, channels * height * width] (2D)
x = torch.flatten(nn.functional.relu(x), 1)

Выходные данные модели также должны иметь такое же количество классов, что и ваш набор данных. Поскольку у вас 120 классов, результат последнего линейного слоя должен быть 120.

self.fc3 = nn.Linear(200, 120)

Кроме того, метки должны находиться в диапазоне [0, 119] , потому что они индексы классов и, как и любая индексация в Python, отсчитываются от нуля. Если ваши метки находятся в диапазоне [1, 120] , вы можете просто вычесть из них единицу.

...