Класс AdaptiveMaxPool2d
Класс AdaptiveMaxPool2d из модуля nn применяет адаптивный макспулинг к входным данным. В отличие от обычного пулинга, этот слой не требует явного указания размера ядра и шага - достаточно задать желаемый размер выходного тензора. Слой автоматически подбирает параметры пулинга, чтобы получить тензор указанной пространственной размерности. Это особенно удобно при работе с изображениями разных размеров, так как позволяет привести их к единой размерности перед подачей в полносвязные слои.
На вход слой принимает тензор формы (N, C, H, W), где N - размер батча, C - число каналов, H и W - высота и ширина изображения. На выходе получается тензор формы (N, C, H_out, W_out), где H_out и W_out - заданные выходные размеры. Для каждого канала слой разбивает входное изображение на адаптивные области и выбирает максимальное значение из каждой области.
Синтаксис
torch.nn.AdaptiveMaxPool2d(output_size, return_indices=False)
Параметры
Первый параметр output_size задаёт желаемый выходной размер. Может быть передан как число - в этом случае выходная высота и ширина будут одинаковыми, либо как кортеж (H_out, W_out), где H_out и W_out - желаемые высота и ширина. Второй параметр return_indices определяет, нужно ли возвращать индексы максимальных элементов для последующего обратного распространения ошибки.
Важно отметить, что слой AdaptiveMaxPool2d работает только с двумерными пространственными данными, такими как изображения. Для одномерных данных используется AdaptiveMaxPool1d, для трёхмерных - AdaptiveMaxPool3d.
Пример
Давайте создадим адаптивный макспулинг, который преобразует входное изображение размером 4x4 в выходное размером 2x2:
import torch
import torch.nn as nn
# Создаём слой адаптивного макспулинга
pool = nn.AdaptiveMaxPool2d(output_size=(2, 2))
# Входной тензор (батч=1, каналов=1, 4x4)
t = torch.tensor([
[[1.0, 2.0, 3.0, 4.0],
[5.0, 6.0, 7.0, 8.0],
[9.0, 10.0, 11.0, 12.0],
[13.0, 14.0, 15.0, 16.0]]
])
res = pool(t)
print(res)
Результат выполнения кода:
tensor([[[6., 8.],
[14., 16.]]])
Слой разбил изображение 4x4 на четыре области размером 2x2 и в каждой выбрал максимальное значение.
Пример
Если передать в output_size одно число, выходное изображение будет квадратным. Давайте преобразуем изображение 5x5 в размер 3x3:
import torch
import torch.nn as nn
# Создаём слой с выходным размером 3x3
pool = nn.AdaptiveMaxPool2d(output_size=3)
# Входной тензор (батч=1, каналов=1, 5x5)
t = torch.randn(1, 1, 5, 5)
t = torch.arange(1, 26).reshape(1, 1, 5, 5).float()
res = pool(t)
print(res)
Результат выполнения кода:
tensor([[[[ 7., 9., 10.],
[17., 19., 20.],
[22., 24., 25.]]]])
Пример
Слой AdaptiveMaxPool2d часто используется в архитектурах нейросетей для приведения карт признаков к фиксированному размеру. Рассмотрим пример с реальным батчем изображений:
import torch
import torch.nn as nn
torch.manual_seed(0)
# Создаём слой
pool = nn.AdaptiveMaxPool2d(output_size=(4, 4))
# Батч из 2 изображений по 3 канала, размер 7x7
t = torch.randn(2, 3, 7, 7)
res = pool(t)
print("Входной размер:", t.shape)
print("Выходной размер:", res.shape)
Результат выполнения кода:
"Входной размер: torch.Size([2, 3, 7, 7])"
"Выходной размер: torch.Size([2, 3, 4, 4])"
Как видите, слой успешно преобразовал изображения 7x7 в 4x4, сохранив количество каналов и размер батча.
Пример
Если требуется получить индексы максимальных элементов, передайте флаг return_indices=True. Это может пригодиться при реализации слоя обратного пулинга:
import torch
import torch.nn as nn
torch.manual_seed(0)
# Создаём слой с возвратом индексов
pool = nn.AdaptiveMaxPool2d(output_size=2, return_indices=True)
t = torch.arange(1, 17).reshape(1, 1, 4, 4).float()
res, indices = pool(t)
print("Результат пулинга:")
print(res)
print("Индексы максимальных элементов:")
print(indices)
Результат выполнения кода:
"Результат пулинга:"
tensor([[[[ 6., 8.],
[14., 16.]]]])
"Индексы максимальных элементов:"
tensor([[[[ 5, 7],
[13, 15]]]])
Индексы указывают на позиции максимальных элементов в развёрнутом виде (нумерация с нуля). Например, индекс 5 соответствует элементу со значением 6 в исходном тензоре.
Смотрите также
-
класс
AdaptiveAvgPool2d,
который выполняет адаптивный средний пулинг -
класс
MaxPool2d,
который выполняет обычный макспулинг с фиксированным размером ядра -
класс
AvgPool2d,
который выполняет обычный средний пулинг -
класс
AdaptiveMaxPool1d,
который выполняет адаптивный макспулинг для одномерных данных