在上一篇博客:数据挖掘入门系列教程(十一点五)之CNN网络介绍中,介绍了CNN的工做原理和工做流程,在这一篇博客,将具体的使用代码来讲明如何使用keras构建一个CNN网络来对CIFAR-10数据集进行训练。html
若是对keras不是很熟悉的话,能够去看一看官方文档。或者看一看我前面的博客:数据挖掘入门系列教程(十一)之keras入门使用以及构建DNN网络识别MNIST,在数据挖掘入门系列教程(十一)这篇博客中使用了keras构建一个DNN网络,并对keras的作了一个入门使用介绍。python
CIFAR-10数据集是图像的集合,一般用于训练机器学习和计算机视觉算法。它是机器学习研究中使用比较广的数据集之一。CIFAR-10数据集包含10 种不一样类别的共6w张32x32彩色图像。10个不一样的类别分别表明飞机,汽车,鸟类,猫,鹿,狗,青蛙,马,轮船 和卡车。每一个类别有6,000张图像git
在keras刚好提供了这些数据集。加载数据集的代码以下所示:github
from keras.datasets import cifar10 (x_train, y_train), (x_test, y_test) = cifar10.load_data() print(x_train.shape, 'x_train samples') print(x_test.shape, 'x_test samples') print(y_train.shape, 'y_trian samples') print(y_test.shape, 'Y_test samples')
输出结果以下:算法
训练集有5w张图片,测试集有1w张图片。在\(x\)数据集中,图片是\((32,32,3)\),表明图片的大小是\(32 \times 32\),为3通道(R,G,B)的图片。网络
咱们能够稍微的展现一下图片的内容,python代码以下所示:机器学习
import matplotlib.pyplot as plt %matplotlib inline plt.figure(figsize=(12,10)) x, y = 8, 6 for i in range(x*y): plt.subplot(y, x, i+1) plt.imshow(x_train[i],interpolation='nearest') plt.show()
下面就是数据集中的部分图片:ide
一样,咱们须要将类标签进行one-hot编码:学习
import keras # 将类向量转换为二进制类矩阵。 y_train = keras.utils.to_categorical(y_train, 10) y_test = keras.utils.to_categorical(y_test, 10)
实际上这一步还有不少牛逼(骚)操做,好比说对数据集进行加强,变换等等,这样均可以在必定程度上提升模型的鲁棒性,防止过拟合。这里咱们就怎么简单怎么来,就只对数据集标签进行one-hot编码就好了。测试
构建的网络模型代码以下所示:
from keras.models import Sequential from keras.layers import Dense, Dropout, Activation, Flatten,Conv2D, MaxPooling2D # 构建CNN网络 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(10)) model.add(Activation('softmax')) # 网络模型的介绍 print(model.summary())
这里解释一下代码:
Conv2D表明2D的卷积层,可能这里会有人问,个人图片不是3通道(RGB)的吗?为何使用的是Conv2D而不是Conv3D。首先先说明,在Conv2D中的这个“2”表明的是卷积层能够在两个维度(也就是width,length)进行移动。那么同理Conv3D中的“3”表明这个卷积层能够在3个维度进行移动(好比说视频中的width ,length,time)。那么针对RGB这种3通道(channels),卷积过程当中输入有多少个通道,则滤波器(卷积核)就有多少个通道。
简单点来讲就是:
输入
单色图片的input,是2D, \(w \times h\)
彩色图片的input,是3D,\(w \times h \times channels\)
卷积核filter
单色图片的filter,是2D, \(w \times h\)
彩色图片的filter,是3D, \(w \times h \times channels\)
值得注意的是,卷积以后的结果是二维的。(由于会将3维卷积获得的结果进行相加)
接着继续解释Conv2D
的参数:
Conv2D(32, (3, 3), padding='same',input_shape=x_train.shape[1:])
32
表示的是输出空间的维度(也就是filter滤波器的输出数量)(3,3)
表明的是卷积核的大小strides
(这里没有用到):这个表明是滑动的步长。input_shape
:输入的维度,这里是(28,28,3)padding
在上一篇博客介绍过,在keras中有两个取值:"valid"
或 "same"
(大小写敏感)。
Flatten这一层就是为了将多维数据变成一维数据:
from keras.optimizers import RMSprop # 利用 RMSprop 来训练模型。 model.compile(loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy'] )
其余的参数在上两篇博客中已经讲了,就再也不赘述。
这里你们能够根据本身的电脑配置适当调整一下batch_size的大小。
history = model.fit(x_train, y_train, batch_size=32, epochs=64, verbose=1, validation_data=(x_test, y_test) )
在i5-10代u,mx250的状况下,训练一轮大概须要27s左右。
训练完成以后,进行评估:
score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1])
结果以下所示:
这个结果能够说的上是一言难尽,😔。
import matplotlib.pyplot as plt # 绘制训练过程当中训练集和测试集合的准确率值 plt.plot(history.history['accuracy']) plt.plot(history.history['val_accuracy']) plt.title('Model accuracy') plt.ylabel('Accuracy') plt.xlabel('Epoch') plt.legend(['Train', 'Test'], loc='upper left') plt.show() # 绘制训练过程当中训练集和测试集合的损失值 plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('Model loss') plt.ylabel('Loss') plt.xlabel('Epoch') plt.legend(['Train', 'Test'], loc='upper left') plt.show()
最终在batch_size=1024
的状况下(为何不用代码中batch_size=32
的那张图呢?由于那张图没有保存,而我实在是不想再训练等那么久了。)
总的来讲效果不是很好,由于我就是用最基本的网络结构,用的图片也没有进行其余处理。不过原本这篇博客就是为了简单的介绍如何使用keras搭建一个cnn网络,效果差一点就差一点吧。若是想获得更好的效果,kaggle欢迎你们。
项目地址:Github