CNN神经网络猫狗分类经典案例

AI:CNN神经网络猫狗分类经典案例

猫狗的训练数据可以在kaggle下载:

https://www.kaggle.com/tongpython/cat-and-dog/data

本例使用ImageDataGenerator在迭代生成训练数据时候,需要把训练数据和验证,测试数据分类放置到data下面三个不同目录文件夹下。如图:

 

因为有猫和狗两类,所有在data/train目录下,再建两个目录data/train/dog和data/train/cat:

同理,其他的data/validation和data/test目录下,再建两个目录:cat和data/,在cat和dog目录下,放置对应的图片。

分类建立完成后,Keras会在ImageDataGenerator迭代过程中,自动的为data/train,data/test,data/validation内部生产训练标签,标签依据就是在data/train,data/test,data/validation下面的分类目录,本例是/dog和/cat目录文件夹作为两分类。

import numpy as np
import matplotlib.pyplot as plt
from keras.preprocessing.image import ImageDataGenerator, image
from keras import layers
from keras import models
from keras.layers import Dropout
from keras import optimizers
from keras.models import load_model

train_dir = './data/train/'
validation_dir = './data/validation/'
model_file_name = 'cat_dog_model.h5'


def init_model():
    model = models.Sequential()

    KERNEL_SIZE = (3, 3)

    model.add(layers.Conv2D(filters=32, kernel_size=KERNEL_SIZE, activation='relu', input_shape=(150, 150, 3)))
    model.add(layers.MaxPooling2D((2, 2)))

    model.add(layers.Conv2D(filters=64, kernel_size=KERNEL_SIZE, activation='relu'))
    model.add(layers.MaxPooling2D((2, 2)))

    model.add(layers.Conv2D(filters=128, kernel_size=KERNEL_SIZE, activation='relu'))
    model.add(layers.MaxPooling2D((2, 2)))

    model.add(layers.Conv2D(filters=128, kernel_size=KERNEL_SIZE, activation='relu'))
    model.add(layers.MaxPooling2D((2, 2)))

    model.add(layers.Flatten())
    model.add(layers.Dense(512, activation='relu'))

    model.add(Dropout(0.5))

    model.add(layers.Dense(1, activation='sigmoid'))

    model.compile(loss='binary_crossentropy',
                  optimizer=optimizers.RMSprop(lr=1e-3),
                  metrics=['accuracy'])

    return model


def fig_loss(history):
    history_dict = history.history
    loss_values = history_dict['loss']
    val_loss_values = history_dict['val_loss']
    epochs = range(1, len(loss_values) + 1)
    plt.plot(epochs, loss_values, 'b', label='Training loss')
    plt.plot(epochs, val_loss_values, 'r', label='Validation loss')
    plt.title('Training and validation loss')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend()
    plt.grid()
    plt.show()


def fig_acc(history):
    history_dict = history.history
    acc = history_dict['accuracy']
    val_acc = history_dict['val_accuracy']
    epochs = range(1, len(acc) + 1)
    plt.plot(epochs, acc, 'g', label='Training acc')
    plt.plot(epochs, val_acc, 'r', label='Validation acc')
    plt.title('Training and validation accuracy')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend()
    plt.grid()
    plt.show()


def fit(model):
    train_datagen = ImageDataGenerator(rescale=1. / 255)
    validation_datagen = ImageDataGenerator(rescale=1. / 255)

    train_generator = train_datagen.flow_from_directory(
        train_dir,
        target_size=(150, 150),
        batch_size=256,
        class_mode='binary')

    validation_generator = validation_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=64,
        class_mode='binary')

    history = model.fit_generator(
        train_generator,
        # steps_per_epoch=,
        epochs=10,
        validation_data=validation_generator,
        # validation_steps=,
    )

    model.save(model_file_name)

    fig_loss(history)
    fig_acc(history)


def predict():
    model = load_model(model_file_name)
    print(model.summary())

    img_path = './data/test/cat/cat.4021.jpg'
    img = image.load_img(img_path, target_size=(150, 150))
    img_tensor = image.img_to_array(img)
    img_tensor = img_tensor / 255
    img_tensor = np.expand_dims(img_tensor, axis=0)
    # 其形状为 (1, 150, 150, 3)
    plt.imshow(img_tensor[0])
    plt.show()

    result = model.predict(img_tensor)
    print(result)


# 画出count个预测结果和图像
def fig_predict_result(model, count):
    test_datagen = ImageDataGenerator(rescale=1. / 255)
    test_generator = test_datagen.flow_from_directory(
        './data/test/',
        target_size=(150, 150),
        batch_size=256,
        class_mode='binary')

    text_labels = []
    plt.figure(figsize=(30, 20))
    # 迭代器可以迭代很多条数据,但我这里只取第一个结果看看
    for batch, label in test_generator:
        pred = model.predict(batch)
        for i in range(count):
            true_reuslt = label[i]
            print(true_reuslt)
            if pred[i] > 0.5:
                text_labels.append('dog')
            else:
                text_labels.append('cat')

            # 4列,若干行的图
            plt.subplot(count / 4 + 1, 4, i + 1)
            plt.title('This is a ' + text_labels[i])
            imgplot = plt.imshow(batch[i])

        plt.show()

        # 可以接着画很多,但是只是随机看看几条结果。所以这里停下来。
        break


if __name__ == '__main__':
    model = init_model()
    fit(model)

    # 利用训练好的模型预测结果。
    predict()

    model = load_model(model_file_name)
    #随机查看10个预测结果并画出它们
    fig_predict_result(model, 10)

 

由于太耗时,本例只训练了10轮。

训练损失和验证损失:

 

训练精度和验证精度:

 

 

随机测试在data/test/目录下的猫狗图片,10张,看看 模型预测的结果:

 

其中1张预测失败,剩余9张预测正确。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangphil

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值