在這篇文章中,咱們將討論一種新的網絡模型GoogleNet,它和我前面所討論的模型有所不一樣,表如今:git
GoogLeNet模型於2014年的一篇論文《Going Deeper With Convolutions》提出,其最大的貢獻在於Inception模塊(Inception有起初、開端的含義),這是一個適合卷積神經網絡的構建模塊,它選用多個過濾器大小的卷積,將模塊轉換爲多級特徵提取器。github
Inception模塊是一種微架構模塊,所謂微架構,就是由深度學習從業者設計的小型構建塊,它使得網絡可以在增長網絡深度的前提下更快地學習,並且更高效。而這些微架構構建塊與諸如CONV、POOL等傳統類型的層堆疊在一塊兒,能夠造成宏架構(macro-architecture)。bash
Inception模塊背後的思想有兩層含義:微信
GoogleNet最初引入的Inception模塊以下圖所示:網絡
注: 在每一個CONV層以後都緊跟一個激活函數(ReLU)。爲節省空間,此激活函數並沒包含在上面的網絡圖中。架構
從圖中能夠看到,輸入層以後有四個不一樣的路徑分支。Inception模塊中的第一個分支只是從輸入中學習一系列1×1局部特徵。框架
第二條路徑首先應用1×1卷積,不只做爲學習局部特徵的一種形式,還能夠減小維數。較大的卷積(即3×3和5×5)須要更多的計算。所以,若是咱們能夠經過應用1×1卷積來減小這些較大過濾器的輸入維數,就能夠減小網絡所需的計算量。機器學習
第三個分支與第二個分支的邏輯相同,區別在於爲了學習5×5過濾器。咱們再次經過1×1卷積下降維數,而後將輸出饋送到5×5過濾器。ide
Inception模塊的第四個分支以1×1的步幅執行3×3最大池化 - 該分支一般被稱爲池投影分支。函數
最後,Inception模塊的全部四個分支匯聚在一塊兒,它們沿着通道維度鏈接在一塊兒。在實現過程當中要特別當心(經過零填充)以確保每一個分支的輸出具備相同的卷大小,從而容許鏈接輸出。
最初的Inception模塊是爲GoogLeNet設計的,在ImageNet數據集上訓練(其中每一個輸入圖像假設爲224×224×3)並得到最好的精度。對於較小的數據集(具備較小的圖像空間維度),咱們能夠簡化Inception模塊,只須要較少的網絡參數。好比下圖表示的Miniception:
左:卷積模塊,負責執行卷積、批量正則化和激活。
中:Miniception模塊執行兩組卷積,一組用於1×1濾波器,另外一組用於3×3濾波器,而後鏈接結果。在3×3濾波器以前不執行降維,由於咱們將使用CIFAR-10數據集,輸入已經很小。
右:下采樣模塊,它同時應用卷積和最大池化以下降維度,而後在過濾器維度上鍊接。
將這些模塊堆疊起來,能夠組成稱之爲MiniGoogleNet的模型結構,以下圖所示:
有了上面的模型定義,接下來咱們就可使用Keras框架來實現之。但在編碼以前,咱們先了解一下Keras中的兩種類型的模型。
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dropout(0.25))
複製代碼
inputs = Input(shape=(784,))
# 輸入inputs,輸出x
x = Dense(64, activation='relu')(inputs)
# 輸入x,輸出x
x = Dense(64, activation='relu')(x)
複製代碼
由於MiniGoogleNet並非那種一條路走到黑的模型,因此咱們不能選擇序列模型,而應該選擇函數式API來構建,代碼以下:
class MiniGoogleNet:
@staticmethod
def conv_module(x, k, kx, ky, stride, channel_dim, padding="same"):
# define a CONV => BN => RELU pattern
x = Conv2D(k, (kx, ky), strides=stride, padding=padding)(x)
x = BatchNormalization(axis=channel_dim)(x)
x = Activation("relu")(x)
return x
@staticmethod
def inception_module(x, num_k1x1, num_k3x3, channel_dim):
# define two CONV module, then concatenate across the channel dimension
conv_1x1 = MiniGoogleNet.conv_module(x, num_k1x1, 1, 1, (1, 1), channel_dim=channel_dim)
conv_3x3 = MiniGoogleNet.conv_module(x, num_k3x3, 3, 3, (1, 1), channel_dim=channel_dim)
x = concatenate([conv_1x1, conv_3x3], axis=channel_dim)
return x
@staticmethod
def downsample_module(x, k, channel_dim):
# define the CONV module and POOL, then concatenate across the channel dimension
conv_3x3 = MiniGoogleNet.conv_module(x, k, 3, 3, (2, 2), channel_dim=channel_dim, padding="valid")
pool = MaxPooling2D((3, 3), strides=(2, 2))(x)
x = concatenate([conv_3x3, pool], axis=channel_dim)
return x
@staticmethod
def build(width, height, depth, classes):
input_shape = (width, height, depth)
channel_dim = -1
if K.image_data_format() == "channels_first":
input_shape = (depth, width, height)
channel_dim = 1
inputs = Input(shape=input_shape)
x = MiniGoogleNet.conv_module(inputs, 96, 3, 3, (1, 1), channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 32, 32, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 32, 48, channel_dim=channel_dim)
x = MiniGoogleNet.downsample_module(x, 80, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 112, 48, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 96, 64, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 80, 80, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 48, 96, channel_dim=channel_dim)
x = MiniGoogleNet.downsample_module(x, 96, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 176, 160, channel_dim=channel_dim)
x = MiniGoogleNet.inception_module(x, 176, 160, channel_dim=channel_dim)
x = AveragePooling2D((7, 7))(x)
x = Dropout(0.5)(x)
# softmax classifier
x = Flatten()(x)
x = Dense(classes)(x)
x = Activation("softmax")(x)
model = Model(inputs, x, name="googlenet")
return model
複製代碼
接下來就是訓練和測試模型,這個在前面的文章中介紹過,其步驟都差很少,因此在這裏我也再也不羅嗦,有興趣的同窗能夠參考我在github上的完整代碼。
寫下這篇文章,我完成了《Deep Learning for Computer Vision with Python》的學習,其實後面還有一章節是講殘差網絡(ResNet),但考慮到ResNet也是採用微架構,其實和GoogleNet差很少,就是模塊構建塊有些區別,因此就不打算寫了。
其實這套書還有第三部,稱爲ImageNet Bundle,裏面有更多大型項目的例子,考慮到我這邊的硬件條件有限,就先不去研究這些複雜的例子。在後面的時間裏,我將專一於移動終端上的機器學習,敬請關注。
以上實例均有完整的代碼,點擊閱讀原文,跳轉到我在github上建的示例代碼。 另外,我在閱讀《Deep Learning for Computer Vision with Python》這本書,在微信公衆號後臺回覆「計算機視覺」關鍵字,能夠免費下載這本書的電子版。