VGGNet的结构和复现
1 结构以及模型退化问题
上述为VGGNet的结构图,左边是VGG16D的步骤 16代表16层,有参数的层,其他结构也是如此
对于这6个机构来说,D中的VGG16是最优的,而VGG19相比较而言,没有VGG16优,VGG16有16层(包括13个卷积层和3个全连接层),而VGG19有19层(包括16个卷积层和3个全连接层),对于出现了的模型退化问题,有几个原因:
1 网络层次越深,提取的特征越是高度抽象,这可以帮助模型理解复杂的、高级的模式。然而,如果网络过深,最后几层可能会从数据中提取过于抽象的特征,与具体的输入图像的关联性减弱,导致模型性能降低
2 在非常深的网络中,梯度在反向传播过程中可能会因为多层传递而变得非常小(梯度消失)或非常大(梯度爆炸),这会使得网络难以训练
3 更深的网络通常有更多的参数,这可能会使模型更容易发生过拟合,特别是当训练数据有限时
等等一些原因
2 代码复现(6种结构的复现)
只是简单的复现
import torch.nn as nn
import torch
class VggBlock(nn.Module):
def __init__(self, in_channel, out_channel, n, use_11 = False, LRN = False) -> None:
super().__init__()
layers = []
for i in range(n):
if use_11 and (i == n-1):
kernel_size = (1, 1)
padding = 0
else:
kernel_size = (3, 3)
padding = 1
conv = nn.Sequential(
nn.Conv2d(in_channel, out_channel, kernel_size=kernel_size, stride=1, padding=padding),
nn.ReLU()
)
layers.append(conv)
in_channel = out_channel
if LRN == True:
layers.append(nn.LocalResponseNorm(size=5))
layers.append(nn.MaxPool2d(2))
self.block = nn.Sequential(*layers)
def forward(self, x):
return self.block(x)
class VGGNet(nn.Module):
def __init__(self, num_classes, features, classify_input_channel) -> None:
super().__init__()
self.num_classes = num_classes
self.features = features
self.pooling = nn.AdaptiveMaxPool2d(7)
self.classify = nn.Sequential(
nn.Linear(in_features=7 * 7 * classify_input_channel, out_features=4096),
nn.ReLU(),
nn.Linear(in_features=4096, out_features=4096),
nn.ReLU(),
nn.Linear(in_features=4096, out_features=self.num_classes),
)
def forward(self, images):
z = self.features(images)
z = self.pooling(z)
z = z.flatten(1)
return self.classify(z)
class VGGNet11A(nn.Module):
def __init__(self, num_classes) -> None:
super().__init__()
features = nn.Sequential(
VggBlock(3, 64, 1),
VggBlock(64, 128, 1),
VggBlock(128, 256, 2),
VggBlock(256, 512, 2),
VggBlock(512, 512, 2)
)
self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)
def forward(self, images):
return self.vggnet(images)
class VGGNet11ALRN(nn.Module):
def __init__(self, num_classes) -> None:
super().__init__()
features = nn.Sequential(
VggBlock(3, 64, 1, LRN=True),
VggBlock(64, 128, 1),
VggBlock(128, 256, 2),
VggBlock(256, 512, 2),
VggBlock(512, 512, 2)
)
self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)
def forward(self, images):
return self.vggnet(images)
class VGGNet13B(nn.Module):
def __init__(self, num_classes) -> None:
super().__init__()
features = nn.Sequential(
VggBlock(3, 64, 2),
VggBlock(64, 128, 2),
VggBlock(128, 256, 2),
VggBlock(256, 512, 2),
VggBlock(512, 512, 2)
)
self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)
def forward(self, images):
return self.vggnet(images)
class VGGNet16C(nn.Module):
def __init__(self, num_classes) -> None:
super().__init__()
features = nn.Sequential(
VggBlock(3, 64, 2),
VggBlock(64, 128, 2),
VggBlock(128, 256, 3, use_11=True),
VggBlock(256, 512, 3, use_11=True),
VggBlock(512, 512, 3, use_11=True)
)
self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)
def forward(self, images):
return self.vggnet(images)
class VGGNet16C(nn.Module):
def __init__(self, num_classes) -> None:
super().__init__()
features = nn.Sequential(
VggBlock(3, 64, 2),
VggBlock(64, 128, 2),
VggBlock(128, 256, 3),
VggBlock(256, 512, 3),
VggBlock(512, 512, 3)
)
self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)
def forward(self, images):
return self.vggnet(images)
class VGGNet16C(nn.Module):
def __init__(self, num_classes) -> None:
super().__init__()
features = nn.Sequential(
VggBlock(3, 64, 2),
VggBlock(64, 128, 2),
VggBlock(128, 256, 4),
VggBlock(256, 512, 4),
VggBlock(512, 512, 4)
)
self.vggnet = VGGNet(num_classes, features, classify_input_channel=512)
def forward(self, images):
return self.vggnet(images)