导包
# 顺序模型
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()