Градиент неравенства PyTorch - PullRequest
1 голос
/ 11 марта 2020

Я написал модель PyTorch примерно следующим образом:

import torch.nn as nn
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.layer1 = nn.Sequential(nn.Linear(64 * 64, 16), nn.LeakyReLU(0.2))
        self.layer2 = nn.Sequential(nn.Linear(16, 32), nn.LeakyReLU(0.2))
        self.layer3 = nn.Sequential(nn.Linear(32, 64), nn.LeakyReLU(0.2))
        self.layer4 = nn.Sequential(nn.Linear(64, 15), nn.Tanh())
    def forward(self, x):
        return (self.layer4(self.layer3(self.layer2(self.layer1(x)))) < 0).float()

Обратите внимание, что я хочу сделать: я хочу, чтобы forward возвращал тензор 0 и 1. Однако, это не тренируется, вероятно, потому, что производная неравенства равна нулю.

Как я могу сделать модель, подобную этой, например, такой серии, если я хочу сделать сегментацию изображения?

1 Ответ

2 голосов
/ 11 марта 2020

Как вы сказали, вы не можете тренировать что-то вроде x<0.
С вами все будет хорошо, даже если вы избавитесь от части <0 и будете использовать

    return self.layer4(self.layer3(self.layer2(self.layer1(x))))

до тех пор, пока вы используете соответствующую потерю. Я думаю, что вы хотели бы использовать это nn.BCEWithLogitsLoss. В этом случае вы должны получить Tanh из последнего слоя, так как nn.BCEWithLogitsLoss внутренне вычисляет с сигмоидом.
(Есть варианты использования nn.BCEloss() с sigmoid на последнем слое, или даже придерживайтесь Tanh, но я не думаю, что есть причина проделывать долгий путь.)

Так что на этапе обучения нейронная сеть старается изо всех сил, чтобы соответствовать выходу до 0 и 1 с. После этого на этапе тестирования вы должны взять выходные данные слоя и задать ему некоторый порог для точного изменения значений на 1 с и 0 (как вы сделали (output<0).float())

Вы найдете полезные источники, если будете искать multilabel classification.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...