k230 MNIST 手写数字识别
案例采用deep learning with python(第二版)一书的mnist案例学习
具体代码如下所示:
构建网络
from tensorflow import keras
from tensorflow.keras import layers
inputs = keras.Input(shape=(28, 28, 1))
x = layers.Conv2D(filters=32, kernel_size=3, activation="relu")(inputs)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=64, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=128, kernel_size=3, activation="relu")(x)
x = layers.Flatten()(x)
outputs = layers.Dense(10, activation="softmax")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.summary()
导入数据并训练模型
from tensorflow.keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28, 28, 1))
train_images = train_images.astype("float32") / 255
test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype("float32") / 255
model.compile(optimizer="rmsprop",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
model.fit(train_images, train_labels, epochs=5, batch_size=64)
精度测试
test_loss, test_acc = model.evaluate(test_images, test_labels)
print(f"Test accuracy: {test_acc:.3f}")
转换模型为onnx
import tensorflow as tf
import os
import onnx
#需要先使用model.save方法保存模型
model.save('model')
#调用tf2onnx将上一步保存的模型导出为ONNX
os.system("python3 -m tf2onnx.convert --saved-model model --output mnist.onnx --opset 11")
检测转换模型
import onnx
onnx_model = onnx.load("./mnist.onnx")
check = onnx.checker.check_model(onnx_model)
print('Check: ', check)
修正输入输出的第一个维度
import onnx
onnx_model = onnx.load("./mnist.onnx")
onnx_model.graph.input[0].type.tensor_type.shape.dim[0].dim_value = 1
onnx_model.graph.output[0].type.tensor_type.shape.dim[0].dim_value = 1
onnx.save(onnx_model, './mnist_dim.onnx')
绘制数字
from matplotlib import pyplot as plt
import numpy as np
nn=0
plt.imshow(train_images[nn,:,:,0])
print(train_images[nn,:,:,0].shape)
print('mnist is: ',train_labels[nn])
# 保存数据
np.save('mnist5',train_images[0,:,:,0])
保存数据为npy格式,便于micropython中的数组导入
模型转换参考如下:
CanMV K230使用经验分享
模型验证
更改保存的npy数据,实现不同手写数据的检测。
代码
import nncase_runtime as nn
import ulab.numpy as np
# init kpu and load kmodel
kpu = nn.kpu()
kpu.load_kmodel("/sdcard/app/tests/hy/mnist/mnist.kmodel") # 存储模型位置
# dump model input and output info
print("inputs info:")
for i in range(kpu.inputs_size()):
print(kpu.inputs_desc(i))
print("outputs info:")
for i in range(kpu.outputs_size()):
print(kpu.outputs_desc(i))
# set input tensor
a=np.load('/sdcard/app/tests/hy/mnist/mnist9.npy') # 存储数据位置
input_data = np.frombuffer(a, dtype=np.float)
input_data = input_data.reshape((1,28,28))
kpu.set_input_tensor(0, nn.from_numpy(input_data))
# run kmodel
kpu.run()
# get output
result = kpu.get_output_tensor(0)
result = result.to_numpy()
print('mnist result is :',np.argmax(result)) # 因为手写数字为0~9,对应数组索引0~9
print('mnist result is :',np.max(result))
工具:在windows下采用CanMV IDE 4.0.5-0 官网可以下载,但linux下的尚未更新,更改将k230的模型集成在ide中,但部分模型路径仍需确认
CanMV IDE下载
ulab官网
可以查询ulab.numpy函数,用于简单计算
后续:通过板载摄像头检测手写数字?