pytorch—卷积,上下采样,卷积神经网络,module模块,数据增强
卷积操作
框在上一层移动,卷积操作生成下一层的每一个点

给不同的k(x,y)可以生成图片上不同的层


最上面的x是b张图片三个通道,每个通道28*28
onek是一个kernel,knernel有三个通道,每个通道3*3
multi_kernel是多个kernel,16个kernel,每个3个通道,每个通道3*3
最左边的是原始一张图的三个通道rgb,他们和第二列k1(kernel1)进行运算得到第四列上面的那个3*3的小绿色矩形
最左边的是原始一张图的三个通道rgb,他们和第三列k2(kernel2)进行运算得到第四列下面的那个3*3的小绿色矩形
import torch input=torch.rand(1,1,28,28) layer=torch.nn.Conv2d(1,3,kernel_size=3,stride=1,padding=0) #conv2d的1指的是input的chanal,3指的是kernel有3个,stride指的是每次走的步长 out=layer(input) #直接对卷积层和输入括号一一下就能得到卷积 print(out.shape) #卷积出来的size==torch.Size([1, 3, 26, 26])
下采样

layer=torch.nn.MaxPool2d(2,stride=2) #矩阵size2*2,步长2
上采样

out=F.interpolate(x,scale_factor=2,mode='nearest') #放大倍数是两倍
batchnorm
有时候在使用到sigmoid函数的时候,输入的范围比较大的时候,有时候会出现不能求导的问题。因此现在要去对输入进行映射,映射到适合能用sigmoid的情况下

batchnorm的实质是对channel进行均值和方差的划分,消掉除了channel以外其它的维度,最终得出的是关于channel的每个channel的均值和方差。如果[6,3,28*28]返回的将是[3]

经典卷积神经网络

何凯明-----resnet深度残差网络
在讨论堆叠层数的情况下能不能改善性能。结果是堆叠层数并不能改善性能。因为层数多了之后就会造成梯度累积误差变大,梯度弥散,梯度爆炸
resnet就是在层级之间加上短接线,训练过程中可以看具体需要来进行短接也就是减少层数。一个32层的在训练过程中如果发现效果不好可以短接减少层数来进行梯度操作。

残差


import torch import torch.nn.functional as F class ResNet(torch.nn.Module): def __init__(self,ch_in,ch_out): self.conv1=torch.nn.Conv2d(ch_in,ch_out,kernel_size=3,stride=1,padding=1) self.bn1=torch.nn.BatchNorm2d(ch_out) self.conv2=torch.nn.Conv2d(ch_out,ch_out,kernel_size=3,stride=1,padding=1) self.bn2 = torch.nn.BatchNorm2d(ch_out) self.extra=torch.nn.Sequential() if ch_out!=ch_in: self.extra=torch.nn.Sequential( torch.nn.Conv2d(ch_in,ch_out,kernel_size=1,stride=1), torch.nn.BatchNorm2d(ch_out) ) def forward(self,x): out=F.relu(self.bn1(self.conv1(x))) #输入进入conv1,出来后进行batchnorm1,然后进行relu out=self.bn2(self.conv2(out)) #将上一步的结果放到conv2,然后出来进行batchnorm2 out=self.extra(x)+out #在out的基础上加上1*1的短接单元 return out
nn.module模块
在里面可以轻易的调用多种常用模块

torch.nn.Sequential可以从上到下执行层级以及其操作
import torch class Net(torch.nn.Module): def __init__(self): super(Net, self).__init__(Net,self) self.net=torch.nn.Sequential( torch.nn.Conv2d(1,35,5,1,1), torch.nn.MaxPool2d(2,2), torch.nn.ReLU(True), torch.nn.BatchNorm2d(32), torch.nn.Conv2d(32, 64, 3, 1, 1), torch.nn.ReLU(True), torch.nn.BatchNorm2d(64), ) def forward(self,x): return self.net(x)
可以使用list(net.named_parameters())查看参数的信息
import torch net=torch.nn.Sequential( torch.nn.Linear(4,2), #第0层 torch.nn.Linear(2, 2), #第一层 ) print(list(net.named_parameters())[0]) print(list(net.named_parameters())[3])
把类的所有操作转移到gpu
import torch #----转移到gpu_______# device=torch.device('cuda') net=torch.nn.Sequential( torch.nn.Linear(4,2), #第0层 torch.nn.Linear(2, 2), #第一层 ) net.to(device)
防止断电,中间进行保存
import torch #----转移到gpu_______# device=torch.device('cuda') net=torch.nn.Sequential( torch.nn.Linear(4,2), #第0层 torch.nn.Linear(2, 2), #第一层 ) net.to(device) #------保存中间状态 torch.save(net.state_dict(),'ckpt.mdl') #------读取保存状态 net.load_state_dict(torch.load('ckpt.mdl'))
训练,测试状态切换
import torch #----转移到gpu_______# device=torch.device('cuda') net=torch.nn.Sequential( torch.nn.Linear(4,2), #第0层 torch.nn.Linear(2, 2), #第一层 ) net.to(device) #------train net.train() #------test net.eval()
将后面两维打平,[2,2,2]变成[2,4]
import torch class Flatten(torch.nn.Module): def __init__(self): super(Flatten,self).__init__() def forward(self,input): return input.view(input.size(0),-1) sd=Flatten() orin=torch.rand(2,2,2) print(orin) print(sd.forward(orin))
数据增强:
将原来的数据进行多样化,原来10张狗的照片转化成20张狗的照片

翻转来一张,镜像来一张,旋转来一张....
使用torchvision包的transforms来改变图片

randomhorizontalflip指的是随机水平翻转,有可能翻转,有可能不翻转
randomverticalflip指的是随机竖直翻转,有可能翻转,有可能不翻转
randomrotation(15)随机转-15度到15度
randomrotation([30,90,180])随机转30或者90或者180
resize([32,32])改变图片成32,32
randomcrop([28,28])随机裁剪成28,28

浙公网安备 33010602011771号