1、网络骨架
import torch.nn as nn
import torch
import torch.nn.functional as Function
class rgd_Net(nn.Module):
def __init__(self):
super().__init__()
# self.conv1=nn.Conv2d(1,20,5)#用20个卷积核(5x5x1)去卷积一维的图(FxFx1),输出为(w*w*20),w=(F-2*P+1)/S
# self.conv2=nn.Conv2d(20,20,5)#用20个卷积核(5x5x20)去卷积一维的图(FxFx20),输出为(w*w*20),w=(F-2*P+1)/S
def forward(self,input):
output=input+1
return output
# x1=Function.relu(self.conv1(x))
# x2=Function.relu(self.conv2(x1))
# return x2
rgd1=rgd_Net()
x=torch.tensor(1.0)
output=rgd1(x)
print(output)
2.1网络骨架需要添加的单元(一) 卷积操作
-例子1
# 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))
# kernel=torch.reshape(kernel,(1,1,3,3))
# print(input.shape)
# print(kernel.shape)
#
# # 卷积操作==stride
# output=F.conv2d(input,kernel,stride=1)# W=(F-2P+1)/S
# print(output)
# output2=F.conv2d(input,kernel,stride=2)
# print(output2)
#
# #卷积操作==padding
# output3=F.conv2d(input,kernel,padding=1)#stride默认为1
# print(output3)
- 例子2
import torch
import torchvision
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch import nn
from torch.utils.tensorboard import SummaryWriter
dataset=torchvision.datasets.CIFAR10("D:\cv_box\pytorch_learning",
train=True,transform=torchvision.transforms.ToTensor(),
download=True)
dataloader=DataLoader(dataset,batch_size=64)
class Rgd(nn.Module):
def __init__(self):
super(Rgd, 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
rgd=Rgd()
print(rgd)#查看这个网络的样子
writer=SummaryWriter("nn.conv2d.logs")#使用tensorboard可视化显示
step=0
# 查看数据的每一个样子
for data in dataloader:#一批64张图片,每个data为64张图片
imgs,targets=data
output=rgd(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)
output_reshape=torch.reshape(output,(-1,3,30,30)) #[64, 6, 30, 30] >>> [64*2,3,30,30]
writer.add_images("outputs",output_reshape,step)
step+=1
2.2网络骨架需要添加的单元(二) 最大池化操作
- 我们经常使用maxpooling2d最大池化(下采样)===减少采样
- 这里需要说明一下池化层的 卷积核的尺寸=遍历移动的步长stride,假设kernel_size=3x3,则stride=3
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("D:\cv_box\pytorch_learning",
train=False,
transform=torchvision.transforms.ToTensor(),
download=True)
dataloader=DataLoader(dataset,batch_size=64)
class RGD(nn.Module):
def __init__(self):
super(RGD,self).__init__()
self.maxpool1=MaxPool2d(kernel_size=3,ceil_mode=True)
def forward(self,input):
output=self.maxpool1(input)
return output
rgd=RGD()
step=0
writer=SummaryWriter("nn_maxpool_logs")
for data in dataloader:
imgs,targets=data
writer.add_images("input",imgs,step)
output = rgd(imgs)
writer.add_images("output",output,step)
step+=1
writer.close()
2.3网络骨架需要添加的单元(三) 非线性激活操作
- 给网络引入更多的非线性特征,符合更多的特征的模型,可以使得模型有更强的泛化的能力
- 一个特别的例子,如果一个全是FC的网络没有非线性会导致,一个网络的所有层数变成一个层y=kx+b这种情况
参考链接
- 例子1:relu
import torch
from torch import nn
from torch.nn import ReLU
input=torch.tensor([[1,-0.5],
[-1,3]])
print(input.shape)
input_tensor=torch.reshape(input,(-1,1,2,2))
print(input_tensor.shape)
class RGD(nn.Module):
def __init__(self):
super(RGD, self).__init__()
self.relu1=ReLU()
def forward(self,input):
output=self.relu1(input)
return output
rgd=RGD()
output=rgd(input_tensor)
print(output)
结果
- 例子2 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
class RGD(nn.Module):
def __init__(self):
super(RGD, self).__init__()
self.relu1=ReLU()
self.sigmoid1=Sigmoid()
def forward(self,input):
output=self.sigmoid1(input)
return output
dataset=torchvision.datasets.CIFAR10("D:\cv_box\pytorch_learning",train=False,
transform=torchvision.transforms.ToTensor(),
download=True)
dataloader=DataLoader(dataset,batch_size=64)
rgd=RGD()
writer=SummaryWriter("nn_nolinear_activate")
step=0
for data in dataloader:
imgs,targets=data
writer.add_images("input",imgs)
writer.add_images("output",rgd(imgs),step)
step+=1
writer.close()
2.4 网络骨架需要添加的单元(四) 正则化层操作
- 正则化是一种为了减小测试误差的行为。
- 当利用复杂的模型拟合数据,过拟合现象的出现导致模型的泛化能力下降时,使用正则化的适用可以降低模型的复杂度。
- 正则化其实就是对原函数添加一个惩罚函数,即损失函数,每次为函数赋值数据集中数据点的时候,通过对原函数的相关参数加一定的惩罚函数(惩罚参数),来使得函数逐渐逼近于我们想要的最优解,并且在不同的情况可以相应改变这个惩罚参数,使得模型训练出来的数据会更加稀疏,更加合理,不会使得模型逼近于某一块区域
- 作为正则化的一种形式
- BN(批量归一化)解决梯度消失或者梯度爆炸
- BN的本质原理:在网络的每一层输入的时候,又插入了一个归一化层,也就是先做一个归一化处理(归一化至:均值0、方差为1),然后再进入网络的下一层。不过文献归一化层,可不像我们想象的那么简单,它是一个可学习、有参数(γ、β)的网络层。
2.5 网络骨架需要添加的单元(五) 线性层
- 就是我们常说的FC层(机器学习里就是MLP)
import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader
dataset=torchvision.datasets.CIFAR10("D:\cv_box\pytorch_learning",
train=False,
transform=torchvision.transforms.ToTensor(),
download=True)
dataloader=DataLoader(dataset,batch_size=64)
class RGD(nn.Module):
def __init__(self):
super(RGD, self).__init__()
self.linear1 =Linear(196608,10)
def forward(self,input):
output=self.linear1(input)
return output
rgd=RGD()
for data in dataloader:
imgs,targets=data
print(imgs.shape)
output_flatten=torch.flatten(imgs)
print(output_flatten.shape)
output_linear=rgd(output_flatten)
print(output_linear.shape)
3.实战演练
构建以下模型
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
class RGD(nn.Module):
def __init__(self):
super(RGD, self).__init__()
self.conv1=Conv2d(3,32,5,padding=2)# N=(W-F+2P)/S+1
self.maxpool1=MaxPool2d(2)
self.conv2=Conv2d(32,32,5,padding=2)
self.maxpool2=MaxPool2d(2)
self.conv3=Conv2d(32,64,5,padding=2)
self.maxpool3=MaxPool2d(2)#结果为64*4*4
self.flatten1=Flatten()#结果为1024
self.linear1=Linear(1024,64)
self.linear2=Linear(64,10)
def forward(self,x):
x=self.conv1(x)
x=self.maxpool1(x)
x=self.conv2(x)
x=self.maxpool2(x)
x=self.conv3(x)
x=self.maxpool3(x)
x=self.flatten1(x)
x=self.linear1(x)
x=self.linear2(x)
return x
rgd=RGD()
print(rgd)
input=torch.ones((64,3,32,32))
output=rgd(input)
print(output.shape)
- 加入Sequential后,在forward里面代码简介很多
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
class RGD(nn.Module):
def __init__(self):
super(RGD, self).__init__()
# self.conv1=Conv2d(3,32,5,padding=2)# N=(W-F+2P)/S+1
# self.maxpool1=MaxPool2d(2)
# self.conv2=Conv2d(32,32,5,padding=2)
# self.maxpool2=MaxPool2d(2)
# self.conv3=Conv2d(32,64,5,padding=2)
# self.maxpool3=MaxPool2d(2)#结果为64*4*4
#
# self.flatten1=Flatten()#结果为1024
#
# self.linear1=Linear(1024,64)
# self.linear2=Linear(64,10)
self.model1 = Sequential(
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self,x):
# x=self.conv1(x)
# x=self.maxpool1(x)
# x=self.conv2(x)
# x=self.maxpool2(x)
# x=self.conv3(x)
# x=self.maxpool3(x)
#
# x=self.flatten1(x)
#
# x=self.linear1(x)
# x=self.linear2(x)
x=self.model1(x)
return x
rgd=RGD()
print(rgd)
input=torch.ones((64,3,32,32))
output=rgd(input)
print(output.shape)
- 可视化网络结构
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.tensorboard import SummaryWriter
class RGD(nn.Module):
def __init__(self):
super(RGD, self).__init__()
# self.conv1=Conv2d(3,32,5,padding=2)# N=(W-F+2P)/S+1
# self.maxpool1=MaxPool2d(2)
# self.conv2=Conv2d(32,32,5,padding=2)
# self.maxpool2=MaxPool2d(2)
# self.conv3=Conv2d(32,64,5,padding=2)
# self.maxpool3=MaxPool2d(2)#结果为64*4*4
#
# self.flatten1=Flatten()#结果为1024
#
# self.linear1=Linear(1024,64)
# self.linear2=Linear(64,10)
self.model1 = Sequential(
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self,x):
# x=self.conv1(x)
# x=self.maxpool1(x)
# x=self.conv2(x)
# x=self.maxpool2(x)
# x=self.conv3(x)
# x=self.maxpool3(x)
#
# x=self.flatten1(x)
#
# x=self.linear1(x)
# x=self.linear2(x)
x=self.model1(x)
return x
writer=SummaryWriter("seq_logs")
step=0
input=torch.ones((64,3,32,32))
rgd=RGD()
writer.add_graph(rgd,input)
writer.close()