pytorch 图像分类
Posted 东东就是我
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pytorch 图像分类相关的知识,希望对你有一定的参考价值。
pytorch 图像分类中轻量级网络
深度可分离卷积 https://blog.csdn.net/tintinetmilou/article/details/81607721
1.MobileNets
https://arxiv.org/pdf/1704.04861.pdf
https://blog.csdn.net/qq_33228039/article/details/101062803
import torch.nn as nn
import torch
class BasicConv2d(nn.Module):
def __init__(self,input_channels,output_channels,kernel_size,**kwargs):
super(BasicConv2d, self).__init__()
self.conv=nn.Conv2d(input_channels,output_channels,kernel_size=kernel_size,**kwargs)
self.bn=nn.BatchNorm2d(output_channels)
self.relu=nn.ReLU(inplace=True)
def forward(self,x):
x=self.conv(x)
x=self.bn(x)
x=self.relu(x)
return x
class DepthSeperabelConv2d(nn.Module):
def __init__(self,input_channels,output_channels,kernel_size,**kwargs):
super(DepthSeperabelConv2d, self).__init__()
self.depthwise=nn.Sequential(
nn.Conv2d(input_channels,input_channels,kernel_size,groups=input_channels,**kwargs),
nn.ReLU(inplace=True)
)
self.pointwise=nn.Sequential(
nn.Conv2d(input_channels,output_channels,1),
nn.BatchNorm2d(output_channels)
)
def forward(self,x):
x=self.depthwise(x)
x=self.pointwise(x)
return x
class MobileNet(nn.Module):
def __init__(self,width_multiplier=1,class_num=100):
super(MobileNet, self).__init__()
alpha=width_multiplier
self.stem=nn.Sequential(
BasicConv2d(3,int(32*alpha),3,padding=1,bias=False),
DepthSeperabelConv2d(
int(32*alpha),
int(64*alpha),
3,
padding=1,
bias=False
)
)
self.conv1=nn.Sequential(
DepthSeperabelConv2d(
int(64*alpha),
int(128*alpha),
3,
stride=2,
padding=1,
bias=False
),
DepthSeperabelConv2d(
int(128*alpha),
int(128*alpha),
3,
padding=1,
bias=False
)
)
# downsample
self.conv2 = nn.Sequential(
DepthSeperabelConv2d(
int(128 * alpha),
int(256 * alpha),
3,
stride=2,
padding=1,
bias=False
),
DepthSeperabelConv2d(
int(256 * alpha),
int(256 * alpha),
3,
padding=1,
bias=False
)
)
# downsample
self.conv3 = nn.Sequential(
DepthSeperabelConv2d(
int(256 * alpha),
int(512 * alpha),
3,
stride=2,
padding=1,
bias=False
),
DepthSeperabelConv2d(
int(512 * alpha),
int(512 * alpha),
3,
padding=1,
bias=False
),
DepthSeperabelConv2d(
int(512 * alpha),
int(512 * alpha),
3,
padding=1,
bias=False
),
DepthSeperabelConv2d(
int(512 * alpha),
int(512 * alpha),
3,
padding=1,
bias=False
),
DepthSeperabelConv2d(
int(512 * alpha),
int(512 * alpha),
3,
padding=1,
bias=False
),
DepthSeperabelConv2d(
int(512 * alpha),
int(512 * alpha),
3,
padding=1,
bias=False
)
)
self.conv4=nn.Sequential(
DepthSeperabelConv2d(
int(512*alpha),
int(1024*alpha),
3,
stride=2,
padding=1,
bias=False
),
DepthSeperabelConv2d(
int(1024*alpha),
int(1024*alpha),
3,
padding=1,
bias=False
)
)
self.avg=nn.AdaptiveAvgPool2d(1)
self.fc=nn.Linear(int(1024*alpha),class_num)
def forward(self, x):
x = self.stem(x)
x = self.conv1(x)
x = self.conv2(x)
x = self.conv3(x)
x = self.conv4(x)
x = self.avg(x)
x = x.view(x.size(0), -1)
x = self.fc(x)
return x
def mobilenet(alpha=1, class_num=100):
return MobileNet(alpha, class_num)
print(mobilenet())
2.Xception(深度分离不增加relu)
https://arxiv.org/pdf/1610.02357.pdf
import torch.nn as nn
import torch
class SeperableConv2d(nn.Module):
def __init__(self,input_channels,output_channels,kernel_size,**kwargs):
super(SeperableConv2d, self).__init__()
self.depthwise=nn.Conv2d(
input_channels,
input_channels,
kernel_size,
groups=input_channels,
bias=False,
**kwargs
)
self.pointwise=nn.Conv2d(input_channels,output_channels,1,bias=False)
def forward(self,x):
x=self.depthwise(x)
x=self.pointwise(x)
return x
class EntryFlow(nn.Module):
def __init__(self):
super(EntryFlow, self).__init__()
self.conv1=nn.Sequential(
nn.Conv2d(3,32,3,stride=2),
nn.BatchNorm2d(32),
nn.ReLU(inplace=True)
)
self.conv2=nn.Sequential(
nn.Conv2d(32,64,3),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True)
)
self.conv3_residual=nn.Sequential(
SeperableConv2d(64,128,3),
nn.BatchNorm2d(128),
nn.ReLU(inplace=True),
SeperableConv2d(128,128,3),
nn.BatchNorm2d(128),
nn.MaxPool2d(3,stride=2)
)
self.conv3_shortcut=nn.Sequential(
nn.Conv2d(64,128,1,stride=2),
nn.BatchNorm2d(128)
)
self.conv4_residual=nn.Sequential(
nn.ReLU(inplace=True),
SeperableConv2d(128,256,3),
nn.BatchNorm2d(256),
nn.ReLU(inplace=True),
SeperableConv2d(256,256,3),
nn.BatchNorm2d(256),
nn.MaxPool2d(3,stride=2)
)
self.conv4_shortcut=nn.Sequential(
nn.Conv2d(128,256,1,stride=2),
nn.BatchNorm2d(256)
)
self.conv5_residual=nn.Sequential(
nn.ReLU(inplace=True),
SeperableConv2d(256,728,3),
nn.BatchNorm2d(728),
nn.ReLU(inplace=True),
SeperableConv2d(728,728,3),
nn.BatchNorm2d(728),
nn.MaxPool2d(3,stride=2)
)
self.conv5_shortcut=nn.Sequential(
nn.Conv2d(256,728,1,stride=2),
nn.BatchNorm2d(728)
)
def forward(self,x):
x=self.conv1(x)
x=self.conv2(x)
residual=self.conv3_residual(x)
shortcut=self.conv3_shortcut(x)
x=residual+shortcut
residual=self.conv4_residual(x)
shortcut=self.conv4_shortcut(x)
x=residual+shortcut
residual=self.conv5_residual(x)
shortcut=self.conv5_shortcut(x)
x=residual+shortcut
return x
class MiddleFlowBlock(nn.Module):
def __init__(self):
super(MiddleFlowBlock, self).__init__()
self.shortcut=nn.Sequential(
)
self.conv1=nn.Sequential(
nn.ReLU(inplace=True),
SeperableConv2d(728,728,3),
nn.BatchNorm2d(728),
nn.ReLU(inplace=True),
SeperableConv2d(728,729,3),
nn.BatchNorm2d(728),
nn.ReLU(inplace=True),
SeperableConv2d(728, 729, 3),
nn.BatchNorm2d(728)
)
def forward(self,x):
residual=self.conv1(x)
shortcut=self.shortcut(x)
return shortcut+residual
class MiddleFlow(nn.Module):
def __init__(self,block):
super(MiddleFlow, self).__init__()
self.middel_block=self._make_flow(block,8)
def forward(self,x):
x=self.middel_block(x)
return x
def _make_flow(self,block,times):
flows=[]
for i in range(times):
flows.append(block())
return nn.Sequential(*flows)
class ExitFlow(nn.Module):
def __init__(self):
super(ExitFlow, self).__init__()
self.residual=nn.Sequential(
nn.ReLU(inplace=True),
SeperableConv2d(728,728,3),
nn.BatchNorm2d(728),
nn.ReLU(inplace=True),
SeperableConv2d(728, 1024, 3),
nn.BatchNorm2d(1024),
nn.MaxPool2d(3,stride=2),
)
self.shortcut=nn.Sequential(
nn.Conv2d(728,1024,1,stride=2),
nn.BatchNorm2d(1024)
)
self.conv=nn.Sequential(
SeperableConv2d(1024,1536,3),
nn.BatchNorm2d(1536),
nn.ReLU(inplace=True),
SeperableConv2d(1536, 2048, 3),
nn.BatchNorm2d(2048),
nn.ReLU(inplace=True),
)
self.avgpool=nn.AvgPool2d((1,1))
def forward(self,x):
shortcut=self.shortcut(x)
residual=self.residual(x)
output=shortcut+residual
output=self.conv(output)
output=self.avgpool(output)
return output
class Xception(nn.Module):
def __init__(self,block,num_class=100):
super(Xception, self).__init__()
self.entry_flow=EntryFlow()
self.middel_flow=MiddleFlow(block=block)
self.exit_flow=ExitFlow()
self.fc=nn.Linear(2048,num_class)
def forward(self,x):
x=self.entry_flow(x)
x=self.middel_flow(x)
x=self.exit_flow(x)
x=x.view(x.size(0),-1)
x=self.fc(x)
return x
def xception():
return Xception(MiddleFlowBlock)
print(xception())
3. Resnext(分组卷积)
https://arxiv.org/pdf/1611.05431.pdf
4. 使用预训练的PyTorch网络进行图像分类