Почему полносвязные сети плохи для картинок

Прежде чем понять, чем хороши CNN, разберёмся, почему обычная нейросеть на картинках проваливается.

Полносвязный слой (fully connected) — слой, где каждый нейрон связан с каждым входным значением. Отлично для табличных данных, но для картинок катастрофичен.

Проблема 1: взрыв числа параметров

Чтобы подать картинку в полносвязную сеть, её «разворачивают» в один длинный вектор пикселей. Посчитаем, сколько связей (весов) понадобится только для первого слоя из 1000 нейронов на цветной картинке 224×224.

width, height, channels = 224, 224, 3
inputs = width * height * channels
hidden = 1000

params = inputs * hidden          # веса первого полносвязного слоя
print("Входных значений (пикселей*каналов):", inputs)
print("Нейронов в скрытом слое:", hidden)
print("Весов в одном слое:", params)
print("В миллионах:", round(params / 1_000_000, 1))

Вывод:

Входных значений (пикселей*каналов): 150528
Нейронов в скрытом слое: 1000
Весов в одном слое: 150528000
В миллионах: 150.5

150 миллионов весов — и это только первый слой для скромной картинки 224×224! Такую сеть невозможно обучить: ей нужны астрономические данные и память, и она мгновенно переобучится.

Проблема 2: потеря пространственной структуры

Разворачивая картинку в вектор, мы теряем геометрию. Для полносвязной сети пиксель в углу и его сосед справа — просто два далёких числа в длинном векторе; сеть не знает, что они рядом. А ведь именно соседство несёт смысл: глаз — это узор из близких пикселей. Полносвязная сеть вынуждена заново учить, какие пиксели «рядом», теряя на это огромный ресурс.

Проблема 3: нет переноса знаний по картинке

Кошка может оказаться в любом углу кадра. Полносвязная сеть, выучив распознавать кошку слева, заново учится распознавать её справа — для неё это разные входы. Это неэффективно: одно и то же знание не переиспользуется.

Что нужно вместо этого

Хорошая «зрительная» архитектура должна:

  • Учитывать локальность: смотреть на маленькие окрестности, а не на всю картинку сразу.
  • Переиспользовать веса: один и тот же детектор признака применять по всей картинке (это резко сокращает параметры).
  • Сохранять геометрию: понимать, какие пиксели рядом.

Всё это даёт свёрточный слой: маленькое ядро (локальность) скользит по всей картинке с одними и теми же весами (переиспользование), сохраняя пространственное расположение. Ровно та свёртка, которую мы делали руками во втором разделе. О ней — следующий урок.

Итог

  • Полносвязный слой на картинке даёт сотни миллионов весов — необучаемо.
  • Разворачивание в вектор теряет геометрию: сеть не знает, какие пиксели рядом.
  • Знание не переносится по картинке: кошку слева и справа учат отдельно.
  • Решение — свёртка: локальность + переиспользование весов + сохранение структуры.
Проверьте себя
1. Почему полносвязный слой плохо подходит для изображений?
AОн не умеет работать с числами
BЧисло весов взрывается (миллионы на один слой), теряется геометрия и не переносится знание по картинке
CОн слишком быстрый
DОн работает только с текстом
2. Что теряется, когда картинку разворачивают в один длинный вектор для полносвязной сети?
AЦвет
BПространственная структура — информация о том, какие пиксели соседствуют
CЯркость
DНичего не теряется
3. Какое ключевое свойство свёрточного слоя резко сокращает число параметров?
AОн использует только один пиксель
BОдно и то же маленькое ядро (с общими весами) применяется по всей картинке
CОн не имеет весов вообще
DОн увеличивает разрешение
Поддержать проект