pytorch 图像分类
Posted 东东就是我
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pytorch 图像分类相关的知识,希望对你有一定的参考价值。
目标检测BackBones
1.DenseNet
再一个block内,每次操作层的输入都是前面所有层的结果的结合
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchsummary import summary
class BN_Conv2d(nn.Module):
def __init__(self,in_channels,out_channels,kernel_size,stride,padding,dilation=1,groups=1,bias=False):
super(BN_Conv2d, self).__init__()
self.seq=nn.Sequential(
nn.Conv2d(in_channels,out_channels,kernel_size=kernel_size,stride=stride,padding=padding,dilation=dilation,groups=groups,bias=bias),
nn.BatchNorm2d(out_channels)
)
def forward(self,x):
return F.relu(self.seq(x))
class DenseBlock(nn.Module):
def __init__(self,in_channels,num_layers,growth_rate):
super(DenseBlock, self).__init__()
self.num_layers=num_layers
self.k0=in_channels
self.k=growth_rate
self.layers=self._make_layers()
def _make_layers(self):
layer_list=[]
for i in range(self.num_layers):
layer_list.append(nn.Sequential(
BN_Conv2d(self.k0+i*self.k,4*self.k,1,1,0),
BN_Conv2d(4*self.k,self.k,3,1,1)
))
return layer_list
def forward(self,x):
feature=self.layers[0](x)
out=torch.cat((x,feature),1)
for i in range(1,len(self.layers)):
feature=self.layers[i](out)
out=torch.cat((feature,out),1)
return out
class DenseNet(nn.Module):
def __init__(self,layers,k,theta,num_class):
super(DenseNet, self).__init__()
self.layers=layers
self.k=k
self.theta=theta
self.conv=BN_Conv2d(3,2*k,7,2,3)
self.blocks,patches=self._make_blocks(2*k)
self.fc=nn.Linear(patches,num_class)
def _make_transition(self,in_chls):
out_chls=int(self.theta*in_chls)
return nn.Sequential(
BN_Conv2d(in_chls,out_chls,1,1,0),
nn.AvgPool2d(2)
),out_chls
def __make_blocks(self, k0):
"""
make block-transition structures
:param k0:
:return:
"""
layers_list = []
patches = 0
for i in range(len(self.layers)):
layers_list.append(DenseBlock(k0, self.layers[i], self.k))
patches = k0 + self.layers[i] * self.k # output feature patches from Dense Block
if i != len(self.layers) - 1:
transition, k0 = self.__make_transition(patches)
layers_list.append(transition)
return nn.Sequential(*layers_list), patches
def forward(self, x):
out = self.conv(x)
out = F.max_pool2d(out, 3, 2, 1)
# print(out.shape)
out = self.blocks(out)
# print(out.shape)
out = F.avg_pool2d(out, 7)
# print(out.shape)
out = out.view(out.size(0), -1)
out = F.softmax(self.fc(out))
return out
def densenet_121(num_classes=1000):
return DenseNet([6, 12, 24, 16], k=32, theta=0.5, num_classes=num_classes)
def densenet_169(num_classes=1000):
return DenseNet([6, 12, 32, 32], k=32, theta=0.5, num_classes=num_classes)
def densenet_201(num_classes=1000):
return DenseNet([6, 12, 48, 32], k=32, theta=0.5, num_classes=num_classes)
def densenet_264(num_classes=1000):
return DenseNet([6, 12, 64, 48], k=32, theta=0.5, num_classes=num_classes)
def test():
net = densenet_264()
summary(net, (3, 224, 224))
x = torch.randn((2, 3, 224, 224))
y = net(x)
print(y.shape)
test()
2.SENet
首先把特征图压缩成一个通道向量,然后通过降采样和上采样过滤出通道的权重,(有点像opencv里的开运算:先腐蚀再膨胀,用来消除小物体)
import torch.nn as nn
import torch
import torch.nn.functional as F
class SE(nn.Module):
def __init__(self,in_chnls,ratio):
super(SE, self).__init__()
self.squeeze=nn.AdaptiveAvgPool2d((1,1))
self.compress=nn.Conv2d(in_chnls,in_chnls//ratio,1,1,0)
self.excitation=nn.Conv2d(in_chnls//ratio,in_chnls,1,1,0)
def forward(self,x):
out=self.squeeze(x)
out=self.compress(out)
out=F.relu(out)
out=self.excitation(out)
return F.sigmoid(out)
3.DarkNet
和Resnet差不多,不过resnet是一个bottleneck 先是1x1,然后3x3 最后1x1 ,darknet就两部1x1 然后3x3
import torch.nn as nn
from torchsummary import summary
import torch.nn.functional as F
from senet1 import SE
class BN_Conv2d_Leaky(nn.Module):
def __init__(self,in_channels,out_channels,kernel_size,stride,padding,dilation=1,groups=1,bias=False):
super(BN_Conv2d_Leaky, self).__init__()
self.seq=nn.Sequential(
nn.Conv2d(in_channels,out_channels,kernel_size=kernel_size,stride=stride,padding=padding,dilation=dilation, groups=groups, bias=bias),
nn.BatchNorm2d(out_channels)
)
def forward(self,x):
return F.leaky_relu(self.seq(x))
class BN_Conv2d(nn.Module):
def __init__(self,in_channels,out_channels,kernel_size,stride,padding,dilation=1,groups=1,bias=False):
super(BN_Conv2d, self).__init__()
self.seq=nn.Sequential(
nn.Conv2d(in_channels,out_channels,kernel_size=kernel_size,stride=stride,padding=padding,dilation=dilation, groups=groups, bias=bias),
nn.BatchNorm2d(out_channels)
)
def forward(self,x):
return self.seq(x)
class Dark_block(nn.Module):
def __init__(self,channels,is_se=False,inner_channnels=None):
super(Dark_block, self).__init__()
self.is_se=is_se
if inner_channnels is None:
inner_channnels=channels//2
self.conv1=BN_Conv2d_Leaky(channels,inner_channnels,1,1,0)
self.conv2=nn.Conv2d(inner_channnels,channels,3,1,1)
self.bn=nn.BatchNorm2d(channels)
if self.is_se:
self.se=SE(channels,16)
def forward(self,x):
out=self.conv1(x)
out=self.conv2(out)
out=self.bn(out)
if self.is_se:
coefficient=self.se(out)
out*=coefficient
out+=x
return F.leaky_relu(out)
class DarkNet(nn.Module):
def __init__(self,layers,num_class,is_se=False):
super(DarkNet, self).__init__()
self.is_se=is_se
filters=[64,128,256,512,1024]
self.conv1 = BN_Conv2d(3, 32, 3, 1, 1)
self.redu1 = BN_Conv2d(32, 64, 3, 2, 1)
self.conv2=self._make_layers(filters[0],layers[0])
self.redu2 = BN_Conv2d(filters[0], filters[1], 3, 2, 1)
self.conv3 = self.__make_layers(filters[1], layers[1])
self.redu3 = BN_Conv2d(filters[1], filters[2], 3, 2, 1)
self.conv4 = self.__make_layers(filters[2], layers[2])
self.redu4 = BN_Conv2d(filters[2], filters[3], 3, 2, 1)
self.conv5 = self.__make_layers(filters[3], layers[3])
self.redu5 = BN_Conv2d(filters[3], filters[4], 3, 2, 1)
self.conv6 = self.__make_layers(filters[4], layers[4])
self.global_pool = nn.AdaptiveAvgPool2d((1, 1))
self.fc = nn.Linear(filters[4], num_class)
def _make_layers(self,num_filter,num_layers):
layers=[]
for _ in range(num_layers):
layers.append(Dark_block(num_filter,self.is_se))
return nn.Sequential(*layers)
def forward(self, x):
out = self.conv1(x)
out = self.redu1(out)
out = self.conv2(out)
out = self.redu2(out)
out = self.conv3(out)
out = self.redu3(out)
out = self.conv4(out)
out = self.redu4(out)
out = self.conv5(out)
out = self.redu5(out)
out = self.conv6(out)
out = self.global_pool(out)
out = out.view(out.size(0), -1)
out = self.fc(out)
return F.softmax(out)
def darknet_53(num_classes=1000):
return DarkNet([1, 2, 8, 8, 4], num_classes)
net = darknet_53()
summary(net, (3, 256, 256))
4.CSPDenseNet
和DenseNet的DenseBlock差不多,不过把输入的通道砍了一半,然后经过block后再组合一起
import torch
import torch.nn as nn
from torchsummary import summary
import torch.nn.functional as F
from senet1 import SE
class BN_Conv2d(nn.Module):
def __init__(self,in_channles,out_channels,kernels_size,stride,padding,dilation=1,groups=1,bias=False):
super(BN_Conv2d, self).__init__()
self.seq=nn.Sequential(
nn.Conv2d(in_channles,out_channels,kernel_size=kernels_size,stride=stride,padding=padding,dilation=dilation,groups=groups,bias=bias),
nn.BatchNorm2d(out_channels)
)
def forward(self,x):
return self.seq(x)
class DenseBlock(nn.Module):
def __init__(self,input_channels,num_layers,grouwth_rate):
super(DenseBlock, self).__init__()
self.num_layers=num_layers
self.k0=input_channels
self.k=grouwth_rate
self.layers=self.__make_layers()
def __make_layers(self):
layer_list=[]
for i in range(self.num_layers):
layer_list.append(nn.Sequential(
BN_Conv2d(self.k0+i*self.k,4*self.k,1,1,0),
BN_Conv2d(4*self.k,self.k,3,1,1)
))
return layer_list
def forward(self,x):
feature=self.layers[0](x)
out=torch.cat((x,feature),1)
for i in range(1,len(self.layers)):
feature=self4. 使用预训练的PyTorch网络进行图像分类