keras实现SqueezeNet 网络,具体网络结构参照https://blog.csdn.net/xbinworld/article/details/50897870博客
之前也这样压缩过自己的网络,识别效果还不错。现在根据模板简单构建下网络。
虽然说参数能够减少很多,其实卷积层数增加了,就是利用时间来换取空间,看个人如何取舍了吧。
#coding:utf-8
import osos.environ['KERAS_BACKEND'] = 'tensorflow'
import numpy as np
from keras.utils.vis_utils import plot_model
from keras import backend as K
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.pooling import GlobalAvgPool2D
from keras.layers import Input,Concatenate
from keras.models import Model
#np.random.seed(55)
'''Fire Module是本文的核心构件,思想非常简单,就是将原来简单的一层conv层变成两层:
squeeze层+expand层,各自带上Relu激活层。在squeeze层里面全是1x1的卷积kernel,数量记为S11;
在expand层里面有1x1和3x3的卷积kernel,数量分别记为E11和E33,
要求S11 < input map number即满足上面的设计原则(2)。
expand层之后将1x1和3x3的卷积output feature maps在channel维度拼接起来。'''
###padding = 'same' output = int{((w,h)-kernel_size+pading_num)/2}+1 ,pading_num = int(kernel_size/2)
###pading = 'valid' output = int{((w,h)-kernel_size)/2}+1
def SqueezeNet(img_w,img_h,n_channels):
x = Input(shape=(img_w,img_h,n_channels))
conv1 = Conv2D(filters=96,kernel_size=(7,7),strides=(2,2),padding='same',activation='relu')(x)
maxpool1 = MaxPooling2D(pool_size=(3,3),strides=(2,2))(conv1)
fire1_squee = Conv2D(filters=16, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(maxpool1)
fire1_expan1 = Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(fire1_squee)
fire1_expan2 = Conv2D(filters=64, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire1_squee)
fire1_out = Concatenate(axis=-1)([fire1_expan1, fire1_expan2])
fire2_squee = Conv2D(filters=16, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire1_out)
fire2_expan1 = Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(fire2_squee)
fire2_expan2 = Conv2D(filters=64, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire2_squee)
fire2_out = Concatenate(axis=-1)([fire2_expan1, fire2_expan2])
fire3_squee = Conv2D(filters=32, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire2_out)
fire3_expan1 = Conv2D(filters=128, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(fire3_squee)
fire3_expan2 = Conv2D(filters=128, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire3_squee)
fire3_out = Concatenate(axis=-1)([fire3_expan1, fire3_expan2])
maxpool2 = MaxPooling2D(pool_size=(3,3),strides=(2,2))(fire3_out)
fire4_squee = Conv2D(filters=32, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(maxpool2)
fire4_expan1 = Conv2D(filters=128, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(fire4_squee)
fire4_expan2 = Conv2D(filters=128, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire4_squee)
fire4_out = Concatenate(axis=-1)([fire4_expan1, fire4_expan2])
fire5_squee = Conv2D(filters=48, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire4_out)
fire5_expan1 = Conv2D(filters=192, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(fire5_squee)
fire5_expan2 = Conv2D(filters=192, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire5_squee)
fire5_out = Concatenate(axis=-1)([fire5_expan1, fire5_expan2])
fire6_squee = Conv2D(filters=48, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire5_out)
fire6_expan1 = Conv2D(filters=192, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(fire6_squee)
fire6_expan2 = Conv2D(filters=192, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire6_squee)
fire6_out = Concatenate(axis=-1)([fire6_expan1, fire6_expan2])
fire7_squee = Conv2D(filters=64, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire6_out)
fire7_expan1 = Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(fire7_squee)
fire7_expan2 = Conv2D(filters=256, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire7_squee)
fire7_out = Concatenate(axis=-1)([fire7_expan1, fire7_expan2])
maxpool3 = MaxPooling2D(pool_size=(3,3),strides=(2,2))(fire7_out)
fire8_squee = Conv2D(filters=64, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(maxpool3)
fire8_expan1 = Conv2D(filters=256, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(fire8_squee)
fire8_expan2 = Conv2D(filters=256, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire8_squee)
fire8_out = Concatenate(axis=-1)([fire8_expan1, fire8_expan2])
conv2 = Conv2D(filters=1000, kernel_size=(1, 1), strides=(1, 1), padding='same', activation='relu')(fire8_out)
Gap = GlobalAvgPool2D(data_format='channels_last')(conv2)
model = Model(inputs=x,outputs=Gap)
return model
if __name__ == '__main__':
model = SqueezeNet(224,224,3)
model.summary()
plot_model(model, to_file='model.png', show_shapes=True, show_layer_names=False)