在深度學習中,我們可以使用預訓練的模型來進行微調或者遷移學習;
有時候在沒有預訓練模型的情況下,我們也使用pytorch或者tf中預定義的模型;
但是手動實現理解深度學習模型也是非常重要的;
這也就是我們為什么要在這里實現CGG16的深度學習模型;
在本教程中,我們將學習到:
一、VGG11網絡
1)網絡的基本架構;
2)不同的卷積和全連接層;
3)參數的數量
4)實現細節
二、使用Pytorch手動實現VGG11
我們將實現原始論文中的VGG11深度學習神經網絡:
一、VGG11網絡
1)網絡的基本架構;
在論文中,作者不止介紹了一種VGG網絡,而是介紹了一系列的網絡配置;
每個都有不同的網絡結構;
他們在層的數量以及層的配置上略有出入;
接下來,我們主要關注的是VGG11,這里的11代表的是,有11個參數層;其中8層卷積層,3層全連接層;
表1&2 ConvNet 網絡配置及網絡參數
2)不同的卷積和全連接層;
3)參數的數量
VGG11有133 百萬個參數,具體的計算過程如下:
參考鏈接
參數總量: 138357544 138348355
參數內存消耗: 527.7570MB
4)實現細節
由於原論文中沒有包含BN層,所以為了學習,我們將按照論文的方式進行網絡搭建;
下面所有實現的細節都和論文相同;包含了卷積層、最大池化層、激活層(ReLU)以及全連接層;
因此,接下來實現的VGG11將包含:
- 11個權重層(卷積+全連接)
卷積層3*3kernel size 以及步長1,padding1
- 2D的最大池化層;
需要注意的是,不是所有的卷積層后面都跟着最大池化層
- ReLU非線性激活函數
首先來看一下VGG11的架構:
表3 VGG11的基本架構
表4. VGG11的所有層
表4 更加直觀的展示了每層的細節;需要注意的是,Dropout層在原始論文中沒有給出來,但是在原始實現的時候論文也用到了Dropout層
二、使用Pytorch手動實現VGG11
1)導入需要的模塊
1 import torch 2 import torch.nn as nn
2)定義VGG11的模塊類
1 # the VGG11 architecture 2 class VGG11(nn.Module): 3 def __init__(self, in_channels, num_classes=1000): 4 super(VGG11, self).__init__() 5 self.in_channels = in_channels 6 self.num_classes = num_classes 7 # convolutional layers 8 self.conv_layers = nn.Sequential( 9 nn.Conv2d(self.in_channels, 64, kernel_size=3, padding=1), 10 nn.ReLU(), 11 nn.MaxPool2d(kernel_size=2, stride=2), 12 nn.Conv2d(64, 128, kernel_size=3, padding=1), 13 nn.ReLU(), 14 nn.MaxPool2d(kernel_size=2, stride=2), 15 nn.Conv2d(128, 256, kernel_size=3, padding=1), 16 nn.ReLU(), 17 nn.Conv2d(256, 256, kernel_size=3, padding=1), 18 nn.ReLU(), 19 nn.MaxPool2d(kernel_size=2, stride=2), 20 nn.Conv2d(256, 512, kernel_size=3, padding=1), 21 nn.ReLU(), 22 nn.Conv2d(512, 512, kernel_size=3, padding=1), 23 nn.ReLU(), 24 nn.MaxPool2d(kernel_size=2, stride=2), 25 nn.Conv2d(512, 512, kernel_size=3, padding=1), 26 nn.ReLU(), 27 nn.Conv2d(512, 512, kernel_size=3, padding=1), 28 nn.ReLU(), 29 nn.MaxPool2d(kernel_size=2, stride=2) 30 ) 31 # fully connected linear layers 32 self.linear_layers = nn.Sequential( 33 nn.Linear(in_features=512*7*7, out_features=4096), 34 nn.ReLU(), 35 nn.Dropout2d(0.5), 36 nn.Linear(in_features=4096, out_features=4096), 37 nn.ReLU(), 38 nn.Dropout2d(0.5), 39 nn.Linear(in_features=4096, out_features=self.num_classes) 40 ) 41 def forward(self, x): 42 x = self.conv_layers(x) 43 # flatten to prepare for the fully connected layers 44 x = x.view(x.size(0), -1) 45 x = self.linear_layers(x) 46 return x
如你所見,VGG11包含了pytorch中常見的方法:__init__()方法和forward()方法
下面我們將解釋這些方法的細節:
__init__() 方法
- 接受 In_channels和num_classes兩個參數;(通道數和分類數量)
- 從11行開始,我們有整個的卷積層定義。使用Sequential類(來自於torch.nn)使得我們可以正確的堆疊這些層;
- 第一個Conv2d()層具有in_channels和self.in_channels;輸出層具有64層;kenel的大小是3,並且padding是1;
- 在2D最大池化后使用ReLU激活函數;
- 之后增加輸出通道的層數,直至達到512層;
- 需要注意的一點:不是所有的卷積層都有最大池化層;
- 最終的卷積層具有512個輸出通道,並且后面接ReLU激活函數和最大池化;
在全連接層,定義self.linear_layers,使用序列模塊定義所有的全連接線性層;
- 對所有的VGG架構來說,全連接部分都是一樣的;
forward()方法
- 在47行,定義卷積操作,輸出特征圖;
- 在49行,展平特征圖,最后輸入線性層;
- 最后得到softmax輸出
三、檢查VGG11實現的正確性
- 參數的檢查,最終的參數應該是132,863,336;
- 檢查最終的輸出;
1 if __name__ == '__main__': 2 # initialize the VGG model for RGB images with 3 channels 3 vgg11 = VGG11(in_channels=3) 4 # total parameters in the model 5 total_params = sum(p.numel() for p in vgg11.parameters()) 6 print(f"[INFO]: {total_params:,} total parameters.") 7 8 # forward pass check 9 # a dummy (random) input tensor to feed into the VGG11 model 10 image_tensor = torch.randn(1, 3, 224, 224) # a single image batch 11 outputs = vgg11(image_tensor) 12 print(outputs.shape)
最后的輸出:
1 [INFO]: 132,863,336 total parameters. 2 torch.Size([1, 1000])
最后檢查通過以后可以在CUDA()上運行。
四、總結和結論
本文主要研究了如何搭建一個VGG11基本框架,后續將會研究如何訓練VGG,如何實現VGG整個架構;