卷积层
通过卷积核(滤波器)在输入数据上滑动,卷积层能够自动检测和提取局部特征,如边缘、纹理、颜色等。不同的卷积核可以捕捉不同类型的特征。
nn.conv2d()
in_channels:输入的通道数,彩色图片一般为3通道
out_channels:通过卷积之后输出的通道数
kernel_size(int or tuple):卷积核的大小,一个数表示正方形
kernel_size(int or tuple):卷积核的大小,一个数表示正方形
stride:计算过程中的步长
padding:输入边缘填充的大小
padding_mode:填充方式,一般设置为0,即填充数为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)
#由于con2d要求尺寸数字为4,变换形状
#元组第一个参数是batch size样本数量(也就是图片的数量),第二个参数是channel图像的通道数量,H高,W宽
input=torch.reshape(input,(1,1,5,5))
kernel=torch.reshape(kernel,(1,1,3,3))
print(input.shape)
print(kernel.shape)
#stride为步长,也就是卷积核移动的格数
output=F.conv2d(input,kernel,stride=1)
print(output)
#向右移动两格,向下移动两格
output2=F.conv2d(input,kernel,stride=2)
print(output2)
#padding为填充原数据,如果为1,上下左右各填充一行一列
output3=F.conv2d(input,kernel,stride=1,padding=1)
print(output3)
实战,对数据集CIFAR10进行卷积
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("./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
#加载数据
dataloader=DataLoader(dataset,batch_size=64)
#定义卷积层
class operate(nn.Module):
def __init__(self):
super(operate, self).__init__()
self.conv1=Conv2d(in_channels=3,out_channels=3,kernel_size=3,stride=1,padding=0)
def forward(self,x):
x=self.conv1(x)
return x
op=operate()
writer=SummaryWriter("conv")
step=0
for data in dataloader:
imgs,targets=data
output=op(imgs)
writer.add_images("input",imgs,step)
writer.add_images("output",output,step)
step+=1
writer.close()
卷积前后的效果
池化层
池化操作通过减小特征图的空间尺寸(如高度和宽度),降低后续层的计算负担,同时保留主要特征信息。
nn.MaxPool2d()
kernel_size:池化核的大小
stride:步长,默认值为池化核的大小
padding:填充大小
dilation:空洞卷积
ceil_mode:设置为True时,为ceil模式向上取整,否则为floor模式,向下取整。在池化过程,如果输入比池化核小的话,是否进行池化,取决于ceil_mode的值,如果为True则保留,否则舍弃。
import torch
from torch import nn
from torch.nn import MaxPool2d
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]],dtype=torch.float32)#设置为浮点数
input=torch.reshape(input,(-1,1,5,5))
#池化层
class operate(nn.Module):
def __init__(self):
super(operate, self).__init__()
self.mp1 = MaxPool2d(kernel_size=3,ceil_mode=True)
def forward(self,input):
output= self.mp1(input)
return output
op=operate()
output=op(input)
print(output)
实战,对CIFAR10进行池化
import torch
import torchvision
#获取数据集
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset=torchvision.datasets.CIFAR10("./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
#加载数据
dataloader=DataLoader(dataset,batch_size=64)
#定义池化层
class operate(nn.Module):
def __init__(self):
super(operate, self).__init__()
self.mp=MaxPool2d(kernel_size=3,ceil_mode=True)
def forward(self,input):
output=self.mp(input)
return output
op=operate()
writer=SummaryWriter("maxpool")
step=0
for data in dataloader:
imgs,targets=data
output=op(imgs)
writer.add_images("input",imgs,step)
writer.add_images("output",output,step)
step+=1
writer.close()
池化结果
非线性激活
让网络能够学习复杂的非线性关系,但可能导致模型过拟合。
nn.relu()
inplace:是否采用返回值的形式接收返回值,如果为True,则直接修改原变量,否则返回一个新变量,原值不变
nn.sigmoid()
函数公式为:
import torch
from torch import nn
from torch.nn import ReLU
input=torch.tensor([[1,0.5],
[-1,3]])
input=torch.reshape(input,(-1,1,2,2))
class operater(nn.Module):
def __init__(self):
super(operater, self).__init__()
self.relu1=ReLU()
def forward(self,input):
output=self.relu1(input)
return output
op=operater()
output=op(input)
print(output)
实战,对CIFAR10进行sigmoid激活
import torch
import torchvision
#获取数据集
from torch import nn
from torch.nn import ReLU, Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset=torchvision.datasets.CIFAR10("./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
#加载数据
dataloader=DataLoader(dataset,batch_size=64)
#激活函数
class operater(nn.Module):
def __init__(self):
super(operater, self).__init__()
self.relu=ReLU()
self.sg=Sigmoid()
def forward(self,input):
output=self.sg(input)
return output
op=operater()
writer=SummaryWriter("sigmoid")
step=0
for data in dataloader:
imgs,targets=data
output=op(imgs)
writer.add_images("input",imgs,step)
writer.add_images("output",output,step)
step+=1
writer.close()
实验结果
正则化
通过约束模型复杂度,确保网络学习到的是有意义的模式,而非噪声。
BatchNormal2d
num_features:通道数
线性层
nn.liner()
in_features:输入数据的大小
out_features:输出数据的大小
bias(bool):偏置值
import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader
dataset=torchvision.datasets.CIFAR10("./data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader=DataLoader(dataset,batch_size=64)
class operater(nn.Module):
def __init__(self):
super(operater, self).__init__()
self.liner1=Linear(196608,10)
def forward(self,input):
output=self.liner1(input)
return output
op=operater()
for data in dataloader:
imgs,targets=data
print(imgs.shape)
input=torch.flatten(imgs)#将数据降成一维
print(input.shape)
output=op(input)
print(output.shape)