Keras 成长之路(四)构建CNN-LeNet5模型并处理MNIST手写数字集(CNN卷积神经网络)

LeNet-5网络对MINST的预测结果

Keras 成长之路(四)构建CNN-LeNet5模型并处理MNIST手写数字集(CNN卷积神经网络)_第1张图片

Show me the code

导包

# 顺序模型
from keras import Sequential
# 网络,卷积,扁平化,Dropout
from keras.layers import Dense, Conv2D, MaxPool2D, Dropout, Flatten
# one hot
from keras import utils
# 优化器
from keras.optimizers import Adam  # 收敛速度快

import numpy as np
import matplotlib.pyplot as plt

数据获取模块

# 返回mnist归一化以后的数据
def get_minst(file_path= "./mnist.npz"):
    # 导入并预处理手写字符集数据,注释的这一行有的朋友可以很快下载
    # 没有请下载mnist.npz文件
    # (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
    with np.load(file_path) as f:
        x_train, y_train, x_test, y_test = 
        f["x_train"], f["y_train"], f["x_test"], f["y_test"]

    # 打印显示原始数据维度
    print("原始数据大小:")
    print("x_train的大小为:", x_train.shape)
    print("y_train的大小为:", y_train.shape)
    print("x_test的大小为:", x_test.shape)
    print("y_test的大小为:", y_test.shape)

    # 转化数据使得一行为一副图像
    x_train = x_train.reshape(x_train.shape[0], -1).astype("float64")
    x_test = x_test.reshape(x_test.shape[0], -1).astype("float64")

    # 将图像除以255进行像素值归一化
    x_train /= 255
    x_test /= 255

    # 将y_train与y_test转化为“one hot”形式
    y_train = utils.to_categorical(y_train)
    y_test = utils.to_categorical(y_test)

    # 打印转化后数据大小
    print("\n转化后数据大小:")
    print("x_train的大小为:", x_train.shape)
    print("y_train的大小为:", y_train.shape)
    print("x_test的大小为:", x_test.shape)
    print("y_test的大小为:", y_test.shape)
    
    return x_train, y_train, x_test, y_test

LeNet-5网络定义

# 定义LeNet5网络,该定义处理深度为1,即灰度图像
def LeNet5(x_train, y_train, x_test, y_test, rows, cols, MAX_LOOP= 3):
    # 将x_train与x_test转化为n_samples * rows * cols * depth大小
    x_train = x_train.reshape(-1, rows, cols, 1)
    x_test = x_test.reshape(-1, rows, cols, 1)
    
    ####### 建立网络 ######
    # 顺序模型
    model = Sequential()

    # 卷积,池化部分
    model.add(Conv2D(input_shape = (rows, cols, 1), 
                     filters= 32, kernel_size= 5, strides= 1,
                     activation= "relu", padding= "same"))
    model.add(MaxPool2D(pool_size= 2, strides= 2, padding= "same"))
    model.add(Conv2D(filters= 64, kernel_size= 5, strides= 1,
                     activation= "relu", padding= "same"))
    model.add(MaxPool2D(pool_size= 2, strides= 2, padding= "same"))
    model.add(Dropout(0.25))

    # 扁平化
    model.add(Flatten())

    # 全连接部分
    model.add(Dense(128, activation= "relu"))
    model.add(Dropout(0.5))
    model.add(Dense(128, activation= "relu"))
    model.add(Dropout(0.5))
    model.add(Dense(10, activation= "softmax"))
    ######################

    # 设置优化器
    adam = Adam()

    # 整合模型
    model.compile(optimizer= adam, 
                  loss= "categorical_crossentropy", 
                  metrics=["accuracy"])

    # 开始训练
    my_batch_size = round(x_train.shape[0] * 0.001)  # 定义batch_size大小
    print("\n开始训练:")
    model.fit(x_train, y_train, batch_size= my_batch_size, epochs= MAX_LOOP)

    # 评价模型
    print("\n评价模型:")
    final_loss, final_accuracy = model.evaluate(x_test, y_test)
    print("loss= ", final_loss)
    print("accuracy= ", final_accuracy)
    
    return model

测试模块

# 选取一副测试集图像进行测试
def test_LeNet5_model(model, x_test, rows, cols, depth):
    # 选取一个测试集合图像的序号
    dex = np.random.randint(0, x_test.shape[0] - 1)
    # 获得该序号的图像
    img = x_test[dex, :].reshape(rows, cols)
    # 利用模型进行预测
    y_predict = np.argmax(model.predict(img.reshape(1, rows, cols, depth)))
    
    # 显示原图像,打印预测结果
    print("\n随机抽取测试集图像进行预测:")
    print("测试集图像序号为:", dex)
    print("原图像为:")
    plt.imshow(img)
    plt.show()
    print("模型预测结果为:", y_predict)

定义主函数

# 定义主函数
def main():
    # 设置图像大小,及深度
    rows = 28
    cols = 28
    depth = 1
    
    # 调用自定义函数,获取MINST数据
    x_train, y_train, x_test, y_test = get_minst()
    
    # 调用自定义“LeNet5”网络进行训练
    model = LeNet5(x_train, y_train, x_test, y_test, rows, cols)
    
    # 随机测试一个测试集图像
    test_LeNet5_model(model, x_test, rows, cols, depth)

调用主函数

# 调用主函数
if __name__ == "__main__":
    main()

你可能感兴趣的:(Keras成长之路)