八、ResNet的网络结构及其代码实现(花的三分类)

@

前文

数据生成器+数据部分展示

# 读取数据
#利用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下载地址:

Tensorflow1.15深度学习

posted @ 2021-12-05 02:40  李好秀  阅读(522)  评论(0编辑  收藏  举报