Погрешность измерения с использованием M C Dropout на питателе - PullRequest
0 голосов
/ 06 августа 2020

Я пытаюсь реализовать байесовскую CNN с использованием M c Dropout на Pytorch, основная идея заключается в том, что, применяя отсев во время тестирования и выполняя множество прямых проходов, вы получаете прогнозы от множества различных моделей. Я нашел применение M c Dropout, и я действительно не понял, как они применили этот метод и как именно они выбрали правильный прогноз из списка прогнозов

вот код


 def mcdropout_test(model):
    model.train()
    test_loss = 0
    correct = 0
    T = 100
    for data, target in test_loader:
        if args.cuda:
            data, target = data.cuda(), target.cuda()
        data, target = Variable(data, volatile=True), Variable(target)
        output_list = []
        for i in xrange(T):
            output_list.append(torch.unsqueeze(model(data), 0))
        output_mean = torch.cat(output_list, 0).mean(0)
        test_loss += F.nll_loss(F.log_softmax(output_mean), target, size_average=False).data[0]  # sum up batch loss
        pred = output_mean.data.max(1, keepdim=True)[1]  # get the index of the max log-probability
        correct += pred.eq(target.data.view_as(pred)).cpu().sum()

    test_loss /= len(test_loader.dataset)
    print('\nMC Dropout Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))


    train()
    mcdropout_test()

Я заменил

data, target = Variable(data, volatile=True), Variable(target)

, добавив

with torch.no_grad(): в начале

И вот как я определил свой CNN

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 192, 5, padding=2)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(192, 192, 5, padding=2)
        self.fc1 = nn.Linear(192 * 8 * 8, 1024)
        self.fc2 = nn.Linear(1024, 256)
        self.fc3 = nn.Linear(256, 10)
        self.dropout = nn.Dropout(p=0.3)
        
        nn.init.xavier_uniform_(self.conv1.weight)
        nn.init.constant_(self.conv1.bias, 0.0)
        nn.init.xavier_uniform_(self.conv2.weight)
        nn.init.constant_(self.conv2.bias, 0.0)
        nn.init.xavier_uniform_(self.fc1.weight)
        nn.init.constant_(self.fc1.bias, 0.0)
        nn.init.xavier_uniform_(self.fc2.weight)
        nn.init.constant_(self.fc2.bias, 0.0)
        nn.init.xavier_uniform_(self.fc3.weight)
        nn.init.constant_(self.fc3.bias, 0.0)


    def forward(self, x):
        x = self.pool(F.relu(self.dropout(self.conv1(x))))  # recommended to add the relu
        x = self.pool(F.relu(self.dropout(self.conv2(x))))  # recommended to add the relu
        x = x.view(-1, 192 * 8 * 8)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(self.dropout(x)))
        x = self.fc3(self.dropout(x))  # no activation function needed for the last layer
        return x

Может ли кто-нибудь помочь мне получить правильную реализацию метода исключения методом Монте-Карло на CNN?

1 Ответ

1 голос
/ 13 августа 2020

Реализовать M C Dropout в Pytorch просто. Все, что нужно сделать, - это установить выпадающие слои вашей модели в режим обучения. Это позволяет использовать разные маски отключения во время различных прямых проходов. Ниже представлена ​​реализация M C Dropout в Pytorch, иллюстрирующая, как несколько прогнозов из различных прямых проходов складываются вместе и используются для вычисления различных метрик неопределенности. В приведенном выше вопросе несколько прогнозов из T различных прямых проходов получаются путем первой установки модели в режим обучения (model.train()). Обратите внимание, что это нежелательно, потому что нежелательная стохастичность будет введена в прогнозы, если в модели есть слои, отличные от выпадающих, такие как норма партии. Следовательно, лучший способ - просто установить отсеиваемые слои в режим обучения, как показано в приведенном выше фрагменте.

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