箱子项目-efficientnet-with-attention

环境:

基础:

  • window 10
  • python 3.6

NVIDIA的GPU并行计算架构:

  • CUDA 10.0
  • cuDNN 7.4.1

python包:

  • Keras==2.2.5
  • h5py==2.10.0
  • matplotlib==3.2.0
  • numpy==1.19.5
  • opencv-python==3.4.1.15
  • opencv-contrib-python==3.4.1.15
  • efficientnet==1.1.1
  • tensorflow-gpu==1.14.0

代码:

import cv2
from keras.utils import np_utils
from matplotlib import pyplot as plt
from keras import optimizers
from keras.models import *
from keras.layers import *
from keras.callbacks import *
from efficientnet.keras import EfficientNetB3

"""
变量说明:
    n_classes:分类的数量(这里为2,即一共有2类)
    n_dataset:单类数据集的数量(这里每一类数量要求相同)
    a_path,b_path:A、B数据集的地址
    X_train,Y_train:数据集,标签集
    img_rows, img_cols:图片大小
    batch_size:一次训练所选取的样本数
    epochs:整个训练数据集被反复训练的次数
    optimizer:优化器
"""

n_classes = 2
dataset = 20
a_path = r"C:\d\WPSCloud\dataset\A"
b_path = r"C:\d\WPSCloud\dataset\B"
img_rows, img_cols = 224, 224
batch_size = 16
epochs = 30
freeze_num = 379
optimizer = optimizers.Adam(lr=0.0001)


# 加载数据集
def load_dataset(a_path, b_path):
    X_train = []
    Y_train = []
    for i in range(dataset):
        img_path = a_path + '/' + 'a' + str(i) + '.jpg'
        img = get_img(img_path, img_rows, img_cols)
        X_train.append(img)
        Y_train.append(0)

        img_path = b_path + '/' + 'b' + str(i) + '.jpg'
        img = get_img(img_path, img_rows, img_cols)
        X_train.append(img)
        Y_train.append(1)
    X_train = np.array(X_train, np.float32)
    Y_train = oneHot(Y_train)
    return X_train, Y_train


# 读取图片
def get_img(file_path, img_rows, img_cols):
    img = cv2.imread(file_path)
    img = cv2.resize(img, (img_rows, img_cols))
    if img.shape[2] == 1:
        img = np.dstack([img, img, img])
    else:
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = img.astype(np.float32)

    return img


# 对标签数据进行one-hot编码
def oneHot(y):
    return np_utils.to_categorical(y, len(np.unique(y)))


# 绘制训练过程中的 loss 和 acc 变化曲线
def history_plot(history_fit):
    plt.figure(figsize=(12, 6))

    # summarize history for accuracy
    plt.subplot(121)
    plt.plot(history_fit.history["acc"])
    plt.plot(history_fit.history["val_acc"])
    plt.title("model accuracy")
    plt.ylabel("accuracy")
    plt.xlabel("epoch")
    plt.legend(["train", "valid"], loc="upper left")

    # summarize history for loss
    plt.subplot(122)
    plt.plot(history_fit.history["loss"])
    plt.plot(history_fit.history["val_loss"])
    plt.title("model loss")
    plt.ylabel("loss")
    plt.xlabel("epoch")
    plt.legend(["train", "test"], loc="upper left")

    plt.show()


# fine-tune 模型
def fine_tune_model(model, optimizer, batch_size, epochs, freeze_num,X_train,Y_train):
    for layer in model.layers[:]:
        layer.trainable = True

    rc = ReduceLROnPlateau(monitor="val_loss",
                           factor=0.2,
                           patience=3,
                           verbose=1,
                           mode='min')

    model_name = model.name + ".hdf5"
    mc = ModelCheckpoint(model_name,
                         monitor="val_loss",
                         save_best_only=True,
                         verbose=1,
                         mode='min')
    el = EarlyStopping(monitor="val_loss",
                       min_delta=0,
                       patience=5,
                       verbose=1,
                       restore_best_weights=True)

    model.compile(optimizer=optimizer,
                  loss='categorical_crossentropy',
                  metrics=["accuracy"])

    history_fit = model.fit(X_train,
                            Y_train,
                            batch_size=batch_size,
                            epochs=epochs,
                            shuffle=True,
                            verbose=1,
                            validation_split=0.3,
                            callbacks=[mc, rc, el])

    print('Finish fine-tune')
    return history_fit


# 定义一个加入Attention模块的Efficient网络架构即efficientnet-with-attention
def efficient_attention_model(img_rows, img_cols,n_classes):
    in_lay = Input(shape=(img_rows, img_cols, 3))
    base_model = EfficientNetB3(input_shape=(img_rows, img_cols, 3), weights="imagenet", include_top=False)
    pt_depth = base_model.get_output_shape_at(0)[-1]
    pt_features = base_model(in_lay)
    bn_features = BatchNormalization()(pt_features)

    # here we do an attention mechanism to turn pixels in the GAP on an off
    atten_layer = Conv2D(64, kernel_size=(1, 1), padding="same", activation="relu")(Dropout(0.5)(bn_features))
    atten_layer = Conv2D(16, kernel_size=(1, 1), padding="same", activation="relu")(atten_layer)
    atten_layer = Conv2D(8, kernel_size=(1, 1), padding="same", activation="relu")(atten_layer)
    atten_layer = Conv2D(1, kernel_size=(1, 1), padding="valid", activation="sigmoid")(atten_layer)  # H,W,1
    # fan it out to all of the channels
    up_c2_w = np.ones((1, 1, 1, pt_depth))  # 1,1,C
    up_c2 = Conv2D(pt_depth, kernel_size=(1, 1), padding="same", activation="linear", use_bias=False, weights=[up_c2_w])
    up_c2.trainable = False
    atten_layer = up_c2(atten_layer)  # H,W,C

    mask_features = multiply([atten_layer, bn_features])  # H,W,C

    gap_features = GlobalAveragePooling2D()(mask_features)  # 1,1,C

    gap_dr = Dropout(0.25)(gap_features)
    dr_steps = Dropout(0.25)(Dense(1000, activation="relu")(gap_dr))
    out_layer = Dense(n_classes, activation="softmax")(dr_steps)
    eb_atten_model = Model(inputs=[in_lay], outputs=[out_layer])

    return eb_atten_model

# 加载数据集和标签集
X_train, Y_train = load_dataset(a_path, b_path)

# 创建Efficient模型
eB_atten_model = efficient_attention_model(img_rows,img_cols,n_classes)

# 进行训练
eB_model_history  = fine_tune_model(eB_atten_model,optimizer,batch_size,epochs,freeze_num,X_train,Y_train)

# 绘制训练过程中的 loss 和 acc 变化曲线
history_plot(eB_model_history)

训练过程中的 loss 和 acc 变化曲线:

箱子项目-efficientnet-with-attention

上一篇:Team Foundation Server 安装配置教程


下一篇:A Child's History of England.227