Keras学习(三)CIFAR10 识别---CNN 实现(1)

【本系列博文是学习 Keras 的笔记,Keras 版本为2.1.5,主要的参考资料为:Keras中文文档】
我们之前一直利用 MNIST 数据进行学习,现在对一个更复杂点的数据集–CIFAR-10–进行实验学习。这一节,主要了解下 Keras 数据增强(data Augmentation)

CIFAR-10数据集

这是一个经典的数据集,包含 6000 张 32 × × 32 的彩色图片,其中训练集 5000 张,测试集 10000 张。 CIFAR-10 如同其名字,一共标注为 10 类,每一类图片 6000 张。这 10 类分别是 airplane、automobile、bird、cat、deer、dog、frog、horse、ship 和 truck, 其中没有任何重叠的情况。CIFAR-10 数据集可在官网直接下载。我把它处理成了 Numpy 的 npz 格式了,更方便读取。
下面简单看看这个数据:

import cv2
import numpy as np
import dataset
(x_train, y_train), (x_test, y_test) = dataset.load_data( './datasets/cifar10.npz')
fig = dataset.show_cifar(x_train,y_train,[10,20],9)
cv2.imwrite('./figs/cifar10/truck.png',fig)

dataset.load_data()读取 npz 格式的数据。x_train 的 大小为 (5000,32,32,3),y_train 是一维数组,数值表示其类别。test 数据具有相同的数据结构。dataset.show_cifar() 能够显示某一类别的数据。dataset.show_cifar() 返回一个 uint8 的三维数组,可以直接输出为一个图片。下面是 truck(大卡车) 的一些示例。

Keras学习(三)CIFAR10 识别---CNN 实现(1)_第1张图片

CNN网络

载入必须的模块:

import keras
import dataset as cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D

载入数据及预处理:

batch_size = 32
num_classes = 10
epochs = 100
(x_train, y_train), (x_test, y_test) = cifar10.load_data('./datasets/cifar10.npz')
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

网络结构,4 个卷积层和 2 个全连接层。卷积层统一使用 3 × × 3 小卷积核,模型参数共 120 万,:

model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same',
                 input_shape=x_train.shape[1:]))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))

下面初始化优化器,并编译模型:

opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)
model.compile(loss='categorical_crossentropy',
              optimizer=opt,
              metrics=['accuracy'])

图片增强

图片增强需要利用到 ImageDataGenerator。

keras.preprocessing.image.ImageDataGenerator(featurewise_center=False,
    samplewise_center=False,
    featurewise_std_normalization=False,
    samplewise_std_normalization=False,
    zca_whitening=False,
    zca_epsilon=1e-6,
    rotation_range=0.,
    width_shift_range=0.,
    height_shift_range=0.,
    shear_range=0.,
    zoom_range=0.,
    channel_shift_range=0.,
    fill_mode='nearest',
    cval=0.,
    horizontal_flip=False,
    vertical_flip=False,
    rescale=None,
    preprocessing_function=None,
    data_format=K.image_data_format())

用以生成一个batch的图像数据,支持实时数据提升。训练时该函数会无限生成数据,直到达到规定的epoch次数为止。

参数

  • featurewise_center:布尔值,使输入数据集去中心化(均值为 0), 按 feature 执行
  • samplewise_center:布尔值,使输入数据的每个样本均值为 0
  • featurewise_std_normalization:布尔值,将输入除以数据集的标准差以完成标准化, 按 feature 执行
  • samplewise_std_normalization:布尔值,将输入的每个样本除以其自身的标准差
  • zca_whitening:布尔值,对输入数据施加 ZCA 白噪化
  • zca_epsilon: ZCA使用的eposilon,默认1e-6
  • rotation_range:整数,数据提升时图片随机转动的角度
  • width_shift_range:浮点数,图片宽度的某个比例,数据提升时图片水平偏移的幅度
  • height_shift_range:浮点数,图片高度的某个比例,数据提升时图片竖直偏移的幅度
  • shear_range:浮点数,剪切强度(逆时针方向的剪切变换角度)
  • zoom_range:浮点数或形如 [lower,upper] 的列表,随机缩放的幅度,若为浮点数,则相当于 [lower,upper] = [1 - zoom_range, 1+zoom_range]
  • channel_shift_range:浮点数,随机通道偏移的幅度
  • fill_mode:‘constant’,‘nearest’,‘reflect’ 或 ‘wrap’ 之一,当进行变换时超出边界的点将根据本参数给定的方法进行处理
  • cval:浮点数或整数,当 fill_mode = constant 时,指定要向超出边界的点填充的值
  • horizontal_flip:布尔值,进行随机水平翻转
  • vertical_flip:布尔值,进行随机竖直翻转
  • rescale: 重放缩因子,默认为 None. 如果为 None 或 0 则不进行放缩,否则会将该数值乘到数据上(在应用其他变换之前)
  • preprocessing_function: 将被应用于每个输入的函数。该函数将在任何其他修改之前运行。该函数接受一个参数,为一张图片(秩为 3 的numpy array),并且输出一个具有相同 shape 的 numpy array
  • data_format:字符串,“channel_first” 或 “channel_last” 之一

方法

  • fit (x, augment = False, rounds=1):计算依赖于数据的变换所需要的统计信息(均值方差等),只有使用 featurewise_center,featurewise_std_normalization或zca_whitening 时需要此函数。
    • x:numpy array,样本数据,秩应为4,在黑白图像的情况下 channel 轴的值为 1,在彩色图像情况下值为 3
    • augment:布尔值,确定是否使用随机提升过的数据
    • round:若设 augment = True,确定要在数据上进行多少轮数据提升,默认值为 1
    • seed: 整数,随机数种子
  • flow(self, X, y, batch_size=32, shuffle=True, seed=None, save_to_dir=None, save_prefix=”, save_format=’png’):接收 numpy 数组和标签为参数,生成经过数据提升或标准化后的 batch 数据,并在一个无限循环中不断的返回 batch 数据

    • x:样本数据,秩应为 4.在黑白图像的情况下 channel 轴的值为 1,在彩色图像情况下值为 3
    • y:标签
    • batch_size:整数,默认32
    • shuffle:布尔值,是否随机打乱数据,默认为True
    • save_to_dir:None或字符串,该参数能让你将提升后的图片保存起来,用以可视化
    • save_prefix:字符串,保存提升后图片时使用的前缀, 仅当设置了save_to_dir 时生效
    • save_format:”png”或”jpeg”之一,指定保存图片的数据格式,默认”jpeg”
    • yields:形如 (x,y) 的 tuple,x是代表图像数据的 numpy 数组,y是代表标签的numpy 数组。该迭代器无限循环.
    • seed: 整数,随机数种子

本例中,我们采用下面的数据增强方式:

   #数据增强
    datagen = ImageDataGenerator(
        featurewise_center=False, 
        samplewise_center=False,  
        featurewise_std_normalization=False,  
        samplewise_std_normalization=False,  
        zca_whitening=False,  
        rotation_range=0,  
        width_shift_range=0.1,  
        height_shift_range=0.1,  
        horizontal_flip=True,  
        vertical_flip=False) 

    datagen.fit(x_train)

    model.fit_generator(datagen.flow(x_train, y_train,
                                     batch_size=batch_size),
                        epochs=epochs,
                        validation_data=(x_test, y_test),
                        workers=4)

对于训练,我们也可以这么写

for e in range(epochs):
    batches = 0
    for x_batch, y_batch in datagen.flow(x_train, y_train, batch_size = batch_size):
        loss = model.train(x_batch, y_batch)
        batches += 1
        if batches >= len(x_train) / batch_size:
            # 我们需要 break 这个循环,因为 generator 循环是无穷的
            break

下面是模型在 test 数据上的测试

scores = model.evaluate(x_test, y_test, verbose = 1)
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])

Test_loss: 0.744941353416
Test accuracy:0.7517

本节代码和数据可以在这里下载到(没有积分的可以私信我)。

你可能感兴趣的:(Keras学习笔记)