原文地址:https://github.com/fchollet/deep-learning-with-python-notebooks/blob/master/5.1-introduction-to-convnets.ipynb
首先,让我们以一个非常简单的闭环实例来看看实际情况。 我们将使用我们的convnet对MNIST数字进行分类,这是您在第2章中已经完成的使用密集连接网络的一项任务(我们的测试精度为97.8%)。 尽管我们的小圆圈将是非常基础的,但它的准确性仍然会从第二章密集连接模型的水中吹出来。
以下6行代码显示了基本的convnet的外观。 它是一堆Conv2D和MaxPooling2D图层。 我们会在一分钟内看到他们具体做什么。 重要的是,一个convnet需要输入形状张量(image_height,image_width,image_channels)(不包括批量维度)。 在我们的例子中,我们将配置我们的convnet处理大小为(28,28,1)的输入,这是MNIST图像的格式。 我们通过将参数input_shape =(28,28,1)传递给我们的第一层来做到这一点。
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'))
让我们展示迄今为止我们的convnet的体系结构:
model.summary()
您可以在上面看到,每个Conv2D和MaxPooling2D图层的输出都是3D形状(高度,宽度,通道)张量。 随着我们深入网络,宽度和高度尺寸趋于缩小。 通道数量由传递给Conv2D图层的第一个参数(例如32或64)控制。
接下来的步骤是将我们最后的输出张量(形状(3,3,64))馈送到密集连接的分类器网络中,就像您已经熟悉的那样:一堆密集层。 这些分类器处理向量,它们是1D,而我们当前的输出是3D张量。 首先,我们将不得不将3D输出平铺到1D,然后在顶部添加一些密集层:
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
我们要做10路分类,所以我们使用一个有10个输出和softmax激活的最终图层。 现在,我们的网络如下所示:
model.summary()
正如你所看到的,我们的(3,3,64)输出在经过两个密集层之前被平坦化为形状的矢量(576,)。
现在,让我们训练一下MNIST数字上的小圆圈。 我们将重用第2章中MNIST示例中已经介绍的很多代码。
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
test_loss, test_acc = model.evaluate(test_images, 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)
test_acc