Я спрашиваю о C классах для функции потери NLLLoss .
В документации говорится:
Потеря отрицательного логарифмического правдоподобия. Полезно обучить проблеме классификации с C классами.
В основном все после этого момента зависит от того, знаете ли вы, что такое класс C, и я подумал, что знаю, что такое C класс был, но документация не имеет особого смысла для меня. Особенно, когда он описывает ожидаемые входные данные (N, C) where C = number of classes
. Вот где я запутался, потому что я думал, что класс C относится только к выводу . Насколько я понимаю, класс C был одним из самых горячих векторов классификаций. В учебниках я часто обнаруживал, что NLLLoss
часто сочетался с LogSoftmax
для решения задач классификации.
Я ожидал использовать NLLLoss
в следующем примере:
# Some random training data
input = torch.randn(5, requires_grad=True)
print(input) # tensor([-1.3533, -1.3074, -1.7906, 0.3113, 0.7982], requires_grad=True)
# Build my NN (here it's just a LogSoftmax)
m = nn.LogSoftmax(dim=0)
# Train my NN with the data
output = m(input)
print(output) # tensor([-2.8079, -2.7619, -3.2451, -1.1432, -0.6564], grad_fn=<LogSoftmaxBackward>)
loss = nn.NLLLoss()
print(loss(output, torch.tensor([1, 0, 0])))
Приведенное выше вызывает следующую ошибку в последней строке:
ValueError: Ожидается 2 или более измерений (получено 1)
Мы можем игнорировать ошибку, потому что Я явно не понимаю, что я делаю. Здесь я объясню мои намерения из приведенного выше исходного кода.
input = torch.randn(5, requires_grad=True)
Случайный одномерный массив для сопряжения с одним горячим вектором [1, 0, 0]
для обучения. Я пытаюсь сделать двоичные биты для одного горячего вектора десятичных чисел.
m = nn.LogSoftmax(dim=0)
Документация для LogSoftmax
говорит, что вывод будет такой же формы, как ввод, но я только видел примеры LogSoftmax(dim=1)
и поэтому я застрял, пытаясь сделать эту работу, потому что я не могу найти относительный пример.
print(loss(output, torch.tensor([1, 0, 0])))
Так что теперь у меня есть вывод NN, и я хочу узнать потери из моей классификации [1, 0, 0]
. В данном примере на самом деле не имеет значения, что представляют собой какие-либо данные. Я просто хочу потерю одного горячего вектора, который представляет классификацию.
В этот момент я застреваю, пытаясь устранить ошибки из функции потерь, связанные с ожидаемыми выходными и входными структурами. Я попытался использовать view(...)
для вывода и ввода, чтобы исправить форму, но это просто вызывает у меня другие ошибки.
Так что это возвращает к моему первоначальному вопросу, и я покажу пример из документации Чтобы объяснить мою путаницу:
m = nn.LogSoftmax(dim=1)
loss = nn.NLLLoss()
input = torch.randn(3, 5, requires_grad=True)
train = torch.tensor([1, 0, 4])
print('input', input) # input tensor([[...],[...],[...]], requires_grad=True)
output = m(input)
print('train', output, train) # tensor([[...],[...],[...]],grad_fn=<LogSoftmaxBackward>) tensor([1, 0, 4])
x = loss(output, train)
Опять же, у нас есть dim=1
на LogSoftmax
, что меня сейчас смущает, потому что посмотрите на данные input
. Это тензор 3x5
, и я потерян.
Вот документация по первому входу для функции NLLLoss
:
Ввод: (N, C) (N, C) где C = количество классов
Входные данные сгруппированы по количеству классов?
Итак, каждый строка входного тензора связана с каждым элементом обучающего тензора?
Если я изменю второе измерение входного тензора, то ничего не сломается и я не понимаю, что происходит.
input = torch.randn(3, 100, requires_grad=True)
# 3 x 100 still works?
Так что я не понимаю, что такое класс C, и я думал, что класс C был классификацией (например, метка) и имеет смысл только на выходах NN.
Я надеюсь, вы понимаете мою путаницу, потому что не должна форма входов для NN быть независимой от формы одного горячего вектора, используемого для классификации ?
Как примеры кода, так и документация говорят, что форма входов определяется количество классификаций, и я не совсем понимаю, почему.
Я пытался изучить документацию и учебные пособия, чтобы понять, что мне не хватает, но после нескольких дней не смог пройти этот пункт Я решил задать этот вопрос. Это было унизительно, потому что я думал, что это будет одна из самых простых вещей для изучения.