基于小土堆学习
卷积指示
在PyTorch中,卷积层是构建卷积神经网络(CNN)的核心组件,它们负责处理具有多个输入平面的输入信号。以下是对您所提及的各种卷积层的详细解释:
一维卷积层(nn.Conv1d)
功能:对由多个输入平面(或通道)组成的输入信号应用一维卷积。
应用场景:常用于处理时间序列数据,如音频信号或文本数据。
二维卷积层(nn.Conv2d)
功能:对由多个输入平面组成的输入信号应用二维卷积。
应用场景:图像处理中最常用的卷积层,用于提取图像特征。
三维卷积层(nn.Conv3d)
功能:对由多个输入平面组成的输入信号应用三维卷积。
应用场景:常用于处理视频数据或三维图像数据,如医学图像。
一维转置卷积层(nn.ConvTranspose1d)
功能:对输入信号应用一维转置卷积操作,通常用于上采样或增大输入数据的尺寸。
应用场景:在需要增大时间序列数据尺寸的场景中使用。
二维转置卷积层(nn.ConvTranspose2d)
功能:对输入图像应用二维转置卷积操作,通常用于上采样或增大输入图像的尺寸。
应用场景:在图像分割、生成对抗网络(GANs)等需要增大图像尺寸的场景中使用。
三维转置卷积层(nn.ConvTranspose3d)
功能:对输入信号应用三维转置卷积操作,通常用于上采样或增大视频数据的尺寸。
应用场景:在处理视频数据时需要增大其尺寸的场景中使用。
延迟初始化卷积层
nn.LazyConv1d、nn.LazyConv2d、nn.LazyConv3d:这些卷积层允许延迟初始化in_channels参数,这在某些情况下可以提供灵活性,例如当输入通道数在模型构建时未知时。
nn.LazyConvTranspose1d、nn.LazyConvTranspose2d、nn.LazyConvTranspose3d:同样,这些转置卷积层也允许延迟初始化in_channels参数。
展开和折叠层(nn.Unfold 和 nn.Fold)
nn.Unfold:从批量的输入张量中提取滑动的局部块,这可以用于实现自定义的卷积操作。
nn.Fold:将滑动的局部块数组组合成一个大的包含张量,这通常与nn.Unfold一起使用,以实现自定义的卷积或转置卷积操作。
总的来说,PyTorch提供了丰富的卷积层类型,以满足不同维度和需求的卷积神经网络构建。这些层可以根据需要进行组合和堆叠,以构建复杂的深度学习模型。
二维卷积层(nn.Conv2d)
功能:对由多个输入平面组成的输入信号应用二维卷积。
应用场景:图像处理中最常用的卷积层,用于提取图像特征。
nn.Conv2d层的工作原理,这是PyTorch中用于对多维输入信号(通常由多个输入平面或通道组成)应用二维卷积的层。以下是对这段描述的详细解读:
输入与输出:
输入尺寸:(N, C_in, H, W),其中N是批量大小,C_in是输入通道数,H是输入平面的高度,W是宽度。
输出尺寸:(N, C_out, H_out, W_out),其中C_out是输出通道数,H_out和W_out是输出平面的高度和宽度。
卷积操作:
输出值out(N_i, C_out_j)是通过将输入input(N_i, k)与权重weight(C_out_j, k)进行二维有效交叉相关(valid 2D cross-correlation)操作,并加上偏置bias(C_out_j)来计算的。
⋆表示二维有效交叉相关操作符。
支持的数据类型:
这个模块支持TensorFloat32数据类型。
在某些ROCm设备上,当使用float16输入时,这个模块在反向传播时会使用不同的精度。
参数:
-
stride:控制交叉相关的步长,可以是单个数字或一个元组。
-
padding:控制应用于输入的填充量。它可以是字符串{‘valid’, ‘same’},或者是一个整数/整数元组,表示在两侧应用的隐式填充量。
-
dilation:控制内核点之间的间距;也称为à trous算法。这个参数较难描述,但可以通过链接查看其可视化效果。
-
groups:控制输入和输出之间的连接。in_channels和out_channels都必须能被groups整除。不同的groups值会导致不同的卷积行为,例如,当groups=1时,所有输入都会卷积到所有输出;当groups=in_channels时,每个输入通道都会与其自己的滤波器集进行卷积。
其他参数: -
kernel_size、stride、padding、dilation这些参数可以是单个整数,此时相同的值将用于高度和宽度维度;也可以是两个整数的元组,此时第一个整数用于高度维度,第二个整数用于宽度维度。
-
总的来说,nn.Conv2d是一个功能强大的层,它允许用户通过调整各种参数来定制二维卷积操作,以满足不同的深度学习模型需求。
torch.nn.functional:车辆运转需要齿轮,通过functional可以了解到齿轮运转的规律。
torch.nn:就像车辆的方向盘,无需了解齿轮的运转规律
对应位相乘然后加在一起;
下一步,再向右边走一步
先横向走,再纵向走,再横向走
stride – the stride of the convolving kernel. Can be a single number or a tuple (sH, sW). Default: 1
sH, sW分别是控制横向步长和纵向步长的,设置为1的话,横向的步和纵向的步是一样的。
下一步:
对上述图片进行代码实现:
import torch
input = torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]])
kernel = torch.tensor([[1,2,1],
[0,1,0],
[2,1,0]])
print(input.shape)
print(kernel.shape)
输出结果为:
C:\Anaconda3\envs\pytorch_test\python.exe H:\Python\Test\nn_conv.py
torch.Size([5, 5])
torch.Size([3, 3])
进程已结束,退出代码0
这个输入张量(input tensor)的形状是 (minibatch, in_channels, iH, iW),其中:
- minibatch 表示小批量大小,即一次处理的样本数量。
- in_channels 表示输入通道数,对于图像数据,如果是灰度图则为1,如果是彩色图(如RGB格式)则为3。
- iH 表示输入的高度。
- iW 表示输入的宽度。
这种形状常用于图像处理领域,特别是在使用卷积神经网络(CNN)时。例如,在处理一批大小为64的RGB图像时,如果每张图像的大小为32x32像素,那么输入张量的形状将是 (64, 3, 32, 32)。
对照代码输出结果和图片,可以看出其尺寸不符合input和weight的格式要求;
需要进行如下处理
import torch
input = torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]])
kernel = torch.tensor([[1,2,1],
[0,1,0],
[2,1,0]])
print(input.shape)
print(kernel.shape)
input = torch.reshape(input,(1,1,5,5))#输入想变化的尺寸大小
#5*5是一个平面,所以第一个数字是1,第二个1是1个通道
kernel = torch.reshape(kernel,(1,1,3,3))#输入想变化的尺寸大小
print(input.shape)
print(kernel.shape)
# torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)
其结果为:
C:\Anaconda3\envs\pytorch_test\python.exe H:\Python\Test\nn_conv.py
torch.Size([5, 5])
torch.Size([3, 3])
torch.Size([1, 1, 5, 5])
torch.Size([1, 1, 3, 3])
进程已结束,退出代码0
调研conv2
import torch
import torch.nn.functional as F
input = torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]])
kernel = torch.tensor([[1,2,1],
[0,1,0],
[2,1,0]])
print(input.shape)
print(kernel.shape)
input = torch.reshape(input,(1,1,5,5))#输入想变化的尺寸大小
#5*5是一个平面,所以第一个数字是1,第二个1是1个通道
kernel = torch.reshape(kernel,(1,1,3,3))#输入想变化的尺寸大小
print(input.shape)
print(kernel.shape)
output = F.conv2d(input,kernel,stride=1)
print(output )
# torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)
结果为
C:\Anaconda3\envs\pytorch_test\python.exe H:\Python\Test\nn_conv.py
torch.Size([5, 5])
torch.Size([3, 3])
torch.Size([1, 1, 5, 5])
torch.Size([1, 1, 3, 3])
tensor([[[[10, 12, 12],
[18, 16, 16],
[13, 9, 3]]]])
进程已结束,退出代码0
将stride=1修改为stride=2,每次移动一个2*2 的路径
import torch
import torch.nn.functional as F
input = torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]])
kernel = torch.tensor([[1,2,1],
[0,1,0],
[2,1,0]])
print(input.shape)
print(kernel.shape)
input = torch.reshape(input,(1,1,5,5))#输入想变化的尺寸大小
#5*5是一个平面,所以第一个数字是1,第二个1是1个通道
kernel = torch.reshape(kernel,(1,1,3,3))#输入想变化的尺寸大小
print(input.shape)
print(kernel.shape)
output = F.conv2d(input,kernel,stride=2)
print(output )
# torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)
输出结果是:
C:\Anaconda3\envs\pytorch_test\python.exe "C:/Program Files/JetBrains/PyCharm Community Edition 2023.1/plugins/python-ce/helpers/pydev/pydevd.py" --multiprocess --qt-support=auto --client 127.0.0.1 --port 13626 --file H:\Python\Test\nn_conv.py
已连接到 pydev 调试器(内部版本号 231.8109.197)torch.Size([5, 5])
torch.Size([3, 3])
torch.Size([1, 1, 5, 5])
torch.Size([1, 1, 3, 3])
tensor([[[[10, 12],
[13, 3]]]])
进程已结束,退出代码0
padding
padding 参数用于指定在输入数据的两侧隐式添加的填充(padding)。这个参数可以有以下几种形式:
- 字符串:‘valid’ 或 ‘same’。
- ‘valid’ 表示不进行任何填充,这是默认值。
- ‘same’ 表示进行填充,使得输出的形状与输入相同。但是,在这种模式下,不支持步长(stride)值大于1的情况。
- 单个数字:表示在输入的高和宽两侧都添加相同数量的填充。
- 元组 (padH, padW):表示在输入的高度两侧添加 padH 数量的填充,在输入的宽度两侧添加 padW 数量的填充。
例如,如果输入是一个形状为 (minibatch, in_channels, iH, iW) 的张量,并且你设置了 padding=‘same’,那么无论卷积操作的其他参数如何,输出的形状都将与输入相同。如果你设置了 padding=1,那么将在输入的高和宽两侧都添加1个单位的填充。如果你设置了 padding=(2, 3),那么将在输入的高度两侧添加2个单位的填充,在宽度两侧添加3个单位的填充。
padding=1,就是在左右上下分别插入一列,默认的值为0
import torch
import torch.nn.functional as F
input = torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]])
kernel = torch.tensor([[1,2,1],
[0,1,0],
[2,1,0]])
print(input.shape)
print(kernel.shape)
input = torch.reshape(input,(1,1,5,5))#输入想变化的尺寸大小
#5*5是一个平面,所以第一个数字是1,第二个1是1个通道
kernel = torch.reshape(kernel,(1,1,3,3))#输入想变化的尺寸大小
print(input.shape)
print(kernel.shape)
output1 = F.conv2d(input,kernel,stride=1)
print(output1 )
output2 = F.conv2d(input,kernel,stride=2)
print(output2 )
output3 = F.conv2d(input,kernel,stride=1,padding=1)
print(output3 )
# torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)
其结果为:
C:\Anaconda3\envs\pytorch_test\python.exe H:\Python\Test\nn_conv.py
torch.Size([5, 5])
torch.Size([3, 3])
torch.Size([1, 1, 5, 5])
torch.Size([1, 1, 3, 3])
tensor([[[[10, 12, 12],
[18, 16, 16],
[13, 9, 3]]]])
tensor([[[[10, 12],
[13, 3]]]])
tensor([[[[ 1, 3, 4, 10, 8],
[ 5, 10, 12, 12, 6],
[ 7, 18, 16, 16, 8],
[11, 13, 9, 3, 4],
[14, 13, 9, 7, 4]]]])
进程已结束,退出代码0
PPT结果演示:
下一步结果: