Траектория «Нейросети» · конспект 4 из 12

Свёрточные сети: свёртка, пулинг, метрики качества

О чём эта тема
Сеть из конспекта 3 (Flatten + Dense) обучаема, но не использует то, что соседние пиксели изображения связаны между собой. Вводится операция свёртки — способ обработки изображения, явно учитывающий эту связь, — и слои, из которых строится свёрточная сеть (CNN): свёртка, ReLU, пулинг, полносвязный слой. Отдельно вводятся метрики качества классификации.
Аннотация
Конспект начинается с объяснения, почему связка Flatten + Dense неэффективна для изображений. Затем вводится операция свёртки с её параметрами — ядром, шагом (stride) и паддингом — и рассматриваются слои ReLU и пулинга в вариантах max, average и sum. Из этих элементов собирается типовая архитектура свёрточной сети: свёртка → ReLU → пулинг → … → Flatten → Dense. Отдельный раздел посвящён метрикам качества классификации — матрице ошибок, accuracy, precision и recall. Завершается конспект реализацией свёрточной сети на Keras для набора данных CIFAR-10.
Пререквизиты
Конспект 3: Dense, Sequential, compile/fit, softmax, категориальная перекрёстная энтропия.
Мотивация
Слой Flatten из конспекта 3 разворачивает изображение \(32\times32\times3\) в вектор длины 3072, теряя при этом информацию о том, какие пиксели были соседями по вертикали и горизонтали, — для полносвязного слоя это просто список из 3072 независимых чисел. Кроме того, один только первый слой Dense(512) на этом векторе занимает 1,5 миллиона параметров (конспект 3, формула (3.1)). Операция свёртки решает обе проблемы: она применяется к соседним пикселям явно и использует один и тот же небольшой набор весов (ядро) по всему изображению.

1. Операция свёртки

Изображение для сети — это матрица чисел (значений яркости), а не рисунок. Ниже — иллюстрация из презентации курса: слева фотография, справа те же данные в виде чисел, которые фактически получает сеть.

Слева фотография трёх собак («What We See»), справа та же область в виде таблицы чисел яркости пикселей («What Computers See»)
Изображение как матрица чисел

Операция свёртки — это не умножение матриц (в смысле произведения матриц из линейной алгебры, как в полносвязном слое конспекта 3), а скользящее окно: небольшая матрица весов (ядро, англ. kernel) поэлементно умножается на область изображения того же размера, произведения суммируются — это даёт одно число выхода, — после чего окно сдвигается. Классический пример из обработки изображений — оператор Собеля, выделяющий вертикальные границы:

Фотография лестницы; горизонтальное ядро Собеля +1 0 -1 / +2 0 -2 / +1 0 -1; результат — карта вертикальных границ
Оператор Собеля: одно и то же ядро применяется по всему изображению

Формально для входа \(X\), ядра \(K\) размера \(k\times k\) и позиции выхода \((i,j)\):

\[ (X * K)_{ij} = \sum_{a=0}^{k-1}\sum_{b=0}^{k-1} X_{i+a,\,j+b}\cdot K_{a,b} \tag{4.1}\]

Ядро в CNN, в отличие от оператора Собеля, не задаётся вручную — его веса (значения \(K_{a,b}\)) подбираются обучением, тем же градиентным спуском (конспект 2, формула (2.5)), что и веса полносвязного слоя.

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

1.1. Что распознаёт ядро: признак

Признак (англ. feature) — это некоторый узнаваемый паттерн во входных данных (например, изгиб контура), на который настроено ядро: чем больше область под окном похожа на этот паттерн, тем больше по модулю значение свёртки (4.1) в этой точке. Ниже — пример из презентации курса: контур мыши и ядро-детектор изгиба (кривой).

Контурный рисунок мыши; жёлтый прямоугольник — положение окна свёртки рядом с ухом
Окно свёртки (жёлтый прямоугольник) наведено на область уха

В этой позиции пиксели под окном образуют изгиб, близкий по форме к тому, на который настроено ядро-детектор кривой, — свёртка в этой точке даёт большое по модулю значение (в примере из презентации — 6600, при том что там же поясняется: «a large number», то есть значение явно выделяется на фоне остальных):

Числовое представление окрестности уха и ядра-детектора кривой; результат умножения и суммирования равен 6600
Пиксели под окном похожи на паттерн ядра → большой отклик

А в другой позиции (нос, без выраженного изгиба под тем же углом) отклик того же ядра равен нулю — паттерн, на который настроено ядро, здесь отсутствует:

Окно свёртки наведено на область носа мыши; результат умножения и суммирования равен 0
Пиксели под окном не похожи на паттерн ядра → нулевой отклик

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

1.2. Шаг и паддинг

Два параметра управляют тем, как окно проходит по изображению. Шаг (stride) \(S\) — на сколько пикселей сдвигается окно на каждом шаге (\(S=1\) — окно сдвигается на 1 пиксель, \(S=2\) — через один). Паддинг (padding) — кольцо нулей толщиной \(P\), добавляемое по краям входа перед свёрткой, чтобы окно могло встать и на краевые пиксели. Размер выхода для входа \(N\times N\) и ядра \(k\times k\):

\[ N_{\text{вых}} = \left\lfloor \frac{N + 2P - k}{S} \right\rfloor + 1 \tag{4.2}\]

Без паддинга (\(P=0\), режим valid) выход меньше входа. При \(P=\lfloor (k-1)/2\rfloor\) и \(S=1\) (режим same) выход получается того же размера, что и вход.

Тренажёр: свёртка и пулинг
вход (7×7, иллюстративно)
выход

Входная матрица подобрана иллюстративно (не измерена): левая половина — значения около 2, правая — около 8, что имитирует вертикальную границу. Нажимайте «Шаг →», чтобы смотреть, как окно последовательно проходит по входу и заполняется выход, либо «К результату», чтобы сразу увидеть готовую карту. Переключите ядро на «Собель горизонтальный» и сравните выход с «тождественным» — граница проявится как большие по модулю значения ровно на стыке половин.

2. Слои ReLU и пулинга

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

Слой пулинга уменьшает пространственный размер карты признаков, заменяя каждое непересекающееся окно \(p\times p\) одним числом. Три распространённых варианта — максимум, среднее и сумма значений в окне:

вход 4×4
12
20
30
0
8
12
2
0
34
70
37
4
112
100
25
12
max-pool 2×2
20
30
112
37
Max-pooling с окном 2×2: левое нижнее окно (34,70,112,100) → максимум 112

Max-pooling — самый употребительный вариант: он сохраняет самый сильный отклик признака в окне и делает результат менее чувствительным к небольшому сдвигу объекта на изображении. Идея та же и для настоящей фотографии, а не только для числовой таблицы: пулинг уменьшает пространственное разрешение карты признаков, сохраняя при этом узнаваемое содержимое. Ниже — иллюстрация из презентации курса: исходная фотография и результат уменьшения после max-, average- и sum-пулинга.

Исходная фотография бабочки
исходное изображение
Результат max-pooling на фотографии бабочки — уменьшенное изображение
max pooling
Результат average-pooling на фотографии бабочки — уменьшенное изображение
average pooling
Результат sum-pooling на фотографии бабочки — уменьшенное изображение
sum pooling
Типичная ошибка Считают, что у слоя пулинга есть обучаемые веса, как у Dense или свёртки. Пулинг — это фиксированная операция (взять максимум/среднее/сумму), у неё нет параметров, которые находились бы градиентным спуском.

2.1. Полносвязный слой в конце сети

После нескольких пар «свёртка + пулинг» карта признаков становится маленькой по пространственным размерам, но глубокой по числу каналов. Её разворачивают в вектор (тем же Flatten, что и в конспекте 3) и подают на один или несколько слоёв Dense — тех же полносвязных слоёв, что уже были описаны:

полносвязный слой полносвязный слой выход
Полносвязный (Dense) слой в конце сети принимает решение по извлечённым признакам — каждый нейрон соединён со всеми выходами предыдущего слоя (число нейронов на схеме уменьшено для наглядности)

2.2. Сборка архитектуры целиком

Типичная CNN — это несколько повторений блока «свёртка → ReLU → пулинг», извлекающих признаки всё более высокого уровня, за которыми следует один или два слоя Dense, принимающих решение о классе:

Входное изображение проходит через свёртку, ReLU и max-pooling по двум параллельным каналам, карты признаков уменьшаются в размере и передаются дальше
Блок «свёртка → ReLU → пулинг» повторяется, карты признаков уменьшаются в размере от слоя к слою

3. Метрики качества классификации

Для каждого примера сеть либо угадала класс, либо нет. Зафиксируем один класс как «положительный» (остальные — «отрицательный») и назовём \(\hat y\) ответ сети, \(y\) — истинную метку. Возможны четыре исхода:

Таблица с числом примеров в каждой из четырёх категорий называется матрицей ошибок (confusion matrix): строки — истинный класс, столбцы — ответ сети.

предсказан положительныйпредсказан отрицательный
истинно положительныйTPFN
истинно отрицательныйFPTN

В терминах проверки статистических гипотез (где отрицательный класс соответствует нулевой гипотезе) ячейки FP и FN — это то же самое, что ошибка первого рода и ошибка второго рода соответственно:

Через элементы матрицы ошибок выражаются метрики качества:

\[ \mathrm{accuracy} = \frac{TP+TN}{TP+TN+FP+FN} \tag{4.3}\]
\[ \mathrm{precision} = \frac{TP}{TP+FP}, \qquad \mathrm{recall} = \frac{TP}{TP+FN} \tag{4.4}\]

Accuracy — доля верных ответов среди всех примеров. Precision — доля верных среди тех, что сеть отнесла к положительному классу (насколько можно доверять положительному ответу сети). Recall — доля найденных сетью среди всех действительно положительных примеров (насколько полно сеть находит нужный класс).

Типичная ошибка Ограничиваются одной accuracy на несбалансированных классах. Если положительных примеров всего 1% выборки, модель, всегда отвечающая «отрицательный класс», получит accuracy 99%, но recall у неё будет нулевым — она не найдёт ни одного положительного примера. Precision и recall показывают эту проблему, accuracy — нет.

4. Реализация: CNN на Keras для CIFAR-10

Каждому слою, разобранному выше, соответствует свой класс в tensorflow.keras.layers:

ПонятиеКласс в Keras
свёртка (4.1)Conv2D(filters, kernel_size, strides, padding, activation)
max-пулингMaxPool2D(pool_size)
average-пулингAveragePooling2D(pool_size)
Flatten (конспект 3)Flatten()
полносвязный слой (конспект 3)Dense(units, activation)

Продолжение кода из конспекта 3 — та же загрузка и подготовка CIFAR-10, но вместо Flatten + Dense в начале сети теперь стоят свёрточные слои:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPool2D, Flatten, Dense, Dropout

model = Sequential()
model.add(Conv2D(filters=32, kernel_size=(3, 3),
                 input_shape=(32, 32, 3), padding='same', activation='relu'))
model.add(Dropout(0.2))
model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same'))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(10, activation='softmax'))

Conv2D(filters=32, kernel_size=(3,3), padding='same', activation='relu') — это слой из 32 разных ядер размера \(3\times3\) (каждое — свой набор весов, обучаемый отдельно), с паддингом same (формула (4.2) с \(S=1\)) и ReLU сразу после свёртки. MaxPool2D(pool_size=(2,2)) — max-пулинг с окном \(2\times2\) (по умолчанию его шаг тоже равен 2, окна не пересекаются). Dropout(0.2) появится и будет объяснён отдельно, в конспекте о переобучении. Компиляция и обучение (compile, fit) — в точности как в конспекте 3, меняется только архитектура model.

Типичная ошибка Указывают в Conv2D число нейронов, как в Dense. Параметр filters — это число независимых ядер свёртки в слое (глубина выходной карты признаков), а не число нейронов в обычном смысле; пространственный размер выхода определяется формулой (4.2), а не значением filters.

Контрольные вопросы