Я тренировал свою сверточную нейронную сеть на тщательно обрезанных печатных цифрах, похожих по стилю на набор данных 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