卷积神经网络,计算机视觉应用几乎都在使用的一种深度学习模型。
一般用于训练数据集较小的问题,比如图像分类。
简介
卷积神经网络是一种多层神经网络,主要由输入层,卷积层,激励函数,池化层和全连接层组成,可以通过一系列方法,成功将数据量庞大的图片识别问题不断降维,最终使其能够被训练。
输入层
即数据的输入。
通过传入参数 input_shape=(28, 28, 1)
来设置网络接收张量的形状。
卷积层
使用卷积核来进行特征提取和特征映射。
当我们输入的图像是 28 * 28 * 1 ,定义一个 3 * 3 的卷积核来对图像进行卷积操作(可以理解为一个滑动窗口,把卷积核与对应的图像像素做乘积然后求和),得到了 3 * 3 的卷积结果。
这个过程我们可以理解为我们使用一个过滤器(卷积核)来过滤图像的各个小区域,从而得到这些小区域的特征值。
激励层
激励层主要对卷积层的输出进行一个非线性映射,因为卷积层的计算还是一种线性计算。
使用的激励函数一般是 ReLu。
卷积层和激励层一般合并在一起成为“卷积层”。
池化层
其实就是下采样。一般在卷积层后边,通过池化来压缩卷积层输出的特征向量,使特征图变小,简化网络计算复杂度,同时改善结果。
全连接层
在这里的作用由提取特征变成了分类。
实例化网络
实例化一个简单的卷积神经网络模型。
1 2 3 4 5 6 7 8 9 10 11
| from keras import layers from keras import 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.Conv2D(64, (3, 3), activation='relu'))
print(model.summary())
|
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_1 (Conv2D) (None, 26, 26, 32) 320 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 13, 13, 32) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 11, 11, 64) 18496 _________________________________________________________________ max_pooling2d_2 (MaxPooling2 (None, 5, 5, 64) 0 _________________________________________________________________ conv2d_3 (Conv2D) (None, 3, 3, 64) 36928 ================================================================= Total params: 55,744 Trainable params: 55,744 Non-trainable params: 0 _________________________________________________________________ None
|
首先是网络层设置,这里是 5 层神经网络。
添加第一个卷积层,滤波器数量是 32,卷积窗口大小是 3 * 3,strides 指卷积沿高度和宽度的步幅,默认(1, 1),padding 是指卷积窗口滑动的方式,两个参数:默认 VALID 和 SAME,SAME 采用的是补全,即宽度不够时先补 0 再滑动,VALID 则直接丢弃多余的元素,激励函数选择 relu。因为是第一层,所以需要说明输入数据的 shape。
第一层 pooling(池化,下采样),将数据分辨率长宽各降低一半。
然后再继续添加,接下来把最后输出张量 (3, 3, 64)展平输入到一个全连接层。
添加全连接层分类器
1 2 3
| model.add(layers.Flatten()) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(10, activation='softmax'))
|
继续打印,查看模型结构:
1 2 3 4 5
| flatten_1 (Flatten) (None, 576) 0 _________________________________________________________________ dense_1 (Dense) (None, 64) 36928 _________________________________________________________________ dense_2 (Dense) (None, 10) 650
|
可以看到数据再丢入分类器之前被展平成了一维 (None, 576)
训练网络
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| from keras.datasets import mnist from keras.utils import to_categorical (train_images, train_labels), (test_images, test_labels) = mnist.load_data() train_images = train_images.reshape((60000, 28, 28, 1)) train_images = train_images.astype('float32') / 255 test_images = test_images.reshape((10000, 28, 28, 1)) test_images = test_images.astype('float32') / 255 train_labels = to_categorical(train_labels) test_labels = to_categorical(test_labels)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(train_images, train_labels, epochs=5, batch_size=64)
test_loss, test_acc = model.evaluate(test_images, test_labels)
print(test_acc)
|
先通过张量变形格式化数据, 然后配置学习过程,开始训练。
最后打印结果可以看到精度为 0.9913 ,比之前的神经网络精度高了很多。