DL(3) - 卷积神经网络AlexNet/VGGNet/InceptionNet之keras实作 (上)

卷积神经网络keras实作


  • 数据 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层,避免过拟合。
  • 网络结构:
    在这里插入图片描述
    在AlexNet时代由于硬件设备的现在,所以将网络拆分成了两部分,在不同GPU上训练最后整合,对于现在我们可以直接将整个网络整合在一起训练。
typekernel size / strideoutput size
conv2d11x11/455x55x96
conv2d5x5/155x55x256
max pool2x2/227x27x256
conv2d3x3/127x27x384
max pool2x2/213x13x384
conv2d3x3/113x13x384
conv2d3x3/113x13x256
max pool2x2/26x6x256
dense4096
dropout0.5
dense4096
dropout0.5
dense1000
  • 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()

在这里插入图片描述
在这里插入图片描述

VGGNet

  • VGG-Nets是由牛津大学VGG(Visual Geometry Group)提出,是2014年ImageNet竞赛定位任务第一名和分类任务第二名中的基础网络。
  • 主要闪光点:
  1. 数据增广:采用更多种方式采集,例如先缩大成512x512,在截取224x224的样本图。
  2. 多使用更小的3x3卷积核。
  3. 层次更深。
  • 网络结构:
    在这里插入图片描述
    每经过一个pooling层,通道数要翻倍。(因为pooling大小减小信息会丢失,所以使通道再翻倍。)

在这里插入图片描述

  • 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)

在这里插入图片描述
在这里插入图片描述

InceptionNet

  • GoogLeNet也称为InceptionNet因其特殊的Inception结构,在2014的ImageNet分类任务上击败了VGG-Nets夺得冠军。至目前从InceptionNet-V1 到 InceptionNet-V4共递进式的发展了4个版本。
  • Inception-V1
    主要闪光点:
  1. 引入Inception结构:替换中间单纯的卷积池化层,是一种分组卷积的思想。
    在这里插入图片描述
    对前一层的输出采用四种不同卷积策略进行卷积,4组不同卷积得到的feature map大小都是保持一致的,最后再将所有的feature map 一张张并排叠起来,作为输出。
    1X1的卷积层做非线性变换,用于降维,减少大量参数。
  2. 中间加入了2个辅助LOSS单元,避免梯度消失的情況,让网络更好地被训练。这两个辅助LOSS单元的计算被乘以0.3,然后和最后的LOSS相加作为最终的损失函数来训练网络。
    在这里插入图片描述
  3. 将最后的全连接层替换成Average Pooling,减少了大量的参数。
  • Inception-V2
    主要闪光点:
  1. 引入BatchNormalization层,在每一层卷积层后面。加速了网络训练,防止梯度消失,一定程度避免过拟合。
  2. 改进Inception结构:使用2个3x3卷积核替代5x5,且减少了28%的参数量。
    在这里插入图片描述
  • Inception-V3
    主要闪光点:
  1. 继续改进Inception结构:nxn卷积核并非最小,可采用一组:1xn和nx1卷积核替换。3x3换成3x1和1x3,且参数量能再降低33%。
    在这里插入图片描述 在这里插入图片描述
  • Inception-V4
    主要闪光点:学习了ResNet,应入了残差连接块。

  • keras 实作Inception-V2:oxflower17 小数据集,同样过拟合明显,但验证集accuracy接近70%。
    网络结构:
    #3x3 reduce卷积 为连接 #3x3卷积1x1卷积
    double #3x3 reduce卷积 为连接 double #3x3卷积1x1卷积
    在这里插入图片描述
    在这里插入图片描述

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()

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值