Функция PyTorch torch.nn.Conv2d

PyTorch torch.nn 参考手册Справочное руководство 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_size
  • bias(Tensor): обучаемое смещение с формой (out_channels,).

Примеры использования

Пример 1: Базовое использование

Создайте простой слой 2D-свёртки:

Пример

import torch
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
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
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
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
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. Она может охватывать достаточно пространственной информации, сохраняя при этом относительно небольшое количество параметров.


PyTorch torch.nn 参考手册Справочное руководство PyTorch torch.nn

Другие расширения