垃圾分类模型想上maixpy(2)

简介: 1-1关于模型部署,MaixPy文档的这一部分中可能有些有用的参考:部署模型到 Maix-I(M1) K210 系列开发板 - Sipeed Wiki 。实际用数字图片进行测试时,手写数字识别的模型无法产生正确的输出。

垃圾分类模型想上maixpy(1):https://developer.aliyun.com/article/1407162?spm=a2c6h.13148508.setting.17.79f64f0ecKMDuK

1-1

关于模型部署,MaixPy文档的这一部分中可能有些有用的参考:部署模型到 Maix-I(M1) K210 系列开发板 - Sipeed Wiki 。

  • 实际用数字图片进行测试时,手写数字识别的模型无法产生正确的输出。

猜测:输入需要进行预处理。训练时使用了img = img / 255.0 ,但是在Maixpy中我不知道如何达成这一步操作。


我尝试了 image.div() 接口,但发现 /255 时就相当于数学中 /1 ,/125 就相当于数学中 /0.5 这种。也就是说,我无法使用这个接口让图像中的像素值变小。接着我使用了如下代码进行测试:

code:10图测试

import sensor, lcd, image
import KPU as kpu
# 测试图像列表
img_names = ['num0', 'num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7', 'num8', 'num9']
# 载入模型
model_addr = 0x300000
task = kpu.load(model_addr)
# 批量测试
for i in range(10):
    img = image.Image("/flash/" + img_names[i] + ".jpg")
    img = img.resize(28, 28)
    img = img.to_grayscale(copy=False)
    img.pix_to_ai()
    success = kpu.set_outputs(task, 0, 1, 1, 10)
    fmap = kpu.forward(task, img)
    plist=fmap[:]
    pmax=max(plist)
    max_index=plist.index(pmax)
    print('\ni = ', i)
    print(plist)
    print(max_index)

对于用于测试的10张图片,输出的 plist 都是:

(3.402823e+38, -3.402823e+38, 3.402823e+38, -3.402823e+38, 3.402823e+38, 3.402823e+38, -3.402823e+38, 3.402823e+38, 3.402823e+38, 3.402823e+38)

很容易发现它只有两个值:3.402823e+38 和 -3.402823e+38,看起来像是溢出了。是不是没有预处理的原因呢?


想对image对象进行/255的预处理,结果发现它没有小数,可以使用image.morph()对每个像素进行除法操作,但是得到的结果只能是0~255。


发现列表和元组都支持小数和除法操作。


有没有什么方便的办法将图像转换为列表或元组呢?运行模型的时候是否支持使用列表或元组作为输入?转换速度如何?


发现fmap = kpu.forward(task, img)中 img 可以是一维的列表。


测试10张手写数字的图片,模型都正确预测。哦耶!

下面的代码实现了对手写数字图片文件的预测:

code:正确预测

import sensor, image, time
import KPU as kpu
def to_list_1(img):
    return [x/255 for x in img[:]]
# 载入图片
img = image.Image("/flash/num0.jpg")
img = img.resize(28, 28)
img = img.to_grayscale(copy=False)
print()
print(img)
img = to_list_1(img)
print(img[:10])
# 载入模型
model_addr = 0x300000
task = kpu.load(model_addr)
# 推理
success = kpu.set_outputs(task, 0, 1, 1, 10)
print(success)
fmap = kpu.forward(task, img)
print(fmap)
# 处理模型输出
plist=fmap[:]
pmax=max(plist)
max_index=plist.index(pmax)
print(plist)
print(max_index)
print()

通过板子摄像头识别的效果要稍差一些,但是通常还是可以产生正确的输出;使用的是mnist测试集中的图片。


对于自己手写的数字,效果比较糟糕。


拖动、缩放图片,可能导致预测结果变化。


猜测:训练集中的数据场景比较单一,又没有经过数据增强。


可以发现两种情况下直方图的差异较大,左为自己手写,右为mnist数据集中的图片。

8d4de87141ec48bcb5122ab2ce2eceb8.png

目前问题:对一张图片的预测时间太长,例如在手写数字识别的例子中为0.7秒。

1-3

尝试将float参数类型的mnist分类模型使用nncase-0.2量化为uint8类型,成功。


目的:提升推理速度。nncase文档中提到使用uint8可以获得k210的kpu加速。


效果:模型推理时间从700ms左右减为40ms左右;从摄像头获得输入,可以获得正确的预测结果。


疑惑:为什么量化需要输入数据集作为参数呢?使用的编译参数

ncc compile mnist_float.tflite mnist_float.kmodel -i tflite -o kmodel -t k210 --inference-type uint8 --dataset ./dataset_mnist --input-std 1 --input-mean 0
ncc compile mobilenet_v2.tflite mobilenet_v2.kmodel -i tflite -o kmodel -t k210 --inference-type uint8 --dataset ./dataset_garbage --input-std 1 --input-mean 0 --dump-weights-range --weights-quantize-threshold 64.000000

不进行量化(建议量化,因为摄像头输入本身是uint8):

ncc compile cifar10.tflite cifar10.kmodel -i tflite -o kmodel -t k210 --inference-type float

1-4

以moblienet-v2网络在mnist上训练了一个模型,然后转为tflite,分析了网络使用算子的支持情况

mobilenet-v2网络代码来源:MobileNet V2 网络结构的原理与 Tensorflow2.0 实现 。

下表为mobilenet-v2中的算子支持情况

算子 支持
Conv2D
Relu6
DepthwiseConv2D
Add
Mean
Shape
StridedSlice
Pack
Reshape
Softmax

修改网络后,开始尝试tflite转kmodel。


bug:Fatal: Invalid dataset, should contain one file at least ,但文件夹明明非空啊。


发现:文件夹的名字打错了,修正后得到了kmodel。


问题:转换过程中显示WARN: Conv2D_19 Fallback to float conv2d due to weights divergence ,暂时不知有什么影响。

连接板子运行时,加载模型失败。


bug:ValueError: [MAIXPY]kpu: load error:2003, ERR_KMODEL_FORMAT: layer_header.body_size <= 0


参考:Fallback to float conv2d due to weight divergence · Issue #164 · kendryte/nncase (github.com) 。


bug2:使用Netron查看网络结构时显示Error loading kmodel. Unsupported version ‘4’ layer ‘strided_slice’.


发现:若不进行量化,可以在Netron正常查看结构,但仍加载时仍然有ValueError。


猜测:是否网络中单层体积太大?记得maixpy文档中说单层不能超过2MB(不知道是指参数量、输出特征图,还是什么)。使用model.summary()查看网络各层,最大的一层Param为410880。不知道每个参数占多大的空间,我们先假定为8字节,于是这层占用内存为410880 ∗ 8 / 102 4 2 = 3.13 M B 410880*8/1024^2=3.13MB410880∗8/1024

2

=3.13MB 。但这样就有一个矛盾,.tflite模型文件的实际大小为8.47MB,如果我按上面的计算方法,将所有层参数的参数大小加起来,会远超这个数值。


疑惑:卷积层的参数量是怎么计算的?前一层输出尺寸为(None, 1, 1, 320),本身输出为(None, 1, 1, 1280)。于是( 320 + 1 ) ∗ 1280 = 410880 (320 + 1) * 1280 = 410880(320+1)∗1280=410880 。但这不应该是全连接层的计算方法吗?我理解中卷积层应该P a r a m =filter∗kernel 。

垃圾分类模型想上maixpy(3):https://developer.aliyun.com/article/1407164?spm=a2c6h.13148508.setting.15.79f64f0ecKMDuK

相关文章
|
7月前
|
编解码 并行计算 TensorFlow
垃圾分类模型想上maixpy(3)
1-5 对比Params与模型文件实际体积。 结果:模型实际大小与Params大小是可以对上的,参数应该是以float32存储。我把“字节”与“位”搞混了,应该是一个字节为8位。
88 0
【yolo训练数据集】标注好的垃圾分类数据集共享
【yolo训练数据集】标注好的垃圾分类数据集共享
2310 139
【yolo训练数据集】标注好的垃圾分类数据集共享
|
2月前
|
机器学习/深度学习 算法
五、分类模型
五、分类模型
46 0
点分类模型实战
点分类模型实战
|
5月前
|
机器学习/深度学习 自然语言处理 算法
什么是数据集的分类?
【7月更文挑战第10天】什么是数据集的分类?
652 1
|
7月前
|
IDE TensorFlow 开发工具
垃圾分类模型想上maixpy(1)
maixpy笔记 Something 上下拉。应该就是强制高、低电平,可以避免不确定的状态。 模型区没有文件系统,模型之间烧录在指定地址。
138 0
|
机器学习/深度学习 数据可视化 计算机视觉
使用深度学习进行图像类别分类
使用预训练卷积神经网络 (CNN) 作为特征提取器来训练图像类别分类器。
138 0
|
机器学习/深度学习 自然语言处理
(路透社数据集)新闻分类:多分类问题实战
(路透社数据集)新闻分类:多分类问题实战
|
数据挖掘
非监督分类
非监督分类
346 0
|
机器学习/深度学习 算法 数据挖掘
监督分类
监督分类,又称训练分类法,用被确认类别的样本像元去识别其他未知类别像元的过程。它就是在分类之前通过目视判读和野外调查,对遥感图像上某些样区中影像地物的类别属性有了先验知识,对每一种类别选取一定数量的训练样本,计算机计算每种训练样区的统计或其他信息,同时用这些种子类别对判决函数进行训练,使其符合于对各种子类别分类的要求,随后用训练好的判决函数去对其他待分数据进行分类。使每个像元和训练样本作比较,按不同的规则将其划分到和其最相似的样本类,以此完成对整个图像的分类。
273 0

热门文章

最新文章