VGG16 结构图 + pytorch代码
VGG16 结构图
需要清晰一点的可以下PDF文件:
链接: https://pan.baidu.com/s/1RaEeupUKzEQPnfy02Idp3g.
密码是:cn0t
pytorch 网络代码
import torch
import torch.nn as nn
import torch.nn.functional as F
class conv_pool_block(nn.Module):
def __init__(self, in_channels, out_channels,conv_size=(3,3), conv_stride=(1,1), pool_size=(2,2), pool_stride=(2,2)):
super(conv_pool_block, self).__init__()
self.block = nn.Sequential(
nn.Conv2d(in_channels, out_channels, kernel_size=conv_size, stride=conv_stride, padding=1),
nn.BatchNorm2d(out_channels),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=pool_size, stride=pool_stride)
# inplace = False 时,不会修改输入对象的值,而是返回一个新创建的对象,所以打印出对象存储地址不同,类似于C语言的值传递
# inplace = True 时,会修改输入对象的值,所以打印出对象存储地址相同,类似于C语言的址传递
# inplace = True ,会改变输入数据的值,节省反复申请与释放内存的空间与时间,只是将原来的地址传递,效率更好
)
def forward(self, x):
x = self.block(x)
return x
class conv_block(nn.Module):
def __init__(self, in_channels, out_channels,conv_size=(3,3), conv_stride=(1,1)):
super(conv_block, self).__init__()
self.block = nn.Sequential(
nn.Conv2d(in_channels, out_channels, kernel_size=conv_size, stride=conv_stride, padding=1),
nn.BatchNorm2d(out_channels),
nn.ReLU(inplace=True)
)
def forward(self, x):
x = self.block(x)
return x
class VGG16(nn.Module):
def __init__(self, input_size, input_channels, class_num):
super(VGG16, self).__init__()
conv_c = [64, 128, 256, 512, 512]
# if input_size//32 != 0:
# raise ValueError("图片Size不是32的倍数!")
l_f_size = int(input_size/32) # Last Feature Map Size
self.layer1_conv_block = conv_block(input_channels, conv_c[0])
self.layer1_conv_pool_block = conv_pool_block(conv_c[0], conv_c[0])
self.layer2_conv_block = conv_block(conv_c[0], conv_c[1])
self.layer2_conv_pool_block = conv_pool_block(conv_c[1], conv_c[1])
self.layer3_conv_block = nn.Sequential(
conv_block(conv_c[1], conv_c[2]),
conv_block(conv_c[2], conv_c[2])
)
self.layer3_conv_pool_block = conv_pool_block(conv_c[2], conv_c[2])
self.layer4_conv_block = nn.Sequential(
conv_block(conv_c[2], conv_c[3]),
conv_block(conv_c[3], conv_c[3])
)
self.layer4_conv_pool_block = conv_pool_block(conv_c[3], conv_c[3])
self.layer5_conv_block = nn.Sequential(
conv_block(conv_c[3], conv_c[4]),
conv_block(conv_c[4], conv_c[4])
)
self.layer5_conv_pool_block = conv_pool_block(conv_c[4], conv_c[4])
self.Flatten = nn.Flatten()
self.layer6_fc = nn.Linear(512*l_f_size*l_f_size, 4096)
self.layer7_fc = nn.Linear(4096, 4096)
self.layer8_fc = nn.Linear(4096, class_num)
def forward(self, x):
in_size = x.size(0)
x = self.layer1_conv_block(x)
x = self.layer1_conv_pool_block(x)
x = self.layer2_conv_block(x)
x = self.layer2_conv_pool_block(x)
x = self.layer3_conv_block(x)
x = self.layer3_conv_pool_block(x)
x = self.layer4_conv_block(x)
x = self.layer4_conv_pool_block(x)
x = self.layer5_conv_block(x)
x = self.layer5_conv_pool_block(x)
# 展平
x = self.Flatten(x)
x = self.layer6_fc(x)
x = self.layer7_fc(x)
x = self.layer8_fc(x)
return x
if __name__ == "__main__":
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
a = VGG16(224, 3, 1000).to(device)
from torchsummary import summary
summary(a, input_size=(3, 224, 224)