卷积操作
卷积核和扫过的小区域对应位置相乘再求和的操作,卷积完成后一般要加个偏置bias。一种Kernel如果分成多个通道上的子Kernel做卷积运算,最后运算结果还要加在一起后,再加偏置。
nn.Conv2d(类式接口)
基本用法
import torchfrom torch import nn"""2维的卷积层,用于图片的卷积"""# 输入图像的通道数=1(灰度图像),卷积核的种类数=3# 卷积核的shape是3乘3的,扫描步长为1,不加paddinglayer = nn.Conv2d(1, 3, kernel_size=3, stride=1, padding=0)"""要输入的原始图像"""# 样本数=1,通道数=1,图像的shape是28乘28的x = torch.rand(1, 1, 28, 28)"""使用上面定义的卷积层layer和输入x,完成一次卷积的前向运算"""out = layer.forward(x)# 得到的还是1张图片,因为用了3种kernel所以输出的通道数变成3了# 因为没加padding,原来28乘28的图像在3乘3卷积下得到的边长是28-3+1=26print(out.shape) # torch.Size([1, 3, 26, 26])"""添加padding看看"""# 这次使用padding为1.所以原始图像上下左右都加了一层0layer = nn.Conv2d(1, 3, kernel_size=3, stride=1, padding=1)print(layer.forward(x).shape) # torch.Size([1, 3, 28, 28])"""步长设置为2看看"""# stride设置为2,也就是每次移动2格子(向上或者向右)layer = nn.Conv2d(1, 3, kernel_size=3, stride=2, padding=1)# 相当于每次跳1个像素地扫描,输出的Feature Map直接小了一半print(layer.forward(x).shape) # torch.Size([1, 3, 14, 14])"""实际使用时,应该这样用!"""out = layer(x)print(out.shape) # torch.Size([1, 3, 14, 14])
运行结果
torch.Size([1, 3, 26, 26])torch.Size([1, 3, 28, 28])torch.Size([1, 3, 14, 14])torch.Size([1, 3, 14, 14])
查看卷积层信息
# 查看一下卷积层的权重(即卷积核)信息和偏置信息print(layer.weight)print(layer.bias)# 查看卷积层形状print(layer.weight.shape)print(layer.bias.shape)
运行结果
tensor([[[[ 0.1277, -0.1672, 0.1102],[ 0.3176, 0.0236, 0.2537],[ 0.0737, 0.0904, 0.0261]]],[[[ 0.0349, -0.2042, 0.1766],[-0.0938, -0.0470, 0.2011],[-0.2460, 0.0876, 0.3124]]],[[[-0.2361, -0.0971, -0.1031],[-0.0756, -0.3073, 0.3227],[-0.1951, -0.2395, -0.0769]]]], requires_grad=True)Parameter containing:tensor([ 0.0790, -0.3261, 0.0697], requires_grad=True)torch.Size([3, 1, 3, 3])torch.Size([3])
F.conv2d(函数式接口)
PyTorch里一般小写的都是函数式的接口,相应的大写的是类式接口。可以这样理解:nn.Conv2d 是 [2D卷积层],而 F.conv2d 是 [2D卷积操作]。
基本用法
import torchfrom torch.nn import functional as F"""手动定义卷积核(weight)和偏置"""w = torch.rand(16, 3, 5, 5) # 16种3通道的5乘5卷积核b = torch.rand(16) # 和卷积核种类数保持一致(不同通道共用一个bias)"""定义输入样本"""x = torch.randn(1, 3, 28, 28) # 1张3通道的28乘28的图像"""2D卷积得到输出"""out = F.conv2d(x, w, b, stride=1, padding=1) # 步长为1,外加1圈paddingprint(out.shape)out = F.conv2d(x, w, b, stride=2, padding=2) # 步长为2,外加2圈paddingprint(out.shape)
运行结果
torch.Size([1, 16, 26, 26])torch.Size([1, 16, 14, 14])
原大小, 卷积核大小
,池化大小
,padding(填充)=
, strids(滑动步长)=
,公式通用:
