卷积神经网络CNN,也称为ConvNet,是计算机视觉应用里面最热门的应用。这篇文章不讲其原理,只讲使用。
这次,也是用MNIST数据集来做例子,因为它刚好就是图像数据。
一开始,当然还是导入MNIST数据集了,不过这次不用把它改变为向量,而是保持它原有的结构,而且在最后加上一个维度,因为通常情况下,图像是有颜色通道的,一般是RGB 3种颜色,所以还有一个维度是颜色的维度,Keras是 channel last,也就是说最后一维代表的是颜色通道。
from keras.datasets import mnist
from keras.utils import to_categorical
(train_X, train_y), (test_X, test_y) = mnist.load_data()
train_X = train_X.reshape(-1, 28, 28, 1) / 255
test_X = test_X.reshape(-1, 28, 28, 1) / 255
train_y = to_categorical(train_y)
test_y = to_categorical(test_y)
首先,需要的keras库,并搭建模型:
Conv2d(32, (3,3))
是指一共32个filter,每个filter的大小为$3\times 3$的小正方形;input_shape=(28, 28, 1)
,是因为还要考虑到颜色通道;MaxPooling2D
是池化层,这里不细说;Flatten()
是将多维的数据转换为1维,只有可以用全连接层进行计算
from keras import layers, models
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3,3), activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
可以使用model.summary()
来看各层的具体情况
model.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_5 (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 13, 13, 32) 0
_________________________________________________________________
conv2d_6 (Conv2D) (None, 11, 11, 64) 18496
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 5, 5, 64) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 1600) 0
_________________________________________________________________
dense_1 (Dense) (None, 128) 204928
_________________________________________________________________
dense_2 (Dense) (None, 10) 1290
=================================================================
Total params: 225,034
Trainable params: 225,034
Non-trainable params: 0
_________________________________________________________________
现在,可以编译模型,并且进行训练了
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(train_X, train_y, epochs=5, batch_size=128)
Epoch 1/5
60000/60000 [==============================] - 5s 81us/step - loss: 0.1995 - acc: 0.9395
Epoch 2/5
60000/60000 [==============================] - 2s 30us/step - loss: 0.0516 - acc: 0.9844
Epoch 3/5
60000/60000 [==============================] - 2s 31us/step - loss: 0.0345 - acc: 0.9895
Epoch 4/5
60000/60000 [==============================] - 2s 30us/step - loss: 0.0251 - acc: 0.9925
Epoch 5/5
60000/60000 [==============================] - 2s 30us/step - loss: 0.0192 - acc: 0.9940
再在验证集上测试一下:
model.evaluate(test_X, test_y)
10000/10000 [==============================] - 0s 36us/step
[0.030761008511787077, 0.99]
使用CNN网络,比之前用全连接层的参数少了很多,但效果更好。