構造
Entry flow → Middle flow ×8 → Exit flow
Entry flow
def Xception():
inputs = Input(shape=(32, 32, 3))
# entry flow
x = Convolution2D(32, (3,3), strides=2)(inputs)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Convolution2D(64, (3,3))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
residual = Convolution2D(128, (1,1), strides=2, padding='same')(x)
residual = BatchNormalization()(residual)
x = SeparableConv2D(128, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(128, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((3, 3), strides=2, padding='same')(x)
x = add([x, residual])
residual = Convolution2D(256, (1,1), strides=2, padding='same')(x)
residual = BatchNormalization()(residual)
x = Activation('relu')(x)
x = SeparableConv2D(256, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(256, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((3, 3), strides=2, padding='same')(x)
x = add([x, residual])
residual = Convolution2D(728, (1,1), strides=2, padding='same')(x)
residual = BatchNormalization()(residual)
x = Activation('relu')(x)
x = SeparableConv2D(728, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(728, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((3, 3), strides=2, padding='same')(x)
x = add([x, residual])
Middle flow
# middle flow
for i in range(8):
residual = x
x = Activation('relu')(x)
x = SeparableConv2D(728, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(728, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(728, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = add([x, residual])
Exit flow
# exit flow
residual = Convolution2D(1024, (1,1), strides=2, padding='same')(x)
residual = BatchNormalization()(residual)
x = Activation('relu')(x)
x = SeparableConv2D(728, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(1024, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((3, 3), strides=2, padding='same')(x)
x = add([x, residual])
x = SeparableConv2D(1536, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = SeparableConv2D(2048, (3,3), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = GlobalAveragePooling2D()(x)
x = Dense(10, kernel_initializer='he_normal', activation='softmax')(x)
model = Model(inputs=inputs, outputs=x)
return model
学習まで
model = Xception()
adam = Adam()
model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
batch_size = 50
epochs = 10
h = model.fit(X_train, Y_train,
batch_size=batch_size,
epochs=epochs,
validation_split=0.2,)