Функция PyTorch torch.nn.AdaptiveAvgPool2d
Справочное руководство PyTorch torch.nn
torch.nn.AdaptiveAvgPool2dЭто модуль адаптивного среднего пулинга в PyTorch.
Он может выполнять пулинг входных карт признаков любого размера до заданного целевого размера без ручного вычисления kernel_size и stride.
Определение функции
torch.nn.AdaptiveAvgPool2d(output_size)
Описание параметров:
output_size(int или tuple): Размер выхода. Может быть (H, W) или одним int (квадрат).
Примеры использования
Пример 1: Базовое использование
Выполните пулинг карты признаков до фиксированного размера:
Пример
import torch
import torch.nn as nn
# пулинг до 1x1
adaptive_pool = nn.AdaptiveAvgPool2d(1)
# входные данные разных размеров
x1 = torch.randn(1, 64, 32, 32)
x2 = torch.randn(1, 64, 16, 16)
x3 = torch.randn(1, 64, 8, 8)
out1 = adaptive_pool(x1)
out2 = adaptive_pool(x2)
out3 = adaptive_pool(x3)
print("32x32 ->", out1.shape)
print("16x16 ->", out2.shape)
print("8x8 ->", out3.shape)
print("nВсе выходы приводятся к 1x1")
import torch.nn as nn
# пулинг до 1x1
adaptive_pool = nn.AdaptiveAvgPool2d(1)
# входные данные разных размеров
x1 = torch.randn(1, 64, 32, 32)
x2 = torch.randn(1, 64, 16, 16)
x3 = torch.randn(1, 64, 8, 8)
out1 = adaptive_pool(x1)
out2 = adaptive_pool(x2)
out3 = adaptive_pool(x3)
print("32x32 ->", out1.shape)
print("16x16 ->", out2.shape)
print("8x8 ->", out3.shape)
print("nВсе выходы приводятся к 1x1")
Пример 2: произвольный размер выхода
Пулинг до неквадратного размера:
Пример
import torch
import torch.nn as nn
# пулинг до 4x4
pool = nn.AdaptiveAvgPool2d((4, 4))
x = torch.randn(2, 128, 32, 32)
out = pool(x)
print("Форма входа:", x.shape)
print("Форма выхода:", out.shape) # (2, 128, 4, 4)
# пулинг до 1x7 (можно использовать для последовательностей)
pool_seq = nn.AdaptiveAvgPool2d((1, 7))
x_seq = torch.randn(2, 64, 10, 20)
out_seq = pool_seq(x_seq)
print("nПулинг последовательности:", x_seq.shape, "->", out_seq.shape)
import torch.nn as nn
# пулинг до 4x4
pool = nn.AdaptiveAvgPool2d((4, 4))
x = torch.randn(2, 128, 32, 32)
out = pool(x)
print("Форма входа:", x.shape)
print("Форма выхода:", out.shape) # (2, 128, 4, 4)
# пулинг до 1x7 (можно использовать для последовательностей)
pool_seq = nn.AdaptiveAvgPool2d((1, 7))
x_seq = torch.randn(2, 64, 10, 20)
out_seq = pool_seq(x_seq)
print("nПулинг последовательности:", x_seq.shape, "->", out_seq.shape)
Пример 3: Использование в CNN
Типичное глобальное усредняющее объединение:
Пример
import torch
import torch.nn as nn
class CNNWithGAP(nn.Module):
def __init__(self, num_classes=10):
super(CNNWithGAP, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(64, 128, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(128, 256, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
)
# глобальное усредняющее объединение
self.avgpool = nn.AdaptiveAvgPool2d(1)
self.classifier = nn.Linear(256, num_classes)
def forward(self, x):
x = self.features(x)
x = self.avgpool(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
model = CNNWithGAP()
x = torch.randn(4, 3, 32, 32)
output = model(x)
print("Форма входа:", x.shape)
print("Форма выхода:", output.shape)
print("nКарта признаков глобально усредняется в один вектор")
import torch.nn as nn
class CNNWithGAP(nn.Module):
def __init__(self, num_classes=10):
super(CNNWithGAP, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(64, 128, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(128, 256, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
)
# глобальное усредняющее объединение
self.avgpool = nn.AdaptiveAvgPool2d(1)
self.classifier = nn.Linear(256, num_classes)
def forward(self, x):
x = self.features(x)
x = self.avgpool(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
model = CNNWithGAP()
x = torch.randn(4, 3, 32, 32)
output = model(x)
print("Форма входа:", x.shape)
print("Форма выхода:", output.shape)
print("nКарта признаков глобально усредняется в один вектор")
Пример 4: Сравнение с обычным пулингом
Пример
import torch
import torch.nn as nn
# адаптивный пулинг против обычного пулинга
adaptive = nn.AdaptiveAvgPool2d(2)
regular = nn.AvgPool2d(kernel_size=16, stride=16)
x = torch.randn(1, 64, 32, 32)
out_adaptive = adaptive(x)
out_regular = regular(x)
print("Вход:", x.shape)
print("Адаптивный пулинг (выход 2x2):", out_adaptive.shape)
print("Обычный средний пулинг (16x16):", out_regular.shape)
import torch.nn as nn
# адаптивный пулинг против обычного пулинга
adaptive = nn.AdaptiveAvgPool2d(2)
regular = nn.AvgPool2d(kernel_size=16, stride=16)
x = torch.randn(1, 64, 32, 32)
out_adaptive = adaptive(x)
out_regular = regular(x)
print("Вход:", x.shape)
print("Адаптивный пулинг (выход 2x2):", out_adaptive.shape)
print("Обычный средний пулинг (16x16):", out_regular.shape)
Адаптивный пулинг против обычного пулинга
| Type | Преимущества | Применимые сценарии |
|---|---|---|
| AdaptiveAvgPool | Произвольный размер входных данных | Входные данные разных масштабов |
| AvgPool | Более быстрое вычисление | Фиксированный размер входа |
Часто задаваемые вопросы
Вопрос 1: Когда использовать адаптивный пулинг?
Когда размер входа не фиксирован или когда его нужно привести к фиксированному размеру.
Вопрос 2: Что такое глобальный средний пулинг?
AdaptiveAvgPool2d(1), который усредняет каждую карту признаков до одного значения.
Сценарии использования
- Сети классификации: Глобальный средний пулинг заменяет полносвязные слои
- Входные данные разных масштабов: Адаптация к изображениям разных размеров
- Агрегация признаков: Извлечение ключевой информации
Совет: Глобальный средний пулинг может значительно уменьшить количество параметров.
Другие расширения