TensorFlow2.0实现GoogLeNet模型

#GoogLeNet模型,参数为mnist数据集
#注意:非比赛数据集,此处仅为实现GoogLeNet模型
import tensorflow as tf
from tensorflow.keras.layers import Input,Dropout,Flatten,Conv2D,MaxPooling2D,Dense,\
    ZeroPadding2D,BatchNormalization,concatenate,AveragePooling2D
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras import regularizers

(X_train,Y_train),(X_test,Y_test) = tf.keras.datasets.mnist.load_data()
X_test1 = X_test
Y_test1 = Y_test
print(X_train.shape[0])

#1表示单色,在TensorFlow下,该通道默认channels_last即(28,28,1),在theano下默认为channels_first,即为(1,28,28)
X_train = X_train.reshape(X_train.shape[0],28,28,1).astype('float32')/255.0
X_test = X_test.reshape(X_test.shape[0],28,28,1).astype('float32')/255.0


Y_train = tf.keras.utils.to_categorical(Y_train, num_classes=10)
Y_test = tf.keras.utils.to_categorical(Y_test, num_classes=10)

#参数设置
Lrn2D_Norm = True
Weight_Decay = 0.0005
DROPOUT = 0.4
DATA_FORMAT = 'channels_last'

#定义conv2D_lrn2d()函数,方便搭建GoogLeNet时直接调用
def conv2D_lrn2d(x,filters,kernel_size,strides=(1,1),padding='same',
                 activation='relu',kernel_regularizer=None,bias_regularizer=None,
                 lrn2d_norm=Lrn2D_Norm,     #局部响应归一化
                 weight_decay=Weight_Decay  #权重衰减系数
                 ):
    #是否对权重和偏置施加正则化
    if weight_decay:
        kernel_regularizer = regularizers.l2(weight_decay)
        bias_regularizer = regularizers.l2(weight_decay)
    else:
        kernel_regularizer = None
        bias_regularizer = None
    #搭建卷积层,对输入数据x进行卷积
    x = Conv2D(filters=filters,kernel_size=kernel_size,
               strides=strides,padding=padding,
               activation=activation,
               kernel_regularizer=kernel_regularizer,bias_regularizer=bias_regularizer)(x)
    #是否需要添加LRN层进行归一化
    if lrn2d_norm:
        x = BatchNormalization()(x)
    return x

#定义inception_module()函数,方便搭建GoogLeNet时直接调用
def inception_module(x,           #输入数据
                     params,      #输入参数为Inception模块中各卷积层中的卷积核个数
                     concat_axis, #设定concentrate()进行拼接的维度
                     padding = 'same',activation='relu',
                     kernel_regularizer=None,bias_regularizer=None,
                     lrn2d_norm=Lrn2D_Norm,weight_decay=None):
    (branch1,branch2,branch3,branch4) = params
    #是否对权重和偏置进行L2正则化
    if weight_decay:
        kernel_regularizer = regularizers.l2(weight_decay)
        bias_regularizer = regularizers.l2(weight_decay)
    else:
        kernel_regularizer = None
        bias_regularizer = None
    #搭建inception模块中1×1的卷积层
    pathway1 = Conv2D(filters=branch1[0],      #卷积核个数
                      kernel_size=(1,1),           #卷积核大小
                      strides=1,padding=padding,
                      activation=activation,
                      kernel_regularizer=kernel_regularizer,
                      bias_regularizer=bias_regularizer)(x)  #该层卷积层输入为x
    #搭建inception模块中的卷积层:1×1->3×3
    pathway2 = Conv2D(filters=branch2[0],      #卷积核个数
                      kernel_size=(1,1),           #卷积核大小
                      strides=1,padding=padding,
                      activation=activation,
                      kernel_regularizer=kernel_regularizer,
                      bias_regularizer=bias_regularizer)(x)  #该层卷积层输入为x
    pathway2 = Conv2D(filters=branch2[1],      #卷积核个数
                      kernel_size=(3,3),           #卷积核大小
                      strides=1,padding=padding,
                      activation=activation,
                      kernel_regularizer=kernel_regularizer,
                      bias_regularizer=bias_regularizer)(pathway2)  #该层卷积层输入为pathway2,即上一层卷积层
    # 搭建inception模块中的卷积层:1×1->5×5
    pathway3 = Conv2D(filters=branch3[0],
                      kernel_size=(1, 1),
                      strides=1, padding=padding,
                      activation=activation,
                      kernel_regularizer=kernel_regularizer,
                      bias_regularizer=bias_regularizer)(x)  # 该层卷积层输入为x
    pathway3 = Conv2D(filters=branch3[1],  # 卷积核个数
                      kernel_size=(5, 5),  # 卷积核大小
                      strides=1, padding=padding,
                      activation=activation,
                      kernel_regularizer=kernel_regularizer,
                      bias_regularizer=bias_regularizer)(pathway3)
    #搭建inception模块中3×3的池化层和1×1的卷积层:3×3->1×1
    pathway4 = MaxPooling2D(pool_size=(3,3),strides=1,
                            padding=padding,data_format=DATA_FORMAT)(x)
    pathway4 = Conv2D(filters=branch4[0],kernel_size=(1,1),
                      strides=1,padding=padding,activation=activation,
                      kernel_regularizer=kernel_regularizer,
                      bias_regularizer=bias_regularizer)(pathway4)

    return concatenate([pathway1,pathway2,pathway3,pathway4],axis=concat_axis)

#定义google_net()函数
def google_net():
    NB_CLASS = 10
    CONCAT_AXIS = 3    #拼接维度为3
    X_input = Input((28,28,1))
    img_input = ZeroPadding2D((3,3))(X_input)
    #调用conv2D_lrn2d()函数,搭建卷积层,lrn2d_norm为False,即该层卷积层不需要LRN层
    x = conv2D_lrn2d(img_input,64,(7,7),2,padding='same',lrn2d_norm=False)
    #最大池化层
    x = MaxPooling2D(pool_size=(2,2),strides=2,padding='same')(x)
    #搭建BN层
    x = BatchNormalization()(x)
    #搭建卷积层
    x = conv2D_lrn2d(x,64,(1,1),1,padding='same',lrn2d_norm=False)
    # 调用conv2D_lrn2d()函数,搭建卷积层,lrn2d_norm为True,即该层卷积层需要LRN层
    x = conv2D_lrn2d(x,192,(3,3),1,padding='same',lrn2d_norm=True)
    #最大池化层
    x = MaxPooling2D(pool_size=(2,2),strides=2,padding='same')(x)
    #调用inception_module模块,搭建inception3a层
    x = inception_module(x,params=[(64,),(96,128),(16,32),(32,)],concat_axis=CONCAT_AXIS)
    #搭建inception3b层
    x = inception_module(x,params=[(128,),(128,192),(32,96),(64,)],concat_axis=CONCAT_AXIS)
    #搭建池化层
    x = MaxPooling2D(pool_size=(2,2),strides=2,padding='same')(x)
    #搭建inception4a层
    x = inception_module(x,params=[(192,),(96,208),(16,48),(64,)],concat_axis=CONCAT_AXIS)
    # 搭建inception4b层
    x = inception_module(x,params=[(160,),(112,224),(24,64),(64,)],concat_axis=CONCAT_AXIS)
    # 搭建inception4c层
    x = inception_module(x,params=[(128,),(128,256),(24,64),(64,)],concat_axis=CONCAT_AXIS)
    # 搭建inception4d层
    x = inception_module(x,params=[(112,),(144,288),(32,64),(64,)],concat_axis=CONCAT_AXIS)
    # 搭建inception4e层
    x = inception_module(x,params=[(256,),(160,320),(32,128),(128,)],concat_axis=CONCAT_AXIS)
    #搭建池化层
    x = MaxPooling2D(pool_size=(2,2),strides=2,padding='same')(x)
    # 搭建inception5a层
    x = inception_module(x,params=[(256,),(160,320),(32,128),(128,)],concat_axis=CONCAT_AXIS)
    # 搭建inception5b层
    x = inception_module(x,params=[(384,),(192,384),(48,128),(128,)],concat_axis=CONCAT_AXIS)
    #搭建平均池化层
    x = AveragePooling2D(pool_size=(1,1),strides=1,padding='valid')(x)
    #搭建平坦层
    x = Flatten()(x)
    #搭建Dropout层
    x = Dropout(DROPOUT)(x)
    #搭建全连接层,即输出层
    x = Dense(units=NB_CLASS,activation='softmax')(x)
    #调用Model()函数,定义该网络模型得输入层为X_input,输出层为x,即全连接层
    model = tf.keras.Model(inputs=X_input,outputs=[x])
    #查看网络模型摘要
    model.summary()
    optimizer = RMSprop(lr = 1e-4)
    objective = 'binary_crossentropy'

    model.compile(loss=objective,optimizer=optimizer,metrics=['accuracy'])
    return model

model = google_net()

#GoogLeNet进行训练和预测
nb_epoch = 4
batch_size = 128
#对已经编译完成的网络模型进行训练和预测
def run_google():
    Training = model.fit(X_train,Y_train,batch_size=batch_size,epochs=nb_epoch,
                         validation_split=0.25,verbose=1)
    predictions = model.predict(X_test,verbose=1)

    return predictions,Training

predictions,Training = run_google()

#画出GoogleNet寻来你过程随epoch变化的曲线
import matplotlib.pyplot as plt
def show_Training_history(Training_history,train,validation):
    plt.plot(Training.history[train],)
    plt.plot(Training.history[validation])
    plt.title('Training history')
    plt.xlabel('epoch')
    plt.ylabel('train')
    plt.legend(['train', 'validation'], loc='lower right')  # 设置图例,位置在右下角
    plt.show()

show_Training_history(Training,'accuracy','val_accuracy')

import numpy as np
#对GoogLeNet进行测试集准确率计算
def test_accuracy():
    err = []
    t = 0
    #将测试集中每一个预测结果与其真实标签对比。若相同则t+1,最终t值为预测正确个数,若不相同则将对应的个数放在err数组中
    for i in range(predictions.shape[0]):
        if np.argmax(predictions[i])==Y_test1[i]:
            t = t + 1
        else:
            err.append(i)

    return t,float(t)*100/predictions.shape[0],err

p = test_accuracy()
print(p)
print('Test accuracy:{} %'.format(p[1]))


运行结果展示:Test accuracy:98.36 %

TensorFlow2.0实现GoogLeNet模型_第1张图片

你可能感兴趣的:(tensorflow,卷积)