maixpy笔记
Something
- 上下拉。应该就是强制高、低电平,可以避免不确定的状态。
- 模型区没有文件系统,模型之间烧录在指定地址。
- 文件系统可以有效帮助我们管理存储介质,例如磨损均衡。
- 理论上只要单层使用内存不超过 2MB, 整体模型可以无限大,只不过要牺牲一点运算速度。
- SRAM与Flash 。其中SRAM掉电易失,容量小,而速度快。
nnc-0.1算子支持
layer | parameters |
Conv2d | kernel={3x3,1x1} stride={1,2} padding=same * |
DepthwiseConv2d | kernel={3x3,1x1} stride={1,2} padding=same * |
FullyConnected | 全连接操作。将输入张量拉伸成一个一维向量,然后与权重矩阵进行点积,最后加上偏差向量。 |
Add | 按位加法操作。将两个输入张量的相应元素相加。 |
MaxPool2d | 二维最大池化操作。对输入张量的每个子区域执行最大值池化,并返回包含每个子区域的最大值的新张量。 |
AveragePool2d | 二维平均池化操作。对输入张量的每个子区域执行平均值池化,并返回包含每个子区域的平均值的新张量。 |
GlobalAveragePool2d | 全局平均池化操作。对输入张量的所有元素求平均值,并返回一个形状为 (1, 1, C) 的张量,其中 C是输入张量的通道数。 |
BatchNormalization | 批量归一化操作。在训练时,对于输入张量的每个通道计算均值和方差,然后使用这些值对输入进行归一化;在预测时,使用固定的均值和方差对输入进行归一化。 |
BiasAdd | 将偏差向量加到输入张量上。 |
Relu | 修正线性单元 (ReLU) 激活函数。将输入张量的所有小于 0 的元素设为 0。 |
Relu6 | 修正线性单元 (ReLU6) 激活函数。将输入张量的所有小于 0 的元素设为 0,将所有大于 6 的元素设为 6。 |
LeakyRelu | 带有小正斜率的修正线性单元 (Leaky ReLU) 激活函数。将输入张量的所有小于 0 的元素乘以一个小于 1 的正斜率。 |
L2Normalization | 二范数归一化操作。对输入张量的所有元素求二范数,然后将输入张量的所有元素除以二范数。 |
Sigmoid | 对输入张量的所有元素应用 Sigmoid 函数。 |
Softmax | 对输入张量的所有元素应用 Softmax 函数。 |
Flatten | 展平张量。将输入张量拉伸成一个一维向量。 |
ResizeNearestNeighbor | 使用最近邻插值法对输入张量进行重新调整大小。 |
可能用到的API
image.to_grayscale([copy=False])
将图像转换为灰度图像。
Commands
os.listdir() ,查看当前目录下的文件
os.chdir() 切换当前目录到文件的目录,比如 os.chdir("/flash")
os.remove(path) 删除文件
ncc compile mnist_float.tflite mnist_float.kmodel -i tflite -o kmodel -t k210 --inference-type float
使用nncase的0.2版本,将.tflite文件转为.kmodel格式
ncc -i tflite -o k210model --inference-type float mnist_float.tflite mnist.kmodel
使用nncase的0.1版本进行模型格式转换
pip show <包名> 用pip查看某个已安装包的信息
conda search <包名> 用conda查看某个包的可安装版本
nvidia-smi 查看电脑的CUDA版本
Skills
1、使用IDE将文件保存到板子
Tool
中使用发送文件
保存为同名文件;Tool
中使用保存为boot.py
,下次板子开机上电时自动执行。
2、执行板子上的文件
例如,板子上有个文件名为hello.py
,下面的代码将执行它。
with open("hello.py") as f: exec(f.read())
3、实现开机自启
开机会自动先执行boot.py
,然后执行main.py
(如果检测到SD卡则执行SD卡里的)。
Problems
“对同一个外设或者引脚重复映射”是什么意思?
我需要做板级配置吗?
很奇怪,为什么只有我手机充电的那根数据线可以连的上板子?
仍然不太清楚“外设”和“引脚”的关系。
一个人读文档发现不一致的地方时是真的难受,而且也找不着解释。例如我使用k f l a s h _ g u i kflash\_guikflash_gui烧录模型时,就没有设置烧录地址的地方,而文档中第一张图里面有地址,后面的图又没有地址了。
用IDE运行官方的人脸识别时,一段时间后就会报错,据说是因为运行内存不够,可以用终端试试。但IDE里的终端我没用明白,我嵌在代码里的print语句正常输出,说明程序确实运行了,但却没有显示画面。而且,为什么会运行一段时间后才显示内存不足呢?是否和脸的数量有关?
RGB565是什么?
摄像头水平镜像是干什么?
import time 导入的包和文档中的 utime 是一样的吗?
这一段代码是不是不能脱离try-finally结构?因为前面是while(True) ?
为什么插上板子时,我电脑上会增加两个串口COM5和COM6,但是只有COM5能用?那COM6是什么?
如何删除板子上的文件呢?
下载.kmodel在0x300000位置后,就连不上板子了,不知道是不是把固件挤掉了。而重新下载.bin固件时,会下载失败。
解决:将开发板设置从“Sipeed Mainxduino"改为“自动选择”后,就好了。但是我记得我之前都是用的“Sipeed Mainxduino"选项。
12-13
试试运行一个maixpy官方提供的模型。
使用MaixHub训练的模型可以在开发板上正常运行,不错不错。在IDE上时只能运行一小会儿就会报错,使用串口终端时又无法显示图像。后来王鹤野建议说打印直接打印结果,我尝试发现确实可以。连串口时板子是在运行的,仅仅是没有图像显示而已。这次尝试的是一个击败K的小模型,训练时验证集精度达到了79.5%,但在尝试中它对盘装菜识别效果较好,其它的尝试识别都失败了。
后续可以进行的尝试:
在Maixhub上训练一个更大的模型,看在串口终端连接下它可以支持多大模型的运行。
将Paddle的模型转换为.kmodel的格式。但是Paddle模型保存的时候都是两个文件,一个参数文件一个模型文件,可以转成一个.kmodel文件吗?
12-27
尝试了将 paddle 框架训练的模型使用 paddle2onnx
转换为 onnx
格式,然后使用 nncase
转换为 kmodel
格式。
但是得到的 kmodel
模型无法使用。在载入模型的那一步 kpu.load(model_addr)
就会直接结束,而且连板子和maixpy IDE的连接都会断开。
12-28
仍然是转换出的 kmodel 无法在板子上加载的问题。据我目前了解,可能是它已经停止对 nncase 转换工具的支持了。参考:【K210踩坑】pytorch模型转kmodel,Dock上使用。(最终未实现) 。
真的烦,别人做什么我就只能用什么,为什么我不会自己写一个模型转换工具呢?
12-29
使用nncase v0.2.0转出的模型需要手动设置输出层形状。不知道是不是我使用方法不对,我的部分代码如下:
model_addr = "/flash/iris.kmodel" task = kpu.load(model_addr) success = kpu.set_outputs(task, 0, 12, 1, 1) print('success: ', success)
但它总是显示:
w*h*ch!=12 [MAIXPY]kpu: set_outputs arg value error: w,c,ch size not match output size success: False
可nncase v0.1.0转出的iris.kmodel的输出就是:
{"fmap": "data"=0x80380e70, "size"=12, "index": 1, "w": 12, "h": 1, "ch": 1, "typecode": f}
不知道出了什么问题,那我干脆就用v0.1.0版本就好了?
12-31
在尝试使用nncase的0.1和0.2对kmodel进行转换时都失败了,它们都不支持SHAPE操作。总体0.2版本的算子支持比0.1版本要丰富许多,比如0.2可以支持Reshape操作。
删除含有SHAPE操作的层后,转换又失败了。
0.1版猜测是不支持我在tensorflow lite中量化后的得到的unit8参数格式。
0.2版则显示Fatal: Invalid tensor type ,可以参考Cannot compile .tflite model (Fatal: Invalid tensor type) · Issue #420 · kendryte/nncase (github.com) 。当我取消tensorflow lite中的量化后,
- 0.1版仍然失败,据chatGPT所说,是因为转换器无法理解模型文件中的某些内容,我没有继续探究这个问题。
1-4对比文档发现,应该是不支持Reshape算子导致。 - 0.2版成功得到了
.kmodel
的模型。
现在,让我们尝试将刚刚得到的模型载入板子。
好家伙,使用IDE传文件又传不进去了,一直显示发送并保存中,请等待... 。此时IDE就一直卡在传送那里,无法断开与板子的连接,却可以打开串口终端;将IDE关闭后,依然有程序在后台运行。
好像是特定文件传不进去,我尝试传另一个 .kmodel 文件时成功了。模型文件从Colab训练后下载后得到,Build a handwritten digit classifier app with TensorFlow Lite 。
改用kflash_gui可以成功烧录进板子。
终于成了!一个手写数字识别的模型成功在板子上被加载,并正常产生了输出。
关于报错kpu:check img format err! ,看很多帖子都说分辨率不正确。在串口终端运行文件时多了一条报错[MAIXPY]kpu: pix_ai is NULL ,查了帖子后发现是内存中图像的修改与kpu中图像的修改不会自动同步的问题,需要每次修改图像后手动同步:.pix_to_ai() ,记得将替换为自己图像变量的变量名。
参考:why pix_to_ai still return none? · Issue #264 · sipeed/MaixPy (github.com) 。
关于 kpu.set_outputs() 总是失败。是啊,是要设置 outputs,我总莫名想象成了 inputs ,制度第n次看到w*h*ch!=40之类的报错提示与输入的形状风牛马不相及(输入是分辨率为28*28的图像),我才突然恍然大悟。
垃圾分类模型想上maixpy(2):https://developer.aliyun.com/article/1407163?spm=a2c6h.13148508.setting.16.79f64f0ecKMDuK