Функция nn.MaxPool2d в PyTorch
Справочное руководство PyTorch torch.nn
torch.nn.MaxPool2dЭто модуль в PyTorch для двумерного max-пулинга.
Слой пулинга может уменьшать пространственный размер карт признаков, снижать объём вычислений и обеспечивать определённую степень инвариантности к сдвигу.
Определение функции
torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
Описание параметров:
kernel_size(int или tuple): размер окна пулинга.stride(int или tuple): шаг перемещения окна пулинга. По умолчанию равенkernel_size。padding(int или tuple): размер заполнения по краю входных данных. По умолчанию равен 0.dilation(int или tuple): расстояние между элементами окна. По умолчанию равно 1.return_indices(bool): возвращать ли индексы максимальных значений. Используется для MaxUnpool2d. По умолчанию False.ceil_mode(bool): использовать ли ceil вместо floor для вычисления размера выходных данных. По умолчанию False.
Примеры использования
Пример 1: Базовое использование
Создайте слой максимального пулинга:
Пример
import torch.nn as nn
# Создайте слой максимального пулинга: окно 2x2, шаг 2
max_pool = nn.MaxPool2d(kernel_size=2, stride=2)
# Создать входной тензор
input_tensor = torch.randn(1, 1, 4, 4)
print("Вход:n", input_tensor.squeeze().tolist())
# Прямое распространение
output = max_pool(input_tensor)
print("nВывод:n", output.squeeze().tolist())
print("nФорма входа:", input_tensor.shape)
print("Форма выхода:", output.shape)
Вывод:
输入: [[-0.4128, 0.2341, -0.9876, 0.4567], [ 0.1234, 0.8765, -0.2345, 0.6789], [-0.5678, 0.3456, 0.7890, -0.1234], [ 0.9012, -0.4567, 0.2345, 0.5678]] 输出: [[0.8765, 0.6789], [0.9012, 0.7890]] 输入形状: torch.Size([1, 1, 4, 4]) 输出形状: torch.Size([1, 1, 2, 2])
Видно, что максимальное значение в каждом окне 2x2 сохраняется.
Пример 2: Разные kernel_size и stride
Настройте параметры пулинга:
Пример
import torch.nn as nn
# Пулинг 3x3, stride 1 (без перекрытия)
pool3x3 = nn.MaxPool2d(kernel_size=3, stride=1)
# Неквадратный пулинг
pool_rect = nn.MaxPool2d(kernel_size=(2, 3), stride=(2, 3))
input_tensor = torch.randn(1, 1, 6, 9)
print("Размер входа:", input_tensor.shape)
print("Вывод пулинга 3x3:", pool3x3(input_tensor).shape)
print("Вывод прямоугольного пулинга:", pool_rect(input_tensor).shape)
Пример 3: Использование padding
Дополнение по краям может в некоторой степени сохранять информацию о краях:
Пример
import torch.nn as nn
# Пулинг с padding
pool_padding = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)
input_tensor = torch.randn(1, 1, 4, 4)
output = pool_padding(input_tensor)
print("Размер входа:", input_tensor.shape)
print("Форма выхода (с дополнением):", output.shape)
Пример 4: Возврат индексов
Использование return_indices позволяет восстановить позиции в декодере:
Пример
import torch.nn as nn
# Создать слой пулинга, который возвращает индексы
pool_indices = nn.MaxPool2d(kernel_size=2, stride=2, return_indices=True)
input_tensor = torch.randn(1, 1, 4, 4)
output, indices = pool_indices(input_tensor)
print("Форма выхода:", output.shape)
print("Форма индексов:", indices.shape)
print("Значения индексов:", indices.squeeze().tolist())
Пример 5: Использование в CNN
Положение слоя пулинга в типичной структуре CNN:
Пример
import torch.nn as nn
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
# Свёрточный слой
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.relu = nn.ReLU()
# Слой пулинга: размер уменьшается вдвое каждый раз
self.pool = nn.MaxPool2d(2, 2)
def forward(self, x):
x = self.relu(self.conv1(x)) # 32x32
x = self.pool(x) # 16x16
x = self.relu(self.conv2(x)) # 16x16
x = self.pool(x) # 8x8
return x
model = SimpleCNN()
input_image = torch.randn(1, 3, 32, 32)
output = model(input_image)
print("Размер входных данных:", input_image.shape)
print("Форма выхода:", output.shape)
Максимальный пулинг против среднего пулинга
| Type | Формула | Особенности | Сценарии использования |
|---|---|---|---|
MaxPool2d |
max(region) | Сохраняет значимые признаки и более устойчив к шуму | Классификация изображений, обнаружение объектов (часто используется) |
AvgPool2d |
mean(region) | Сглаживает признаки и сохраняет информацию о фоне | Глобальный средний пулинг, извлечение признаков |
ЧАВО
Вопрос 1: можно ли убрать слой пулинга?
Современные сети, такие как ResNet и DenseNet, обычно используют свёртки с меньшим шагом вместо пулинга, но пулинг всё ещё часто используется для быстрого понижения размерности.
Вопрос 2: Какова связь между stride и kernel_size?
Когда stride = kernel_size, окна пулинга не перекрываются; когда stride < kernel_size, окна пулинга перекрываются.
Сценарии использования
nn.MaxPool2dОсновные сценарии применения включают:
- Сети классификации изображений: Постепенное уменьшение разрешения и извлечение высокоуровневых признаков
- Обнаружение объектов: Сохранение позиций значимых признаков
- Сокращение вычислений: Уменьшение размера карт признаков
- Увеличение рецептивного поля: Позволяет последующим слоям видеть больший диапазон признаков
Другие расширения