Класс LPPool2d
Класс LPPool2d применяет пулинг на основе LP-нормы к двумерным
входным данным. В отличие от обычного максимального или среднего
пулинга, этот слой вычисляет норму степени p для каждой области,
что позволяет учитывать не только максимальные, но и другие значения.
Это делает пулинг более устойчивым к выбросам и полезным для
обработки карт признаков, где важна не только максимальная активация.
Параметрами слоя являются размер окна kernel_size, степень
нормы norm_type и шаг stride.
Синтаксис
torch.nn.LPPool2d(norm_type, kernel_size, stride=None, ceil_mode=False)
Для применения слоя к тензору используется метод forward.
Параметры
-
norm_type(float) - степень нормы (например, 2 для L2-нормы) -
kernel_size(int или tuple) - размер окна пулинга -
stride(int или tuple, необязательный) - шаг пулинга. По умолчанию равенkernel_size -
ceil_mode(bool, необязательный) - еслиTrue, используется округление вверх для границ. По умолчаниюFalse
Пример с L2-нормой
Создадим слой с L2-нормой (норма Евклида) и применим его к двумерному тензору:
import torch
import torch.nn as nn
pool = nn.LPPool2d(norm_type=2, kernel_size=2, stride=2)
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([
[[ 8.1240, 11.3137]],
[[21.2603, 24.5764]]
])
Каждое значение вычислено как L2-норма элементов в окне 2x2.
Пример с L1-нормой
Применим L1-норму (сумма абсолютных значений) к тому же тензору:
import torch
import torch.nn as nn
pool = nn.LPPool2d(norm_type=1, kernel_size=2, stride=2)
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([
[[14.0000, 22.0000]],
[[46.0000, 54.0000]]
])
Значения равны сумме элементов в каждом окне 2x2.
Пример с шагом, отличным от размера окна
Установим шаг пулинга меньше размера окна, чтобы получить перекрывающиеся области:
import torch
import torch.nn as nn
pool = nn.LPPool2d(norm_type=2, kernel_size=2, stride=1)
t = torch.tensor([
[[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0],
[7.0, 8.0, 9.0]]
])
res = pool(t)
print(res)
Результат выполнения кода:
tensor([
[[ 7.4162, 8.6023],
[12.8062, 13.9284]]
])
Окна перекрываются, так как шаг равен 1.
Пример использования в нейронной сети
Добавим слой LPPool2d в последовательную модель:
import torch
import torch.nn as nn
model = nn.Sequential(
nn.Conv2d(3, 16, kernel_size=3, padding=1),
nn.ReLU(),
nn.LPPool2d(norm_type=2, kernel_size=2, stride=2),
nn.Conv2d(16, 32, kernel_size=3, padding=1),
nn.ReLU(),
nn.LPPool2d(norm_type=2, kernel_size=2, stride=2),
nn.Flatten(),
nn.Linear(32 * 8 * 8, 10)
)
t = torch.randn(4, 3, 32, 32)
res = model(t)
print(res.shape)
Результат выполнения кода:
torch.Size([4, 10])
Модель последовательно применяет свёртки и пулинг на основе L2-нормы.
Смотрите также
-
класс
MaxPool2d,
который выполняет максимальный пулинг -
класс
AvgPool2d,
который выполняет средний пулинг -
класс
AdaptiveAvgPool2d,
который адаптивно усредняет выходной размер -
класс
FractionalMaxPool2d,
который выполняет дробный максимальный пулинг