Keras学习之三:用CNN实现cifar10图像分类模型
1 卷积神经网络简介
卷积神经网络和全连接神经网络一样,都是由多个神经网络层连接而成。不同的是CNN一般是由多个卷积层,池化层交替连接起来,用于提取输入数据的高层特征,并缩小数据的维度。最后对提取出的特征进行神经网络分类形成最终的输出。更详细的卷积神经网络相关知识可参见第4节提供的链接。
2 Keras对CNN的支持
keras.layers包中实现了与CNN相关的层模型,分别实现在convolutional和pooling模块中。
2.1 convolutional模块
convolutional模块中实现了卷积层的层模型,用于数据的特征提取。
层名 | 作用 | 原型 |
---|---|---|
Conv1D | 1维卷积层 | Conv1D(filters, kernel_size, strides=1, padding=’valid’) |
Conv2D | 2维卷积层 | Conv2D(filters, kernel_size, strides=(1, 1), padding=’valid’,dilation_rate=(1, 1)) |
UpSampling1D | 1维上采样,将数据重复指定的次数 | UpSampling2D(size=2) |
UpSampling2D | 2维上采样,将数据在2个维度上重复指定的次数 | UpSampling2D(size=(2, 2)) |
ZeroPadding2D | 边界填充0 | ZeroPadding2D(padding=(1, 1)) |
2D参数说明:
参数 | 说明 |
---|---|
filters | 卷积核的数目,也是处理后输出的深度 |
kernel_size | 过滤器的窗口大小 |
strides | 过滤器卷积的步长 |
padding | 补0策略,valid/same |
activation | 激活函数 |
dilation_rate | 指定dilated convolution中的膨胀比例 |
2.2 pooling模块
pooling模块中实现池化层的的最大池化与平均池化的层模型,用于数据维度的缩减。
层名 | 作用 | 原型 |
---|---|---|
MaxPooling1D | 对1维输入进行最大值池化过滤 | MaxPooling1D(pool_size=2, strides=None, padding=’valid’) |
AveragePooling1D | 对1维输入进行平均池化过滤 | AveragePooling1D(pool_size=2, strides=None, padding=’valid’) |
MaxPooling2D | 对2维输入进行最大值池化过滤 | MaxPooling2D(pool_size=(2, 2), strides=None, padding=’valid’, data_format=None) |
AveragePooling2D | 对3维输入进行平均池化过滤 | AveragePooling2D(pool_size=(2, 2), strides=None, padding=’valid’, data_format=None) |
GlobalMaxPooling1D | 对1维输入进行全局最大值池化过滤 | GlobalMaxPooling1D() |
GlobalAveragePooling1D | 对1维输入进行全局平均值池化过滤 | GlobalAveragePooling1D() |
GlobalMaxPooling2D | 对2维输入进行全局最大值池化过滤 | GlobalMaxPooling2D() |
GlobalAveragePooling2D | 对2维输入进行全局平均值池化过滤 | GlobalAveragePooling2D() |
2D参数说明
参数 | 说明 |
---|---|
pool_size | 过滤器的大小,通常取(2,2)或(3,3) |
strides | 过滤器的移动步长,取2使得输出shape缩小一半 |
padding | valid为1填充,same为0填充 |
data_format | 字符串,channels_first或channels_last之一 |
cifar10分类代码
下面的代码实现了一个下面结构的CNN模型,其结构为:卷积层->池化层->卷积层->池化层->全连结层->全连结层->Softmax层。
import keras
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
num_classes = 10
model_name = 'cifar10.h5'
# The data, shuffled and split between train and test sets:
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train = x_train.astype('float32')/255
x_test = x_test.astype('float32')/255
# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', input_shape=x_train.shape[1:]))
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(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'))
model.summary()
# initiate RMSprop optimizer
opt = keras.optimizers.rmsprop(lr=0.001, decay=1e-6)
# train the model using RMSprop
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
hist = model.fit(x_train, y_train, epochs=40, shuffle=True)
model.save(model_name)
# evaluate
loss, accuracy = model.evaluate(x_test, y_test)
print loss, accuracy