На этом шаге мы рассмотрим, как использование этого приема меняет работу нейронной сети.
В примере сверточной нейронной сети вы могли заметить, что размер карты признаков уменьшается вдвое после каждого слоя MaxPooling2D. Например, перед первым слоем MaxPooling2D карта признаков имела размер 26 × 26, но операция выбора максимального значения из соседних уменьшила ее до размера 13 × 13. В этом заключается предназначение данной операции: агрессивное уменьшение разрешения карты признаков, во многом подобное свертке с пробелами.
Операция выбора максимального значения из соседних заключается в следующем: из входной карты признаков извлекается окно и из него выбирается максимальное значение для каждого канала. Концептуально это напоминает свертку, но вместо преобразования локальных шаблонов с обучением на линейных преобразованиях (ядро свертки) они преобразуются с использованием жестко заданной тензорной операции выбора максимального значения. Главное отличие от свертки состоит в том, что выбор максимального значения из соседних обычно производится с окном 2 × 2 и шагом 2, чтобы уменьшить разрешение карты признаков в два раза. Собственно свертка, напротив, обычно выполняется с окном 3 × 3 и без шага (шаг равен 1).
С какой целью вообще производится снижение разрешения карты признаков? Почему бы просто не убрать слои MaxPooling2D и не использовать карты признаков большего размера? Рассмотрим этот вариант. Сверточная основа модели в таком случае будет выглядеть так, как показано в следующем примере.
inputs = keras.Input(shape=(28, 28, 1)) x = layers.Conv2D(filters=32, kernel_size=3, activation="relu")(inputs) x = layers.Conv2D(filters=64, kernel_size=3, activation="relu")(x) x = layers.Conv2D(filters=128, kernel_size=3, activation="relu")(x) x = layers.Flatten()(x) outputs = layers.Dense(10, activation="softmax")(x) model_no_max_pool = keras.Model(inputs=inputs, outputs=outputs)
Сводная информация о модели:
print(model_no_max_pool.summary())
Model: "functional"
Layer (type) Output Shape Param #
input_layer (InputLayer) (None, 28, 28, 1) 0
conv2d (Conv2D) (None, 26, 26, 32) 320
conv2d_1 (Conv2D) (None, 24, 24, 64) 18,496
conv2d_2 (Conv2D) (None, 22, 22, 128) 73,856
flatten (Flatten) (None, 61952) 0
dense (Dense) (None, 10) 619,530
Total params: 712,202 (2.72 MB)
Trainable params: 712,202 (2.72 MB)
Non-trainable params: 0 (0.00 B)
Что не так в этой конфигурации? Две вещи:
Проще говоря, уменьшение разрешения используется для уменьшения количества коэффициентов в карте признаков для обработки, а также внедрения иерархий пространственных фильтров путем создания последовательных слоев свертки для просмотра все более крупных окон (с точки зрения долей исходных данных, которые они охватывают).
Обратите внимание, что операция выбора максимального значения не единственный способ уменьшения разрешения. Как вы уже знаете, в предыдущих сверточных слоях можно также использовать шаг свертки. Кроме того, вместо выбора максимального значения можно использовать операцию выбора среднего значения по соседним элементам (average pooling), когда каждый локальный шаблон преобразуется путем взятия среднего значения для каждого канала в шаблоне вместо максимального. Однако операция выбора максимального значения обычно дает лучшие результаты, чем эти альтернативные решения. Причина в том, что признаки, как правило, кодируют пространственное присутствие некоторого шаблона или понятия в разных клетках карты признаков (отсюда и название - карта признаков), соответственно, максимальное присутствие признаков намного информативнее среднего присутствия. Поэтому для снижения разрешения более разумно сначала получить плотные карты признаков (путем обычной свертки без пробелов), а затем рассмотреть максимальные значения признаков в небольших шаблонах, а не разреженные окна из входных данных (путем свертки с пробелами) или усредненные шаблоны, которые могут привести к пропуску информации о присутствии.
На данном этапе у вас должно сложиться достаточно полное представление об основах сверточных нейронных сетей - картах признаков, операциях свертки и выбора максимального значения по соседним элементам, а также о том, как сконструировать небольшую сверточную нейронную сеть для решения такой простой задачи, как классификация цифр из набора MNIST. Теперь перейдем к более полезным и практичным вариантом применения.
Со следующего шага мы займемся обучением сверточной нейронной сети на небольшом наборе данных.