根据昨天的测试我们知道小画家画风的数字模型认不出来,那麽我们可以追加训练让它学习自己画的字。
这次我决定再改一下资料格式,并用 tensorflow.keras 的内建函式读取。
资料格式如下,一个资料夹代表一个标签,image_dataset_from_directory 会自动的将资料夹名称转为标签。
因为内建函式没有黑白转换那麽细的设定,所以我手动把图片改成黑底白字了。
import tensorflow as tf
saved_model_path = "mnist"
model = tf.keras.models.load_model(saved_model_path)
# 读取 img 资料夹,32 个一批,图片大小转 28*28,灰阶模式,标签是整数
# 不打乱,因为在打乱的情况拿资料会导致每次拿的顺序都不同
raw_keras_ds = tf.keras.preprocessing.image_dataset_from_directory("img", batch_size=32, image_size=(28, 28), color_mode="grayscale", label_mode='int', shuffle=False)
这次改用 pandas 整理输出资料
import pandas as pd
predictions, labels = tuple(zip(*raw_keras_ds))
results = model.predict(predictions)
results = [ [round(j, 2) for j in i] for i in results]
df = pd.DataFrame(results)
df.insert(0, 'label', labels[0])
df.insert(0, 'filepath', raw_keras_ds.file_paths)
print(df.to_markdown())
filepath | label | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.png | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 1.png | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 2.png | 2 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
3 | 3.png | 3 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
4 | 4.png | 4 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
5 | 5.png | 5 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
6 | 6.png | 6 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
7 | 7.png | 7 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
8 | 8.png | 8 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
9 | 9.png | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
6, 7, 8 的预测都错误。
而如果有人想问我为啥结果和昨天不一样...我也不知道,也许 opencv 处理图片的方式和 image_dataset_from_directory 的方式不同。
但错的和昨天差不多,不过结果被四舍五入了。
batch_size 务必大於资料量,因为原本 image_dataset_from_directory 是使用 batch_size 一批一批的的拿资料。
但为了在结果展示更多资讯,我用了以下两个方式拿 label 和 file_paths。
predictions, labels = tuple(zip(*raw_keras_ds))
raw_keras_ds.file_paths
如果 batch_size 只有 5 ,那麽他们只会拿到第一批的五笔资料。
说好的追加训练其实只要一行
model.fit(raw_keras_ds, epochs=5)
追加训练後的结果,只剩下 7 被认成 1 了。
filepath | label | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.png | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 1.png | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 2.png | 2 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
3 | 3.png | 3 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
4 | 4.png | 4 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
5 | 5.png | 5 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
6 | 6.png | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
7 | 7.png | 7 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
8 | 8.png | 8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
9 | 9.png | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
虽然官方的函式库的确很方便,但我还是比较习惯手刻。
因为不熟悉函式库,很多都要上网查。
<<: 爬虫怎麽爬 从零开始的爬虫自学 DAY7 python变数合法取名
>>: D-24 资料结构 data structure ? List ? Dictionary
今天更新了手机的作业系统到iOS 15,比起以前,更喜欢常关注以及思考为什麽Apple要这样做的原因...
到了第11天,终於回归主题了,今天就来开始串接永丰的api吧! 本来是这麽想的,不过突然发现... ...
今天来稍微简单介绍一下区块链的技术介绍。 我们可以谈谈为什麽区块链可以储存数据,不用害怕被篡改,就是...
前言 JS 30 是由加拿大的全端工程师 Wes Bos 免费提供的 JavaScript 简单应用...
关於 时区 因为取资料的方式都以时间线的方式取得(http, websocket) 所以时区是一个必...