第1层: 3x3x3x64, 步长为1, padding=1
第2层: 3x3x64x64, 步长为1, padding=1
第3层: 3x3x64x128, 步长为1, padding=1
第4层: 3x3x128x128, 步长为1, padding=1
第5层: 3x3x128x256, 步长为1, padding=1
第6层: 3x3x256x256, 步长为1, padding=1
第7层: 3x3x256x256, 步长为1, padding=1
第8层: 3x3x256x512, 步长为1, padding=1
第9层: 3x3x512x512, 步长为1, padding=1
第10层:3x3x512x512, 步长为1, padding=1
第11层: 3x3x512x512, 步长为1, padding=1
第12层: 3x3x512x512, 步长为1, padding=1
第13层:3x3x512x512, 步长为1, padding=1
第14层: 512*7*7, 4096的全连接操作
第15层: 4096, 4096的全连接操作
第16层: 4096, num_classes 的 全连接操作
代码如下,特征图维度的计算,加上备注了
import torch
from torch import nn
class VGG(nn.Module):
def __init__(self, num_classes):
super(VGG, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=3, padding=1), #输入是3*224*224,输出是64*224*224,(224+1*2-3)/1+1=224
nn.ReLU(True),
nn.Conv2d(64, 64, kernel_size=3, padding=1), #输入是64*224*224,输出是64*224*224,(224+1*2-3)/1+1=224
nn.ReLU(True),
nn.MaxPool2d(kernel_size=2, stride=2), #输入是64*224*224,输出是64*112*112,(224-2)/2+1*2=112
nn.Conv2d(64, 128, kernel_size=3, padding=1), #输入是64*112*112,输出是128*112*112 ,(112+1*2-3)/1 +1=112
nn.ReLU(True),
nn.Conv2d(128, 128, kernel_size=3, padding=1), #输入是128*112*112,输出是128*112*112 ,(110-3)/1 +1=112
nn.ReLU(True),
nn.MaxPool2d(kernel_size=2, stride=2), #输入是128*112*112,输出是128*56*56 ,(112-2)/2 +1=56
nn.Conv2d(128, 256, kernel_size=3, padding=1), #输入是128*56*56,输出是256*56*56 ,(54-3)/1 +1=56
nn.ReLU(True),
nn.Conv2d(256, 256, kernel_size=3, padding=1), #输入是256*56*56,输出是256*56*56 ,(51-3)/1 +1=56
nn.ReLU(True),
nn.Conv2d(256, 256, kernel_size=3, padding=1), #输入是256*56*56,输出是256*56*56 ,(50-3)/1 +1=56
nn.ReLU(True),
nn.MaxPool2d(kernel_size=2, stride=2), #输入是256*56*56,输出是256*28*28 ,(56-2)/2 +1=28
nn.Conv2d(256, 512, kernel_size=3, padding=1), #输入是256*28*28,输出是512*28*28 ,(24-3)/1 +1=28
nn.ReLU(True),
nn.Conv2d(512, 512, kernel_size=3, padding=1), #输入是512*28*28,输出是512*28*28 ,(22-3)/1 +1=28
nn.ReLU(True),
nn.Conv2d(512, 512, kernel_size=3, padding=1), #输入是512*28*28,输出是512*28*28 ,(20-3)/1 +1=28
nn.ReLU(True),
nn.MaxPool2d(kernel_size=2, stride=2), #输入是512*28*28,输出是512*14*14 ,(28-2)/2 +1=14
nn.Conv2d(512, 512, kernel_size=3, padding=1), #输入是512*14*14,输出是512*14*14 ,(9-3)/1 +1=14
nn.ReLU(True),
nn.Conv2d(512, 512, kernel_size=3, padding=1), #输入是512*14*14,输出是512*14*14 ,(7-3)/1 +1=14
nn.ReLU(True),
nn.Conv2d(512, 512, kernel_size=3, padding=1), #输入是512*14*14,输出是512*14*14 ,(5-3)/1 +1=14
nn.ReLU(True),
nn.MaxPool2d(kernel_size=2, stride=2),) #输入是512*14*14,输出是512*7*7 ,(14-2)/2 +1=7
self.classifier = nn.Sequential(
nn.Linear(512*7*7, 4096), #输入是512*7*7,输出是1*1*4096
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, 4096), #输如为1*1*4096,输出为1*1*4096
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, num_classes) #输入为1*1*4096,输出为1*1*1000
)
def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
if __name__ =='__main__':
# model = torchvision.models.AlexNet()
model = VGG(10)
# print(model)
input = torch.randn(8,3,224,224) #输入的是224*224的3通道图片,8的话指的是有8张图片
# print(input)
out = model(input)
print(input.shape)
print(out.shape)