Функция PyTorch torch.nn.Conv2d
Справочное руководство PyTorch torch.nn
torch.nn.Conv2dЭто модуль в PyTorch для двумерной свёртки, который является ключевым компонентом свёрточных нейронных сетей (CNN).
Он извлекает пространственные признаки, применяя обучаемые ядра свёртки к входному тензору, и широко используется в задачах обработки изображений и компьютерного зрения.
Определение функции
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
Параметры:
in_channels(int): Количество входных каналов. Например, 3 для RGB-изображения.out_channels(int): Количество выходных каналов, т. е. количество ядер свёртки.kernel_size(int или tuple): Размер ядра свёртки. Может быть целым числом (квадратное ядро) или кортежем (высота x ширина).stride(int или tuple): Шаг перемещения ядра свёртки. По умолчанию 1.padding(int или tuple): Размер заполнения по краям входных данных. По умолчанию 0.dilation(int или tuple): Расстояние между элементами ядра свёртки. По умолчанию 1 (стандартная свёртка).groups(int): Количество групп для групповой свёртки. По умолчанию 1 (стандартная свёртка).bias(bool): указывает, добавлять ли член смещения. По умолчанию —True。padding_mode(str): режим дополнения. Необязательно'zeros'、'reflect'、'replicate'、'circular'。
Атрибуты:
weight(Tensor): обучаемые веса с формой (out_channels, in_channels/groups, kernel_sizebias(Tensor): обучаемое смещение с формой (out_channels,).
Примеры использования
Пример 1: Базовое использование
Создайте простой слой 2D-свёртки:
Пример
import torch.nn as nn
# Создайте слой свёртки: входные 3 канала, выходные 32 канала, ядро 3x3
conv = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3)
# Выведите формы весов и смещения
print("Форма веса:", conv.weight.shape) # torch.Size([32, 3, 3, 3])
print("Форма смещения:", conv.bias.shape) # torch.Size([32])
# Создайте входной тензор: batch=1, channels=3, height=32, width=32
input_tensor = torch.randn(1, 3, 32, 32)
# Прямое распространение
output = conv(input_tensor)
print("Размер входа:", input_tensor.shape) # torch.Size([1, 3, 32, 32])
print("Размер выхода:", output.shape) # torch.Size([1, 32, 30, 30])
Результат вывода:
权重形状: torch.Size([32, 3, 3, 3]) 偏置形状: torch.Size([32]) 输入形状: torch.Size([1, 3, 32, 32]) 输出形状: torch.Size([1, 32, 30, 30])
По умолчанию padding=0, поэтому размер выхода уменьшится. Если нужно сохранить размер, можно добавить padding.
Пример 2: Использование padding для сохранения размеров
Добавив padding, можно сохранить размеры входа и выхода согласованными:
Пример
import torch.nn as nn
# Создание свёрточного слоя с padding: padding=1 сохраняет размер
conv_pad = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=1)
# Ввод
input_tensor = torch.randn(1, 3, 32, 32)
# Прямое распространение
output = conv_pad(input_tensor)
print("Размер входа:", input_tensor.shape)
print("Размер выхода:", output.shape) # Сохраняется 32x32
Результат вывода:
输入形状: torch.Size([1, 3, 32, 32]) 输出形状: torch.Size([1, 32, 32, 32])
Пример 3: Разные stride и dilation
Настройка шага и дилатации может изменять размер выхода и рецептивное поле:
Пример
import torch.nn as nn
# Свёртка с шагом: stride=2 уменьшает размер
conv_stride = nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1)
input_tensor = torch.randn(1, 3, 32, 32)
output_stride = conv_stride(input_tensor)
print("Stride=2 -> Форма выхода:", output_stride.shape)
# Свёртка с дилатацией: dilation=2 увеличивает рецептивное поле
conv_dilation = nn.Conv2d(3, 32, kernel_size=3, dilation=2)
output_dilation = conv_dilation(input_tensor)
print("Dilation=2 -> Форма выхода:", output_dilation.shape)
Результат вывода:
Stride=2 -> 输出形状: torch.Size([1, 32, 16, 16]) Dilation=2 -> 输出形状: torch.Size([1, 32, 28, 28])
Пример 4: Групповая свёртка
Параметр groups позволяет реализовать групповую свёртку, обычно используемую в легковесных сетях:
Пример
import torch.nn as nn
# Групповая свёртка: groups=2 делит вход на 2 группы
conv_group = nn.Conv2d(in_channels=4, out_channels=8, kernel_size=3, groups=2)
# Вход с 4 каналами
input_tensor = torch.randn(1, 4, 16, 16)
# Прямое распространение
output = conv_group(input_tensor)
print("Размер входа:", input_tensor.shape)
print("Форма выхода:", output.shape)
print("Форма весов:", conv_group.weight.shape) # Форма весов отличается после группировки
Результат вывода:
输入形状: torch.Size([1, 4, 16, 16]) 输出形状: torch.Size([1, 8, 14, 14]) 权重形状: torch.Size([8, 2, 3, 3])
Пример 5: Использование в нейронных сетях
Постройте простую сеть распознавания рукописных цифр:
Пример
import torch.nn as nn
class SimpleCNN(nn.Module):
def __init__(self, num_classes=10):
super(SimpleCNN, self).__init__()
# Первый свёрточный блок
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
self.bn1 = nn.BatchNorm2d(32)
self.relu1 = nn.ReLU()
# Второй свёрточный блок
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.bn2 = nn.BatchNorm2d(64)
self.relu2 = nn.ReLU()
# Слой пулинга
self.pool = nn.MaxPool2d(2, 2)
# Полносвязный слой
self.fc = nn.Linear(64 * 7 * 7, num_classes)
def forward(self, x):
# Первый свёрточный блок
x = self.conv1(x)
x = self.bn1(x)
x = self.relu1(x)
x = self.pool(x)
# Второй свёрточный блок
x = self.conv2(x)
x = self.bn2(x)
x = self.relu2(x)
x = self.pool(x)
# Выравнивание и классификация
x = x.view(x.size(0), -1)
x = self.fc(x)
return x
# Создание модели
model = SimpleCNN(num_classes=10)
# Тестовый ввод: batch=4, изображение в оттенках серого 28x28
input_image = torch.randn(4, 1, 28, 28)
output = model(input_image)
print("Размер входных данных:", input_image.shape)
print("Размер выхода:", output.shape) # torch.Size([4, 10])
Расчёт размера выхода
Формула для расчёта размера выхода свёрточного слоя:
H_out = floor((H_in + 2 * padding[0] - dilation[0] * (kernel_size[0] - 1) - 1) / stride[0]) + 1 W_out = floor((W_in + 2 * padding[1] - dilation[1] * (kernel_size[1] - 1) - 1) / stride[1]) + 1
Часто задаваемые вопросы
Вопрос 1: Как выбрать размер ядра?
Типичные размеры ядра:
1x1: Используется для изменения количества каналов, добавления нелинейности3x3: Наиболее часто используется, обеспечивает баланс между числом параметров и рецептивным полем5x5、7x7: Большее рецептивное поле, но большее количество параметров
Вопрос 2: Как выбрать отступы и шаг?
- Чтобы сохранить размер карты признаков, используйте
padding = (kernel_size - 1) / 2 - Для уменьшения размерности используйте
stride > 1
Сценарии использования
nn.Conv2dЭто один из самых важных слоёв в компьютерном зрении. Основные сценарии применения включают:
- Классификация изображений: Извлечение признаков изображения, таких как VGG, ResNet, и т. д.
- Обнаружение объектов: YOLO, Faster R-CNN, и т. д.
- Семантическая сегментация: U-Net, FCN, и т. д.
- Перенос стиля: Генерация художественных изображений
Совет: В современных CNN чаще всего используется свёртка 3x3. Она может охватывать достаточно пространственной информации, сохраняя при этом относительно небольшое количество параметров.
Другие расширения