卷积神经网络的padding是什么?如何计算?

世界杯积分规则 2025-08-10 10:47:50 9876

文章目录

为什么需要padding?

1.Valid Padding(有效填充)

2.Same Padding(相同填充)

2.1.如何计算padding?

1. 计算总 padding

2. 分配 padding:

2.2.举例子

1. 步幅为 1 的 Same Padding

2. 步幅不为 1 的 Same Padding

3.F.pad()和卷积中的padding互相转换

1.torch.nn.functional.pad()函数

2.举例

为什么需要padding?

控制输出尺寸: 卷积操作通常会减少输入图像的尺寸。例如,使用3×3 卷积核时,边缘的像素不会像中间部分的像素一样得到处理(因为卷积核无法完全跨越边缘区域),导致输出图像的尺寸小于输入图像。通过适当的 padding,可以保持输入和输出尺寸相同,或者控制输出的尺寸。

保留边缘信息: 如果没有padding,卷积操作会丢失输入图像的边缘部分的信息。通过为输入图像添加零填充,卷积核可以处理这些边缘区域,从而保留更多的信息。

1.Valid Padding(有效填充)

定义:在卷积操作中没有额外的填充,也就是在卷积时不添加任何零填充。此时,输出图像的尺寸会小于输入图像,具体减少的大小取决于卷积核的尺寸和步幅。

输出尺寸:由于没有 padding,输出尺寸通常会小于输入尺寸,且与卷积核大小和步幅有关。

优点:计算效率较高,减少了不必要的计算。

缺点:会丢失图像的边缘信息。

2.Same Padding(相同填充)

定义:通过添加零填充来确保输出的尺寸与输入尺寸相同(在步幅为 1 时)。为了实现这一点,通常需要在输入的边缘添加一定数量的零。

输出尺寸:输入和输出尺寸相同(对于步幅为1的情况)。当步幅大于1时,输出尺寸会根据步幅的大小调整,但仍尽量保持输入和输出的比例相同。

优点:能够保留输入的边缘信息,适用于需要保持特征图大小不变的任务。

缺点:可能会引入一些零值,这对网络学习可能是无用的。

2.1.如何计算padding?

1. 计算总 padding

P_h = (H - 1) * S + K - H

P_w = (W - 1) * S + K - W

2. 分配 padding:

P_top = P_h // 2

P_bottom = P_h - P_top

P_left = P_w // 2

P_right = P_w - P_left

2.2.举例子

1. 步幅为 1 的 Same Padding

当stride = 1,dilation=1,卷积公式的输出为H_out = H_in+2p-k+1,要保证H_out = H_in,所以2p = k-1,p = (k-1)/2。假设输入尺寸是 5×5,卷积核大小是 3×3,步幅为 1。我们希望卷积操作后的输出尺寸与输入相同。计算padding:

import torch

import torch.nn as nn

# 定义输入数据(5x5)

input_data = torch.randn(1, 1, 5, 5) # Batch size = 1, Channels = 1, Height = 5, Width = 5

# 定义卷积层,kernel_size = 3, padding = 1 (为了使用same padding)

conv_layer = nn.Conv2d(1, 1, kernel_size=3, stride=1, padding=1)

# 输出卷积后的数据

output_data = conv_layer(input_data)

print(f'输入形状: {

input_data.shape}')

print(f'输出形状: {

output_data.shape}')

输入形状: torch.Size([1, 1, 5, 5])

输出形状: torch.Size([1, 1, 5, 5])

2. 步幅不为 1 的 Same Padding

根据公式推导得,P = (S(H-1)-H+K)/2,当S=2,上述例子为,P = floor[(8-4+3)/2]=3

import torch

import torch.nn as nn

# 定义输入数据(5x5)

input_data = torch.randn(1, 1, 5, 5) # Batch size = 1, Channels = 1, Height = 5, Width = 5

# 定义卷积层,kernel_size = 3, padding = 1 (为了使用same padding)

conv_layer = nn.Conv2d(1, 1, kernel_size=3, stride=2, padding=3)

# 输出卷积后的数据

output_data = conv_layer(input_data)

print(f'输入形状: {

input_data.shape}')

print(f'输出形状: {

output_data.shape}')

输入形状: torch.Size([1, 1, 5, 5])

输出形状: torch.Size([1, 1, 5, 5])

3.F.pad()和卷积中的padding互相转换

1.torch.nn.functional.pad()函数

torch.nn.functional.pad(input, pad, mode='constant', value=0)

参数说明

input (Tensor): 输入张量。

pad (tuple or int): 指定每个维度上的填充宽度。可以是一个整数或一个元组。

如果是整数,表示所有维度的两侧都填充相同的值。

如果是元组,元组的长度必须是输入张量维度的两倍。元组的形式为 (pad_left,pad_right, pad_top, pad_bottom, …),表示每个维度上的填充宽度。

mode (str, optional): 填充模式,默认为 ‘constant’。可选值有:

constant: 使用常数值填充,默认值为 0。

reflect: 使用边界元素的反射值填充。

replicate:使用边界元素的复制值填充。

circular: 使用循环方式填充。

value (float, optional): 当 mode 为 constant’时,指定填充的常数值,默认为 0。

2.举例

input = torch.arange(1, 65,dtype=torch.float).view(2, 2, 4, 4)

padded_input = F.pad(input, pad=[2, 2, 1, 1], mode='constant', value=0)

conv_padding = nn.Conv2d(in_channels=2, out_channels

站点统计