TensorFlow 入门 (基于Keras) 手写数字识别 保存 导入

前言
提示:第一次写博客 记录学习过程 如有不对地方希望能指出:

|@Auth | HeisitHe|
|@IDE  | PyCharm  |
| @Motto|  (Always Be Coding) |
|@Function|作用见文件名|
版本
python3.9.12
TensorFlow-Gpu2.9.0
GPURTX2060
CUDA11.6
cudnn8.3.3.40

提示:以下是本篇文章正文内容,下面案例可供参考

🙍‍♂️一、Keras是什么?

Keras是一个由Python编写的开源人工神经网络库,可以作为Tensorflow、Microsoft-CNTK和Theano的高阶应用程序接口,进行深度学习模型的设计、调试、评估、应用和可视化。Keras在代码结构上由面向对象方法编写,完全模块化并具有可扩展性。

#biao’q二、搭建步骤

🙅‍♂️1.引入库baioq

代码如下:

from keras.models import Sequential     #构建序列化模型  搭建神经网络模型骨架
from keras.layers import Conv2D, MaxPool2D ,Dense, Flatten ,Dropout    #使用 Conv2D 进行2d卷积运算  , MaxPoll2D 用于池化层 运算取最大值
#Dense 分类器使用  Flatten用于多维数据压缩 过渡为全连接层  Dropout 放在全连接层后面 防止过拟合 提升模型泛化能力
from keras.utils import np_utils    # 独热编码 将类别向量转化为 0,1矩阵 减小计算量 加速收敛
import tensorflow as tf
from keras.datasets import mnist     #导入手写数字级 第一次导入需下载
import matplotlib.pyplot as plt     #经典绘图库
from keras.utils.vis_utils import plot_model   #绘制 神经模型

进入正题

🙆‍♀️2.读入数据

代码如下:

(x_train,y_train),(x_test,y_test)=mnist.load_data() //导入数据 mnist 库 包含 60000张 手写数字 训练集 10000 张测试集


返回值是一个元组

🙆‍♂️ 3.数据处理

img = 28
#验证集  10000
x_val=x_train[50000:]
y_val=y_train[50000:]
#训练集  50000
x_train=x_train[:50000]
y_train=y_train[:50000]

x_train = x_train.reshape(x_train.shape[0], img, img, 1).astype('float32')    #将图像转换为4维矩阵 放入训练 
#将数据类型由 Uint 8 转为 float32 提高精确率
x_val =x_val.reshape((x_val.shape[0], img, img, 1)).astype('float32')
x_test = x_test.reshape(x_test.shape[0], img, img, 1).astype('float32')
# 原始图像数据的像素灰度值范围是 0-255  像数值比例缩小
x_train /= 255
x_test /= 255
#独热化 将三维维矩阵 值 转化为 0,1  10个类别
y_train = np_utils.to_categorical(y_train, 10)  
y_test =np_utils.to_categorical(y_test, 10)
y_val = np_utils.to_categorical(y_val,10)

💁‍♀️4. 构建神经 模型

采用序列模型 Sequential() 搭建模型骨架 本节搭建了两个卷积层 两个池化层 两个全连接层 分类输出
用 softmax 做 0-9 的 10 分类

in_channels=in_channel 输入通道数,即输入数据的通道数
out_channels=10 输出通道数,即输出数据的通道数
kernel_size 卷积核大小,一般是int,也可tuple,如3【表示3×3】;(5,4)【表示5×4】
stride=1 卷积移动的步长
padding=padding 是否用0 填充数据四周

model=Sequential()
//                
model.add(Conv2D(filters=30, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))      
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Dropout(0.2))
model.add(Dropout)        #Dropout 放在全连接层后面 防止过拟合 提升模型泛化能力
model.add(Dense(100, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='adam',
               loss='categorical_crossentropy',
              metrics=['accuracy'])

💁‍♂️5.绘制 模型

plot_model(model, to_file='model.jpg', show_shapes=True, show_layer_names=True, rankdir='TB')
plt.figure(figsize=(5, 5))    #显示图片大小
img = plt.imread("model.jpg")    
plt.imshow(img)
plt.axis('off')     #关闭坐标
plt.show()
model.summary()

绘制模型时发生错误
ImportError: You must install pydot (`pip install pydot`) and install graphviz (see instructions at https://graphviz.gitlab.io/download/) for plot_model/model_to_dot to work.
点击查看解决详情


创建的模型

🙋‍♂️6.模型编译

compile 编译模型 内包含 定义损失函数、优化器、评估指标等参数

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

🤦‍♂️7.训练 模型

history = model.fit(x=x_train, y=y_train, 
epochs=20, batch_size=128, verbose=2,
validation_data=(x_val,y_val),validation_batch_size=10) 
#validation 验证集
# batch_size 每次训练放入大小 一撮 
#verbose = 0,在控制台没有任何输出   verbose = 1 :显示进度条     verbose = 2:为每个epoch输出一行记录
evaluate=model.evaluate(x_test,y_test)    #模型评估 测试集 测试精度作为最终模型好坏评估标准
loss=evaluate[0]
accuracy=evaluate[0]    

💇‍♂️8.优化过程 绘图

def draw(history,loss,accuracy):
    fontproperties = "SimHei"
    plt.plot(history.history[loss],color="r")
    plt.plot(history.history[accuracy],color="b")
    plt.title('优化曲线',fontproperties="SimHei")
    plt.xlabel("轮数",fontproperties='SimHei')
    plt.ylabel("值",fontproperties='SimHei')
    plt.legend(['loss', 'accuracy'], loc='best')
    x_major_locator = MultipleLocator(1)
    # # 把x轴的刻度间隔设置为1,并存在变量里
    y_major_locator = MultipleLocator(0.05)
    # 把y轴的刻度间隔设置为0.01,并存在变量里
    ax = plt.gca()
    # ax为两条坐标轴的实例
    ax.xaxis.set_major_locator(x_major_locator)
    # 把x轴的主刻度设置为1的倍数
    ax.yaxis.set_major_locator(y_major_locator)
    # 把y轴的主刻度设置为10的倍数
    plt.ylim(0,1)
    plt.show()

训练集更新

验证集更新

🧖‍♀️9.保存 模型 权重

model.save("./model/handwritten_numeral_recognition.h5")

🤹‍♀️三.导入保存好的模型

👴模型导入

from keras.models import load_model
model = load_model("./model/handwritten_numeral_recognition.h5")
model.summary()

继续训练直接model.fit()

🚶‍♀️四.完整代码

🧘‍♀️第一部分

from keras.models import Sequential
from keras.layers import Conv2D, MaxPool2D
from keras.layers import Dense, Flatten ,Dropout
from keras.utils import np_utils
from keras.datasets import mnist
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator



def data_Process():

    (x_train,y_train),(x_test,y_test)=mnist.load_data()
    #数据预处理
    #验证集  10000
    x_val=x_train[50000:]
    y_val=y_train[50000:]
    #训练集  50000
    x_train=x_train[:50000]
    y_train=y_train[:50000]
    img = 28
    # 将图像转换为4维矩阵 放入训练
    x_val =x_val.reshape((x_val.shape[0], img, img, 1)).astype('float32')
    # 将数据类型由 Uint 8 转为 float32 提高精确率
    x_train = x_train.reshape(x_train.shape[0], img, img, 1).astype('float32')
    x_test = x_test.reshape(x_test.shape[0], img, img, 1).astype('float32')
    # 原始图像数据的像素灰度值范围是 0-255  像数值比例缩小
    x_train /= 255
    x_test /= 255
    # 独热化 将三维维矩阵 值 转化为 0,1  10个类别
    y_train = np_utils.to_categorical(y_train,10)
    y_val = np_utils.to_categorical(y_val,10)
    y_test = np_utils.to_categorical(y_test,10)
    return x_train,x_val,x_test,y_train,y_val,y_test

def cnn_Model():
    model=Sequential()
    model.add(Conv2D(filters=30, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))
    model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
    model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))
    model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
    model.add(Flatten())
    model.add(Dropout)        #Dropout 放在全连接层后面 防止过拟合 提升模型泛化能力
    model.add(Dense(100, activation='relu'))
    model.add(Dense(10, activation='softmax'))
    model.compile(optimizer='adam',
                   loss='categorical_crossentropy',
                  metrics=['accuracy'])
    return model



def draw(history,loss,accuracy):
    fontproperties = "SimHei"
    plt.plot(history.history[loss],color="r")
    plt.plot(history.history[accuracy],color="b")
    plt.title('优化曲线',fontproperties="SimHei")
    plt.xlabel("轮数",fontproperties='SimHei')
    plt.ylabel("值",fontproperties='SimHei')
    plt.legend(['loss', 'accuracy'], loc='best')
    x_major_locator = MultipleLocator(1)
    # # 把x轴的刻度间隔设置为1,并存在变量里
    y_major_locator = MultipleLocator(0.05)
    # 把y轴的刻度间隔设置为0.01,并存在变量里
    ax = plt.gca()
    # ax为两条坐标轴的实例
    ax.xaxis.set_major_locator(x_major_locator)
    # 把x轴的主刻度设置为1的倍数
    ax.yaxis.set_major_locator(y_major_locator)
    # 把y轴的主刻度设置为10的倍数
    # plt.ylim(0,1)
    plt.show()

def run():
    x_train,x_val,x_test,y_train,y_val,y_test =data_Process()
    history = cnn_Model().fit(x_train, y_train, epochs=30, batch_size=128, verbose=1,validation_data=(x_val,y_val),validation_batch_size=10)

    evaluate=cnn_Model().evaluate(x_test,y_test)    #评估值 accuracy  loss 只有有1个
    print(evaluate)
    print("-" * 20)
    print(history.history["accuracy"])     # history 对象 保存了每一轮训练过程的 loss accuracy 字典对象
    print("-"*20)
    cnn_Model().save("./模型/handwritten_numeral_recognition.h5")
    draw(history, "loss", "accuracy")
    draw(history, "val_loss", "val_accuracy")

if __name__=="__main__":
    run()

🧗‍♂️第二部分(外部导入)

import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import keras.datasets.mnist

(x_train,y_train),(x_test,y_test)=keras.datasets.mnist.load_data()

model=keras.models.load_model(r"../model/handwritten_numeral_recognition.h5")
model.summary()
#
#
#  导入照片时 注意图片大小   训练大小为 28*28  96 px * 96 px

for i in range(10):
    img = plt.imread('./picture/%d'%(i)+'.jpg')

    image=Image.open('./picture/%d'%(i)+'.jpg')
    image = image.convert('L')   # 图片灰度化
    test_my_img=image.resize((28,28))    #修改图片大小

    date=np.asarray(test_my_img)     # 图片转为 np数组
    test_my_img = date.reshape(1,28,28,1)     
    p = model.predict(test_my_img)
    predicte=np.argmax(p[0])
    print(predicte)
    plt.title(predicte)
    plt.imshow(img)
    plt.show()

🌹总结

	抛砖引玉,我的学习记录,希望能给到你帮助。
	水平有限,有错误的地方  希望能提出 改正

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2022年5月20日
下一篇 2022年5月20日

相关推荐