Función torch.nn.Conv2d de PyTorch
Referencia de PyTorch torch.nn
torch.nn.Conv2dEs el módulo de PyTorch para convolución 2D, y es un componente central de las redes neuronales convolucionales (CNN).
Extrae características espaciales aplicando núcleos de convolución aprendibles al tensor de entrada, y se usa ampliamente en tareas de procesamiento de imágenes y visión por computadora.
Definición de la función
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
Descripción de parámetros:
in_channels(int): Número de canales de entrada. Por ejemplo, una imagen RGB es 3.out_channels(int): Número de canales de salida, es decir, el número de núcleos de convolución.kernel_size(int o tuple): Tamaño del núcleo de convolución. Puede ser un entero (cuadrado) o una tupla (alto x ancho).stride(int o tuple): Paso (stride) del núcleo de convolución. El valor predeterminado es 1.padding(int o tuple): Tamaño de relleno (padding) en los bordes de la entrada. El valor predeterminado es 0.dilation(int o tuple): Espaciado entre los elementos del núcleo de convolución. El valor predeterminado es 1 (convolución estándar).groups(int): Número de grupos en la convolución en grupos. El valor predeterminado es 1 (convolución estándar).bias(bool): Si se añade un término de sesgo. El valor predeterminado esTrue。padding_mode(str): Modo de relleno. Opciones'zeros'、'reflect'、'replicate'、'circular'。
Atributos:
weight(Tensor): Pesos aprendibles con forma (out_channels, in_channels/groups, kernel_sizebias(Tensor): Sesgo aprendible con forma (out_channels,).
Ejemplos de uso
Ejemplo 1: Uso básico
Crear una capa de convolución 2D simple:
Ejemplo
import torch.nn as nn
# Crear capa convolucional: 3 canales de entrada, 32 canales de salida, kernel 3x3
conv = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3)
# Imprimir las formas de los pesos y sesgos
print(Forma de pesos:, conv.weight.shape) # torch.Size([32, 3, 3, 3])
print(Forma del sesgo:, conv.bias.shape) # torch.Size([32])
# Crear tensor de entrada: batch=1, canales=3, alto=32, ancho=32
input_tensor = torch.randn(1, 3, 32, 32)
# Propagación hacia adelante
output = conv(input_tensor)
print(Forma de entrada:, input_tensor.shape) # torch.Size([1, 3, 32, 32])
print(Forma de salida:, output.shape) # torch.Size([1, 32, 30, 30])
El resultado es:
权重形状: torch.Size([32, 3, 3, 3]) 偏置形状: torch.Size([32]) 输入形状: torch.Size([1, 3, 32, 32]) 输出形状: torch.Size([1, 32, 30, 30])
Por defecto, padding=0, por lo que el tamaño de salida se reduce. Si se necesita mantener el tamaño, se puede añadir padding.
Ejemplo 2: Uso de padding para mantener el tamaño
Añadiendo padding se puede mantener el tamaño consistente entre entrada y salida:
Ejemplo
import torch.nn as nn
# Crear una capa convolucional con padding: padding=1 mantiene las dimensiones
conv_pad = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=1)
# Entrada
input_tensor = torch.randn(1, 3, 32, 32)
# Propagación hacia adelante
output = conv_pad(input_tensor)
print(Forma de entrada:, input_tensor.shape)
print(Forma de salida:, output.shape) # protegermantener 32x32
El resultado es:
输入形状: torch.Size([1, 3, 32, 32]) 输出形状: torch.Size([1, 32, 32, 32])
Ejemplo 3: Diferentes stride y dilation
Ajustar stride y dilation puede cambiar el tamaño de salida y el campo receptivo:
Ejemplo
import torch.nn as nn
# Convolución de paso: stride=2 reduce el tamaño
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 -> forma de salida:", output_stride.shape)
# Convolución dilatada: dilation=2 aumenta el campo receptivo
conv_dilation = nn.Conv2d(3, 32, kernel_size=3, dilation=2)
output_dilation = conv_dilation(input_tensor)
print("Dilation=2 -> forma de salida:", output_dilation.shape)
El resultado es:
Stride=2 -> 输出形状: torch.Size([1, 32, 16, 16]) Dilation=2 -> 输出形状: torch.Size([1, 32, 28, 28])
Ejemplo 4: Convolución en grupos
El parámetro groups permite implementar convolución en grupos, que se usa a menudo en redes ligeras:
Ejemplo
import torch.nn as nn
# Convolución por grupos: groups=2 divide la entrada en 2 grupos
conv_group = nn.Conv2d(in_channels=4, out_channels=8, kernel_size=3, groups=2)
# Entrada de 4 canales
input_tensor = torch.randn(1, 4, 16, 16)
# Propagación hacia adelante
output = conv_group(input_tensor)
print(Forma de entrada:, input_tensor.shape)
print(Forma de salida:, output.shape)
print(Forma de pesos:, conv_group.weight.shape) # Después de agrupar, la forma de los pesos es diferente
El resultado es:
输入形状: torch.Size([1, 4, 16, 16]) 输出形状: torch.Size([1, 8, 14, 14]) 权重形状: torch.Size([8, 2, 3, 3])
Ejemplo 5: Uso en redes neuronales
Construir una red simple de reconocimiento de dígitos escritos a mano:
Ejemplo
import torch.nn as nn
class SimpleCNN(nn.Module):
def __init__(self, num_classes=10):
super(SimpleCNN, self).__init__()
# Primer bloque de convolución
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
self.bn1 = nn.BatchNorm2d(32)
self.relu1 = nn.ReLU()
# Segundo bloque de convolución
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.bn2 = nn.BatchNorm2d(64)
self.relu2 = nn.ReLU()
# Capa de pooling
self.pool = nn.MaxPool2d(2, 2)
# Capa totalmente conectada
self.fc = nn.Linear(64 * 7 * 7, num_classes)
def forward(self, x):
# Primer bloque de convolución
x = self.conv1(x)
x = self.bn1(x)
x = self.relu1(x)
x = self.pool(x)
# Segundo bloque de convolución
x = self.conv2(x)
x = self.bn2(x)
x = self.relu2(x)
x = self.pool(x)
# Aplanar y clasificar
x = x.view(x.size(0), -1)
x = self.fc(x)
return x
# Crear modelo
model = SimpleCNN(num_classes=10)
# Entrada de prueba: batch=4, imagen en escala de grises 28x28
input_image = torch.randn(4, 1, 28, 28)
output = model(input_image)
print(Forma de entrada:, input_image.shape)
print(Forma de salida:, output.shape) # torch.Size([4, 10])
Cálculo del tamaño de salida
Fórmula de cálculo del tamaño de salida de la capa de convolución:
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
Preguntas frecuentes
Q1: ¿Cómo elegir el tamaño del núcleo de convolución?
Tamaños de núcleo de convolución comunes:
1x1: Para cambiar el número de canales y añadir no linealidad.3x3: Es el más común, equilibra la cantidad de parámetros y el campo receptivo.5x5、7x7: Campo receptivo más grande, pero mayor cantidad de parámetros.
Q2: ¿Cómo elegir padding y stride?
- Para mantener el tamaño del mapa de características, usar
padding = (kernel_size - 1) / 2 - Para submuestreo, usar
stride > 1
Casos de uso
nn.Conv2dEs una de las capas más importantes en visión por computadora, los principales casos de uso incluyen:
- Clasificación de imágenes: Para extraer características de imágenes, como VGG, ResNet, etc.
- Detección de objetos: YOLO, Faster R-CNN, etc.
- Segmentación semántica: U-Net, FCN, etc.
- Transferencia de estilo: Generar imágenes artísticas
Consejo: En las CNN modernas, la convolución 3x3 es la más utilizada; puede cubrir suficiente información espacial manteniendo una cantidad relativamente pequeña de parámetros.
Otras extensiones