torch.nn提供的工具:
- Containers:神经网络的骨架
- Convolution Layers:卷积层
- Pooling Layers:池化层
- Non-linear Activations:非线性激活
- Normalization Layers:正则化层
1 Containers
Containers包含的模块:
其中最常用的是 Module 模块(为所有神经网络提供基本骨架)
1.1 Module 模块
- __init__:初始化函数
- forward: 前向传播
- conv为卷积,relu为非线性处理
举例:
import torch
from torch import nn
class MyNN(nn.Module): #搭建的神经网络MyNN继承了Module类(父类)
def __init__(self): #初始化函数
super().__init__() #必须调用父类的初始化函数
def forward(self,input): #前向传播(输入和输出中间的处理过程)
output = input + 1
return output
mynn = MyNN()
x = torch.tensor(1.0)
output = mynn(x)
print(output)
2 Convolution Layers
2.1 关于卷积操作
torch.nn 是 torch.nn.functional 的封装,可先查看torch.nn.functional
TORCH.NN.FUNCTIONAL.CONV2D:
- input:输入,尺寸要求4个参数 (batch,通道数,高,宽)
- weight:权重/卷积核,尺寸要求4个参数
使用 torch.reshape 函数改变维度
- bias:偏置
- stride:步进
- padding:填充,对输入图像进行填充,值可以为一个数或一个元组,默认情况下不进行填充例如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]])
kernal = torch.tensor([[1,2,1],
[0,1,0],
[2,1,0]])
# 尺寸只有高和宽,不符合要求
print(input.shape) #5×5
print(kernal.shape) #3×3
# 尺寸变换为符合条件的四个参数
input = torch.reshape(input,(1,1,5,5))
kernal = torch.reshape(kernal,(1,1,3,3))
# 尺寸符合要求
print(input.shape)
print(kernal.shape)
# 无padding,步进为1
output = F.conv2d(input,kernal,stride=1)
print('output',output)
# 无padding,步进为2
output2 = F.conv2d(input,kernal,stride=2)
print('output2',output2)
# padding为1,步进为1
output3 = F.conv2d(input,kernal,stride=1,padding=1)
print('output3',output3)
2.2 Conv2d
- in_channels :输入的通道数,彩色图像 in_channels的值为3
- out_channels :输出的通道数
- in_channels 和 out_channels 都为 1 时,拿一个卷积核在输入图像中进行操作
- out_channels 为 2 时,卷积层会生成两个卷积核(不一定一样),得到两个输出,叠加后作为最后输出
- kernel_size :数或元组,卷积核大小
- 卷积核的参数是从一些分布中进行采样得到的
- 实际训练过程中,卷积核中的值会不断进行调整
- stride=1 :卷积过程中的步进大小
- padding=0 :卷积过程中对原始图像边缘是否进行填充
- dilation=1 :每一个卷积核对应位的距离
- groups=1 :一般设置为1,很少改动,改动的话为分组卷积
- bias=True :通常为True,对卷积后的结果是否加减一个常数的偏置
- padding_mode='zeros' :选择padding填充的模式
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10("./datasets",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset,batch_size=64)
# 搭建神经网络
class MyNN(nn.Module):
def __init__(self):
super(MyNN, self).__init__()
self.conv1 = Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0)
def forward(self,x):
x = self.conv1(x)
return x
mynn = MyNN()
# 打印网络结构
print(mynn) #MyNN((conv1): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1)))
writer = SummaryWriter("log3")
step = 0
for data in dataloader:
imgs,targets = data
output = mynn(imgs)
print(imgs.shape) #输入大小 torch.Size([64, 3, 32, 32]) batch_size=64,in_channels=3(彩色图像),每张图片是32×32的
print(output.shape) #经过卷积后的输出大小 torch.Size([64, 6, 30, 30]) 卷积后变成6个channels,但原始图像减小,所以是30×30的
writer.add_images("input",imgs,step)
#经过卷积后的输出大小 torch.Size([64, 6, 30, 30]) 卷积后变成6个channels,但原始图像减小,所以是30×30的
output = torch.reshape(output,(-1,3,30,30))
writer.add_images("output",output,step)
step += 1
writer.close()
- 其中out_channels=6代表输出图片的通道数是6通道的,6通道数的图片无法显示,直接使用tensorboard可视化会报错,所以在执行writer.add_images("output",output,step)这行代码前对output进行reshape,reshape成3通道数的图片。
- reshape的第一个参数未知时,可以填入-1,会自动进行计算
- 改变通道数相当于把多余的像素给切出来了,放到了batch_size中。
64张输入图像,卷积后的图像数64×2