#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 %