在数据集CIFAR10上使用Keras构建卷积神经网络

Keras是一套构建深度学习模型的高级API,使用Keras可以使构建深度学习模型和摆乐高积木类似,使用不同的组件构建模型即可,不需要复杂的深度学习网络构造。

CIFAR10数据集共有60000张彩色图像,这些图像是32*32,分为10个类,每类6000张图。内容如下

《在数据集CIFAR10上使用Keras构建卷积神经网络》

对于多分类图像识别问题,我们最常采用的方法就是卷积神经网络,重点在于构造合适的网络结构,使得训练精度尽可能高。我们先给出代码,然后对代码进行解释。

from keras import models
from keras import layers
from keras import optimizers
from keras.datasets import cifar10
from keras.utils import to_categorical
from keras.preprocessing.image import ImageDataGenerator
import tools

epchos = 50
steps_per_epoch = 1000
batch_size = 50
model_save_path = "model/cifar.h5"

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=(32, 32, 3)))
model.add(layers.Conv2D(32, (3, 3), padding='same', activation='relu'))
model.add(layers.Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(layers.Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))

model.add(layers.Conv2D(128, (3, 3), padding='same', activation='relu'))
model.add(layers.Conv2D(256, (3, 3), padding='same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))

model.add(layers.Flatten())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

(train_images, train_labels), (test_images, test_labels) = cifar10.load_data()

train_datagen = ImageDataGenerator(
    rescale=1./255,
    width_shift_range=0.1,
    height_shift_range=0.1,
    rotation_range=20,
    horizontal_flip=True,
)

test_datagen = ImageDataGenerator(rescale=1./255)

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

model.compile(optimizer=optimizers.RMSprop(1e-4, decay=1e-6),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

history = model.fit_generator(
    train_datagen.flow(train_images, train_labels, batch_size=batch_size), 
    steps_per_epoch=steps_per_epoch,
    epochs=epchos,
    validation_data=test_datagen.flow(test_images, test_labels, batch_size=batch_size),
    validation_steps=200,
    workers=4)

model.save(model_save_path)

tools.show_accuracy(history)
tools.show_loss(history)

首先是一些常量定义,我们训练模型训练50个epoch,也就是50轮,每轮执行1000次,每个批次使用训练集的50个样本,训练出的模型最终保存在model/cifar.h5文件。

接下来构建我们的卷积神经网络,主要有三块,第一块包括四个卷基层,一个最大池化层和一个Dropout层;第二块包含两个卷积层,一个最大池化层和一个Dropout层;第三块是一个密集连接层,将卷积层的输出平展后,经过一个密集层,最后是输出层。我们使用relu作为激活函数,由于是多分类问题,输出层采用softmax。

这里有几个需要注意的地方,说明一下,我们前面说到,这些训练集图片大小为32*32,图片不大,代码中的卷积层,都使用了参数padding=same,这样,在卷积操作时,会在原始图片外额外添加像素,防止卷积操作后,图片变小。而最大池化层我们不添加padding=same是因为添加的像素可能会对我们的池化操作造成不良影响(添加的额外数据比例过大,本身图片不大),但是这样同样存在一个问题,每一次经过最大池化层后,图像都会减小,当减小到一定程度时,我们就没有办法继续训练了,也就无法添加更多的层了。Dropout层的作用很明显,由于我们的训练集数据不算太多,为了有效防止过拟合的产生。

接下来的内容主要是准备训练集和测试集数据,对于训练集,我们采用ImageDataGenerator添加必要的变换来生成图片,同样是为了防止过拟合,增加可用的数据集规模。而对于测试集,我们为了便于测试,只是做了归一化处理,并不需要对图像进行变形。

to_categorical函数是将label转化为one-shot的形式。

使用compile构建模型,参数中指定了使用的优化算法,使用的误差以及希望训练过程返回的指标。然后就可以使用fit_generator训练模型了。

之后的两个工具方法,是用来显示训练时候的精度和损失的,我将《Python深度学习》这本书中常用的两段代码进行了封装。

import matplotlib.pyplot as plt

def show_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, 'bo', label='Training loss')
    plt.plot(epochs, val_loss_values, 'b', label='Validation loss')
    plt.title('Train and validation loss')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend()

    plt.show()

def show_accuracy(history):
    history_dict = history.history
    acc = history_dict['acc']
    val_acc = history_dict['val_acc']

    epochs = range(1, len(acc) + 1)

    plt.plot(epochs, acc, 'bo', label='Training accuracy')
    plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
    plt.title('Train and validation accuracy')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend()

    plt.show()

经过训练后,模型的精度能达到86%-87%,然后从网上尝试下载一些图片,用模型试试分类吧。

from keras.models import load_model
from PIL import Image
import numpy as np

type_list = ["飞机", "汽车", "鸟", "猫", "鹿", "狗", "狐狸", "马", "船", "卡车"]

pic_path = '3.jpg'
model_path = "model/cifar.h5"

im = Image.open(pic_path)
im = np.array(im).reshape(1, 32, 32, 3)
model = load_model(model_path)

result = model.predict(im)
may_be = np.argmax(result)
print(type_list[may_be])

虽然不到90%的精度,但是对于一些常规的图片,识别率还是不错的。如果想进一步提高训练精度,大家可以尝试调整一下网络的结构和超参数。

《在数据集CIFAR10上使用Keras构建卷积神经网络》

 

    原文作者:有理叔
    原文地址: https://blog.csdn.net/yjp19871013/article/details/93377657
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞