VGG是一个很简单很常用的分类网络模型
conv3是3x3的卷积,stride为1,padding为1
maxpool是最大池化下采样,stride为2,kernel_size为2
由于网络的模型很简单,所以直接记录代码
import torch
import torch.nn as nn
net_type = {}
# 记录每一种网络的输出channel,
net_type["11"] = [64, 'm', 128, 'm', 256, 256, 'm', 512, 512, 'm', 512, 512, 'm']
net_type["13"] = [64, 64, 'm', 128, 128, 'm', 256, 256, 'm', 512, 512, 'm', 512, 512, 'm']
net_type["16"] = [64, 64, 'm', 128, 128, 'm', 256, 256, 256,
'm', 512, 512, 512, 'm', 512, 512, 512, 'm']
net_type["19"] = [64, 64, 'm', 128, 128, 'm', 256, 256, 256, 256,
'm', 512, 512, 512, 512, 'm', 512, 512, 512, 512, 'm']
class VGG(nn.Module):
def __init__(self,n="16",shape=224):
super(VGG, self).__init__()
self.conv_net = self.make_layer(n)
self.fc_net = nn.Sequential(
# 随机失活神经元,p=0.5 防止过拟合
nn.Dropout(),
nn.Linear((shape//32)**2*512, 4096),
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(True),
nn.Linear(4096, 1000)
)
def forward(self,x):
x = self.conv_net(x)
# 展平处理
x = torch.flatten(x,start_dim=1)
x = self.fc_net(x)
x = x.sigmoid()
return x
def make_layer(self,n="16"):
inchannel = 3
layer = []
for i in net_type[n]:
if i == "m":
layer.append(nn.MaxPool2d(kernel_size=2,stride=2))
# vgg网络中所有conv的stride=1,kernel_size=3
# 所有maxpool kernel_size =2,stride=2
else:
layer.append(nn.Conv2d(inchannel,out_channels=i,kernel_size=3,padding=1))
layer.append(nn.ReLU(True))
inchannel = i
return nn.Sequential(*layer)