GoogLeNet Inception V4网络结构
GoogLeNet Inception ResNet网络结构
代码实践
GoogLeNet Inception ResNet V2
代码语言:javascript复制# -*- coding: utf-8 -*-
import numpy as np
from keras.layers import Input, merge, Dropout, Dense, Lambda, Flatten, Activation
from keras.layers.convolutional import MaxPooling2D, Conv2D, AveragePooling2D
from keras.layers.normalization import BatchNormalization
from keras.layers.merge import concatenate, add
from keras.regularizers import l1_l2
from keras.models import Model
from keras.callbacks import CSVLogger, ReduceLROnPlateau, ModelCheckpoint, EarlyStopping
lr_reducer = ReduceLROnPlateau(monitor='val_loss', factor=np.sqrt(0.5), cooldown=0, patience=3, min_lr=1e-6)
early_stopper = EarlyStopping(monitor='val_acc', min_delta=0.0005, patience=15)
csv_logger = CSVLogger('resnet34_cifar10.csv')
from keras.utils.vis_utils import plot_model
import os
from keras.preprocessing.image import ImageDataGenerator
from keras.utils import np_utils
from keras.datasets import cifar10
from keras import backend as K
import tensorflow as tf
tf.python.control_flow_ops = tf
import warnings
warnings.filterwarnings('ignore')
filter_control = 8
def bn_relu(input):
"""Helper to build a BN -> relu block
"""
norm = BatchNormalization()(input)
return Activation("relu")(norm)
def inception_resnet_stem(input_shape, small_mode=False):
input_layer = input_shape
if small_mode:
strides = (1, 1)
else:
strides = (2, 2)
stem_conv1_3x3 = Conv2D(name="stem_conv1_3x3/2",
filters=32 // filter_control,
kernel_size=(3, 3),
strides=strides,
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(input_layer)
stem_conv2_3x3 = Conv2D(name="stem_conv2_3x3/1",
filters=32 // filter_control,
kernel_size=(3, 3),
strides=(1, 1),
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(stem_conv1_3x3)
stem_conv3_3x3 = Conv2D(name="stem_conv3_3x3/1",
filters=64 // filter_control,
kernel_size=(3, 3),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(stem_conv2_3x3)
stem_pool1_3x3 = MaxPooling2D(name="stem_pool1_3x3/2",
pool_size=(3, 3),
strides=strides,
padding='valid')(stem_conv3_3x3)
stem_conv4_3x3 = Conv2D(name="stem_conv4_3x3/2",
filters=96 // filter_control,
kernel_size=(3, 3),
strides=strides,
padding='valid',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(stem_conv3_3x3)
stem_merge1 = concatenate([stem_pool1_3x3, stem_conv4_3x3])
stem_conv5_1x1 = Conv2D(name="stem_conv5_1x1/1",
filters=64 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(stem_merge1)
stem_conv6_3x3 = Conv2D(name="stem_conv6_3x3/1",
filters=96 // filter_control,
kernel_size=(3, 3),
strides=(1, 1),
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(stem_conv5_1x1)
stem_conv7_1x1 = Conv2D(name="stem_conv7_1x1/1",
filters=64 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(stem_merge1)
stem_conv8_7x1 = Conv2D(name="stem_conv8_7x1/1",
filters=64 // filter_control,
kernel_size=(7, 1),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(stem_conv7_1x1)
stem_conv9_1x7 = Conv2D(name="stem_conv8_1x7/1",
filters=64 // filter_control,
kernel_size=(1, 7),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(stem_conv8_7x1)
stem_conv10_3x3 = Conv2D(name="stem_conv10_3x3/1",
filters=96 // filter_control,
kernel_size=(3, 3),
strides=(1, 1),
padding='valid',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(stem_conv9_1x7)
stem_merge2 = concatenate([stem_conv6_3x3, stem_conv10_3x3])
stem_pool2_3x3 = MaxPooling2D(name="stem_pool2_3x3/2",
pool_size=(3, 3),
strides=strides,
padding='valid')(stem_merge2)
stem_conv11_3x3 = Conv2D(name="stem_conv11_3x3/2",
filters=192 // filter_control,
kernel_size=(3, 3),
strides=strides,
padding='valid',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(stem_merge2)
stem_merge3 = concatenate([stem_pool2_3x3, stem_conv11_3x3])
return bn_relu(stem_merge3)
def inception_resnet_v2_A(i, input):
# 输入是一个ReLU激活
init = input
inception_A_conv1_1x1 = Conv2D(name="inception_A_conv1_1x1/1" i,
filters=32 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(input)
inception_A_conv2_1x1 = Conv2D(name="inception_A_conv2_1x1/1" i,
filters=32 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(input)
inception_A_conv3_3x3 = Conv2D(name="inception_A_conv3_3x3/1" i,
filters=32 // filter_control,
kernel_size=(3, 3),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(inception_A_conv2_1x1)
inception_A_conv4_1x1 = Conv2D(name="inception_A_conv4_1x1/1" i,
filters=32 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(input)
inception_A_conv5_3x3 = Conv2D(name="inception_A_conv5_3x3/1" i,
filters=48 // filter_control,
kernel_size=(3, 3),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(inception_A_conv4_1x1)
inception_A_conv6_3x3 = Conv2D(name="inception_A_conv6_3x3/1" i,
filters=64 // filter_control,
kernel_size=(3, 3),
strides=(1, 1),
padding='same',
kernel_initializer='he_normal',
activation='relu',
kernel_regularizer=l1_l2(0.0001))(inception_A_conv5_3x3)
inception_merge1 = concatenate([inception_A_conv1_1x1, inception_A_conv3_3x3, inception_A_conv6_3x3])
inception_A_conv7_1x1 = Conv2D(name="inception_A_conv7_1x1/1" i,
filters=384 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='linear')(inception_merge1)
out = add([input, inception_A_conv7_1x1])
return bn_relu(out)
def inception_resnet_v2_B(i, input):
# 输入是一个ReLU激活
init = input
inception_B_conv1_1x1 = Conv2D(name="inception_B_conv1_1x1/1" i,
filters=192 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='relu')(input)
inception_B_conv2_1x1 = Conv2D(name="inception_B_conv2_1x1/1" i,
filters=128 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='relu')(input)
inception_B_conv3_1x7 = Conv2D(name="inception_B_conv3_1x7/1" i,
filters=160 // filter_control,
kernel_size=(1, 7),
strides=(1, 1),
padding='same',
activation='relu')(inception_B_conv2_1x1)
inception_B_conv4_7x1 = Conv2D(name="inception_B_conv4_7x1/1" i,
filters=192 // filter_control,
kernel_size=(7, 1),
strides=(1, 1),
padding='same',
activation='relu')(inception_B_conv3_1x7)
inception_B_merge = concatenate([inception_B_conv1_1x1, inception_B_conv4_7x1])
inception_B_conv7_1x1 = Conv2D(name="inception_B_conv7_1x1/1" i,
filters=1154 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='linear')(inception_B_merge)
out = add([input, inception_B_conv7_1x1])
return bn_relu(out)
def inception_resnet_v2_C(i, input):
# 输入是一个ReLU激活
inception_C_conv1_1x1 = Conv2D(name="inception_C_conv1_1x1/1" i,
filters=192 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='relu')(input)
inception_C_conv2_1x1 = Conv2D(name="inception_C_conv2_1x1/1" i,
filters=192 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='relu')(input)
inception_C_conv3_1x3 = Conv2D(name="inception_C_conv3_1x3/1" i,
filters=224 // filter_control,
kernel_size=(1, 3),
strides=(1, 1),
padding='same',
activation='relu')(inception_C_conv2_1x1)
inception_C_conv3_3x1 = Conv2D(name="inception_C_conv3_3x1/1" i,
filters=256 // filter_control,
kernel_size=(3, 1),
strides=(1, 1),
padding='same',
activation='relu')(inception_C_conv3_1x3)
ir_merge = concatenate([inception_C_conv1_1x1, inception_C_conv3_3x1])
inception_C_conv4_1x1 = Conv2D(name="inception_C_conv4_1x1/1" i,
filters=2048 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='linear')(ir_merge)
out = add([input, inception_C_conv4_1x1])
return bn_relu(out)
def reduction_A(input, k=192, l=224, m=256, n=384):
pool_size = (3, 3)
strides = (2, 2)
reduction_A_pool1 = MaxPooling2D(name="reduction_A_pool1/2",
pool_size=pool_size,
strides=strides,
padding='valid')(input)
reduction_A_conv1_3x3 = Conv2D(name="reduction_A_conv1_3x3/1",
filters=n // filter_control,
kernel_size=pool_size,
strides=strides,
activation='relu')(input)
reduction_A_conv2_1x1 = Conv2D(name="reduction_A_conv2_1x1/1",
filters=k // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='relu')(input)
reduction_A_conv2_3x3 = Conv2D(name="reduction_A_conv2_3x3/1",
filters=l // filter_control,
kernel_size=(3, 3),
strides=(1, 1),
padding='same',
activation='relu')(reduction_A_conv2_1x1)
reduction_A_conv3_3x3 = Conv2D(name="reduction_A_conv3_3x3/1",
filters=m // filter_control,
kernel_size=pool_size,
strides=strides,
activation='relu')(reduction_A_conv2_3x3)
reduction_A_merge = concatenate([reduction_A_pool1, reduction_A_conv1_3x3, reduction_A_conv3_3x3])
return reduction_A_merge
def reduction_B(input):
pool_size = (3, 3)
strides = (2, 2)
reduction_B_pool1 = MaxPooling2D(name="reduction_B_pool1/2",
pool_size=pool_size,
strides=strides,
padding='valid')(input)
reduction_B_conv1_1x1 = Conv2D(name="reduction_B_conv3_3x3/1",
filters=256 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='relu')(input)
reduction_B_conv2_3x3 = Conv2D(name="reduction_B_conv2_3x3/1",
filters=288 // filter_control,
kernel_size=pool_size,
strides=strides,
activation='relu')(reduction_B_conv1_1x1)
reduction_B_conv3_1x1 = Conv2D(name="reduction_B_conv3_1x1/1",
filters=256 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='relu')(input)
reduction_B_conv4_3x3 = Conv2D(name="reduction_B_conv4_3x3/1",
filters=288 // filter_control,
kernel_size=pool_size,
strides=strides,
activation='relu')(reduction_B_conv3_1x1)
reduction_B_conv5_1x1 = Conv2D(name="reduction_B_conv5_1x1/1",
filters=256 // filter_control,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='relu')(input)
reduction_B_conv5_3x3 = Conv2D(name="reduction_B_conv5_3x3/1",
filters=288 // filter_control,
kernel_size=(3, 3),
strides=(1, 1),
padding='same',
activation='relu')(reduction_B_conv5_1x1)
reduction_B_conv6_3x3 = Conv2D(name="reduction_B_conv6_3x3/1",
filters=320 // filter_control,
kernel_size=pool_size,
strides=strides,
activation='relu')(reduction_B_conv5_3x3)
reduction_B_merge = concatenate(
[reduction_B_pool1, reduction_B_conv2_3x3, reduction_B_conv4_3x3, reduction_B_conv6_3x3])
return reduction_B_merge
def create_inception_resnet_v2(input_shape, nb_classes=10, small_mode=False):
input_layer = Input(input_shape)
x = inception_resnet_stem(input_layer, small_mode)
# 10 x Inception Resnet A
for i in range(10):
x = inception_resnet_v2_A(str(i), x)
# Reduction A
x = reduction_A(x, k=256, l=256, m=384, n=384)
# 20 x Inception Resnet B
for i in range(20):
x = inception_resnet_v2_B(str(i), x)
# 对32*32*3的数据可以更改pooling层
aout = AveragePooling2D((5, 5), strides=(3, 3))(x)
aout = Conv2D(name="conv1_1x1/1",
filters=128,
kernel_size=(1, 1),
strides=(1, 1),
padding='same',
activation='relu')(aout)
aout = Conv2D(name="conv1_5x5/1",
filters=768,
kernel_size=(5, 5),
strides=(1, 1),
padding='same',
activation='relu')(aout)
aout = Flatten()(aout)
aout = Dense(nb_classes, activation='softmax')(aout)
# Reduction Resnet B
x = reduction_B(x)
# 10 x Inception Resnet C
for i in range(10):
x = inception_resnet_v2_C(str(i), x)
# 需要视情况更改
x = AveragePooling2D((4, 4), strides=(1, 1))(x)
# Dropout
x = Dropout(0.8)(x)
x = Flatten()(x)
# Output
out = Dense(output_dim=nb_classes, activation='softmax')(x)
# 简单起见去掉附加目标函数
# model = Model(input_layer, output=[out, aout], name='Inception-Resnet-v2')
model = Model(input_layer, output=out, name='Inception-Resnet-v2')
return model
if __name__ == "__main__":
with tf.device('/gpu:3'):
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=1, allow_growth=True)
os.environ["CUDA_VISIBLE_DEVICES"] = "3"
tf.Session(config=K.tf.ConfigProto(allow_soft_placement=True,
log_device_placement=True,
gpu_options=gpu_options))
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
# reorder dimensions for tensorflow
x_train = np.transpose(x_train.astype('float32') / 255., (0, 1, 2, 3))
x_test = np.transpose(x_test.astype('float32') / 255., (0, 1, 2, 3))
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
# convert class vectors to binary class matrices
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
s = x_train.shape[1:]
batch_size = 128
nb_epoch = 10
nb_classes = 10
model = create_inception_resnet_v2(s, nb_classes, False, True)
model.summary()
plot_model(model, to_file="GoogLeNet-Inception-Resnet-V2.jpg", show_shapes=True)
model.compile(optimizer='adadelta',
loss='categorical_crossentropy',
metrics=['accuracy'])
# Model saving callback
checkpointer = ModelCheckpoint("weights-improvement-{epoch:02d}-{val_acc:.2f}.hdf5", monitor='val_loss',
verbose=0,
save_best_only=False, save_weights_only=False, mode='auto')
print('Using real-time data augmentation.')
datagen_train = ImageDataGenerator(
featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
rotation_range=0,
width_shift_range=0.125,
height_shift_range=0.125,
horizontal_flip=True,
vertical_flip=False)
datagen_train.fit(x_train)
history = model.fit_generator(datagen_train.flow(x_train, y_train, batch_size=batch_size, shuffle=True),
samples_per_epoch=x_train.shape[0],
nb_epoch=nb_epoch, verbose=1,
validation_data=(x_test, y_test),
callbacks=[lr_reducer, early_stopper, csv_logger, checkpointer])