Как предсказать метку в модели классификации MultiClass в pytorch? - PullRequest
0 голосов
/ 15 декабря 2018

Я сейчас работаю над своим мини-проектом, где предсказываю жанры фильмов на основе их постеров.Итак, в наборе данных, который у меня есть, каждый фильм может иметь от 1 до 3 жанров, поэтому каждый экземпляр может принадлежать нескольким классам.Всего у меня 15 классов (15 жанров).Поэтому сейчас я сталкиваюсь с проблемой того, как делать предсказания с использованием pytorch для этой конкретной проблемы.

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

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

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 ('Законченное обучение')

Вопрос 1 (для обучающей части)).Что бы вы могли предложить использовать в качестве функции активации.Я думал о BCEWithLogitsLoss (), но я не уверен, насколько он будет хорош.

, и тогда точность прогноза для testset определяется следующим образом: для всей сети:

correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))

и для каждого класса:

class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs, 1)
        c = (predicted == labels).squeeze()
        for i in range(4):
            label = labels[i]
            class_correct[label] += c[i].item()
            class_total[label] += 1


for i in range(10):
    print('Accuracy of %5s : %2d %%' % (
        classes[i], 100 * class_correct[i] / class_total[i]))

, где вывод выглядит следующим образом:

Accuracy of plane : 36 % 
Accuracy of   car : 40 % 
Accuracy of  bird : 30 % 
Accuracy of   cat : 19 % 
Accuracy of  deer : 28 % 
Accuracy of   dog : 17 % 
Accuracy of  frog : 34 % 
Accuracy of horse : 43 % 
Accuracy of  ship : 57 % 
Accuracy of truck : 35 % 

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

Например:

The Matrix (1999)                ['Action: 91%', 'Drama: 25%', 'Adventure: 13%']
The Others (2001)                ['Drama: 76%', 'Horror: 65%', 'Action: 41%']
Alien: Resurrection (1997)       ['Horror: 67%', 'Action: 64%', 'Drama: 43%']
The Martian (2015)               ['Drama: 95%', 'Adventure: 81%']

Учитывая, что каждый фильм не всегда имеет 3 жанра, иногда 2, а иногда 1. Поэтому, как я вижу, я должен найти3 максимальных значения, 2 максимальных значения или 1 максимальное значение моего выходного списка, который является списком из 15 жанров, поэтому, например, если

, мои прогнозируемые жанры - [Movie, Adventure], тогда

Функция some_kind_of_function (output) должна выдавать значения

[1 0 0 0 0 0 0 0 0 0 0 1 0 0 0],

, которые впоследствии можно сравнить с ground_truth.Я не думаю, что torchmax будет работать в этом случае, потому что он дает только одно максимальное значение из [массива weigts], поэтому

Какой лучший способ его реализовать?

Заранее спасибоСпасибо за любую помощь или предложение:)

1 Ответ

0 голосов
/ 15 декабря 2018
  1. Вы правы, вы хотите выполнить двоичную классификацию (постер X - драматический фильм или нет? Это боевик или нет?) Для каждой пары жанровых плакатов.BinaryCrossEntropy(WithLogits) - это путь.
  2. Что касается наилучшей метрики для оценки вашего алгоритма, то вам решать, что вы ищете.Но вы можете исследовать такие идеи, как точность и вспомнить или f1 счет . Лично , я бы, вероятно, выбрал 3 лучших для каждого жанра (так как это максимальное количество жанров, назначенных для каждого плаката) и посмотрел бы, если те, которые ожидаются, обнаружатся с высокой вероятностью и если неожиданные (в случае фильма с двумя жанрами "наземной правды") показывать в последних местах со значительно меньшей вероятностью.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...