1.DenseNet网络结构

论文题目:《Densely Connected Convolutional Networks》

论文地址:https://arxiv.org/abs/1608.06993

DenseNet是CVPR2017的Best Paper,网络的基本思路与ResNet差不多,但是它的不同之处是将前面所有层与后面层的密集连接,目的是实现特征重用。这一特点使DenseNet在参数和计算成本更少的情形下实现比ResNet更优的性能。Densenet由DenseBlock和间隔模块Transition Layer组成。

2.数据集

采用kaggle上的猫狗数据集,总共10000张图片,猫和狗分别有5000张,取4000张图片作为训练集,1000张图片作为验证集

kaggle数据集地址:https://www.kaggle.com/chetankv/dogs-cats-images

每张图片的大小都不同,进行训练的时候需要将所有图片resize到相同的大小(224×224),然后输入到网络进行训练。

3.训练代码

新建train.py文件:

import numpy as np

from tensorflow.keras.optimizers import Adam

import cv2

from tensorflow.keras.preprocessing.image import img_to_array

from sklearn.model_selection import train_test_split

from tensorflow.python.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau

from tensorflow.keras.applications.densenet import DenseNet121

import os

from tensorflow.keras.preprocessing.image import ImageDataGenerator

import matplotlib.pyplot as plt



norm_size = 224

datapath = 'data/train'

EPOCHS = 100

INIT_LR = 1e-3

labelList = []

dicClass = {'cat': 0, 'dog': 1}

classnum = 2

batch_size = 256



# 加载数据

def loadImageData():

    imageList = []

    listImage = os.listdir(datapath)

    for img in listImage:

        labelName = dicClass[img.split('.')[0]]

        print(labelName)

        labelList.append(labelName)

        dataImgPath = os.path.join(datapath, img)

        print(dataImgPath)

        image = cv2.imdecode(np.fromfile(dataImgPath, dtype=np.uint8), -1)

        image = cv2.resize(image, (norm_size, norm_size), interpolation=cv2.INTER_LANCZOS4)

        image = img_to_array(image)

        imageList.append(image)

    imageList = np.array(imageList, dtype="int") / 255.0

    return imageList





print("开始加载数据")

imageArr = loadImageData()

labelList = np.array(labelList)

print("加载数据完成")

print(labelList)



model = DenseNet121(weights=None, classes=classnum)

optimizer = Adam(lr=INIT_LR)

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

trainX, valX, trainY, valY = train_test_split(imageArr, labelList, test_size=0.3, random_state=42)





train_datagen = ImageDataGenerator(featurewise_center=True,

                                   featurewise_std_normalization=True,

                                   rotation_range=20,

                                   width_shift_range=0.2,

                                   height_shift_range=0.2,

                                   horizontal_flip=True)

val_datagen = ImageDataGenerator()  # 验证集不做图片增强



train_generator = train_datagen.flow(trainX, trainY, batch_size=batch_size, shuffle=True)

val_generator = val_datagen.flow(valX, valY, batch_size=batch_size, shuffle=True)

checkpointer = ModelCheckpoint(filepath='weights_bestDogVSCcat_Deset_model.hdf5',

                               monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')



reduce = ReduceLROnPlateau(monitor='val_accuracy', patience=10,

                           verbose=1,

                           factor=0.5,

                           min_lr=1e-6)

history = model.fit_generator(train_generator,

                              steps_per_epoch=trainX.shape[0] / batch_size,

                              validation_data=val_generator,

                              epochs=EPOCHS,

                              validation_steps=valX.shape[0] / batch_size,

                              callbacks=[checkpointer, reduce],

                              verbose=1, shuffle=True)

model.save('my_DogVSCat_model_Desnet.h5')

print(history)



loss_trend_graph_path = r"WW_loss.jpg"

acc_trend_graph_path = r"WW_acc.jpg"



print("Now,we start drawing the loss and acc trends graph...")

# summarize history for accuracy

fig = plt.figure(1)

plt.plot(history.history["accuracy"])

plt.plot(history.history["val_accuracy"])

plt.title("Model accuracy")

plt.ylabel("accuracy")

plt.xlabel("epoch")

plt.legend(["train", "test"], loc="upper left")

plt.savefig(acc_trend_graph_path)

plt.close(1)

# summarize history for loss

fig = plt.figure(2)

plt.plot(history.history["loss"])

plt.plot(history.history["val_loss"])

plt.title("Model loss")

plt.ylabel("loss")

plt.xlabel("epoch")

plt.legend(["train", "test"], loc="upper left")

plt.savefig(loss_trend_graph_path)

plt.close(2)

print("We are done, everything seems OK...")

4.测试代码

新建test.py文件对模型进行测试:

import cv2

import numpy as np

from tensorflow.keras.preprocessing.image import img_to_array

from tensorflow.keras.models import load_model

import time

import os

os.environ['CUDA_VISIBLE_DEVICES'] = '0'

norm_size = 224

imagelist = []

emotion_labels = {

    0: 'cat',

    1: 'dog'

}

# emotion_classifier = load_model("my_model_Desnet.h5")

emotion_classifier = load_model("save_weights/weights_bestDogVSCcat_Deset_model.hdf5")

# emotion_classifier = load_model("weights_best_Deset_model.hdf5")

# emotion_classifier = load_model("dogVScat_Desnet121.h5")

t1 = time.time()

image = cv2.imdecode(np.fromfile('test/test1.jpg', dtype=np.uint8), -1)

# load the image, pre-process it, and store it in the data list

image = cv2.resize(image, (norm_size, norm_size), interpolation=cv2.INTER_LANCZOS4)

image = img_to_array(image)

imagelist.append(image)

imageList = np.array(imagelist, dtype="float") / 255.0

pre = np.argmax(emotion_classifier.predict(imageList))

emotion = emotion_labels[pre]

t2 = time.time()

print(emotion)

t3 = t2-t1

print(t3)

有问题请添加qq:498609554交流!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐