数据生成器+数据部分展示
# 读取数据 #利用ImageDataGenerator构造数据生成器 from keras.preprocessing.image import ImageDataGenerator IMSIZE = 224 # 根据花的图片数据,构造训练集数据生成器和验证集数据生成器 train_generator = ImageDataGenerator(rescale=1. / 255).flow_from_directory('../../data/data_res/train', target_size=(IMSIZE, IMSIZE), batch_size=5, class_mode='categorical' ) validation_generator = ImageDataGenerator(rescale=1. / 255).flow_from_directory('../../data/data_res/validation', target_size=(IMSIZE, IMSIZE), batch_size=5, class_mode='categorical')
#显示数据 from matplotlib import pyplot as plt plt.figure() fig, ax = plt.subplots(2, 5) fig.set_figheight(7) fig.set_figwidth(15) ax = ax.flatten() X, Y = next(train_generator) for i in range(10): ax[i].imshow(X[i, :, :, :])
构建ResNet模型
首先构建残差学习模块之前的网络结构。
# 构建模型。 from keras.layers import Dense, Flatten from keras.layers import Input from keras.layers import Activation, Conv2D, BatchNormalization, add, MaxPooling2D, AveragePooling2D from keras import Model NB_CLASS = 3 IM_WIDTH = 224 IM_HEIGHT = 224 input_shape = Input(shape=(IM_WIDTH, IM_HEIGHT, 3)) x = Conv2D(64, (7, 7), padding='same', strides=(2, 2), activation='relu')(input_shape) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='same')(x) x0 = x x0
接着构建残差学习模块,其中利用循环的方法进行构建完整的ResNet_50网络结构。
conv2——x
# 一个block,第一个block里面需要更改步长 for i in range(3): x = Conv2D(64, (1, 1), padding='same', strides=(1, 1), activation='relu')(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(64, (3, 3), padding='same', strides=(1, 1), activation='relu')(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(256, (1, 1), padding='same', strides=(1, 1), activation=None)(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization #下面两步为了把输入64通道的数据转换为256个通道,用来让x0和x维数相同 #可以进行加法计算,文章中虚线得得部分 x0 = Conv2D(256, (1, 1), padding='same', strides=(1, 1), activation=None)(x) x0 = BatchNormalization()(x0) #add把输入的x和经过一个block之后输出的结果加在一起 x = add([x, x0]) #求和之后的结果再做一次relu x = Activation('relu')(x) x0 = x x0
conv3——x
#第一个block x = Conv2D(128, (1, 1), padding='same', strides=(2, 2), activation='relu')(x0) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(128, (3, 3), padding='same', strides=(1, 1), activation='relu')(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(512, (1, 1), padding='same', strides=(1, 1), activation=None)(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x1 = Conv2D(512, (1, 1), padding='same', strides=(2, 2), activation=None)(x0) x1 = BatchNormalization()(x1) #一个卷积层加一个batch normalization #add把输入的x和经过一个block之后输出的结果加在一起 x = add([x, x1]) #求和之后的结果再做一次relu x = Activation('relu')(x) #把输入存到另外一个变量中 x1 = x x1
#第2-4个block for i in range(3): x = Conv2D(128, (1, 1), padding='same', strides=(1, 1), activation='relu')(x1) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(128, (3, 3), padding='same', strides=(1, 1), activation='relu')(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(512, (1, 1), padding='same', strides=(1, 1), activation=None)(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization #下面两步为了把输入64通道的数据转换为256个通道,用来让x0和x维数相同 #可以进行加法计算,文章中虚线得得部分 #可以不用 #x1 = Conv2D(256, (1, 1), padding='same', strides=(1, 1), activation=None)(x1) #x1 = BatchNormalization()(x1) #add把输入的x和经过一个block之后输出的结果加在一起 x = add([x, x1]) #求和之后的结果再做一次relu x = Activation('relu')(x) #把输入存到另外一个变量中 x1 = x x1
conv4——x
#conv4——x #第一个block x = Conv2D(256, (1, 1), padding='same', strides=(2, 2), activation='relu')(x1) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(256, (3, 3), padding='same', strides=(1, 1), activation='relu')(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(1024, (1, 1), padding='same', strides=(1, 1), activation=None)(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x2 = Conv2D(1024, (1, 1), padding='same', strides=(2, 2), activation=None)(x1) x2 = BatchNormalization()(x2) #一个卷积层加一个batch normalization #add把输入的x和经过一个block之后输出的结果加在一起 x = add([x, x2]) #求和之后的结果再做一次relu x = Activation('relu')(x) #把输入存到另外一个变量中 x2 = x x2
#第2-6个block for i in range(5): x = Conv2D(256, (1, 1), padding='same', strides=(1, 1), activation='relu')(x2) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(256, (3, 3), padding='same', strides=(1, 1), activation='relu')(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(1024, (1, 1), padding='same', strides=(1, 1), activation=None)(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization #下面两步为了把输入64通道的数据转换为256个通道,用来让x0和x维数相同 #可以进行加法计算,文章中虚线得得部分 #可以不用 #x2 = Conv2D(256, (1, 1), padding='same', strides=(1, 1), activation=None)(x2) #x2 = BatchNormalization()(x2) #add把输入的x和经过一个block之后输出的结果加在一起 x = add([x, x2]) #求和之后的结果再做一次relu x = Activation('relu')(x) #把输入存到另外一个变量中 x2 = x x2
conv5——x
#conv5——x #第一个block x = Conv2D(512, (1, 1), padding='same', strides=(2, 2), activation='relu')(x2) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(512, (3, 3), padding='same', strides=(1, 1), activation='relu')(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(2048, (1, 1), padding='same', strides=(1, 1), activation=None)(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x3 = Conv2D(2048, (1, 1), padding='same', strides=(2, 2), activation=None)(x2) x3 = BatchNormalization()(x3) #一个卷积层加一个batch normalization #add把输入的x和经过一个block之后输出的结果加在一起 x = add([x, x3]) #求和之后的结果再做一次relu x = Activation('relu')(x) #把输入存到另外一个变量中 x3 = x x3
#第2-6个block for i in range(2): x = Conv2D(512, (1, 1), padding='same', strides=(1, 1), activation='relu')(x3) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(512, (3, 3), padding='same', strides=(1, 1), activation='relu')(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization x = Conv2D(2048, (1, 1), padding='same', strides=(1, 1), activation=None)(x) x = BatchNormalization()(x) #一个卷积层加一个batch normalization #下面两步为了把输入64通道的数据转换为256个通道,用来让x0和x维数相同 #可以进行加法计算,文章中虚线得得部分 #可以不用 #x3 = Conv2D(256, (1, 1), padding='same', strides=(1, 1), activation=None)(x3) #x3 = BatchNormalization()(x3) #add把输入的x和经过一个block之后输出的结果加在一起 x = add([x, x3]) #求和之后的结果再做一次relu x = Activation('relu')(x) #把输入存到另外一个变量中 x3 = x x3
ResNet模型构建完成
#在reset最后的部分添加一个dense层,并输出一个二维的结果用来分类 x = x3 x = AveragePooling2D(pool_size=(7, 7), padding="same")(x) x = Flatten()(x) predictions = Dense(NB_CLASS, activation='softmax')(x) model_res = Model(inputs=input_shape, outputs=predictions) model_res.summary()
ResNet模型编译
# 模型编译。利用compile函数实现。 from keras.optimizers import Adam model_res.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.001), metrics=['accuracy'])
ResNet 模型拟合
#模型拟合。利用fit_generator进行拟合,并观察循环过程中,参数的变化。 model_res.fit_generator(train_generator, steps_per_epoch=100, epochs=5, validation_data=validation_generator, validation_steps=100)
GitHub下载地址:
Be First to Comment