天天看點

DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet

卷積神經網絡keras實作

  • AlexNet
  • VGGNet
  • InceptionNet
  • 資料 oxflower17 ,使用keras實作AlexNet,VggNet,InceptionNet

AlexNet

  • 如果說 LeNet是卷積神經網絡的開山鼻祖,那麼在2012年ImageNet競賽中以超過第二名10.9個百分點的AlexNet就是激起深度學習和卷積神經網絡千層浪的巨石。
  • 主要閃光點:
  1. 資料增廣:ImageNet1000類,輸入圖檔規定是256×256彩色圖檔,AlexNet在256x256圖中随機裁剪多張224*224圖作為訓練資料。
  2. 第一次采用Relu激活函數替代Sigmoid。
  3. 采用dropout層,避免過拟合。
  • 網絡結構:
    DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
    在AlexNet時代由于硬體裝置的現在,是以将網絡拆分成了兩部分,在不同GPU上訓練最後整合,對于現在我們可以直接将整個網絡整合在一起訓練。
type kernel size / stride output size
conv2d 11x11/4 55x55x96
conv2d 5x5/1 55x55x256
max pool 2x2/2 27x27x256
conv2d 3x3/1 27x27x384
max pool 2x2/2 13x13x384
conv2d 3x3/1 13x13x384
conv2d 3x3/1 13x13x256
max pool 2x2/2 6x6x256
dense 4096
dropout 0.5
dense 4096
dropout 0.5
dense 1000
  • keras 實作:使用的oxflower17 資料集太小,訓練集accuracy基本達到99%,驗證集accuracy接近50%,過拟合明顯。
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
import tflearn.datasets.oxflower17 as oxflower17
from sklearn.model_selection import train_test_split

x, y = oxflower17.load_data()
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2,shuffle = True)

model = keras.models.Sequential()
model.add(keras.layers.Conv2D(filters=96,kernel_size=(11,11),strides=4,padding='same',activation='relu',input_shape=(224,224,3)))
model.add(keras.layers.Conv2D(filters=256,kernel_size=(5,5),strides=1,padding='same',activation='relu'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2),strides=2))
model.add(keras.layers.Conv2D(filters=384,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2),strides=2))
model.add(keras.layers.Conv2D(filters=384,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.Conv2D(filters=256,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2),strides=2))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(4096,activation='relu'))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(4096,activation='relu'))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(17,activation='softmax'))
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.summary()
cb = [ keras.callbacks.EarlyStopping(patience=30,min_delta=1e-4),
       keras.callbacks.ModelCheckpoint('./AlexNet.h5',save_best_only=True) ]
his = model.fit(x_train,y_train,batch_size=64,epochs=100,validation_data=(x_test,y_test),callbacks=cb)

pd.DataFrame(his.history).plot(figsize=(8,5))
plt.grid(True)
# plt.gca().set_ylim(0,1)
plt.show()
           
DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet

VGGNet

  • VGG-Nets是由牛津大學VGG(Visual Geometry Group)提出,是2014年ImageNet競賽定位任務第一名和分類任務第二名中的基礎網絡。
  • 主要閃光點:
  1. 資料增廣:采用更多種方式采集,例如先縮大成512x512,在截取224x224的樣本圖。
  2. 多使用更小的3x3卷積核。
  3. 層次更深。
  • 網絡結構:
    DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
    每經過一個pooling層,通道數要翻倍。(因為pooling大小減小資訊會丢失,是以使通道再翻倍。)
DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
  • keras 實作:同樣使用oxflower17 小資料集,依舊過拟合明顯,但模型效果确實更好,驗證集accuracy接近60%。
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
import tflearn.datasets.oxflower17 as oxflower17
from sklearn.model_selection import train_test_split

x, y = oxflower17.load_data()
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2,shuffle = True)

model = keras.models.Sequential()
model.add(keras.layers.Conv2D(filters=64,kernel_size=(3,3),strides=1,padding='same',activation='relu',input_shape=(224,224,3)))
model.add(keras.layers.Conv2D(filters=64,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2),strides=2))
model.add(keras.layers.Conv2D(filters=128,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.Conv2D(filters=128,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2),strides=2))
model.add(keras.layers.Conv2D(filters=256,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.Conv2D(filters=256,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.Conv2D(filters=256,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2),strides=2))
model.add(keras.layers.Conv2D(filters=512,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.Conv2D(filters=512,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.Conv2D(filters=512,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2),strides=2))
model.add(keras.layers.Conv2D(filters=512,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.Conv2D(filters=512,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.Conv2D(filters=512,kernel_size=(3,3),strides=1,padding='same',activation='relu'))
model.add(keras.layers.MaxPool2D(pool_size=(2,2),strides=2))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(4096,activation='relu'))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(4096,activation='relu'))
model.add(keras.layers.Dropout(0.5))
model.add(keras.layers.Dense(17,activation='softmax'))
model.compile(optimizer=keras.optimizers.Adam(lr=0.00001),loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.summary()
cb = [  keras.callbacks.EarlyStopping(patience=30,min_delta=1e-4),
      	keras.callbacks.ModelCheckpoint('./VggNet16.h5',save_best_only=True) ]
his = model.fit(x_train,y_train,batch_size=64,epochs=100,validation_data=(x_test,y_test),callbacks=cb)
           
DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet

InceptionNet

  • GoogLeNet也稱為InceptionNet因其特殊的Inception結構,在2014的ImageNet分類任務上擊敗了VGG-Nets奪得冠軍。至目前從InceptionNet-V1 到 InceptionNet-V4共遞進式的發展了4個版本。
  • Inception-V1

    主要閃光點:

  1. 引入Inception結構:替換中間單純的卷積池化層,是一種分組卷積的思想。
    DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet

    對前一層的輸出采用四種不同卷積政策進行卷積,4組不同卷積得到的feature map大小都是保持一緻的,最後再将所有的feature map 一張張并排疊起來,作為輸出。

    1X1的卷積層做非線性變換,用于降維,減少大量參數。

  2. 中間加入了2個輔助LOSS單元,避免梯度消失的情況,讓網絡更好地被訓練。這兩個輔助LOSS單元的計算被乘以0.3,然後和最後的LOSS相加作為最終的損失函數來訓練網絡。
    DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
  3. 将最後的全連接配接層替換成Average Pooling,減少了大量的參數。
  • Inception-V2

    主要閃光點:

  1. 引入BatchNormalization層,在每一層卷積層後面。加速了網絡訓練,防止梯度消失,一定程度避免過拟合。
  2. 改進Inception結構:使用2個3x3卷積核替代5x5,且減少了28%的參數量。
    DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
  • Inception-V3

    主要閃光點:

  1. 繼續改進Inception結構:nxn卷積核并非最小,可采用一組:1xn和nx1卷積核替換。3x3換成3x1和1x3,且參數量能再降低33%。
    DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
    DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
  • Inception-V4

    主要閃光點:學習了ResNet,應入了殘差連接配接塊。

  • keras 實作Inception-V2:oxflower17 小資料集,同樣過拟合明顯,但驗證集accuracy接近70%。

    網絡結構:

    #3x3 reduce卷積 為連接配接 #3x3卷積 的 1x1卷積。

    double #3x3 reduce卷積 為連接配接 double #3x3卷積 的 1x1卷積。

    DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
    DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
import tflearn.datasets.oxflower17 as oxflower17
from sklearn.model_selection import train_test_split

x, y = oxflower17.load_data()
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2,shuffle = True)

def Conv2D_BN(inputs,filter,kernel,padding,stride):
  outputs = keras.layers.Conv2D(filters=filter,kernel_size=kernel,padding=padding,strides=stride,activation='relu')(inputs)
  outputs = keras.layers.BatchNormalization()(outputs)
  return outputs

def InceptionBlock_1(inputs,channel_for_branch):
  channel_branch1,channel_branch2,channel_branch3,channel_branch4 = channel_for_branch

  branch_1_1 = Conv2D_BN(inputs,channel_branch1[0],(1,1),'same',1)

  branch_3_3 = Conv2D_BN(inputs,channel_branch2[0],(1,1),'same',1)
  branch_3_3 = Conv2D_BN(branch_3_3,channel_branch2[1],(3,3),'same',1)

  branch_3_3_2 = Conv2D_BN(inputs,channel_branch3[0],(1,1),'same',1)
  branch_3_3_2 = Conv2D_BN(branch_3_3_2,channel_branch3[1],(3,3),'same',1)
  branch_3_3_2 = Conv2D_BN(branch_3_3_2,channel_branch3[1],(3,3),'same',1)

  branch_pooling = keras.layers.AveragePooling2D(pool_size=(3,3),strides=1,padding='same')(inputs)
  branch_pooling = Conv2D_BN(branch_pooling,channel_branch4[0],(1,1),'same',1)

  outputs = keras.layers.concatenate([branch_1_1,branch_3_3,branch_3_3_2,branch_pooling])
  return outputs

def InceptionBlock_2(inputs,channel_for_branch):
  channel_branch1,channel_branch2 = channel_for_branch

  branch_3_3 = Conv2D_BN(inputs,channel_branch1[0],(1,1),'same',1)
  branch_3_3 = Conv2D_BN(branch_3_3,channel_branch1[1],(3,3),'same',2)

  branch_3_3_2 = Conv2D_BN(inputs,channel_branch2[0],(1,1),'same',1)
  branch_3_3_2 = Conv2D_BN(branch_3_3_2,channel_branch2[1],(3,3),'same',1)
  branch_3_3_2 = Conv2D_BN(branch_3_3_2,channel_branch2[1],(3,3),'same',2)

  branch_pooling = keras.layers.MaxPool2D(pool_size=(3,3),strides=2,padding='same')(inputs)

  outputs = keras.layers.concatenate([branch_3_3,branch_3_3_2,branch_pooling])
  return outputs

def InceptionBlock_3(inputs,channel_for_branch):
  channel_branch1,channel_branch2,channel_branch3,channel_branch4 = channel_for_branch

  branch_1_1 = Conv2D_BN(inputs,channel_branch1[0],(1,1),'same',1)

  branch_3_3 = Conv2D_BN(inputs,channel_branch2[0],(1,1),'same',1)
  branch_3_3 = Conv2D_BN(branch_3_3,channel_branch2[1],(3,3),'same',1)

  branch_3_3_2 = Conv2D_BN(inputs,channel_branch3[0],(1,1),'same',1)
  branch_3_3_2 = Conv2D_BN(branch_3_3_2,channel_branch3[1],(3,3),'same',1)
  branch_3_3_2 = Conv2D_BN(branch_3_3_2,channel_branch3[1],(3,3),'same',1)

  branch_pooling = keras.layers.MaxPool2D(pool_size=(3,3),strides=1,padding='same')(inputs)
  branch_pooling = Conv2D_BN(branch_pooling,channel_branch4[0],(1,1),'same',1)

  outputs = keras.layers.concatenate([branch_1_1,branch_3_3,branch_3_3_2,branch_pooling])
  return outputs

inputs = keras.Input(shape=(224,224,3))
x = Conv2D_BN(inputs,64,(7,7),'same',2)
x = keras.layers.MaxPool2D(pool_size=(3,3),strides=2,padding='same')(x)
x = Conv2D_BN(x,64,(1,1),'same',1)
x = Conv2D_BN(x,192,(3,3),'same',1)
x = keras.layers.MaxPool2D(pool_size=(3,3),strides=2,padding='same')(x)
x = InceptionBlock_1(x,[(64,),(64,64),(64,96),(32,)])
x = InceptionBlock_1(x,[(64,),(64,96),(64,96),(64,)])
x = InceptionBlock_2(x,[(128,160),(64,96)])
x = InceptionBlock_1(x,[(224,),(64,96),(96,128),(128,)])
x = InceptionBlock_1(x,[(192,),(96,128),(96,128),(128,)])
x = InceptionBlock_1(x,[(160,),(128,160),(128,160),(128,)])
x = InceptionBlock_1(x,[(96,),(128,192),(160,192),(128,)])
x = InceptionBlock_2(x,[(128,192),(192,256)])
x = InceptionBlock_1(x,[(352,),(192,320),(160,224),(128,)])
x = InceptionBlock_3(x,[(352,),(192,320),(192,224),(128,)])
x = keras.layers.AveragePooling2D(pool_size=(7,7),strides=1)(x)
x = keras.layers.Flatten()(x)
x = keras.layers.Dense(17,activation='softmax')(x)
model = keras.Model(inputs=inputs,outputs=x)
model.compile(optimizer=keras.optimizers.Adam(lr=0.00001),loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.summary()
cb = [  keras.callbacks.EarlyStopping(patience=30,min_delta=1e-4),
      	keras.callbacks.ModelCheckpoint('./InceptionNet.h5',save_best_only=True) ]
his = model.fit(x_train,y_train,batch_size=64,epochs=100,validation_data=(x_test,y_test),callbacks=cb)

pd.DataFrame(his.history).plot(figsize=(8,5))
plt.grid(True)
# plt.gca().set_ylim(0,1)
plt.show()
           
DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet
DL(3) - 卷積神經網絡AlexNet/VGGNet/InceptionNet之keras實作 (上)AlexNetVGGNetInceptionNet

繼續閱讀