一、歷史背景
深度學習自從2012年AlexNet問世以來,神經網絡的規模和複雜度越來越高,而且高性能顯卡的出現使得深度神經網絡(DNN)被廣泛使用。但是,DNN本身的特性也在這一過程中表現出來,如網絡中間層之間的映射關係、全連接層帶來的計算負擔等問題導致了網絡的訓練的低效性和精度問題。
在這個背景下,Google團隊在2014年推出了InceptionV1網絡架構,該網絡的主要目的是解決深度神經網絡模型訓練中的低效性問題和精度問題。
二、網絡架構
InceptionV1架構主要由多個包含不同卷積和池化核的並行卷積層組成。其中,每個卷積層都作用於輸入的相同維度且相加作為該層的輸出。這種方式的獨特優勢在於可以擺脫神經網絡不同層之間精度和效率權衡的限制。
InceptionV1網絡的架構可以簡化為以下結構:
Layer Output Shape Kernel Size/Stride
================================================
Input (224, 224, 3) -
Conv1 (112, 112, 64) 3x3/2
MaxPool1 (56, 56, 64) 3x3/2
Conv2 (28, 28, 192) 3x3/1
MaxPool2 (14, 14, 192) 3x3/2
Inception3a (14, 14, 256) -
Inception3b (14, 14, 480) -
MaxPool3 (7, 7, 480) 3x3/2
Inception4a (7, 7, 512) -
Inception4b (7, 7, 512) -
Inception4c (7, 7, 512) -
Inception4d (7, 7, 528) -
Inception4e (7, 7, 832) -
MaxPool4 (3, 3, 832) 3x3/2
Inception5a (3, 3, 832) -
Inception5b (3, 3, 1024) -
AvgPool (1, 1, 1024) 5x5/1
Dropout (1, 1, 1024) -
Output (1, 1, 1000) -
三、Inception模塊
Inception模塊是InceptionV1的核心模塊,它是由幾種局部網絡混合而成,每種局部網絡都是由卷積、池化、卷積和卷積組成的。該模塊結構如下所示:
Layer Output Shape Kernel Size/Stride
================================================
Input (28, 28, 192) -
Conv1x1 (28,28,64) 1x1/1
Conv3x3 (28,28,96) 3x3/1
Conv5x5 (28,28,16) 5x5/1
MaxPool3 (28,28,32) 3x3/1
concat (28, 28, 192) -
Inception模塊串聯起來形成了InceptionV1的整個網絡。這種混合的方式增加了網絡的寬度和深度,且使用了稀疏卷積計算,使得網絡更加有效和高效。
四、訓練方法和效果
為了訓練InceptionV1網絡,Google團隊在ImageNet數據集上訓練了3M張圖片,參數數目達到了500萬。該網絡在ImageNet數據集上實現了top-5準確率為89.9%的結果,這個結果讓該網絡成為2014年ImageNet比賽的冠軍。
五、代碼示例
InceptionV1的代碼示例可以在TensorFlow框架中找到,以下為示例代碼:
import tensorflow as tf
def inception_v1(inputs, num_classes=1000, is_training=True, dropout_keep_prob=0.4):
'''
inception v1網絡
:param inputs: 輸入圖像數據,形狀[batch_size, height, width, channels]
:param num_classes: 分類數目
:param is_training: 是否為訓練模式
:param dropout_keep_prob: dropout保留比例
:return: 最後一層的logits輸出,shape=[batch_size, num_classes]
'''
def inception_module(inputs, filters):
'''
inception module
:param inputs:輸入
:param filters: 卷積核數目
:return: 輸出
'''
# 1x1卷積網絡
conv1x1 = tf.layers.conv2d(inputs=inputs,
filters=filters[0],
kernel_size=1,
strides=1,
activation=tf.nn.relu,
padding='same')
# 3x3卷積網絡
conv3x3_reduce = tf.layers.conv2d(inputs=inputs,
filters=filters[1],
kernel_size=1,
strides=1,
activation=tf.nn.relu,
padding='same')
conv3x3 = tf.layers.conv2d(inputs=conv3x3_reduce,
filters=filters[2],
kernel_size=3,
strides=1,
activation=tf.nn.relu,
padding='same')
# 5x5卷積網絡
conv5x5_reduce = tf.layers.conv2d(inputs=inputs,
filters=filters[3],
kernel_size=1,
strides=1,
activation=tf.nn.relu,
padding='same')
conv5x5 = tf.layers.conv2d(inputs=conv5x5_reduce,
filters=filters[4],
kernel_size=5,
strides=1,
activation=tf.nn.relu,
padding='same')
# 3x3最大池化網絡
max_pool = tf.layers.max_pooling2d(inputs=inputs,
pool_size=3,
strides=1,
padding='same')
max_pool_project = tf.layers.conv2d(inputs=max_pool,
filters=filters[5],
kernel_size=1,
strides=1,
activation=tf.nn.relu,
padding='same')
# 將所有的分支在通道維度上連接起來
outputs = tf.concat([conv1x1, conv3x3, conv5x5, max_pool_project], axis=-1)
return outputs
# 開始搭建網絡
conv1 = tf.layers.conv2d(inputs, 64, 7, strides=2, padding='same', activation=tf.nn.relu)
max_pool1 = tf.layers.max_pooling2d(conv1, 3, 2, padding='same')
conv2_reduce = tf.layers.conv2d(max_pool1, 64, 1, strides=1, padding='same', activation=tf.nn.relu)
conv2 = tf.layers.conv2d(conv2_reduce, 192, 3, strides=1, padding='same', activation=tf.nn.relu)
max_pool2 = tf.layers.max_pooling2d(conv2, 3, 2, padding='same')
inception3a = inception_module(max_pool2, [64, 96, 128, 16, 32, 32])
inception3b = inception_module(inception3a, [128, 128, 192, 32, 96, 64])
max_pool3 = tf.layers.max_pooling2d(inception3b, 3, 2, padding='same')
inception4a = inception_module(max_pool3, [192, 96, 208, 16, 48, 64])
inception4b = inception_module(inception4a, [160, 112, 224, 24, 64, 64])
inception4c = inception_module(inception4b, [128, 128, 256, 24, 64, 64])
inception4d = inception_module(inception4c, [112, 144, 288, 32, 64, 64])
inception4e = inception_module(inception4d, [256, 160, 320, 32, 128, 128])
max_pool4 = tf.layers.max_pooling2d(inception4e, 3, 2, padding='same')
inception5a = inception_module(max_pool4, [256, 160, 320, 32, 128, 128])
inception5b = inception_module(inception5a, [384, 192, 384, 48, 128, 128])
# 利用平均池化進行預測
avg_pool = tf.layers.average_pooling2d(inception5b, 7, 1)
flatten = tf.layers.flatten(avg_pool)
# 對最後一層進行dropout降低過擬合風險
dropout = tf.layers.dropout(flatten, dropout_keep_prob, training=is_training)
logits = tf.layers.dense(dropout, num_classes)
return logits
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/237640.html