小白介绍一下SqueezeNet的Model部分
小白介绍一下SqueezeNet的Model部分

源码全部
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.functional as F
import numpy as np
import torch.optim as optim
import math
class fire(nn.Module):
def __init__(self, inplanes,squeeze_planes, expand_planes):
super(fire,self).__init__()
self.conv1= nn.Conv2d(inplanes,squeeze_planes, kernel_size=1,stride=1)
self.bn1=nn.BatchNorm2d(squeeze_planes)
self.relu1=nn.ReLU(inplanes = True)
self.conv2 = nn.Conv2d(squeeze_planes,expand_planes,kernel_size=1,stride=1)
self.bn2=nn.BatchNorm2d(expand_planes)
self.conv3 = nn.Conv2d(squeeze_planes, expand_planes, kernel_size=1, stride=1, padding=1)
self.bn3=nn.BatchNorm2d(expand_planes)
self.relu2 = nn.ReLU(inplanes=True)
#using MSR
for m in self.modules():
if isinstance((m, nn.Conv2d)):
n= m.kernel_size[0] * m.kernel_size[1]* m.in_channels
m.weight.data.normal_(0,math.sqrt(2./n))
def forward(self,x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu1(x)
out1 = self.conv2(x)
out1 = self.bn2(out1)
out2 = self.conv3(x)
out2 = self.bn3(out2)
out = torch.cat([out1,out2 ],1)
out = self.relu2(out)
return out
class SqueezeNet(nn.Module):
def __init__(self):
super(SqueezeNet, self).__init__()
self.conv1 = nn.Conv2d(3,96,kernel_size=3,stride=1, padding=1) #32
self.bn1 =nn.BatchNorm2d(96)
self.relu= nn.ReLU(inplace=True)
self.maxpool1= nn.MaxPool2d(kernel_size=2,stride=2) #16
self.fire2= fire(96,16,64)
self.fire3 = fire(128, 16, 64)
self.fire4 = fire(128, 32, 128)
self.maxpool2 = nn.MaxPool2d(kernel_size=2 ,stride=2) #8
self.fire5 = fire(256, 32, 128)
self.fire6 = fire(256, 48, 192)
self.fire7 = fire(384, 48, 192)
self.fire8 = fire(384, 64, 256)
self.maxpool3 = nn.MaxPool2d(kernel_size=2,stride=2) #4
self.fire9= fire(512,64,256)
self.conv2 = nn.Conv2d(512, 10, kernel_size=1, stride=1, padding=1)
self.avg_pool =nn.AvgPool2d(kernel_size=4,stride=4)
self.softmax = nn.LogSoftmax(dim=1)
for m in self.modules():
if isinstance(m,nn.Conv2d):
n = m.kernel_size[0] * m.kernel_size[1] * n.in_channels
m.weight.data.normal_(0,math.sqrt(2. /n))
elif isinstance(m, nn.BatchNorm2d):
m.weight.data.fill_(1)
m.bias.data.zero_()
def forward(self, x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
x = self.maxpool1(x)
x = self.fire2(x)
x = self.fire3(x)
x = self.fire4(x)
x = self.maxpool2(x)
x = self.fire5(x)
x = self.fire6(x)
x = self.fire7(x)
x = self.fire8(x)
x = self.maxpool3(x)
x = self.fire9(x)
x = self.conv2(x)
x = self.avg_pool(x)
x = self.softmax(x)
return x
def fire_layer(inp, s, e):
f= fire( inp, s ,e )
return f
def squeezenet(pretrained = False):
net = SqueezeNet()
return net
首先导入依赖包
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.functional as F
import numpy as np
import torch.optim as optim
import math
导入pytorch,以及pytorch的神经网络模块nn,自动梯度计算autograd,numpy和参数训练优化optim,math计算函数
定义conv1 1X1的卷积模块,以及该模块的BatchNorm和ReLu
self.conv1= nn.Conv2d(inplanes,squeeze_planes, kernel_size=1,stride=1)
self.bn1=nn.BatchNorm2d(squeeze_planes)
self.relu1=nn.ReLU(inplanes = True)
定义conv2 1X1的卷积模块,以及该模块的BatchNorm
self.conv2 = nn.Conv2d(squeeze_planes,expand_planes,kernel_size=1,stride=1)
self.bn2=nn.BatchNorm2d(expand_planes)
定义conv3 1X1的卷积模块,以及该模块的BatchNorm和ReLu,修补
self.conv3 = nn.Conv2d(squeeze_planes, expand_planes, kernel_size=1, stride=1, padding=1)
self.bn3=nn.BatchNorm2d(expand_planes)
self.relu2 = nn.ReLU(inplanes=True)
定义用MSR进行 3组卷积模块对所有输入参数进行归一化
for m in self.modules():
if isinstance((m, nn.Conv2d)):
n= m.kernel_size[0] * m.kernel_size[1]* m.in_channels
m.weight.data.normal_(0,math.sqrt(2./n))
类fire,定义了forward前向计算
def forward(self,x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu1(x)
out1 = self.conv2(x)
out1 = self.bn2(out1)
out2 = self.conv3(x)
out2 = self.bn3(out2)
out = torch.cat([out1,out2 ],1)
out = self.relu2(out)
return out
定义了conv1 的输入,通过卷积的BatchNorm和Relu,分别是到conv2和conv3的输入,如卷积conv2经过BatchNorm 输出out1, conv3经过BatchNorm输出out2,通过2个部分的输出通过cat连接到一起,最好在通过第2个relu的输出,完成整个的Module的前向过程。
定义了SqueezeNet网络的类
def __init__(self):
super(SqueezeNet, self).__init__()
self.conv1 = nn.Conv2d(3,96,kernel_size=3,stride=1, padding=1) #32
self.bn1 =nn.BatchNorm2d(96)
self.relu= nn.ReLU(inplace=True)
self.maxpool1= nn.MaxPool2d(kernel_size=2,stride=2) #16
self.fire2= fire(96,16,64)
self.fire3 = fire(128, 16, 64)
self.fire4 = fire(128, 32, 128)
self.maxpool2 = nn.MaxPool2d(kernel_size=2 ,stride=2) #8
self.fire5 = fire(256, 32, 128)
self.fire6 = fire(256, 48, 192)
self.fire7 = fire(384, 48, 192)
self.fire8 = fire(384, 64, 256)
self.maxpool3 = nn.MaxPool2d(kernel_size=2,stride=2) #4
self.fire9= fire(512,64,256)
self.conv2 = nn.Conv2d(512, 10, kernel_size=1, stride=1, padding=1)
self.avg_pool =nn.AvgPool2d(kernel_size=4,stride=4)
self.softmax = nn.LogSoftmax(dim=1)
定义了初始化的__init__()函数
分别定义了3X3的卷积层,一个BatchNorm bn层,一个ReLu激活层
1个2X2的MaxPooling 卷积池
后面有定义了3个Fire Module,接着定义了2X2的卷积池,接下来定义了4个FireModule。接着定义了1个2X2的卷积池。后面定义一个1X1的FireModule,最后定义了AvgPooling层,网络输出一个Sofemax层。完成多个分类
将所有卷积层的参数归一化,将BatchNorm层的所权重参数这种为1,偏置参数设置为0
for m in self.modules():
if isinstance(m,nn.Conv2d):
n = m.kernel_size[0] * m.kernel_size[1] * n.in_channels
m.weight.data.normal_(0,math.sqrt(2. /n))
elif isinstance(m, nn.BatchNorm2d):
m.weight.data.fill_(1)
m.bias.data.zero_()
定义SqueezeNet的前向处理foreword
def forward(self, x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
x = self.maxpool1(x)
x = self.fire2(x)
x = self.fire3(x)
x = self.fire4(x)
x = self.maxpool2(x)
x = self.fire5(x)
x = self.fire6(x)
x = self.fire7(x)
x = self.fire8(x)
x = self.maxpool3(x)
x = self.fire9(x)
x = self.conv2(x)
x = self.avg_pool(x)
x = self.softmax(x)
按照顺序依次连接就结束,返回x