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 torchclass 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 = 1conv = nn.Sequential(nn.Conv2d(in_channel, out_channel, kernel_size=kernel_size, stride=1, padding=padding),nn.ReLU())layers.append(conv)in_channel = out_channelif 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_classesself.features = featuresself.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)