参考链接: pytorch实现MobileNet
实验代码展示:
import torch
import torch.nn as nn
import torch.nn.functional as F
class Block(nn.Module):
'''Depthwise conv + Pointwise conv
实现深度卷积和逐点卷积'''
def __init__(self, in_planes, out_planes, stride=1):
super(Block, self).__init__()
self.conv1 = nn.Conv2d(
in_planes, in_planes, kernel_size=3, stride=stride,
padding=1, groups=in_planes, bias=False)
self.bn1 = nn.BatchNorm2d(in_planes)
self.conv2 = nn.Conv2d(
in_planes, out_planes, kernel_size=1,
stride=1, padding=0, bias=False)
self.bn2 = nn.BatchNorm2d(out_planes)
self.relu_1 = torch.nn.ReLU()
self.relu_2 = torch.nn.ReLU()
def forward(self, x):
out = self.relu_1(self.bn1(self.conv1(x)))
out = self.relu_2(self.bn2(self.conv2(out)))
return out
class MobileNet(nn.Module):
# (128,2) means conv planes=128, conv stride=2,
# by default conv stride=1
cfg = [64, (128,2), 128, (256,2), 256, (512,2),
512, 512, 512, 512, 512, (1024,2), 1024]
def __init__(self, num_classes=10):
super(MobileNet, self).__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=3,
stride=1, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(32)
self.layers = self._make_layers(in_planes=32)
self.linear = nn.Linear(1024, num_classes)
self.relu = torch.nn.ReLU()
def _make_layers(self, in_planes):
layers = []
for x in self.cfg:
out_planes = x if isinstance(x, int) else x[0]
stride = 1 if isinstance(x, int) else x[1]
layers.append(Block(in_planes, out_planes, stride))
in_planes = out_planes
return nn.Sequential(*layers)
def forward(self, x):
out = self.relu(self.bn1(self.conv1(x))) # torch.Size([1, 32, 32, 32])
out = self.layers(out)
out = F.avg_pool2d(out, 2)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out
if __name__ == '__main__':
net = MobileNet()
x = torch.randn(1,3,32,32)
y = net(x)
print(y.size())
控制台输出结果:
Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。
尝试新的跨平台 PowerShell https://aka.ms/pscore6
加载个人及系统配置文件用了 1237 毫秒。
(base) PS C:\Users\chenxuqi\Desktop\News4cxq\test4cxq> & 'D:\Anaconda3\envs\ssd4pytorch1_2_0\python.exe'
'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2021.1.502429796\pythonFiles\lib\python\debugpy\launcher' '61501' '--' 'c:\Users\chenxuqi\Desktop\News4cxq\test4cxq\mobilenetV2.py'
torch.Size([1, 10])
(base) PS C:\Users\chenxuqi\Desktop\News4cxq\test4cxq> conda activate ssd4pytorch1_2_0
(ssd4pytorch1_2_0) PS C:\Users\chenxuqi\Desktop\News4cxq\test4cxq>
实验代码展示:
import torch
import torch.nn as nn
import torch.nn.functional as F
class Block(nn.Module): # (N,in_planes,H,W) -> (N,out_planes,H,W)
'''Depthwise conv + Pointwise conv
实现深度卷积和逐点卷积'''
def __init__(self, in_planes, out_planes, stride=1):
super(Block, self).__init__()
self.conv1 = nn.Conv2d(
in_planes, in_planes, kernel_size=3, stride=stride,
padding=1, groups=in_planes, bias=False)
self.bn1 = nn.BatchNorm2d(in_planes)
self.conv2 = nn.Conv2d(
in_planes, out_planes, kernel_size=1,
stride=1, padding=0, bias=False)
self.bn2 = nn.BatchNorm2d(out_planes)
self.relu_1 = torch.nn.ReLU()
self.relu_2 = torch.nn.ReLU()
def forward(self, x):
out = self.relu_1(self.bn1(self.conv1(x)))
out = self.relu_2(self.bn2(self.conv2(out)))
return out
class MobileNet(nn.Module):
# (128,2) means conv planes=128, conv stride=2,
# by default conv stride=1
cfg = [64, (128,2), 128, (256,2), 256, (512,2),
512, 512, 512, 512, 512, (1024,2), 1024] # out_planes, stride
def __init__(self, num_classes=10):
super(MobileNet, self).__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=3,
stride=1, padding=1, bias=False) # 只改变通道数
self.bn1 = nn.BatchNorm2d(32)
self.layers = self._make_layers(in_planes=32)
# self.linear = nn.Linear(1024, num_classes)
self.relu = torch.nn.ReLU()
def _make_layers(self, in_planes):
layers = []
for x in self.cfg: # out_planes, stride
out_planes = x if isinstance(x, int) else x[0]
stride = 1 if isinstance(x, int) else x[1]
layers.append(Block(in_planes, out_planes, stride))
in_planes = out_planes
return nn.ModuleList(layers)
def forward(self, x):
out = self.relu(self.bn1(self.conv1(x))) # torch.Size([1, 32, 32, 32])
# print(out.shape)
for index, layer in enumerate(self.layers):
out = layer(out) # torch.Size([1, 1024, 2, 2])
# print(index, out.shape)
if index == 7:
self.intermediate = out
# print('intermediate.shape:', self.intermediate.shape)
return out
if __name__ == '__main__':
net = MobileNet()
x = torch.randn(4,3,300,300)
y = net(x)
# print('输出数据的维度是:', y.size())
# torch.Size([4, 32, 300, 300])
# 0 torch.Size([4, 64, 300, 300])
# 1 torch.Size([4, 128, 150, 150])
# 2 torch.Size([4, 128, 150, 150])
# 3 torch.Size([4, 256, 75, 75])
# 4 torch.Size([4, 256, 75, 75])
# 5 torch.Size([4, 512, 38, 38])
# 6 torch.Size([4, 512, 38, 38])
# 7 torch.Size([4, 512, 38, 38])
# intermediate.shape: torch.Size([4, 512, 38, 38])
# 8 torch.Size([4, 512, 38, 38])
# 9 torch.Size([4, 512, 38, 38])
# 10 torch.Size([4, 512, 38, 38])
# 11 torch.Size([4, 1024, 19, 19])
# 12 torch.Size([4, 1024, 19, 19])
# 输出数据的维度是: torch.Size([4, 1024, 19, 19])