Какие преобразования мне нужно сделать, чтобы запустить набор данных через нейронную сеть? - PullRequest
0 голосов
/ 30 ноября 2018

Я новичок в области глубокого изучения и Pytorch, но я надеюсь, что кто-то может помочь мне с этим.Мой набор данных содержит изображения разных размеров.Я пытаюсь создать простую нейронную сеть, которая может классифицировать изображения.Однако я получаю ошибки несоответствия.

Нейронная сеть

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3)
        self.conv2 = nn.Conv2d(32, 32, 3)
        self.fc1 = nn.Linear(32 * 3 * 3, 200)
        self.fc2 = nn.Linear(200, 120)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.relu(self.conv2(x))
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x
net = Net()

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

Определите преобразования и назначьте обучающий набор и набор проверки

transform = transforms.Compose(
    [transforms.Grayscale(1),
     transforms.RandomCrop((32,32)),
     transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

data_dir = 'dataset'
full_dataset = datasets.ImageFolder(os.path.join(data_dir, 'train'), transform = transform)

train_size = int(0.8 * len(full_dataset))
val_size = len(full_dataset) - train_size
trainset, valset = torch.utils.data.random_split(full_dataset, [train_size, val_size])

trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                           shuffle=True, num_workers=2)
valloader = torch.utils.data.DataLoader(valset, batch_size=4,
                                           shuffle=False, num_workers=2)
classes = full_dataset.classes

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

Нейронная сеть поезда

for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

При запуске этого последнего фрагмента кода я получаю следующую ошибку: size mismatch, m1: [3584 x 28], m2: [288 x 200] at /Users/soumith/miniconda2/conda-bld/pytorch_1532623076075/work/aten/src/TH/generic/THTensorMath.cpp:2070, когдавыполняется следующая строка: outputs = net(inputs)

Мой код представляет собой разновидность кода, приведенного в этого руководства по Pytorch .Может кто-нибудь сказать мне, что я делаю неправильно?

ОБНОВЛЕНИЕ

Я обновил класс нейронной сети так:

class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # 1 input image channel, 6 output channels, 5x5 square convolution
        # kernel
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        # an affine operation: y = Wx + b
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        # Max pooling over a (2, 2) window
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        # If the size is a square you can only specify a single number
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = x.view(-1, self.num_flat_features(x))
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

    def num_flat_features(self, x):
        size = x.size()[1:]  # all dimensions except the batch dimension
        num_features = 1
        for s in size:
            num_features *= s
        return num_features

net = Net()

Но сейчасЯ получаю ошибку в loss = criterion(outputs, labels): Assertion cur_target >= 0 && cur_target < n_classes' failed. at /Users/soumith/miniconda2/conda-bld/pytorch_1532623076075/work/aten/src/THNN/generic/ClassNLLCriterion.c:93

1 Ответ

0 голосов
/ 30 ноября 2018

В первой конфигурации вы неправильно настроили self.fc1.Вам нужно, чтобы входные данные имели размеры 32 * 28 * 28 вместо 32 * 3 * 3, поскольку ваши изображения 32 * 32, а ядро ​​и шаг - 3 и 1 соответственно.См. это видео для более простого объяснения.Попробуйте настроить вторую конфигурацию самостоятельно, если не можете, прокомментируйте ниже.

...