MicroPython动手做(10)——零基础学MaixPy之神经网络KPU-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

楼主: eagler8

MicroPython动手做(10)——零基础学MaixPy之神经网络KPU

[复制链接]
 楼主| 发表于 2020-4-9 08:46 | 显示全部楼层
KPU的基础架构
让我们回顾下经典神经网络的基础运算操作:
  • 卷积(Convolution):1x1卷积,3x3卷积,5x5及更高的卷积
  • 批归一化(Batch Normalization)
  • 激活(Activate)
  • 池化(Pooling)
  • 矩阵运算(Matrix Calculate):矩阵乘,加
对于基础的神经网络结构,仅具备1,2,3,4 四种操作;
对于新型网络结构,比如ResNet,在卷积结果后会加一个变量,就需要使用第五种操作,矩阵运算。
对于MAIX的主控芯片K210来说,它内置实现了 卷积,批归一化,激活,池化 这4钟基础操作的硬件加速,但是没有实现一般的矩阵运算,所以在实现的网络结构上有所限制。
对于需要额外操作的网络结构,用户必须在硬件完成基础操作后,手工插入CPU干预的处理层实现,会导致帧数降低,所以建议用户优化自己的网络结构到基础网络形式。
所幸的是,该芯片的第二代将支持通用矩阵计算,并固化更多类型的网络结构。
在KPU中,上述提到的4种基础操作并非是单独的加速模块,而是合成一体的加速模块,有效避免了CPU干预造成的损耗,但也丧失了一些操作上的灵活性。
从standalone sdk/demo 以及 Model Compiler 中分析出 KPU加速模块的原理框图如下,看图即懂。

08.jpg

 楼主| 发表于 2020-4-9 09:06 | 显示全部楼层
#MicroPython动手做(10)——零基础学MaixPy之神经网络KPU
#实验程序之一:运行人脸识别demo(简单演示)
#模型下载地址:http://dl.sipeed.com/MAIX/MaixPy/model/face_model_at_0x300000.kfpkg
下载后模型文件夹内有二个文件
09.jpg
10.jpg

 楼主| 发表于 2020-4-9 10:30 | 显示全部楼层
打开kflash_gui
使用kfpkg将 二个模型文件 与 maixpy 固件打包下载到 flash

11.jpg

 楼主| 发表于 2020-4-9 10:34 | 显示全部楼层
打包kfpkg时出错,好像是文件地址范围不同.......

12.jpg
 楼主| 发表于 2020-4-9 11:04 | 显示全部楼层
尝试多次一直不行,两者不兼容。后来干脆不打包了,只烧录模型文件kfpkg(原来烧录过MaixPy固件V0.4.0),没想到可以了,这下明白了,固件和模型分开烧录也行。


13 (1).jpg
 楼主| 发表于 2020-4-9 11:08 | 显示全部楼层
[mw_shl_code=arduino,true]#MicroPython动手做(10)——零基础学MaixPy之神经网络KPU
#实验程序之一:运行人脸识别demo(简单演示)
#模型下载地址:http://dl.sipeed.com/MAIX/MaixPy ... l_at_0x300000.kfpkg

import sensor
import image
import lcd
import KPU as kpu

lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.run(1)
task = kpu.load(0x300000) #使用kfpkg将 kmodel 与 maixpy 固件打包下载到 flash
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025)
a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
while(True):
    img = sensor.snapshot()
    code = kpu.run_yolo2(task, img)
    if code:
        for i in code:
            print(i)
            a = img.draw_rectangle(i.rect())
    a = lcd.display(img)
a = kpu.deinit(task)[/mw_shl_code]
 楼主| 发表于 2020-4-9 11:14 | 显示全部楼层
15.jpg
 楼主| 发表于 2020-4-9 11:16 | 显示全部楼层
串口输出了大量数据

14.jpg
 楼主| 发表于 2020-4-9 11:23 | 显示全部楼层
{"x":0, "y":31, "w":107, "h":145, "value":0.611305, "classid":0, "index":0, "objnum":1}
{"x":0, "y":31, "w":107, "h":145, "value":0.500000, "classid":0, "index":0, "objnum":1}
{"x":1, "y":31, "w":107, "h":144, "value":0.500000, "classid":0, "index":0, "objnum":1}
{"x":0, "y":31, "w":107, "h":145, "value":0.556360, "classid":0, "index":0, "objnum":1}
{"x":13, "y":34, "w":83, "h":139, "value":0.556360, "classid":0, "index":0, "objnum":1}
{"x":0, "y":31, "w":107, "h":145, "value":0.500000, "classid":0, "index":0, "objnum":1}
{"x":0, "y":31, "w":107, "h":145, "value":0.500000, "classid":0, "index":0, "objnum":1}
{"x":0, "y":31, "w":107, "h":145, "value":0.556360, "classid":0, "index":0, "objnum":1}
{"x":0, "y":31, "w":107, "h":145, "value":0.500000, "classid":0, "index":0, "objnum":1}
{"x":15, "y":36, "w":83, "h":111, "value":0.556360, "classid":0, "index":0, "objnum":1}
{"x":13, "y":33, "w":83, "h":139, "value":0.556360, "classid":0, "index":0, "objnum":1}
{"x":14, "y":47, "w":83, "h":111, "value":0.500000, "classid":0, "index":0, "objnum":1}
{"x":0, "y":31, "w":107, "h":144, "value":0.556360, "classid":0, "index":0, "objnum":1}
{"x":13, "y":32, "w":83, "h":139, "value":0.500000, "classid":0, "index":0, "objnum":1}
{"x":14, "y":32, "w":83, "h":139, "value":0.611305, "classid":0, "index":0, "objnum":1}
{"x":0, "y":31, "w":107, "h":144, "value":0.556360, "classid":0, "index":0, "objnum":1}

 楼主| 发表于 2020-4-9 12:13 | 显示全部楼层
KPU是通用的神经网络处理器,它可以在低功耗的情况下实现卷积神经网络计算,时时获取被检测目标的大小、坐标和种类,对人脸或者物体进行检测和分类。KPU模块方法:

1. 加载模型
从flash或者文件系统中加载模型
import KPU as kpu
task = kpu.load(offset or file_path)

参数
offtset: 模型在 flash 中的偏移大小,如 0xd00000 表示模型烧录在13M起始的地方
file_path: 模型在文件系统中为文件名, 如 “/sd/xxx.kmodel”

返回
kpu_net: kpu 网络对象

2. 初始化yolo2网络
为yolo2网络模型传入初始化参数
import KPU as kpu
task = kpu.load(offset or file_path)
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025)
kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)

参数
kpu_net: kpu 网络对象
threshold: 概率阈值
nms_value: box_iou 门限
anchor_num: 锚点数
anchor: 锚点参数与模型参数一致

3. 反初始化
import KPU as kpu
task = kpu.load(offset or file_path)
kpu.deinit(task)

参数
kpu_net: kpu_load 返回的 kpu_net 对象

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-27 09:47 , Processed in 0.133364 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表