Как преобразовать 35 классов набора данных городских пейзажей в 19 классов? - PullRequest
1 голос
/ 18 июня 2019

Ниже приведен небольшой фрагмент моего кода. Используя это, я могу обучить свою модель под названием 'lolnet' на наборе данных городских пейзажей Но набор данных содержит 35 классов / меток [0-34].

imports ***

trainloader = torch.utils.data.DataLoader(
    datasets.Cityscapes('/media/farshid/DataStore/temp/cityscapes/', split='train', mode='fine',
                    target_type='semantic', target_transform =trans,
                    transform=input_transform ), batch_size = batch_size, num_workers = 2)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
net = lolNet()
criterion = CrossEntropyLoss2d()

net.to(device)
num_of_classes = 34

for epoch in range(int(0), 200000):

    lr = 0.0001

    for batch, data in enumerate(trainloader, 0):

        inputs, labels = data
        labels = labels.long()
        inputs, labels = inputs.to(device), labels.to(device)

        labels = labels.view([-1, ])

        optimizer = optim.Adam(net.parameters(), lr=lr)

        optimizer.zero_grad()
        outputs = net(inputs)

        outputs = outputs.view(-1, num_of_class)


        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()

        outputs = outputs.to('cpu')
        outputs = outputs.data.numpy()
        outputs = outputs.reshape([-1, num_of_class])

        mask = np.zeros([outputs.shape[0]])
        #
        for i in range(len(outputs)):
            mask[i] = np.argmax(outputs[i])

        mask = mask.reshape([-1, 1])

        IoU = jaccard_score(labels.to('cpu').data, mask, average='micro')

Но я хочу тренировать свою модель только в 19 классах. Эти 19 классов найдены здесь . Метки для обучения сохраняются как «ignoreInEval» = True. Этот помощник по загрузке данных Pytorch для этого набора данных не дает никакой подсказки.

Поэтому мой вопрос заключается в том, как я могу обучить свою модель на желаемых 19 классах этого набора данных, используя API Pytorch "наборы данных. Городские пейзажи".

Ответы [ 2 ]

1 голос
/ 19 июня 2019

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

  • Обучите свою модель всем 35 классам, но игнорируйте нежелательные классы во время фазы тестирования (не фазы оценки).
  • Настройка Datasetкласс для загрузки изображений только из целевых классов.

Причина, по которой первый способ предпочтительнее, заключается в том, что вы можете обучить более обобщенную модель, и она должна работать лучше в реальном мире.Недостаток в том, что вам нужно больше ресурсов / времени для обучения модели.

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

from torch.utils.data.dataset import Dataset
from torchvision import transforms

class MyCustomDataset(Dataset):
    def __init__(self, ..., transforms=None):
        # custom list of image path, labels...
        self.transforms = transforms

    def __getitem__(self, index):
        # stuff
        ...
        data = # Some data read from a file or image
        if self.transforms is not None:
            data = self.transforms(data)
        # If the transform variable is not empty
        # then it applies the operations in the transforms with the order that it is created.
        return (img, label)

    def __len__(self):
        return count # of how many data(images?) you have
0 голосов
/ 18 июня 2019

Вы загружаете модель и веса.

import torch
import torch.nn as nn
import torchvision.models as models

r = models.resnet50(pretrained=True)

Обратите внимание, что в исходном повторном отправлении имеется 1000 категорий / классов.Поэтому, когда вы загружаете предварительно подготовленную модель, последняя fc будет для 1000 классов.

Вот метод forward(), который у вас есть, и над этим кодом находится ваша модель.

Вы можете удалить последний fc полностью подключенный слой из исходной модели resnet50 и добавить свой новый fc точно с 19 классами (19 выходов), и вы можете обучить классификатор только для этого последнего слоя.Остальные слои, кроме последнего, должны быть заморожены.

Таким образом, вы изучите только 19 классов, которые вам нужны.


Обратите внимание, что метод resent __init__ также может принимать числоклассы, так что вы можете попробовать это, но в этом случае вы не можете загрузить предварительно обученные веса, поэтому вам нужно использовать pretrained=False и вам нужно тренироваться с нуля.

import torch
import torch.nn as nn
import torchvision.models as models

r = models.resnet50(num_classes=19, pretrained=False)
...