VGG代码解读
VGG代碼解讀
目錄
- VGG代碼解讀
 
- 概述
- 網絡結構圖
- VGG代碼細節分析
概述
VGG跟AlexNet在結構上沒有本質上的區別,在AlexNet的基礎上變得更深了,依然是“直通”式的結構,提出了局部響應結構(LRN),效果改善很小。整體上的架構仍然是卷積、激活、池化提取特征,然后前向神經網絡做分類器。
網絡結構圖
vgg_A、vgg_B、vgg_C、vgg_D、vgg_E分別對應不同的vgg結構變種,其中LRN(local response network)是局部響應網絡,實驗結果表明加上LRN的效果沒有明顯改善,因此pytorch官方的代碼里面沒有給出LRN的實現。
 
VGG代碼細節分析
import numpy as np import torch.nn as nn from .utils import load_state_dict_from_url from typing import Union,List,Dict,Any,cast # 不同的vgg結構變種 __all__ = ['VGG', 'vgg11', 'vgg11_bn', 'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn','vgg19_bn', 'vgg19', ] # vgg預訓練模型的下載地址 model_urls = {'vgg11': 'https://download.pytorch.org/models/vgg11-bbd30ac9.pth','vgg13': 'https://download.pytorch.org/models/vgg13-c768596a.pth','vgg16': 'https://download.pytorch.org/models/vgg16-397923af.pth','vgg19': 'https://download.pytorch.org/models/vgg19-dcbb9e9d.pth','vgg11_bn': 'https://download.pytorch.org/models/vgg11_bn-6002323d.pth','vgg13_bn': 'https://download.pytorch.org/models/vgg13_bn-abd245e5.pth','vgg16_bn': 'https://download.pytorch.org/models/vgg16_bn-6c64b313.pth','vgg19_bn': 'https://download.pytorch.org/models/vgg19_bn-c79401a0.pth', }class VGG(nn.Module):def __init__(self,features:nn.Modules,num_classes:int = 1000,init_weights:bool = True,)->None:super(VGG,self).__init__()self.features = featuresself.avgpool = nn.AdaptiveAvgPool2d((7,7))# 分類器(前面的卷積層已經全部寫好,提取出特征了)self.classifier = nn.Sequential(nn.Linear(512*7*7,4096),nn.RuLU(True),nn.Dropout(),nn.Linear(4096,4096),nn.RuLU(True),nn.Dropout(),nn.Linear(4096,num_classes),)if init_weights:self._initialize_weights()def forward(self,x:torch.Tensor)->torch.Tensor:# pipeline:提取特征、池化、攤平、分類x = self.features(x)x = self.avgpool(x)# 把x維度進行調整,保持batch數一致,[batch_size,一個展開后的特征層]# 下面這個語句也可以寫成 x = x.view(x.size(0),-1)x = self.flatten(x,1)x = self.classifier(x)return x# 參數初始化方法def _initialize_weights(self)->None:for m in self.modules():# 卷積層的參數初始化方法用kaiming_normalif isinstance(m,nn.Conv2d):nn.init.kaiming_normal_(m.weight,mode = 'fan_out', nonlinearity='relu')# 卷積層的bias全部初始化常數0,也就是不加偏置if m.bias is not None:nn.init.constant(m.bias,0)# batch_normalization的權重初始化成常數1,偏置初始化成常數0elif isinstance(m,nn.BatchNorm2d):nn.init.constant_(m.weight,1)nn.init.constant_(m.bias,0)# 前向網絡的權重初始化成均值為0,方差為0.01的隨機weights,偏置初始化成常數1elif isinstance(m,nn.Linear):# nn.init.constant_(x,mean = mean, std = std)表示將x初始化成期望為0,方差為0.01的隨機數nn.init.constant_(m.weight,0,0.01)nn.init.constant_(m.bias,1)elif isinstance(m,nn.Linear):nn.init.normal_(m.weight,0,0.01)nn.init.constant_(m.bias,0) # layers是一個列表,存儲了神經網絡的結構 # nn.ReLU(inplace = True)類似于C語言的地址傳遞,會改變輸入的值,節省內存 # 默認nn.ReLU(inplace = False),這相當于C語言的值傳遞,不會改變輸入的值 def make_layers(cfg:List[Union[str,int],batch_norm:bool = False])->nn.Sequential:layers: List[nn.Module] = []in_channels = 3for v in cfg:# M代表最大池化if v=='M':layers+=[nn.MaxPool2d(kernel_size = 2, stride=2)]elsev = cast(int,v)# 添加卷積層conv2d = nn.Conv2d(in_channels,v,kernel_size = 3,padding = 1)# 如果有batch normalization那就加上BN層if batch_norm:layers+=[conv2d,nn.BatchNorm2d(v),nn.ReLU(inplace=True)]# 否則直接卷積+激活輸出else:layers+=[conv2d,nn.ReLU(inplace=True)]# 將當前層卷積核的大小當做下一層網絡的輸入channel大小in_channels = v# 返回network的網絡結構return nn.Sequential(*layers)# 'M'代表最大池化 # cfgs的'A'、'B'、'D'、'E'對應不同的網絡結構,網絡結構圖參考鏈接 # https://blog.csdn.net/qq_39777550/article/details/104870919 cfgs: Dict[str, List[Union[str, int]]] = {'A': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],'B': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],'D': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],'E': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'], }# torch.hub.load_state_dict_from_url(url, model_dir=None, map_location=None, # progress=True, check_hash=False, file_name=None) # load_state_dict_from_url當中progress這個參數默認是True,用來顯示下載進度條 # progress (bool, optional) – whether or not to display a progress bar to stderr Default: Truedef _vgg(arch:str,cfg:str,batch_norm:bool,pretrained:bool,process:bool,**kwargs)->VGG:if pretrained:# 如果調用預訓練模型,那么就不用初始化參數了,直接用寫好的模型參數即可kwargs['init_weights'] = Falsemodel = VGG(make_layers(cfg[cfg],batch_norm = batch_norm),**kwargs)if pretrained:# 下載預訓練模型state_dict = load_state_dict_from_url(model_urls[arch],process = process)# 加載預訓練模型model.load_state_dict(state_dict)return model # 不同的vgg模型對應不同的網絡結構(不同網絡深度) def vgg11(pretrained:bool = False,process:bool = True, **kwargs:Any)->VGG:return _vgg('vgg11','A',False,pretrained,process,**kwargs)def vgg11_bn(pretrained: bool = False, progress: bool = True, **kwargs: Any) -> VGG:r"""VGG 11-layer model (configuration "A") with batch normalization`"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`._Args:pretrained (bool): If True, returns a model pre-trained on ImageNetprogress (bool): If True, displays a progress bar of the download to stderr"""return _vgg('vgg11_bn', 'A', True, pretrained, progress, **kwargs)def vgg13(pretrained: bool = False, progress: bool = True, **kwargs: Any) -> VGG:r"""VGG 13-layer model (configuration "B")`"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`._Args:pretrained (bool): If True, returns a model pre-trained on ImageNetprogress (bool): If True, displays a progress bar of the download to stderr"""return _vgg('vgg13', 'B', False, pretrained, progress, **kwargs)def vgg13_bn(pretrained: bool = False, progress: bool = True, **kwargs: Any) -> VGG:r"""VGG 13-layer model (configuration "B") with batch normalization`"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`._Args:pretrained (bool): If True, returns a model pre-trained on ImageNetprogress (bool): If True, displays a progress bar of the download to stderr"""return _vgg('vgg13_bn', 'B', True, pretrained, progress, **kwargs)def vgg16(pretrained: bool = False, progress: bool = True, **kwargs: Any) -> VGG:r"""VGG 16-layer model (configuration "D")`"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`._Args:pretrained (bool): If True, returns a model pre-trained on ImageNetprogress (bool): If True, displays a progress bar of the download to stderr"""return _vgg('vgg16', 'D', False, pretrained, progress, **kwargs)def vgg16_bn(pretrained: bool = False, progress: bool = True, **kwargs: Any) -> VGG:r"""VGG 16-layer model (configuration "D") with batch normalization`"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`._Args:pretrained (bool): If True, returns a model pre-trained on ImageNetprogress (bool): If True, displays a progress bar of the download to stderr"""return _vgg('vgg16_bn', 'D', True, pretrained, progress, **kwargs)def vgg19(pretrained: bool = False, progress: bool = True, **kwargs: Any) -> VGG:r"""VGG 19-layer model (configuration "E")`"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`._Args:pretrained (bool): If True, returns a model pre-trained on ImageNetprogress (bool): If True, displays a progress bar of the download to stderr"""return _vgg('vgg19', 'E', False, pretrained, progress, **kwargs)# 加上了batch_normalization的vgg網絡 def vgg19_bn(pretrained: bool = False, progress: bool = True, **kwargs: Any) -> VGG:r"""VGG 19-layer model (configuration 'E') with batch normalization`"Very Deep Convolutional Networks For Large-Scale Image Recognition" <https://arxiv.org/pdf/1409.1556.pdf>`._Args:pretrained (bool): If True, returns a model pre-trained on ImageNetprogress (bool): If True, displays a progress bar of the download to stderr"""return _vgg('vgg19_bn', 'E', True, pretrained, progress, **kwargs)總結
 
                            
                        - 上一篇: 最简易上手的Numpy学习笔记一
- 下一篇: iMeta:高颜值高被引绘图网站imag
