import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
(train_image,train_label),(test_image,test_label) = tf.keras.datasets.fashion_mnist.load_data()
print(train_image.shape)
print(train_label)
>> (60000, 28, 28)
[9 0 0 ... 3 0 5]
# 把输入数据拓宽一个维度,转换成(num,hight,weight,channel)
train_images = np.expand_dims(train_image, -1)
test_images = np.expand_dims(test_image, -1)
train_images.shape
>> (60000, 28, 28, 1)
# 新建顺序模型
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(32, (3,3), input_shape = train_images.shape[1: ], activation = 'relu')) # 输入维度为3,取图片的后三维
model.add(tf.keras.layers.MaxPool2D(pool_size = (2,2))) #下采样,降低参数数量,同时增强下一层卷积的视野
model.add(tf.keras.layers.Conv2D(64, kernel_size = (3,3), activation = 'relu'))
model.add(tf.keras.layers.GlobalAveragePooling2D()) #把卷积之后的图片转换为2维,连到全连接层
model.add(tf.keras.layers.Dense(10, activation = 'softmax'))
model.summary()
>>
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_2 (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 13, 13, 32) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 11, 11, 64) 18496
_________________________________________________________________
global_average_pooling2d_1 ( (None, 64) 0
_________________________________________________________________
dense_1 (Dense) (None, 10) 650
=================================================================
Total params: 19,466
Trainable params: 19,466
Non-trainable params: 0
_________________________________________________________________
# 模型编译
model.compile(optimizer='adam',
loss = 'sparse_categorical_crossentropy',
metrics = ['acc']
)
history = model.fit(train_images, train_label, epochs=20, validation_data=(test_images,test_label))
>>
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 32s 527us/sample - loss: 0.7983 - acc: 0.7568 - val_loss: 0.5376 - val_acc: 0.8111
Epoch 2/20
60000/60000 [==============================] - 32s 529us/sample - loss: 0.4884 - acc: 0.8296 - val_loss: 0.4993 - val_acc: 0.8262
...
Epoch 14/20
60000/60000 [==============================] - 26s 441us/sample - loss: 0.2627 - acc: 0.9064 - val_loss: 0.3258 - val_acc: 0.8891
Epoch 15/20
60000/60000 [==============================] - 28s 460us/sample - loss: 0.2544 - acc: 0.9100 - val_loss: 0.3256 - val_acc: 0.8876
Epoch 16/20
60000/60000 [==============================] - 31s 524us/sample - loss: 0.2499 - acc: 0.9105 - val_loss: 0.3323 - val_acc: 0.8868
Epoch 17/20
60000/60000 [==============================] - 35s 576us/sample - loss: 0.2455 - acc: 0.9121 - val_loss: 0.3455 - val_acc: 0.8830
Epoch 18/20
60000/60000 [==============================] - 29s 491us/sample - loss: 0.2382 - acc: 0.9144 - val_loss: 0.3173 - val_acc: 0.8884
Epoch 19/20
60000/60000 [==============================] - 30s 500us/sample - loss: 0.2348 - acc: 0.9151 - val_loss: 0.3155 - val_acc: 0.8880
Epoch 20/20
60000/60000 [==============================] - 32s 531us/sample - loss: 0.2310 - acc: 0.9167 - val_loss: 0.3366 - val_acc: 0.8834
plt.figure(figsize=(20,8),dpi = 200)
plt.plot(history.epoch, history.history.get('acc'), label = 'acc')
plt.plot(history.epoch, history.history.get('val_acc'), label = 'val_acc')
plt.legend()
>>
<matplotlib.legend.Legend at 0x18f7148ecc8>
通过绘制训练epochs与训练数据集的准确率和测试数据集的准确率折线图的观察到,模型在训练数据集上的准确率比验证数据集上的准确率高,而且模型的准确率在最后还一直呈现上升趋势,说明模型过拟合了并且模型的没有完全达到状态,下面对其进行优化。
# 新建顺序模型
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(64, (3,3),
input_shape = train_images.shape[1: ],
activation = 'relu',padding = "same")) # 输入维度为3,取图片的后三维
model.add(tf.keras.layers.Conv2D(64, kernel_size = (3,3), activation = 'relu', padding = 'same'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.MaxPool2D(pool_size = (2,2))) # 下采样,降低参数数量,同时增强下一层卷积的视野
model.add(tf.keras.layers.Conv2D(128, kernel_size = (3,3), activation = 'relu',padding = 'same'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.MaxPool2D(pool_size = (2,2)))
model.add(tf.keras.layers.Conv2D(256, kernel_size = (3,3), activation = 'relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.GlobalAveragePooling2D()) # 把卷积之后的图片转换为2维,连到全连接层
model.add(tf.keras.layers.Dense(10, activation = 'softmax'))
model.summary()
>>
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_4 (Conv2D) (None, 28, 28, 64) 640
_________________________________________________________________
conv2d_5 (Conv2D) (None, 28, 28, 64) 36928
_________________________________________________________________
dropout (Dropout) (None, 28, 28, 64) 0
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 14, 14, 64) 0
_________________________________________________________________
conv2d_6 (Conv2D) (None, 14, 14, 128) 73856
_________________________________________________________________
dropout_1 (Dropout) (None, 14, 14, 128) 0
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 7, 7, 128) 0
_________________________________________________________________
conv2d_7 (Conv2D) (None, 5, 5, 256) 295168
_________________________________________________________________
dropout_2 (Dropout) (None, 5, 5, 256) 0
_________________________________________________________________
global_average_pooling2d_1 ( (None, 256) 0
_________________________________________________________________
dense_1 (Dense) (None, 10) 2570
=================================================================
Total params: 409,162
Trainable params: 409,162
Non-trainable params: 0
_________________________________________________________________
model.compile(
optimizer='adam',
loss = 'sparse_categorical_crossentropy',
metrics = ['acc']
)
history = model.fit(train_images, train_label, epochs=20, validation_data=(test_images,test_label))
>>
Epoch 1/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.7331 - acc: 0.7903 - val_loss: 0.5045 - val_acc: 0.8555
Epoch 2/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.3989 - acc: 0.8558 - val_loss: 0.4424 - val_acc: 0.8773
Epoch 3/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.3585 - acc: 0.8683 - val_loss: 0.4049 - val_acc: 0.8851
Epoch 4/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.3288 - acc: 0.8810 - val_loss: 0.3946 - val_acc: 0.8867
Epoch 5/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.3084 - acc: 0.8876 - val_loss: 0.3423 - val_acc: 0.9027
Epoch 6/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2901 - acc: 0.8941 - val_loss: 0.3753 - val_acc: 0.8991
Epoch 7/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2826 - acc: 0.8963 - val_loss: 0.3452 - val_acc: 0.9002
Epoch 8/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2719 - acc: 0.9010 - val_loss: 0.3152 - val_acc: 0.9117
Epoch 9/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2663 - acc: 0.9027 - val_loss: 0.3082 - val_acc: 0.9103
Epoch 10/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2605 - acc: 0.9038 - val_loss: 0.2891 - val_acc: 0.9025
Epoch 11/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2544 - acc: 0.9065 - val_loss: 0.3096 - val_acc: 0.9154
Epoch 12/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2512 - acc: 0.9088 - val_loss: 0.2958 - val_acc: 0.9105
Epoch 13/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2469 - acc: 0.9092 - val_loss: 0.2882 - val_acc: 0.9178
Epoch 14/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2436 - acc: 0.9108 - val_loss: 0.2783 - val_acc: 0.9124
Epoch 15/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2400 - acc: 0.9123 - val_loss: 0.2788 - val_acc: 0.9185
Epoch 16/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2400 - acc: 0.9125 - val_loss: 0.2649 - val_acc: 0.9191
Epoch 17/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2376 - acc: 0.9136 - val_loss: 0.2707 - val_acc: 0.9193
Epoch 18/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2368 - acc: 0.9139 - val_loss: 0.2546 - val_acc: 0.9191
Epoch 19/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2327 - acc: 0.9155 - val_loss: 0.3030 - val_acc: 0.9174
Epoch 20/20
1875/1875 [==============================] - 8s 4ms/step - loss: 0.2314 - acc: 0.9154 - val_loss: 0.2615 - val_acc: 0.9239
plt.figure(figsize=(20,8),dpi = 200)
plt.plot(history.epoch, history.history.get('acc'), label = 'acc')
plt.plot(history.epoch, history.history.get('val_acc'), label = 'val_acc')
plt.legend()
>>
<matplotlib.legend.Legend at 0x7f85d0736990>
可以看到测试数据集的准确率一直在训练数据集之上,说明模型没有过拟合,但是训练数据集依然有上升的趋势,说明模型还是训练不足,可以考虑继续优化。