mnist数据集
from keras import layers
from keras import models
model = models.Sequential()
#padding为填充,若值为valid则对边界数据不处理,若为same则保留边界处的卷积结果,
#通常会使输入和输出的shape相同,为valid时输出为(26,26,32)
#设卷积神经网络处理大小为(28,28,1)的输入张量
model.add(layers.Conv2D(32, (3, 3),padding = 'valid', activation='relu', input_shape=(28, 28, 1)))
#最大池化运算,在此之前特征图的尺寸为26*26,但最大池化运算将其减半为13*13,最大池化通常使用2*2的窗口和步幅2,目的是将特征图下采样2倍
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'))
model.summary()
目前神经网络的架构:
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
下一步将最后的输出张量输入到一个密集连接分类器网络中。这些分类器能处理1D的向量,但当前的输出为3D的张量。所以首先需要将3D输出为1D。
#Flatten()用于把多维的输入一维化,常用在从卷积层到全连接层的过渡,因为之前的输出是3D张量
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
现在的架构为
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
_________________________________________________________________
flatten_1 (Flatten) (None, 576) 0
_________________________________________________________________
dense_1 (Dense) (None, 64) 36928
_________________________________________________________________
dense_2 (Dense) (None, 10) 650
=================================================================
Total params: 93,322
Trainable params: 93,322
Non-trainable params: 0
训练卷积神经网络:
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))
#训练图像本身保存于uint8类型的数组中,形状为(60000,28,28)取值区间为0-255,所以需要把其转换为float32数组
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255
#转为one_hot编码
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)
test_acc
#结果为0.9932