K210神经网络的训练以及出现内存不足的情况memory not enough解决方案

目录

介绍

最近在搞K210神经网络搭建识别数字,在烧入代码的时候就有很多坑,记录一下我的坑,希望能给大家提供帮助,首先就是数据集的采集,我刚开始是用手机,然还要转化图片大小类型就很麻烦,在网上找到一位大佬的代码,可以直接用K210拍照并且储存在SD卡中还可以加文件夹如有需要这里,可以得到大量的数据集,还有一种方法就是将要识别的物体用K210几个角度录像,然后用软件一帧一帧的节取,这个方法也是很方便也是可取的(这是我们实验室学长告诉我的但是我觉得麻烦就没弄),这个教程网上也有很多,我就不再赘述了,刚刚学习模型训练可以少一点,熟悉一下过程,后面再加更多的训练集,收集好数据集后就可以训练了,注意这里有很多很多种训练方法,我这里用的是MaixHub官网训练,因为这种训练方法简单对初学者很友好。

开始训练

 点这里进入MaiHub官网里面不仅可以自己可以训练,还可以白嫖模型库里的数据,就很方便,先简单注册一下自己的账号,然后就可以开始进行数据集的训练了。

 在开始这还会有一个小问题,就是要获取机械码,其实它教程里也有讲解,可以到这里看一下,就是烧一个脚本进K210然后通过串口的到机械码,获得机械码后,就是模型训练,这的采集方法很多,但是我吗直接用我们收集到的数据传入即可。数据类别分为训练集跟验证集,一个用于训练一个用于验证,一般10:1就可以吧。

 然后就是无止境的圈出目标参数。当然你的数据集越多就圈得越多,但是识别也就越精准。

 训练结束了过后就可以开始训练了,这里训练的模型也有不少,tf:支持在任意 WEB 平台运行

awnn:支持 Maix-II 系列开发板, 芯片 v831 v833  nncase:支持 Maix-I 系列开发板, 芯片 k210

nccn:支持手机、树莓派以及任何能用CPU运行 ncnn 推理器的芯片,我这里用nncase,因为我的是K210,选好参数后就直接点击下面的创建训练任务即可,是以下界面就证明你的训练是可以的,就只需要耐心等待即可

训练完成 

训练完成后可以在右下角看到验证结果和准确率等信息,然后点击右上角的部署即可下载部署文件,下载下来后你将得到一个压缩包,其中包括  json文件,KMODEL文件,和一个python文件,KMODEL就是训练模型,你只需要把它粘贴到SD卡中就行,如果没有SD卡也可以用kflash_gui 烧入,但是烧如时要注意代码路径要与烧入路径一致,一般0x00000用于烧入固件

用MPyLDE打开python文件,得到

# generated by maixhub, tested on maixpy3 v0.4.8
# copy files to TF card and plug into board and power on
import sensor, image, lcd, time
import KPU as kpu
import gc, sys

input_size = (224, 224)
labels = ['7', '8']
anchors = [2.66, 3.67, 4.09, 4.94, 2.94, 4.22, 3.44, 4.62, 3.28, 3.87]

def lcd_show_except(e):
    import uio
    err_str = uio.StringIO()
    sys.print_exception(e, err_str)
    err_str = err_str.getvalue()
    img = image.Image(size=input_size)
    img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))
    lcd.display(img)

def main(anchors, labels = None, model_addr="/sd/m.kmodel", sensor_window=input_size, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):
    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    sensor.set_windowing(sensor_window)
    sensor.set_hmirror(sensor_hmirror)
    #sensor.set_vflip(sensor_vflip)
    lcd.rotation(1)
    sensor.run(1)

    lcd.init(type=1)
    lcd.rotation(lcd_rotation)
    lcd.clear(lcd.WHITE)

    if not labels:
        with open('labels.txt','r') as f:
            exec(f.read())
    if not labels:
        print("no labels.txt")
        img = image.Image(size=(320, 240))
        img.draw_string(90, 110, "no labels.txt", color=(255, 0, 0), scale=2)
        lcd.display(img)
        return 1
    try:
        img = image.Image("startup.jpg")
        lcd.display(img)
    except Exception:
        img = image.Image(size=(320, 240))
        img.draw_string(90, 110, "loading model...", color=(255, 255, 255), scale=2)
        lcd.display(img)

    try:
        task = None
        task = kpu.load(model_addr)
        kpu.init_yolo2(task, 0.5, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1]
        while(True):
            img = sensor.snapshot()
            t = time.ticks_ms()
            objects = kpu.run_yolo2(task, img)
            t = time.ticks_ms() - t
            if objects:
                for obj in objects:
                    pos = obj.rect()
                    img.draw_rectangle(pos)
                    img.draw_string(pos[0], pos[1], "%s : %.2f" %(labels[obj.classid()], obj.value()), scale=2, color=(255, 0, 0))
            img.draw_string(0, 200, "t:%dms" %(t), scale=2, color=(255, 0, 0))
            lcd.display(img)
    except Exception as e:
        raise e
    finally:
        if not task is None:
            kpu.deinit(task)


if __name__ == "__main__":
    try:
        # main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=0)
        main(anchors = anchors, labels=labels, model_addr="/sd/model-5015.kmodel")
    except Exception as e:
        sys.print_exception(e)
        lcd_show_except(e)
    finally:
        gc.collect()

memory not enough报错

每个人的都应该不一样,接下来就直接运行就可以了,当然你能够运行的话,但是!!!!!我的就T—T,太惨了,它一直报错,不知道有没有好兄弟跟我一样,然后就是无尽的找错的过程

 这个报错的原因就是内存不足,当然解决方案也有很多,这个内存不足不是flash和SD卡内存不足,而是运行内存不足,所以清理SD卡是没有用的。

解决方案一

更换固件,固件的种类很多,有openmv版,有mini版等等, 固件下载地址点这里,这里面是官方的不同版本的固件可以任意选择,不知道为什么我的下载mini版固件就LDE连接不上K210,(后来查资料是因为mini版本不支持LDE)所以我选择的是openmv版本,这样可以减少固件的运行内存,普通的固件是2M左右,而mini就在1M左右。要是更换了固件还是不行,那就进行方案二

解决方案二

方案二就有点麻烦了,它涉及到K210的内存管理,我们一步一步来,首先了解一下在 MaixPy 中, 目前使用了两种内存管理, 一种是 GC(垃圾回收), 另一种是系统堆内存, 两者同时存在。我们要做的就是减少GC所占的内存,从而增加系统堆内存运行一下代码可以改变GC的值

from Maix import utils
import machine

print(utils.gc_heap_size())

utils.gc_heap_size(1024*1024) # 1MiB
machine.reset()

这里设置的是1MiB可以按情况改变其值。然后还可以观察系统堆内存的大小运行以下代码即可得到

import gc

print(gc.mem_free() / 1024) # stack mem

import Maix

print(Maix.utils.heap_free() / 1024) # heap mem

'''
>>> 
raw REPL; CTRL-B to exit
>OK
352.0937
4640.0
>
MicroPython v0.5.1-136-g039f72b6c-dirty on 2020-11-18; Sipeed_M1 with kendryte-k210
Type "help()" for more information.
>>> 
'''

将内存分布调到合适就可以正常运行了,当然在无尽尝试的过程中总是会遇到一些困难,这有一个问题汇总的手册,我也是看这个搞懂的,利用MaixPy得到模型是一种最简单的方法,之后我再写利用yolo建立模型的问题,希望能帮到大家,本人是小白,要是大家有什么问题欢迎在评论区留言。


文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2023年4月20日
下一篇 2023年4月20日

相关推荐