Почему моя CNN для задачи двоичной классификации имеет постоянную точность 50% с BCELoss против 80%+ с перекрестной энтрPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Почему моя CNN для задачи двоичной классификации имеет постоянную точность 50% с BCELoss против 80%+ с перекрестной энтр

Сообщение Anonymous »

Я создаю CNN с нуля с помощью Pytorch. У меня есть сбалансированный набор данных изображений, разделенный пополам для обоих классов. Я пытаюсь использовать функцию BCEwithLogitsLoss из torch.nn, поскольку я читал, что она обычно лучше всего подходит для таких случаев, как мой. Однако по какой-то причине кажется, что моя сеть вообще ничего не изучает, когда я использую эту функцию потерь! Он остается с неизменной точностью ~ 50%, при этом он всегда угадывает только один класс. Когда я вместо этого использую обычную функцию CrossEntropyLoss и расширяю выходные узлы моего последнего слоя до 2, моя сеть фактически начинает обучение! В то время как с «правильной» функцией потерь моя сеть никогда не достигает точности даже 1% для целевого класса, используя перекрестную энтропийную потерю я могу достичь даже 90%+ через несколько эпох.
Насколько я понимаю, потеря перекрестной энтропии лучше подходит для задач многоклассовой классификации, тогда как двоичная перекрестная энтропия лучше подходит для задач двоичной классификации, как указано в названии, поэтому я не понимаю, как это может быть так.
Изначально я начал с более простой CNN, поскольку создавал ее впервые. Таким образом, после некоторых дополнительных исследований я пришел к выводу, что отчасти это может быть связано с отсутствием слоев и сложности. Поэтому я добавил больше слоев и в итоге получил вот такой план:

Код: Выделить всё

import torch.nn as nn
import torch.nn.functional as F

class ConvolutionalNN(nn.Module):
def __init__(self):
super(ConvolutionalNN, self).__init__()

self.conv1 = nn.Conv2d(3, 9, 5)
self.conv2 = nn.Conv2d(9, 27, 5)
self.conv3 = nn.Conv2d(27, 54, 5)
self.conv4 = nn.Conv2d(54, 108, 5)
self.conv5 = nn.Conv2d(108, 216, 5)
self.conv6 = nn.Conv2d(216, 432, 5)

self.pool = nn.MaxPool2d(3, 3)

self.fc1 = nn.Linear(432*4*4, 256)
self.fc2 = nn.Linear(256, 64)
self.fc3 = nn.Linear(64, 2)

def forward(self, x):
x = (F.relu(self.conv1(x))) #First convolutional layer, then activation function
x = self.pool(F.relu(self.conv2(x))) #Second layer, activation function, then pooling layer
x = (F.relu(self.conv3(x)))
x = self.pool(F.relu(self.conv4(x)))
x = (F.relu(self.conv5(x)))
x = self.pool(F.relu(self.conv6(x)))
x = x.reshape(-1, 432*4*4) #Flattens the tensor
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)

return x
Отчасти меня вдохновили двойные сверточные слои, используемые в VGGNET. Кроме того, у меня нет опыта в этом, поэтому, если у кого-то есть какие-либо предложения, я буду более чем рад их принять.
Я использовал скорость обучения 0,001 и 0,0001. Я использую оптимизатор Адама. Более того, мои метки не имеют горячего кодирования. В приведенном выше случае я использовал 2 выходных узла для взаимодействия с CrossEntropyLoss, однако ранее я использовал 1 выходной узел для BCE.
Я с нетерпением жду любой помощи! Спасибо вам огромное!

Подробнее здесь: https://stackoverflow.com/questions/784 ... 0-accuracy
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»