(九)神经网络
2.神经网络卷积层
import torch
import torch.nn.functional as F
input = torch.tensor([[1,2,0,3,1], #2Dinput
[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], #2D张量卷积核
[0,1,0],
[2,1,0]])
#使用torch.reshape将输入张量和卷积核的形状调整为适合卷积操作的形状。
input = torch.reshape(input,(1,1,5,5))#这表示输入张量具有一个通道(channel),高度和宽度为5。
# (batch_size, channels, height, width)batch_size 是1,因为只有一个输入图像。
kernel = torch.reshape(kernel,(1,1,3,3))
print(input.shape)
print(kernel.shape)
output = F.conv2d(input,kernel,stride=1)
print(output)
2D张量通常表示一个二维的数据结构,就像一个矩阵一样。矩阵是一个由行和列组成的二维数组。图像主要是二维。同样,2D张量也是一个二维数组,其中的元素可以用两个坐标来索引,通常表示为 (行, 列)
。
使用F.conv2d
函数进行二维卷积操作。stride=1
表示卷积核在输入上每次移动的步幅为1。
打印卷积操作的结果,即输出张量。卷积操作的结果是通过在输入上滑动卷积核并计算对应元素乘积的和来得到的。
#运行结果:
torch.Size([1, 1, 5, 5])
torch.Size([1, 1, 3, 3])
tensor([[[[10, 12, 12],
[18, 16, 16],
[13, 9, 3]]]])
padding在输入图像上下左右两边会进行空白填充,最后结果会发生改变
output = F.conv2d(input,kernel,stride=1,padding =1)
#结果
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]]]])
对图像进行卷积操作:
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("../data1",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset,batch_size=64)#加载数据,每批次64个图像
class Tudui(nn.Module):#神经网络模型 Tudui
def __init__(self):
super(Tudui,self).__init__()
self.conv1 = Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride =1,padding=0) #in_channnels=3彩色图像3个通道
#out_channnels=6卷积层卷完后有6个结果,kernel_size=3卷积核是3*3的
def forward(self,x):
x = self.conv1(x)#通过self.conv1对输入进行卷积操作
return x
tudui = Tudui()#创建土堆类的实例
for data in dataloader:
imgs,targets = data
output = tudui(imgs)#对图像进行神经网络处理
print(imgs.shape)#torch.Size([64, 3, 32, 32])
print(output.shape)#torch.Size([64, 6, 30, 30])
卷积后的图像高和宽会会减小:
-
卷积核的大小(Kernel Size): 卷积核定义了在输入上滑动时覆盖的区域大小。如果卷积核较大,输出的尺寸可能较小,因为每个卷积操作都会减小输出的尺寸。
-
步幅(Stride): 步幅表示卷积核在输入上滑动的步长。较大的步幅会导致输出的尺寸减小,因为卷积核之间的重叠较少。
-
填充(Padding): 填充是在输入的边界上添加额外像素,以便更好地处理边缘信息。有时填充可以保持输出尺寸与输入尺寸相同,但通常它会导致输出尺寸变大
在tensorboard中显示时会出现报错:
writer = SummaryWriter("../logs")
step = 0
for data in dataloader:
imgs,targets = data
output = tudui(imgs)#对图像进行神经网络处理
print(imgs.shape)#torch.Size([64, 3, 32, 32])
print(output.shape)#torch.Size([64, 6, 30, 30])
writer.add_images("input",imgs,step)
writer.add_images("output", output, step)
step = step + 1
原因是在调用writer.add_images时会在内部调用make_grid函数,用来将多个图像组合成网格,便于可视化,而在使用 make_grid
函数时,通常通道数应为 3,这里的output通道数为6,因此会出现报错。