基于Keras:CIFAR-10-分类

一、概述

  • CIFAR-10是一个比较经典的数据集,主要用于图像分类;
  • 该数据集共有60000张彩色图像,这些图像是32*32,分为10个类,每类6000张图。这里面有50000张用于训练,构成了5个训练批,每一批10000张图;另外10000用于测试,单独构成一批。
  • 测试批的数据里,取自10类中的每一类,每一类随机取1000张。抽剩下的就随机排列组成了训练批,对应的具体类别示例如下所示。在这里插入图片描述

二、基于简单卷积神经网络的CIFAR-10分类

  • 导入数据
    • Keras提供了数据加载的函数: cifar10.load_data(),每次导入数据时,会从内置的网络地址下载数据集到本地。但通常下载缓慢,并不支持断点续传,下载过程中网络稍不稳定中断之后就必须从头开始下载。
    • 因此,可离线下载好数据,再放在特定文件夹下面,具体做法为:

    1.直接下载:http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
    2.将下载下来的文件放到~/.keras/datasets/ 目录下,然后将文件名改名为cifar-10-batches-py.tar.gz ,再次运行代码的时候,则会先检查本地是否存在,存在则使用本地的该数据集,不会再进行下载。

  • 网络结构
32 x 32 32 filter, Size:3 x 3 rate: 0.2 32 filter, Size:3 x 3 rate: 0.2 Size: (2 x 2) 512个神经元+Relu激活 rate: 0.5 10个神经元+softmax激活
输入层 卷积层① Dropout层① 卷积层② Dropout层② (最大)池化层 Flatten 层 全连接层 Dropout层 输出层
  • 完整实现代码
from keras.datasets import cifar10
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.optimizers import SGD
from keras.constraints import maxnorm
from keras.utils import np_utils
from keras import backend
backend.set_image_data_format('channels_first')


# 设定随机数种子
seed = 7
np.random.seed(seed)


# 导入数据
(x_train, y_train), (x_validation, y_validation) = cifar10.load_data()
x_train = x_train.astype('float32')
x_validation = x_validation.astype('float32')
x_train = x_train/255.0
x_validation = x_validation/255.0

# 进行one-hot编码
y_train = np_utils.to_categorical(y_train)
y_validation = np_utils.to_categorical(y_validation)
num_classes = y_train.shape[1]


# 定义模型创建函数
def create_model(epochs=25):
    model = Sequential()
    model.add(Conv2D(32, (3, 3), input_shape=(3, 32, 32), padding='same', activation='relu', kernel_constraint=maxnorm(3)))
    model.add(Dropout(0.2))
    model.add(Conv2D(32, (3, 3), activation='relu', padding='same', kernel_constraint=maxnorm(3)))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Flatten())
    model.add(Dense(512, activation='relu', kernel_constraint=maxnorm(3)))
    model.add(Dropout(0.5))
    model.add(Dense(10, activation='softmax'))
    lrate = 0.01
    decay = lrate/epochs
    sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
    # 编译模型
    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

    return model


epochs = 25
model = create_model(epochs)

# 训练模型及评估模型
model.fit(x=x_train, y=y_train, epochs=epochs, batch_size=32, verbose=2)
score = model.evaluate(x=x_validation, y=y_validation, verbose=0)
print('Accuracy: %.2f%%' % (score[1] * 100))
  • 训练及评估结果(可看出训练时间较长)
Epoch 1/25
 - 590s - loss: 1.6989 - acc: 0.3823
Epoch 2/25
 - 584s - loss: 1.3085 - acc: 0.5293
Epoch 3/25
 - 584s - loss: 1.1180 - acc: 0.6011
Epoch 4/25
 - 579s - loss: 0.9892 - acc: 0.6509
...
Epoch 23/25
 - 561s - loss: 0.2258 - acc: 0.9221
Epoch 24/25
 - 561s - loss: 0.2148 - acc: 0.9257
Epoch 25/25
 - 558s - loss: 0.2110 - acc: 0.9271
Accuracy: 70.91%

三、基于大型卷积神经网络的CIFAR-10分类

  • 卷积神经网络结构

主要按照特征图为32/64/128各两次重复构建模型

输入层:32 x 32
卷积层1-1: 32 filter, Size:3 x 3
Dropout层1: 概率为0.2
卷积层1-2: 32 filter, Size:3 x 3
池化层:MaxPooling, Size = (2, 2)
卷积层2-1: 64 filter, Size:3 x 3
Dropout层2: 概率为0.5
卷积层2-2: 64 filter, Size:3 x 3
池化层:MaxPooling, Size = (2, 2)
卷积层3-1: 128 filter, Size:3 x 3
Dropout层3: 概率为0.2
卷积层3-2: 128 filter, Size:3 x 3
池化层:MaxPooling, Size = (2, 2)
Flatten 层
Dropout层4: 概率为0.5
全连接层: 1024神经元+Relu激活
Dropout层5: 概率为0.2
全连接层: 512神经元+Relu激活
Dropout层:6 概率为0.5
输出层:10个神经元+softmax激活
  • 完整实现代码
from keras.datasets import cifar10
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.optimizers import SGD
from keras.constraints import maxnorm
from keras.utils import np_utils
from keras import backend
backend.set_image_data_format('channels_first')

# 设定随机数种子
seed = 7
np.random.seed(seed)

# 导入数据
(x_train, y_train), (x_validation, y_validation) = cifar10.load_data()

# 将数据格式化到0~1
x_train = x_train.astype('float32')
x_validation = x_validation.astype('float32')
x_train = x_train/255.0
x_validation = x_validation/255.0


# 进行one-hot编码
y_train = np_utils.to_categorical(y_train)
y_validation = np_utils.to_categorical(y_validation)
num_classes = y_train.shape[1]

# 定义模型创建函数
def create_model(epochs=25):
    model = Sequential()
    model.add(Conv2D(32, (3, 3), input_shape=(3, 32, 32), padding='same', activation='relu', kernel_constraint=maxnorm(3)))
    model.add(Dropout(0.2))
    model.add(Conv2D(32, (3, 3), activation='relu', padding='same', kernel_constraint=maxnorm(3)))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same', kernel_constraint=maxnorm(3)))
    model.add(Dropout(0.5))
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same', kernel_constraint=maxnorm(3)))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Conv2D(128, (3, 3), activation='relu', padding='same', kernel_constraint=maxnorm(3)))
    model.add(Dropout(0.2))
    model.add(Conv2D(128, (3, 3), activation='relu', padding='same', kernel_constraint=maxnorm(3)))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Flatten())
    model.add(Dropout(0.5))
    model.add(Dense(1024, activation='relu', kernel_constraint=maxnorm(3)))
    model.add(Dropout(0.2))

    model.add(Dense(512, activation='relu', kernel_constraint=maxnorm(3)))
    model.add(Dropout(0.5))
    model.add(Dense(10, activation='softmax'))
    lrate = 0.01
    decay = lrate/epochs
    sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)

    # 编译模型
    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

    return model


epochs = 25
model = create_model(epochs)

# 训练模型及评估模型
model.fit(x=x_train, y=y_train, epochs=epochs, batch_size=32, verbose=2)
score = model.evaluate(x=x_validation, y=y_validation, verbose=0)
print('Accuracy: %.2f%%' % (score[1] * 100))

  • 训练及评估结果(训练了7个多小时)
Epoch 1/25
 - 984s - loss: 2.0213 - acc: 0.2438
Epoch 2/25
 - 989s - loss: 1.6381 - acc: 0.3902
Epoch 3/25
 - 977s - loss: 1.4468 - acc: 0.4665
Epoch 4/25
 - 1493s - loss: 1.3066 - acc: 0.5236
Epoch 5/25
 - 1044s - loss: 1.2014 - acc: 0.5657
...
Epoch 21/25
 - 1046s - loss: 0.7111 - acc: 0.7487
Epoch 22/25
 - 982s - loss: 0.7010 - acc: 0.7506
Epoch 23/25
 - 1096s - loss: 0.6867 - acc: 0.7595
Epoch 24/25
 - 1037s - loss: 0.6756 - acc: 0.7610
Epoch 25/25
 - 987s - loss: 0.6701 - acc: 0.7647
Accuracy: 76.30%
  • 对比说明
    从训练结果可看出,相比简单的神经网络,后者精度得到了一点提高,但不是特别大; 可根据其他论文中采用其他网络结构进行训练及评估。

猜你喜欢

转载自blog.csdn.net/yph001/article/details/82950570