import torch
from torch import nn
###先定义残差块
class ResdualBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride):
super(ResdualBlock, self).__init__()
self.conv0 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=1, stride=1, bias=False)
self.bn0 = nn.BatchNorm2d(128)
self.relu = nn.ReLU()
self.conv1 = nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, stride=1, padding=1, groups=128, bias=False)
self.bn1 = nn.BatchNorm2d(128)
self.relu = nn.ReLU()
self.conv2 = nn.Conv2d(in_channels=128, out_channels=128, kernel_size=1, stride=1, bias=False)
self.bn2 = nn.BatchNorm2d(128)
self.conv3 = nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, stride=2, padding=1, groups=128, bias=False)
self.bn3 = nn.BatchNorm2d(128)
self.conv4 = nn.Conv2d(in_channels=128, out_channels=256, kernel_size=1, stride=1, bias=False)
self.bn4 = nn.BatchNorm2d(256)
self.shortcut = nn.Sequential()
if stride != 1 and in_channels != out_channels:
self.shortcut = nn.Sequential(nn.Conv2d(in_channels, out_channels=256, stride=2, kernel_size=1, bias=False),
nn.BatchNorm2d(out_channels))
def forward(self, x):
identity = x
out = self.conv0(x)
out = self.bn0(out)
out = self.relu(out)
out = self.conv1(out)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out)
out = self.conv3(out)
out = self.bn3(out)
out = self.relu(out)
out = self.conv4(out)
out = self.bn4(out)
out += self.shortcut(identity)
out = self.relu(out)
return out
###开始拼接上下部分,要求图片大小先裁剪为640*640
class myfunc(nn.Module):
def __init__(self, num_classes=1000):
super(myfunc,self).__init__()
self.conv5 = nn.Sequential(
nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, stride=2, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(inplace=True)
)
#320*320*32
self.conv6 = nn.Sequential(
nn.Conv2d(in_channels=32,out_channels=32,kernel_size=3,stride=2,padding=1,groups=32),
nn.BatchNorm2d(32),
nn.ReLU(inplace=True)
)
# 320*320*32
self.conv7 = nn.Sequential(
nn.Conv2d(in_channels=32, out_channels=64, kernel_size=1, stride=1),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True)
)
#320*320*64
self.conv8 = nn.Sequential(
nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, stride=2,padding=1,groups=64),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True)
)
#160*160*64
self.layer1 = self.make_layer(64,256)
self.conv9 = nn.Sequential(
nn.Conv2d(in_channels=256,out_channels=256,kernel_size=3,stride=1,padding=1,groups=256,bias=False),
nn.BatchNorm2d(256),
nn.ReLU(inplace=True)
)
self.conv10 = nn.Sequential(
nn.Conv2d(in_channels=256,out_channels=256,kernel_size=1,stride=1,bias=False),
nn.BatchNorm2d(256),
nn.ReLU(inplace=True)
)
self.conv11 = nn.Sequential(
nn.Conv2d(in_channels=256, out_channels=512, kernel_size=1, stride=1, bias=False),
nn.BatchNorm2d(512),
nn.ReLU(inplace=True)
)
#80*80*512
self.avgpool = nn.AdaptiveAvgPool2d((1,1))#1*1*512
self.fc = nn.Linear(512,num_classes)
def make_layer(self, in_channels, out_channels, stride=2):
layer = []
layer.append(ResdualBlock(in_channels,out_channels,stride))
return nn.Sequential(*layer)
def forward(self,x):
out = self.conv5(x)
out = self.conv6(out)
out = self.conv7(out)
out = self.conv8(out)
out = self.layer1(out)
out = self.conv9(out)
out = self.conv10(out)
out = self.conv11(out)
out = self.avgpool(out)
out = torch.flatten(out,1)
out = self.fc(out)
return out
model = myfunc().cuda()
print(model)
from torchsummary import summary
print(summary(model,(3, 640, 640)))
myfunc(
(conv5): Sequential(
(0): Conv2d(3, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
(1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(conv6): Sequential(
(0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=32)
(1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(conv7): Sequential(
(0): Conv2d(32, 64, kernel_size=(1, 1), stride=(1, 1))
(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(conv8): Sequential(
(0): Conv2d(64, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=64)
(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(layer1): Sequential(
(0): ResdualBlock(
(conv0): Conv2d(64, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn0): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU()
(conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=128, bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=128, bias=False)
(bn3): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv4): Conv2d(128, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn4): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(shortcut): Sequential(
(0): Conv2d(64, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
)
(conv9): Sequential(
(0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=256, bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(conv10): Sequential(
(0): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(conv11): Sequential(
(0): Conv2d(256, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
)
(avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
(fc): Linear(in_features=512, out_features=1000, bias=True)
)
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
Conv2d-1 [-1, 32, 320, 320] 896
BatchNorm2d-2 [-1, 32, 320, 320] 64
ReLU-3 [-1, 32, 320, 320] 0
Conv2d-4 [-1, 32, 160, 160] 320
BatchNorm2d-5 [-1, 32, 160, 160] 64
ReLU-6 [-1, 32, 160, 160] 0
Conv2d-7 [-1, 64, 160, 160] 2,112
BatchNorm2d-8 [-1, 64, 160, 160] 128
ReLU-9 [-1, 64, 160, 160] 0
Conv2d-10 [-1, 64, 80, 80] 640
BatchNorm2d-11 [-1, 64, 80, 80] 128
ReLU-12 [-1, 64, 80, 80] 0
Conv2d-13 [-1, 128, 80, 80] 8,192
BatchNorm2d-14 [-1, 128, 80, 80] 256
ReLU-15 [-1, 128, 80, 80] 0
Conv2d-16 [-1, 128, 80, 80] 1,152
BatchNorm2d-17 [-1, 128, 80, 80] 256
ReLU-18 [-1, 128, 80, 80] 0
Conv2d-19 [-1, 128, 80, 80] 16,384
BatchNorm2d-20 [-1, 128, 80, 80] 256
ReLU-21 [-1, 128, 80, 80] 0
Conv2d-22 [-1, 128, 40, 40] 1,152
BatchNorm2d-23 [-1, 128, 40, 40] 256
ReLU-24 [-1, 128, 40, 40] 0
Conv2d-25 [-1, 256, 40, 40] 32,768
BatchNorm2d-26 [-1, 256, 40, 40] 512
Conv2d-27 [-1, 256, 40, 40] 16,384
BatchNorm2d-28 [-1, 256, 40, 40] 512
ReLU-29 [-1, 256, 40, 40] 0
ResdualBlock-30 [-1, 256, 40, 40] 0
Conv2d-31 [-1, 256, 40, 40] 2,304
BatchNorm2d-32 [-1, 256, 40, 40] 512
ReLU-33 [-1, 256, 40, 40] 0
Conv2d-34 [-1, 256, 40, 40] 65,536
BatchNorm2d-35 [-1, 256, 40, 40] 512
ReLU-36 [-1, 256, 40, 40] 0
Conv2d-37 [-1, 512, 40, 40] 131,072
BatchNorm2d-38 [-1, 512, 40, 40] 1,024
ReLU-39 [-1, 512, 40, 40] 0
AdaptiveAvgPool2d-40 [-1, 512, 1, 1] 0
Linear-41 [-1, 1000] 513,000
================================================================
Total params: 796,392
Trainable params: 796,392
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 4.69
Forward/backward pass size (MB): 257.82
Params size (MB): 3.04
Estimated Total Size (MB): 265.55
----------------------------------------------------------------
None