Свёрточные сети (CNN) для изображений

Урок объясняет, как свёрточные сети экономно и осмысленно работают с изображениями.

Свёртка — это операция, при которой маленькое окно весов (ядро, фильтр) скользит по входу и в каждой позиции считает взвешенную сумму, выделяя локальный признак.

Ключевая идея: общий детектор

Вместо отдельного веса на каждый пиксель CNN использует маленькое ядро (например, 3×3) и прогоняет его по всей картинке. Один и тот же набор из девяти весов ищет, скажем, вертикальный край в каждой точке изображения. Это решает сразу две проблемы MLP: параметров мало (девять вместо миллионов) и детектор работает в любой позиции (инвариантность к сдвигу).

Свёртка на одномерном примере

Чтобы увидеть суть без матриц, возьмём одномерный сигнал и ядро-детектор перепада [-1, 1]. Там, где сигнал меняется, свёртка даст ненулевой отклик — это и есть «найденный край».

def conv1d(signal, kernel):
    k = len(kernel)
    out = []
    for i in range(len(signal) - k + 1):
        window = signal[i:i+k]
        out.append(sum(w * x for w, x in zip(window, kernel)))
    return out

signal = [0, 0, 0, 5, 5, 5, 0, 0]
edges = conv1d(signal, [-1, 1])   # детектор перепада
print("Сигнал:        ", signal)
print("После свёртки: ", edges)

def maxpool(xs, size=2):
    return [max(xs[i:i+size]) for i in range(0, len(xs), size)]
print("После max-пулинга:", maxpool([abs(v) for v in edges]))

Вывод:

Сигнал:         [0, 0, 0, 5, 5, 5, 0, 0]
После свёртки:  [0, 0, 5, 0, 0, -5, 0]
После max-пулинга: [0, 5, 5, 0]

Свёртка выдала всплески ровно там, где сигнал скакнул вверх (+5) и вниз (-5) — детектор нашёл границы блока. Внутри ровных участков отклик нулевой. Так фильтр «подсвечивает» нужный признак.

Пулинг: сжимаем и обобщаем

Пулинг уменьшает размер карты признаков, оставляя в каждом окне максимум (max-pooling) или среднее. Это сокращает вычисления и даёт устойчивость к мелким сдвигам: даже если признак чуть сместился, максимум в окне сохранится. В примере четыре значения схлопнулись в более компактное представление.

Из чего собрана типичная CNN

СлойЧто делает
свёрточныйнаходит локальные признаки фильтрами
активация (ReLU)добавляет нелинейность
пулингуменьшает размер, обобщает
полносвязный (в конце)по найденным признакам выдаёт ответ

Слои чередуются: ранние свёртки ловят края, последующие — текстуры и части объектов, а финальные полносвязные слои собирают из них решение. Так устроены классические сети вроде LeNet, AlexNet, ResNet — фундамент компьютерного зрения.

Каналы и фильтры

В реальной CNN на каждом свёрточном слое не один фильтр, а десятки и сотни — и каждый ищет свой признак (один — горизонтальные края, другой — пятна определённого цвета, третий — диагонали). Их отклики складываются в стопку карт признаков (по карте на фильтр), которая становится входом следующего слоя. Так глубина сети наращивает богатство признаков: из простых краёв собираются текстуры, из текстур — части объектов, из частей — объекты целиком. Цветная картинка и на входе имеет три канала (R, G, B), поэтому фильтр первого слоя тоже трёхмерный — он смотрит сразу на все каналы в своём окне.

Важно, что обучаются именно веса фильтров — теми же backprop и градиентным спуском, что мы прошли. Никто не задаёт ядро [-1, 1] вручную: сеть сама выясняет, какие фильтры полезны для задачи. Наш ручной пример с детектором перепада — лишь иллюстрация того, что фильтр в принципе умеет находить; в обученной сети таких выученных детекторов тысячи.

Итог

  • Свёртка — скользящее ядро, ищущее локальный признак во всех позициях.
  • Общие веса дают мало параметров и инвариантность к сдвигу.
  • Пулинг сжимает карту признаков и добавляет устойчивость к мелким сдвигам.
Проверьте себя
1. В чём главное преимущество свёртки перед полносвязным слоем для картинок?
AОна быстрее печатает
BОбщее маленькое ядро даёт мало параметров и работает в любой позиции
CОна не требует активации
DОна увеличивает изображение
2. Что делает слой пулинга?
AДобавляет нейроны
BУменьшает размер карты признаков и обобщает (например, max в окне)
CСчитает функцию потерь
DИнициализирует веса
3. Почему в примере свёртка дала всплески только на границах блока?
AИз-за ошибки округления
BЯдро [-1,1] реагирует на перепад значений, а внутри ровных участков перепада нет
CТак работает пулинг
DСигнал был случайным
Поддержать проект