| """ | |
| AlexNet Keras implementation | |
| """ | |
| # Import necessary libs | |
| import os | |
| from keras.models import Model | |
| from keras.layers import Conv2D, MaxPool2D, ZeroPadding2D, Dense, Dropout, \ | |
| Activation, Flatten, BatchNormalization, Input | |
| from keras.regularizers import l2 | |
| from keras.preprocessing.image import ImageDataGenerator | |
| from keras.utils import multi_gpu_model | |
| from keras.callbacks import TensorBoard, EarlyStopping | |
| import math | |
| os.environ["CUDA_VISIBLE_DEVICES"] = "2, 3" | |
| def AlexNet(input_shape=(224, 224, 3), num_classes=10, l2_reg=0.0, weights=None): | |
| """ | |
| AlexNet model | |
| :param input_shape: input shape | |
| :param num_classes: the number of classes | |
| :param l2_reg: | |
| :param weights: | |
| :return: model | |
| """ | |
| input_layer = Input(shape=input_shape) | |
| # Layer 1 | |
| # In order to get the same size of the paper mentioned, add padding layer first | |
| x = ZeroPadding2D(padding=(2, 2))(input_layer) | |
| x = conv_block(x, filters=96, kernel_size=(11, 11), | |
| strides=(4, 4), padding="valid", l2_reg=l2_reg, name='Conv_1_96_11x11_4') | |
| x = MaxPool2D(pool_size=(3, 3), strides=(2, 2), padding="valid", name="maxpool_1_3x3_2")(x) | |
| # Layer 2 | |
| x = conv_block(x, filters=256, kernel_size=(5, 5), | |
| strides=(1, 1), padding="same", l2_reg=l2_reg, name="Conv_2_256_5x5_1") | |
| x = MaxPool2D(pool_size=(3, 3), strides=(2, 2), padding="valid", name="maxpool_2_3x3_2")(x) | |
| # Layer 3 | |
| x = conv_block(x, filters=384, kernel_size=(3, 3), | |
| strides=(1, 1), padding="same", l2_reg=l2_reg, name="Conv_3_384_3x3_1") | |
| # Layer 4 | |
| x = conv_block(x, filters=384, kernel_size=(3, 3), | |
| strides=(1, 1), padding="same", l2_reg=l2_reg, name="Conv_4_384_3x3_1") | |
| # Layer 5 | |
| x = conv_block(x, filters=256, kernel_size=(3, 3), | |
| strides=(1, 1), padding="same", l2_reg=l2_reg, name="Conv_5_256_3x3_1") | |
| x = MaxPool2D(pool_size=(3, 3), strides=(2, 2), padding="valid", name="maxpool_3_3x3_2")(x) | |
| # Layer 6 | |
| x = Flatten()(x) | |
| x = Dense(units=4096)(x) | |
| x = BatchNormalization()(x) | |
| x = Activation('relu')(x) | |
| # Layer 7 | |
| x = Dense(units=4096)(x) | |
| x = BatchNormalization()(x) | |
| x = Activation('relu')(x) | |
| # Layer 8 | |
| x = Dense(units=num_classes)(x) | |
| x = BatchNormalization()(x) | |
| x = Activation("softmax")(x) | |
| if weights is not None: | |
| x.load_weights(weights) | |
| model = Model(input_layer, x, name="AlexNet") | |
| return model | |
| def conv_block(layer, filters, kernel_size=(3, 3), strides=(1, 1), padding='valid', l2_reg=0.0, name=None): | |
| x = Conv2D(filters=filters, | |
| kernel_size=kernel_size, | |
| strides=strides, | |
| padding=padding, | |
| kernel_regularizer=l2(l2_reg), | |
| kernel_initializer="he_normal", | |
| name=name)(layer) | |
| x = BatchNormalization()(x) | |
| x = Activation('relu')(x) | |
| return x | |
| input_shape = (224, 224, 3) | |
| num_classes = 10 | |
| alexnet = AlexNet(input_shape=input_shape, num_classes=num_classes) | |
| alexnet.summary() | |
| parallel_model = multi_gpu_model(alexnet, gpus=2) | |
| epochs = 200 | |
| model_name = "AlexNet-2" | |
| train_dir = r'/home/lst/datasets/cifar-10-images_train/' | |
| test_dir = r'/home/lst/datasets/cifar-10-images_test/' | |
| batch_size = 256 | |
| target_weight_height = (224, 224) | |
| parallel_model.compile(loss=['categorical_crossentropy'], | |
| optimizer='adadelta', | |
| metrics=["accuracy"]) | |
| tensorboard = TensorBoard(log_dir=f'./logs/{model_name}', histogram_freq=0, | |
| write_graph=True, write_images=False) | |
| early_stopping = EarlyStopping(monitor='val_loss', patience=20, verbose=1) | |
| train_datagen = ImageDataGenerator( | |
| rotation_range=40, | |
| width_shift_range=0.2, | |
| height_shift_range=0.2, | |
| rescale=1. / 255, | |
| shear_range=0.2, | |
| zoom_range=0.2, | |
| horizontal_flip=True, | |
| fill_mode="nearest") | |
| test_datagen = ImageDataGenerator(rescale=1. / 255) | |
| train_generator = train_datagen.flow_from_directory( | |
| train_dir, | |
| target_size=target_weight_height, | |
| batch_size=batch_size, | |
| class_mode='categorical') | |
| validation_generator = test_datagen.flow_from_directory( | |
| test_dir, | |
| target_size=target_weight_height, | |
| batch_size=batch_size, | |
| class_mode='categorical') | |
| num_train_samples = train_generator.samples | |
| num_val_samples = validation_generator.samples | |
| history = parallel_model.fit_generator(train_generator, | |
| validation_data=validation_generator, | |
| steps_per_epoch=math.ceil(num_train_samples / batch_size), | |
| validation_steps=math.ceil(num_val_samples / batch_size), | |
| epochs=epochs, | |
| callbacks=[tensorboard, early_stopping], | |
| ) | |
| parallel_model.save(f"{model_name}.h5") |
来源:https://www.cnblogs.com/sun-321/p/11919616.html