关于VGGNet网络结构浅谈(主要是VGG16结构)
文章目錄
- 1.首先看一下論文中一張表:
- 2.VGG16網絡結構解釋:
- 3.網絡構成詳解:
- 4.VGG16使用的卷積核大小都是3x3的,使用比之前小的卷積核有什么作用:
- 5.Tensorflow2.6.0實現VGG16網絡結構:
 
1.首先看一下論文中一張表:
 注解:
 (1)可以看到表中從左->右網絡結構逐漸變得更深和復雜;層數從11->11->13->16->16->19;
 (2)所有的激活函數使用的都是ReLU函數;
 (3)層與層之間的間隔使用Max Pool(最大池化);
 (4)使用的卷積核大小都是3*3的卷積,通道數逐漸增加(因為寬和高在變小,所以通道數增加對特征的保留更好);
 (5)根據卷積層來設計其中子層的數量;
 (6)最后接的都是全連接層,神經元為4096->4096->1000,最后使用softmax函數輸出1000類別概率;
VGG16之特征提取和網絡參數的查看(偏置和權重):
 https://mydreamambitious.blog.csdn.net/article/details/123928764(其中包含了詳細的網絡結構)
2.VGG16網絡結構解釋:
以下兩幅圖都是VGG16結構:
 
 
 圖片來源:
 https://blog.csdn.net/xiaobumi123/article/details/105550967
 https://blog.csdn.net/qq_37939213/article/details/90380639
 注解:
 (1)VGG16包含16個層,其中第一個卷積層是由:2個conv3-64組成,后接一個maxpool層;
 (2)第二層由兩個:conv3-128組成,后接一個maxpool層;
 (3)第三層由三個:conv3-256組成,后接一個maxpool層;
 (4)第四層由三個:conv3-512組成,后接一個maxpool層;
 (5)第五層由三個:conv3-512組成,后接一個maxpool層;
 (6)最后是三個全連接層:其中包含兩個FC4096和一個FC1000(類別數)。
 所以這就是VGG16名字的由來。
3.網絡構成詳解:
首先是輸入層:2242443
 (一)第一層:
 
注解:
 (1)首先輸入圖片大小為224x224x3(這個可以通過成剪裁實現);
(2)輸入圖片時候使用64個3x3(kernel_size)的卷積核大小進行卷積,得到的特征圖大小為224x224x64。
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(224+21-3)/1+1=224.所以最后得到的特征圖大小為224x224x64.
 甚至我們的高寬步長可以不用設置一樣,當然這里需要一樣。
 (3)使用激活函數ReLU進非線性變換。
 (4)再進行卷積:
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(224+21-3)/1+1=224.所以最后得到的特征圖大小為224x224x64.
 (5)再進行激活:ReLU
 (6)最后就是最大池化:
 使用大小為2x2,步長為strides=2的池化單元進行最大池化。input_size+2padding-kernel_size)/strides+1=(224+20-2)/2+1=112.
 輸出的特征圖大小為:112x112x64.
(二):輸入特征圖大小112x112x64:
 
(1)輸入圖片時候使用128個3x3(kernel_size)的卷積核大小進行卷積,得到的特征圖大小為112x112x128。
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(112+21-3)/1+1=112.所以最后得到的特征圖大小為112x112x128.
 甚至我們的高寬步長可以不用設置一樣,當然這里需要一樣。
 (2)使用激活函數ReLU進非線性變換。
 (3)再進行卷積:
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(112+21-3)/1+1=112.所以最后得到的特征圖大小為112x112x128.
 (4)再進行激活:ReLU
 (5)最后就是最大池化:
 使用大小為2x2,步長為strides=2的池化單元進行最大池化。input_size+2padding-kernel_size)/strides+1=(112+20-2)/2+1=56.
 輸出的特征圖大小為:56x56x256.
(三):輸入特征圖大小為:56x56x256
 
 (1)輸入圖片時候使用256個3x3(kernel_size)的卷積核大小進行卷積,得到的特征圖大小為56x56x256。
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(56+21-3)/1+1=56.所以最后得到的特征圖大小為56x56x256.
 甚至我們的高寬步長可以不用設置一樣,當然這里需要一樣。
 (2)使用激活函數ReLU進非線性變換。
 (3)再進行卷積:
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(56+21-3)/1+1=56.所以最后得到的特征圖大小為56x56x256.
 (4)再進行激活:ReLU
 (5)再進行卷積:
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(56+21-3)/1+1=56.所以最后得到的特征圖大小為56x56x256.
 (6)再進行激活:ReLU
 (7)最后就是最大池化:
 使用大小為2x2,步長為strides=2的池化單元進行最大池化。input_size+2padding-kernel_size)/strides+1=(56+20-2)/2+1=28.
 輸出的特征圖大小為:28x28x256.
(四):輸入的特征圖大小為:28x28x256
 
 (1)輸入圖片時候使用512個3x3(kernel_size)的卷積核大小進行卷積,得到的特征圖大小為28x28x512。
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(28+21-3)/1+1=28.所以最后得到的特征圖大小為28x28x512.
 甚至我們的高寬步長可以不用設置一樣,當然這里需要一樣。
 (2)使用激活函數ReLU進非線性變換。
 (3)再進行卷積:
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(28+21-3)/1+1=28.所以最后得到的特征圖大小為28x28x512.
 (4)再進行激活:ReLU
 (5)再進行卷積:
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(28+21-3)/1+1=28.所以最后得到的特征圖大小為28x28x512.
 (6)再進行激活:ReLU
 (7)最后就是最大池化:
 使用大小為2x2,步長為strides=2的池化單元進行最大池化。input_size+2padding-kernel_size)/strides+1=(28+20-2)/2+1=14.
 輸出的特征圖大小為:14x14x512.
(五):輸入的特征圖大小為:14x14x512
 
 (1)輸入圖片時候使用512個3x3(kernel_size)的卷積核大小進行卷積,得到的特征圖大小為14x14x512。
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(14+21-3)/1+1=14.所以最后得到的特征圖大小為14x14x512.
 甚至我們的高寬步長可以不用設置一樣,當然這里需要一樣。
 (2)使用激活函數ReLU進非線性變換。
 (3)再進行卷積:
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(14+21-3)/1+1=14.所以最后得到的特征圖大小為14x14x512.
 (4)再進行激活:ReLU
 (5)再進行卷積:
 填充:padding=1(padding=‘same’);步長:strides=[1,1]
 計算公式:(input_size+2padding-kernel_size)/strides+1=(14+21-3)/1+1=14.所以最后得到的特征圖大小為14x14x512.
 (6)再進行激活:ReLU
 (7)最后就是最大池化:
 使用大小為2x2,步長為strides=2的池化單元進行最大池化。input_size+2padding-kernel_size)/strides+1=(14+20-2)/2+1=7.
 輸出的特征圖大小為:7x7x512.
(六):全連接層(輸入的特征圖大小為7x7x512):
 
 (1)改用為4096個神經元,首先經過Dense層;
 (2)經過激活函數ReLU層;
 (3)使用Dropout:防止過擬合,隨機的斷開其中的一些連接(只是邏輯上斷開)。
(七)全連接層:
 
(1)改用為4096個神經元,首先經過Dense層;
 (2)經過激活函數ReLU層;
 (3)使用Dropout:防止過擬合,隨機的斷開其中的一些連接(只是邏輯上斷開)。
(八)最后一層全連接層:
 (1)改用為1000個神經元,首先經過Dense層;
(九)最后經過softmax層:
 
 輸出1000個類別概率值:
4.VGG16使用的卷積核大小都是3x3的,使用比之前小的卷積核有什么作用:
請看我這篇文章:
 https://mydreamambitious.blog.csdn.net/article/details/123027344
 其中有一點就是增大感受野:兩個3x3的卷積核可以替代一個5x5的卷積核;三個3x3的卷積核可以替代一個7x7的卷積核
 
 注解:其中VGG16的參數量是非常大的,其中主要的參數都集中在了全連接層:
 如果去掉全連接層的話,參數量為:
 
 參數近相差十倍。
5.Tensorflow2.6.0實現VGG16網絡結構:
import os import keras from tensorflow.keras import layers#但是在這里我添加了BatchNormalization model_vgg16=keras.Sequential([#網絡的輸入layers.InputLayer(input_shape=(224,224,3)),layers.Conv2D(64,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(64,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.MaxPool2D(pool_size=[2,2]),layers.Conv2D(128,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(128,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.MaxPool2D(pool_size=[2,2]),layers.Conv2D(256,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(256,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(256,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.MaxPool2D(pool_size=[2,2]),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.MaxPool2D(pool_size=[2, 2]),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.MaxPool2D(pool_size=[2, 2]),#這里也可以使用全局平均池化layers.GlobalAveragePooling2D(),# layers.Flatten(),layers.Dense(4096),layers.Activation('relu'),layers.BatchNormalization(),layers.Dropout(0.5),layers.Dense(4096),layers.Activation('relu'),layers.BatchNormalization(),layers.Dropout(0.5),layers.Dense(1000),layers.Activation('softmax'), ]) #輸出網絡的結構 # model_vgg16.summary()
 
 
 
 
總結
以上是生活随笔為你收集整理的关于VGGNet网络结构浅谈(主要是VGG16结构)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 计算机控制技术第二版答案于微波,微波技术
- 下一篇: 遥感图像分类
