CNN: MINST


import keras
print(keras.__version__)
2.7.0
from keras import Sequential
from keras.datasets import mnist
from keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense
from keras.utils import np_utils
from tensorflow.keras.optimizers import RMSprop
import matplotlib.pyplot as plt

数据预处理

# 一些参数
batch_size = 128
epochs = 10
num_classes = 10
img_rows, img_cols = 28, 28
input_shape = (img_rows, img_cols, 1)   # 输入数据形状

# 获取数据
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# 归一化
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0

# 改变数据形状,格式为(n_samples, rows, cols, channels)
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)

# 控制台打印输出样本数量信息
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
60000 train samples
10000 test samples

one-hot 编码

https://blog.csdn.net/dulingtingzi/article/details/51374487

# 样本标签转化为one-hot编码格式
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)

创建CNN模型

顺序模型 (Keras提供的模型为两类:Sequential 顺序模型;Model 类模型)

https://blog.csdn.net/weixin_42886817/article/details/99831718

model = Sequential() 

过滤 卷积核 激活函数 输入形状

model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu',input_shape=input_shape))
model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))# 卷积核 3*3

最大池化 MaxPooling

model.add(MaxPooling2D(pool_size=(2, 2))) 

防止过拟合 Dropout

model.add(Dropout(rate=0.2)) 
model.add(Flatten())#填充空白区域

全连接层 Dense,激活函数 relu

model.add(Dense(units=128, activation='relu'))
model.add(Dropout(rate=0.5))

softmax分类

model.add(Dense(num_classes, activation='softmax'))

在控制台输出模型参数信息

model.summary()     
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 26, 26, 32)        320       
                                                                 
 conv2d_1 (Conv2D)           (None, 24, 24, 64)        18496     
                                                                 
 max_pooling2d (MaxPooling2D  (None, 12, 12, 64)       0         
 )                                                               
                                                                 
 dropout (Dropout)           (None, 12, 12, 64)        0         
                                                                 
 flatten (Flatten)           (None, 9216)              0         
                                                                 
 dense (Dense)               (None, 128)               1179776   
                                                                 
 dropout_1 (Dropout)         (None, 128)               0         
                                                                 
 dense_1 (Dense)             (None, 10)                1290      
                                                                 
=================================================================
Total params: 1,199,882
Trainable params: 1,199,882
Non-trainable params: 0
_________________________________________________________________

学习率(步长): 分别测试 learning_rate=0.1 和 0.01 ,观察实验结果

损失函数 交叉熵损失函数:categorical_crossentropy

rmsprop = RMSprop(learning_rate=0.01, rho=0.9, epsilon=1e-08, decay=0.0) 
# 学习率learning_rate 
# rho:大或等于0的浮点数
# epsilon:大或等于0的小浮点数,防止除0错误

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=rmsprop,
              metrics=['accuracy'])

训练模型

# 训练模型
model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test))
Epoch 1/10
469/469 [==============================] - 99s 208ms/step - loss: 0.2891 - accuracy: 0.9191 - val_loss: 0.1135 - val_accuracy: 0.9717
Epoch 2/10
469/469 [==============================] - 99s 211ms/step - loss: 0.1171 - accuracy: 0.9682 - val_loss: 0.0558 - val_accuracy: 0.9847
Epoch 3/10
469/469 [==============================] - 100s 214ms/step - loss: 0.1118 - accuracy: 0.9710 - val_loss: 0.0601 - val_accuracy: 0.9837
Epoch 4/10
469/469 [==============================] - 100s 212ms/step - loss: 0.1121 - accuracy: 0.9713 - val_loss: 0.0763 - val_accuracy: 0.9823
Epoch 5/10
469/469 [==============================] - 100s 213ms/step - loss: 0.1144 - accuracy: 0.9723 - val_loss: 0.0537 - val_accuracy: 0.9864
Epoch 6/10
469/469 [==============================] - 100s 214ms/step - loss: 0.1250 - accuracy: 0.9709 - val_loss: 0.0687 - val_accuracy: 0.9870
Epoch 7/10
469/469 [==============================] - 100s 213ms/step - loss: 0.1359 - accuracy: 0.9700 - val_loss: 0.0571 - val_accuracy: 0.9869
Epoch 8/10
469/469 [==============================] - 100s 214ms/step - loss: 0.1342 - accuracy: 0.9702 - val_loss: 0.1563 - val_accuracy: 0.9809
Epoch 9/10
469/469 [==============================] - 101s 214ms/step - loss: 0.1493 - accuracy: 0.9682 - val_loss: 0.0715 - val_accuracy: 0.9860
Epoch 10/10
469/469 [==============================] - 100s 212ms/step - loss: 0.1498 - accuracy: 0.9673 - val_loss: 0.0730 - val_accuracy: 0.9808






预测

n = 5   # 给出需要预测的图片数量,为了方便,只取前5张图片
predicted_number = model.predict(x_test[:n], n)

画图

# 画图
plt.figure(figsize=(10, 3))
for i in range(n):
    plt.subplot(1, n, i + 1)
    t = x_test[i].reshape(28, 28)   # 向量需要reshape为矩阵
    plt.imshow(t, cmap='gray')      # 以灰度图显示
    plt.subplots_adjust(wspace=2)   # 调整子图间的间距,挨太紧了不好看
    # 第一个数字是真实标签,第二个数字是预测数值
    # 如果预测正确,绿色显示,否则红色显示
    # 预测结果是one-hot编码,需要转化为数字
    if y_test[i].argmax() == predicted_number[i].argmax():
        plt.title('%d\n%d' % (y_test[i].argmax(), predicted_number[i].argmax()), color='green')
    else:
        plt.title('%d,%d' % (y_test[i].argmax(), predicted_number[i].argmax()), color='red')
    plt.xticks([])  # 取消x轴刻度
    plt.yticks([])
plt.show()


AI