mobilenet v1
論文解讀
論文地址:https://arxiv.org/abs/1704.04861
核心思想就是通過depthwise conv替代普通conv.
有關depthwise conv可以參考https://www.cnblogs.com/sdu20112013/p/11759928.html
模型結構:
類似於vgg這種堆疊的結構.
每一層的運算量
可以看到,運算量並不是與參數數量絕對成正比,當然整體趨勢而言,參數量更少的模型會運算更快.
代碼實現
https://github.com/marvis/pytorch-mobilenet
網絡結構:
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
def conv_bn(inp, oup, stride):
return nn.Sequential(
nn.Conv2d(inp, oup, 3, stride, 1, bias=False),
nn.BatchNorm2d(oup),
nn.ReLU(inplace=True)
)
def conv_dw(inp, oup, stride):
return nn.Sequential(
nn.Conv2d(inp, inp, 3, stride, 1, groups=inp, bias=False),
nn.BatchNorm2d(inp),
nn.ReLU(inplace=True),
nn.Conv2d(inp, oup, 1, 1, 0, bias=False),
nn.BatchNorm2d(oup),
nn.ReLU(inplace=True),
)
self.model = nn.Sequential(
conv_bn( 3, 32, 2),
conv_dw( 32, 64, 1),
conv_dw( 64, 128, 2),
conv_dw(128, 128, 1),
conv_dw(128, 256, 2),
conv_dw(256, 256, 1),
conv_dw(256, 512, 2),
conv_dw(512, 512, 1),
conv_dw(512, 512, 1),
conv_dw(512, 512, 1),
conv_dw(512, 512, 1),
conv_dw(512, 512, 1),
conv_dw(512, 1024, 2),
conv_dw(1024, 1024, 1),
nn.AvgPool2d(7),
)
self.fc = nn.Linear(1024, 1000)
def forward(self, x):
x = self.model(x)
x = x.view(-1, 1024)
x = self.fc(x)
return x
參考論文中的結構,第一層是普通的卷積層,后面接的都是可分離卷積.
這里注意groups參數的用法. 當groups=輸入channel數目時,即對每個channel分別做卷積.默認groups=1,此時即為普通卷積.
訓練偽代碼
# create model
model = Net()
# define loss function (criterion) and optimizer
criterion = nn.CrossEntropyLoss().cuda()
optimizer = torch.optim.SGD(model.parameters(), args.lr,
momentum=args.momentum,
weight_decay=args.weight_decay)
# load data
train_loader = torch.utils.data.DataLoader()
# train
for every epoch:
input,target=get_from_data
#前向傳播得到預測值
output = model(input_var)
#計算loss
loss = criterion(output, target_var)
#反向傳播更新網絡參數
optimizer.zero_grad()
loss.backward()
optimizer.step()