混了两天范例,该认真点了XD
今天要训练模型,储存模型,读取模型,拿模型分类图片,
以下程序码是昨天的范例,但在最後加上 save ,来储存模型。
为了自己测试方便,我把档案副档名改成了 Jupyter Notebook 的格式(ipynb)。
# a02_tf_mnist.ipynb
import tensorflow as tf
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 训练
model.fit(x_train, y_train, epochs=5)
# 用测试资料评估
model.evaluate(x_test, y_test, verbose=2)
# 将模型存在 mnist 资料夹
model.save("mnist")
资料夹格式如下,我目前的版本是tensorflow 2.6.0,
其他版本格式可能不同。
接下来再开一个新档案,a03_tf_category.py
# a03_tf_category.ipynb
import tensorflow as tf
saved_model_path = "mnist"
# 读取模型
model = tf.keras.models.load_model(saved_model_path)
# 显示模型资讯
model.summary()
# 显示模型的输入输出格式
print(model.input)
# KerasTensor(type_spec=TensorSpec(shape=(None, 28, 28), dtype=tf.float32, name='flatten_input'), name='flatten_input', description="created by layer 'flatten_input'")
print(model.output)
# KerasTensor(type_spec=TensorSpec(shape=(None, 10), dtype=tf.float32, name=None), name='dense_1/Softmax:0', description="created by layer 'dense_1'")
可以从以下资讯中得知,输入是一个三维浮点数阵列
第一个维度没有限制长度,而二三维长度限制是 28。
shape=(None, 28, 28), dtype=tf.float32
接下来看看最初怎麽训练的。
mnist 是手写数字集。
mnist.load_data() 会回传 shape == (60000, 28, 28),且数值介於 0~255 的浮点数。
也就是 60000 张 28 x 28 的手写数字。
https://www.tensorflow.org/api_docs/python/tf/keras/datasets/mnist/load_data
而在训练前,范例将数值除以 255,变成介於 0~1 的浮点数。
x_train, x_test = x_train / 255.0, x_test / 255.0
那麽如果我们要用这个模型来分类,要做的预处理就是把图片处理成 28x28,介於 0~1 的浮点数阵列。
安装 opencv
conda install -c anaconda opencv
之後来处理图片,这里我画了3张图
使用 opencv ,读取读片,转灰阶,缩小为 28x28。
import cv2
# 读取图片 1
img = cv2.imread('1.png')
print(img.shape) # (100, 100, 3)
# 预设图片读进来是彩色,有RGB的维度,於是我在这里把图片转灰阶
imggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print(imggray.shape) # (100, 100)
# 缩小为 28x28
resized = cv2.resize(imggray, (28, 28))
print(resized.shape) # (28, 28)
# mnist 的图集黑色是255,白色是 0,而图片读进来是 黑色是0,白色是 255
# 所以在这里除255後,也顺便把黑白翻转过来。
resized = 1 - resized / 255.0
# 原本的格式是将 N 张图片丢进去训练,,所以预测时也不能直接丢,而是在外面包一层阵列。
# 最後将阵列化 resized 转成 tensor 进行预测。
model(tf.constant([resized]))
# <tf.Tensor: shape=(1, 10), dtype=float32, numpy=
# array([[1.1365917e-04, 9.4607556e-01, 3.3843194e-03, 9.3289698e-03,
# 3.3142285e-03, 3.7603064e-03, 1.8111777e-03, 7.1768690e-04,
# 3.1470988e-02, 2.3163184e-05]], dtype=float32)>
# 科学记号不方便看,所以在这里改为小数点後两位。
# mnist 的顺序是从 0 开始,所以 1.png 这张题片摆在第2位。
# 输出是一组机率阵列。
[[round(float(j), 2) for j in i] for i in model(tf.constant([resized]))]
# [[0.0, 0.95, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 0.03, 0.0]]
接下来一次分类三张图吧
def readimg(imgpath):
img = cv2.imread(imgpath)
imggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
resized = cv2.resize(imggray, (28, 28))
return 1 - resized / 255.0
imgfiles = ["1.png", "2.png", "3.png"]
imgs = [readimg(i) for i in imgfiles]
[[round(float(j), 2) for j in i] for i in model(tf.constant(imgs))]
# [[0.0, 0.95, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 0.03, 0.0],
# [0.0, 0.0, 0.99, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
# [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]
<<: [从0到1] C#小乳牛 练成基础程序逻辑 Day 4 - I/O 宣告变数 赋予值
今天我们来配 OSPF。 OSPF 是一种 IGP (Interior Gateway Protoc...
本篇重点 建立Index,加快SQLite存取速率 产生日K线资料 产生周K线资料 产生月K线资料 ...
Not Defined VS undefined undefined: 在创造阶段只有变数在记忆体里...
早起运动Day6 - 生日快乐我的国家 三点多有起来记录了一下梦话,接着再睡了回去,我想那是在...
案例说明及适用场景 Odoo CRM 简单区分的话 商机 自动建立 商机 阶段管理 商机 转为订单 ...