Нейронная сеть свертки цифр двоичного изображения имеет очень высокую достоверность, когда на изображении ничего нет.

Я тренировал свою сверточную нейронную сеть на тщательно обрезанных печатных цифрах, похожих по стилю на набор данных Mnist. Он работает отлично, почти на 100 процентов как на обучающих, так и на тестовых данных.

Сначала я тренировал его на 4-канальных бинарных изображениях, где белый цвет был «255», а черный — «0». Он имеет 10 выходных данных, по одному для каждой цифры, которые я затем программирую, чтобы получить вероятность для каждой категории.

Однако я хочу использовать метод скользящего окна для анализа страницы цифр. Это невозможно, потому что для полностью белого ввода он возвращает почти 100% уверенности в том, что это 4, в то время как для всего остального почти ничего.

Я подумал, что это может быть связано с тем, что нейронная сеть обучалась на белом пространстве изображения, а не на черном пространстве, поскольку черные пиксели имели значение 0, поэтому я инвертировал изображения и снова обучил сеть. опять же, он просто возвращает действительно близкую к 100% уверенность на полностью белом изображении.

Для обоих он возвращает низкие проценты для каждого класса, когда изображение полностью черное, как и должно быть, хотя 4 по-прежнему является самым высоким

Я не понимаю интуицию, стоящую за этим, поэтому любая помощь была бы отличной, даже если бы вы могли просто сказать, что это не обычное поведение. Этого следует ожидать? Должен ли я создать еще один класс для вещей, которые не являются цифрами, и обучить его этому?

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

class fully_convolutional_1channel(nn.Module):
    def __init__(self): 

        super(fully_convolutional_1channel, self).__init__()

        self.conv1 = nn.Conv2d(1, 6, 5)

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

        self.conv2 = nn.Conv2d(6, 16, 5)

        self.fconv1 = nn.Conv2d(16, 120, (4,2))


        self.fconv2 = nn.Conv2d(120, 84,  1)
        self.fconv3 = nn.Conv2d(84, 10, 1)


    def forward(self, x):

        x = self.conv1(x)

        x = F.relu(x)
        #relu does not change size



        x = self.pool(x)

        x = self.pool(F.relu(self.conv2(x)))

        #x = x.view(-1, 16 * 4 * 2)


        x = F.relu(self.fconv1(x))

        x = F.relu(self.fconv2(x))


        x = self.fconv3(x)

        #print(list(x.size))

        return x

person Ralph Sinnhuber    schedule 20.02.2018    source источник


Ответы (1)


Должен ли я создать еще один класс для вещей, которые не являются цифрами, и обучить его этому?

Да. Ваша сеть обучена распознавать цифры, а не пробелы. Вы можете либо переобучить сеть с помощью этой стратегии, либо предварительно обработать страницу цифр, чтобы избежать заполнения сети пробелами.

person nicobonne    schedule 21.02.2018
comment
ок, отлично, большое спасибо... просто подумал, что это ожидаемое событие, потому что мне это кажется очень странным - person Ralph Sinnhuber; 21.02.2018
comment
@RalphSinnhuber, если вас устраивает мой вопрос, вы можете его принять :) - person nicobonne; 21.02.2018