GoogleNet系列網絡原理及結構詳解:從Inception-v1到v4
- 1. Google Net綜述
- 2. Inception v1
- 3. Inception v2
- 4. Inception v3
- 5. Inception v4
- 5.1 論文地址
- 5.2 網絡結構
- 5.2.1 Inception-resnet-v1
- 5.2.1.1 stem前饋網絡
- 5.2.1.2 Inception-resnet-A結構
- 5.2.1.3 Inception-resnet-B結構
- 5.2.1.4 Inception-resnet-C結構
- 5.2.1.5 Reduction-A/B結構
- 5.2.2 Inception-resnet-v2
- 5.2.2.1 stem前饋網絡
- 5.2.2.2 Inception-resnet-A結構
- 5.2.2.3 Inception-resnet-B結構
- 5.2.2.4 Inception-resnet-C結構
- 5.2.2.5 Reduction-A/B結構
- 5.2.3 Inception v4
- 5.3 核心思想
- 5.4 性能比較
- 5.5 試驗結果
- 6. 總結
- 7. 這一期到這裏就結束啦,大佬們的鼓勵就是我更新最大的動力,歡迎點贊關注哦~
1. Google Net綜述
Google Net是2014年Google團隊在ImageNet比賽上提出的網絡,獲得了識別第一名、檢測第二名的成績;
其主要特點就是提出了一種叫做Inception的結構進行堆疊;
這種結構的主要特點就是加大了網絡的深度和寬度(主要是寬度),將不同感受野大小的特徵層進行堆疊,並且不增加運算量,提高了計算資源的利用效率。
相比於兩年前ImageNet比賽的冠軍(也是卷積神經網絡的開山之作),參數少了12倍,而top-5損失率卻從16.42%下降到了6.67%。
2. Inception v1
2.1 論文地址
https://arxiv.org/pdf/1409.4842.pdf
2.2 網絡結構
Inception v1的網絡結構如圖所示:
圖(a)是作者提出的一個基本的Inception v1網絡結構,其基本思想就是,對一個特徵層分別使用不同大小卷積核進行卷積操作(包括1x1、3x3、5x5卷積層,和一個3x3的最大池化層),從而獲得了不同感受野大小的特徵層;最後通過一個concat堆疊,就得到了Inception v1的輸出特徵層;
圖(b)是作者又提出的改進結構,改進的原因是由於Inception v1的輸入層可能是上一個Inception v1經
過concat的輸出層,深度會非常大,這樣的話即使是少量的5x5的卷積操作也會導致計算量大幅增加;
因此在3x3、5x5卷積前加入了1x1卷積進行降維操作;即通過1x1卷積,在不改變特徵層感受野大小的情況下,減小特徵層的深度從而減少計算;並且1x1卷積後接上RELU激活也能夠在一定程度上增加網絡的非線性特性;
2.3 實驗結果
其中:
(1)Number-of-models 是融合模型的數目;
(2)Number-of-Crops 是每張檢測圖片裁剪區域的數目;
(3)Cost 是隻檢測一張圖片的計算花銷(模型數目x裁剪區域數目);
可以看到模型越多、取樣越多,準確率就越高,但相應地計算開銷就會越大。
2.4 代碼實現
import tensorflow as tf
slim = tf.contrib.slim
def Incvption_v1_net(inputs, scope):
with tf.variable_scope(scope):
with slim.arg_scope([slim.conv2d],
activation_fn=tf.nn.relu, padding='SAME',
weights_regularizer=slim.l2_regularizer(5e-3)):
net = slim.max_pool2d(
inputs, [3, 3], strides=2, padding='SAME', scope='max_pool')
net_a = slim.conv2d(net, 64, [1, 1], scope='conv2d_a_1x1')
net_b = slim.conv2d(net, 96, [1, 1], scope='conv2d_b_1x1')
net_b = slim.conv2d(net_b, 128, [3, 3], scope='conv2d_b_3x3')
net_c = slim.conv2d(net, 16, [1, 1], scope='conv2d_c_1x1')
net_c = slim.conv2d(net_c, 32, [5, 5], scope='conv2d_c_5x5')
net_d = slim.max_pool2d(
net, [3, 3], strides=1, scope='pool3x3', padding='SAME')
net_d = slim.conv2d(
net_d, 32, [1, 1], scope='conv2d_d_1x1')
net = tf.concat([net_a, net_b, net_c, net_d], axis=-1)
return net
3. Inception v2
3.1 論文地址
https://arxiv.org/pdf/1502.03167.pdf
3.2 網絡結構
Inception v2 並沒有在結構上作出太大改變,但是首次提出了使用Batch Normalization ,即將一個batch的數據變換到均值爲0、方差爲1的正太分佈上,從而使數據分佈一致,每層的梯度不會隨着網絡結構的加深發生太大變化,從而避免發生梯度消失。
3.3 計算公式
輸入的是一個batch的圖片(或者特徵層),格式爲NHWC;
計算過程:
(1)計算數據的均值u;
(2)計算數據的方差σ^2;
(3)通過公式 x’=(x-u)/√(σ^2+ε)標準化數據;
(4)通過公式 y=γx’+β 進行縮放平移;
注:
(1)ε 是一個較小正數值,防止除零;
(2)其中γ和β是可訓練參數;
(3)使用batch normalization時,全鏈接層可以不必加上bias,因爲這時β就相當於加上了一個偏置值;
(4)輸入測試數據時,u和σ取的是全部train_data的均值和標準差;
3.4 實驗結果
可以看到使用batch-normalization之後,Top-5 Error 從6.67%下降到了4.9%。
3.5 代碼實現
import tensorflow as tf
slim = tf.contrib.slim
def Incvption_v1_net(inputs, scope):
with tf.variable_scope(scope):
with slim.arg_scope([slim.conv2d],
activation_fn=tf.nn.relu, padding='SAME',
weights_regularizer=slim.l2_regularizer(5e-3)):
net = slim.max_pool2d(
inputs, [3, 3], strides=2, padding='SAME', scope='max_pool')
net_a = slim.conv2d(net, 64, [1, 1], scope='conv2d_a_1x1')
net_b = slim.conv2d(net, 96, [1, 1], scope='conv2d_b_1x1')
net_b = slim.conv2d(net_b, 128, [3, 3], scope='conv2d_b_3x3')
net_c = slim.conv2d(net, 16, [1, 1], scope='conv2d_c_1x1')
net_c = slim.conv2d(net_c, 32, [5, 5], scope='conv2d_c_5x5')
net_d = slim.max_pool2d(
net, [3, 3], strides=1, scope='pool3x3', padding='SAME')
net_d = slim.conv2d(
net_d, 32, [1, 1], scope='conv2d_d_1x1')
net = tf.concat([net_a, net_b, net_c, net_d], axis=-1)
net = tf.layers.batch_normalization(net, name='BN')
return net
4. Inception v3
4.1 論文地址
https://arxiv.org/pdf/1512.00567.pdf
4.2 網絡結構
圖(Figure 5)是一作者的基本思路,即一個5x5大小的卷積層和兩個3x3大小的卷積層得到的特徵層的感受野大小是相同的,都是5(如圖);
但是如果使用兩個3x3卷積核代替5x5的卷積核,能夠有效減小參數量;比如對於同樣的深度C,一個5x5卷積核的參數量是 5^2 x C,而兩個3x3卷積核的參數量是 2 x 3^2 x C;
圖(Figure 7)在這個思想的基礎上,作者又提出了分別使用一個nx1卷積層和一個1xn卷積層,來代替nxn的卷積層,就得到了我們最終的Inception v3的結構;
4.3 補充
在整體架構方面,作者還提出了減小特徵層大小、增加深度(通道數)的策略:
4.4 實驗結果
可以看到相比於Inception v2的4.9%,Inception v3的 Top-5 Error 已經下降到了3.58%。
4.5 代碼實現
import tensorflow as tf
slim = tf.contrib.slim
def Incvption_v1_net(inputs, scope):
with tf.variable_scope(scope):
with slim.arg_scope([slim.conv2d],
activation_fn=tf.nn.relu, padding='SAME',
weights_regularizer=slim.l2_regularizer(5e-3)):
net = slim.max_pool2d(
inputs, [3, 3], strides=2, padding='SAME', scope='max_pool')
net_a = slim.conv2d(net, 64, [1, 1], scope='conv2d_a_1x1')
net_b = slim.conv2d(net, 96, [1, 1], scope='conv2d_b_1x1')
net_b_1 = slim.conv2d(net_b, 128, [1, 3], scope='conv2d_b_1x3')
net_b_2 = slim.conv2d(net_b, 128, [3, 1], scope='conv2d_b_3x1')
net_c = slim.conv2d(net, 16, [1, 1], scope='conv2d_c_1x1')
net_c = slim.conv2d(net_c, 32, [3, 3], scope='conv2d_c_3x3')
net_c_1 = slim.conv2d(net_c, 32, [1, 3], scope='conv2d_c_1x3')
net_c_2 = slim.conv2d(net_c, 32, [3, 1], scope='conv2d_c_3x1')
net_d = slim.max_pool2d(
net, [3, 3], strides=1, scope='pool3x3', padding='SAME')
net_d = slim.conv2d(
net_d, 32, [1, 1], scope='conv2d_d_1x1')
net = tf.concat(
[net_a, net_b_1, net_b_2, net_c_1, net_c_2, net_d], axis=-1)
net = tf.layers.batch_normalization(net, name='BN')
return net
5. Inception v4
5.1 論文地址
https://arxiv.org/pdf/1602.07261.pdf
5.2 網絡結構
作者基於ResNet的殘差和思想,在Inception v3的基礎上提出了Inception-resnet-v1和Inception-resnet-v2,並修改了Inception v3,提出了Inception v4的結構;
5.2.1 Inception-resnet-v1
從下到上依次爲:
(1)input:輸入圖片;
(2)stem:前饋網絡;
(3)5個Inception-resnet-A結構;
(4)Reduction-A結構;
(5)10個Inception-resnet-B結構;
(6)Reduction-B結構;
(7)5個Inception-resnet-C結構;
(8)平均池化層;
(9)Dropout層;
(10)Softmax;
其中,reduction用於縮小特徵層;
5.2.1.1 stem前饋網絡
5.2.1.2 Inception-resnet-A結構
5.2.1.3 Inception-resnet-B結構
5.2.1.4 Inception-resnet-C結構
5.2.1.5 Reduction-A/B結構
5.2.2 Inception-resnet-v2
5.2.2.1 stem前饋網絡
5.2.2.2 Inception-resnet-A結構
5.2.2.3 Inception-resnet-B結構
5.2.2.4 Inception-resnet-C結構
5.2.2.5 Reduction-A/B結構
5.2.3 Inception v4
5.2.3.1 stem前饋網絡
(與Inception-resnet-v2相同)
5.2.3.2 Inception-A結構
5.2.3.3 Inception-B結構
5.2.3.4 Inception-C結構
5.2.3.5 Reduction-A結構
5.2.3.6 Reduction-B結構
5.3 核心思想
這裏作者借鑑了ResNet提出的思想:假設本來要學習的函數爲H(x),現在轉換爲F(x)+x,這樣雖然效果相同,但是由於進行反向傳播時x項導數始終爲1,有效避免了梯度消失問題。
5.4 性能比較
- 相比於Inception v3,Inception-resnet-v1由於使用了殘差單元,訓練速度更快,但是測試準確率比Inception v3更快;
- 相比於Inception v4,Inception-resnet-v2訓練速度快、準確率高;
5.5 試驗結果
可以看到這時Top-5 Error已經下降到了3.1%。
6. 總結
AlexNet、VGG等結構都是通過增大網絡的深度(層數)來獲得更好的訓練效果,但層數的增加會帶來很多負作用,比如overfit、梯度消失、梯度爆炸等。Inception的提出則從另一種角度來提升訓練結果:能更高效的利用計算資源,在相同的計算量下能提取到更多的特徵,從而提升訓練結果。
7. 這一期到這裏就結束啦,大佬們的鼓勵就是我更新最大的動力,歡迎點贊關注哦~
Ps:下一期更新一下ResNet系列,我們下期再見