Maix Bit(K210)保姆级入门上手教程---自训练模型之云端训练

慈云数据 2024-04-05 技术支持 131 0

Maix Bit(K210)保姆级入门上手教程系列

Maix Bit(K210)保姆级入门上手教程—环境搭建

Maix Bit(K210)保姆级入门上手教程—外设基本使用


这是K210快速上手系列文章,主要内容是,介绍MaixHub这个线上训练模型的使用,以及如何部署到K210中。

阅读本文的前提:读者对基本的监督式学习有一定的了解,之道学习率、迭代次数、网络模型等有一定的概念。没有的话,自行补充啦或者点这里,阅读官方文档学习相关基础~

本文内容多来自官方文档,目的是为了帮助读者快速上手训练自己的模型,侵权删!

文章目录

  • Maix Bit(K210)保姆级入门上手教程系列
  • 一、K210硬件介绍
    • 1、内存介绍
    • 2、KPU介绍
    • 二、MaixHub介绍
    • 三、获取图片数据
      • 1、网上获取
      • 2、线下获取
      • 四、训练模型
      • 五、部署模型
        • 1、普通模型部署
        • 2、大模型部署
          • a、修改gc内存
          • b、加载mini的固件
          • c、kpu.load_flash加载模型
          • 五、参考资料

            一、K210硬件介绍

            一般来说运行神经网络模型有两种方式。一种是直接通过CPU进行运行,一种是通过KPU或者GPU加速运行。K210中使用KPU的方式加速运行网络模型,使得其运行速度得到加快。

            1、内存介绍

            在这里插入图片描述

            MaixPy 中的存储介质主要由 Flash,SD 卡组成,分为三块区域,分别是 MaixPy.bin 固件区,xxx.kmodel 模型区,文件系统区:Flash 上为 spiffs(SPI Flash File System),SD 卡为 Fatfs(FAT file system)。

            通常起始于 0x300000,模型文件之所以一般不烧录在 Flash 的文件系统,原因有下:

            Flash 中文件系统拥有的内存并不够大,不足以放入大模型,更大的模型可以放入 SD 卡中。直接读取模型文件比经过文件系统读取速率更快。

            但是也会有以下原因会将模型烧录在flash中,就是模型本身比较大,就需要烧录到flash中,而不是SD卡中。因为模型大,SD卡加载模型可能会出现内存不足的情况。

            内存管理

            在 MaixPy 中, 目前使用了两种内存管理, 一种是 GC(垃圾回收), 另一种是系统堆内存, 两者同时存在。

            比如:芯片有 6MiB 内存,加入固件使用了前面的 2MiB, 还剩 4MiB, 默认 GC使用 512KiB, 剩下的给系统堆内存管理。

            注意:

            GC 内存的总大小是可以设置的, 所以,根据具体的使用情况可以适当修改GC内存大小, 比如:

            为了加载更大的模型,可以把 GC内存设置小一点

            如果分配新的变量提示内存不足, 可以适当将GC内存设置大一点即可。如果都不够了, 就要考虑缩减固件大小,或者优化代码了。

            2、KPU介绍

            KPU是通用的神经网络处理器,它可以在低功耗的情况下实现卷积神经网络计算,时时获取被检测目标的大小、坐标和种类,对人脸或者物体进行检测和分类。KPU 实现了 卷积、批归一化、激活、池化 这 4 种基础操作的硬件加速, 但是它们不能分开单独使用,是一体的加速模块。KPU使用也有一些限制。

            内存限制

            • K210 有 6MB 通用 RAM 和 2MB KPU 专用 RAM。模型的输入和输出特征图存储在 2MB KPU RAM 中。权重和其他参数存储在 6MB 通用 RAM 中。

              加速限制

              加速限制比较多,有一些算子是能完全加速,有一些不能,大概知道这个就行了。具体哪些可以,哪些不可以自己上官方查啦~

              二、MaixHub介绍

              MaixHub网站提供模型训练功能和模型分享功能, 只需要准备好需要训练的数据集, 不需要搭建训练环境和代码, 上传训练数据即可快速训练出模型,方便快速制作你的 AI 应用,或者入门学习 AI 训练的流程和原理。

              三、获取图片数据

              1、网上获取

              获取图片数据,可以自己爬虫获取,也可以从实际运行的开发环境中获取。如果是实际运行的环境获取的话(建议采用这个方式,用自己获取到的图片训练,精度会更高),可以参考下面的代码。如果是爬虫获取,可以参考

              百度爬取图片

              2、线下获取

              我这里写了一个简单从摄像头获取数据的代码,可以参考一下。目前支持两种获取图片的方式,定时获取或者按键获取。

              但是由于个人水平实在有限,不能解决python中使用uos.mkdri()创建的目录不能正常使用python进行删除的问题(建议通过相关接口修改字典的内容,因为创建的目录不能正常删除,除非在PC上操作)。

              如果出现目录或者文件异常,可能是没有正常关闭文件导致的。可以在PC上面把创建的东西删除就可以。

              注意,需要SD卡,文件都是在SD卡中操作的。

              基本流程的话,首先调用init()创建索引文件。之后会根据字典的内容创建相应的目录存放文件。例如:init()创建的字典文格式如下。

              会自动创建目录/pic/sit/right和/pic/sit/error,之后会自动读取以及保存right或者error的值作为图片名词。

              dictx={'sit': {'right': 0, 'error': 0}, 'object': {'portable_battery': 0, 'Instant_noodles': 0,'mouse': 0}}
              

              如果是使用Maix Bit板子,下面代码能直接运行:按键就是开发板上的按键

              from machine import Timer
              from Maix import GPIO 
              from fpioa_manager import fm
              import sensor, lcd
              import uos,sys
              def create_dir(dir,chdir='/sd'):
                  try:
                      if(uos.stat(dir)):
                          print("PATH existed")
                  except:
                          uos.mkdir(dir)
              # 函数整个字典读取,文件默认名字是index.txt
              def read_pic_index(file_path='/sd/pic'):
                  uos.chdir('/sd/pic')
                  file = open('index.txt','r+',encoding='utf-8')
                  index= eval(file.read())   #读取的str转换为字典
                  file.close()
                  return index
              # 添加一个字典,第一次创建,写key=='none'
              def add_pic_index(key,dict_value,file_path='/sd/pic'):
                  if(key!='none' ):
                      index = read_pic_index(file_path)
                      file = open('index.txt',"w+",encoding='utf-8')
                      index[key]=dict_value
                      file.write(str(index))      #把字典转化为str
                      file.close()
                  else:# 第一次创建
                      create_dir('pic',file_path)
                      uos.chdir(file_path)
                      #print(uos.getcwd())
                      file = open('index.txt',"w+",encoding='utf-8')
                      file.write(str(dict_value))      #把字典转化为str
                      file.close()
                      
              # 删除一个字典
              def del_pic_index(key,file_path='/sd/pic'):
                  import sys
                  global index   # 声明全局索引
                  
                  index = read_pic_index('index.txt')
                  file = open('index.txt','w+')
                  
                  try:
                      del index[str(key)]
                  except KeyError:
                      print('key :'+key +' have been del or without this key')   
                      #file.close()
                  else:
                      pass
                  file.write(str(index))      #把字典转化为str
                  file.close()
              # 打印所有的索引
              def print_pic_index(file_path='sd/pic'):
                  cat_index=read_pic_index('index.txt')
                  for key in cat_index:
                      print("key:%s value:%s"%(key,str(cat_index[key])))
              # 获取key的索引
              def get_pic_key_index(key,file_path='sd/pic'):
                  cat_index=read_pic_index('index.txt')
                  for fkey in cat_index:
                      if fkey==key:
                          return cat_index[key];
              # 设置某一个key的index
              def set_pic_key_index(key,dict_value,file_path='sd/pic'):
                  add_pic_index(key,dict_value,file_path)
              # 清楚所有的index
              def clear_pic_index(file_path='sd/pic'):
                  cat_index=read_pic_index(file_path)
                  for key in cat_index:
                      del_pic_index(key,file_path)
              # 这里解释以下,init()创建一个索引文件,保存标签图片
              # 比如,/sd/pic/index.txt中的数据就是dictx的数据,使用前需要先调用init()
              # 存放图片也跟这个有关系,存放图片的路径会是,/sd/pic/sit/right或者
              # /sd/pic/sit/error
              def init():
                  # init()执行一次就行了,之后屏蔽掉就OK
                  dictx={'sit': {'right': 0, 'error': 0}, 'object': {'portable_battery': 0, 'Instant_noodles': 0,
                       'mouse': 0}}
                  try:
                      if uos.stat('/sd/pic'):
                          print("PATH existed")
                  except:
                      uos.mkdir('/sd/pic')
                      add_pic_index('none',dictx)
                      index=read_pic_index()
                      print(index)
              # 初始化摄像头
              def sensor_init():
                  sensor.reset()
                  sensor.set_pixformat(sensor.RGB565)
                  sensor.set_framesize(sensor.QVGA)
                  sensor.run(1)
                  sensor.skip_frames()
              # 获取一帧图片
              def get_frame_pic():
                  img = sensor.snapshot()
                  return img
              # 获取获取图片计数和图片设置路径
              pic_num=1
              save_path=''
              # 保存图片设置
              def save_pic(timer):
                  global pic_num
                  global save_path
                  img=get_frame_pic()
                  lcd.display(img)
                  file_name=save_path+'/'+str(pic_num)+'.jpg'
                  print(file_name)
                  img.save(file_name, quality=95)
                  pic_num+=1
              #开发板上RST的按键IO
              KEY=16 
              # 保存图片,保存的数量,1张图片拍摄的时间间隔(ms),这里使用计时器的方式
              # 参数:ikey是字典类标签,iikey是某一个标签
              # 参数:num是保存图片数量,file_index_path就是标签保存途径
              # 参数:interval是’period‘获取一张图片间隔,推荐300~500ms
              # 参数:mode是模式,按键’key‘,模式’period‘
              # 注意:使用按键的方式,interval将不再起作用
              def start_obtain(ikey,iikey,file_index_path='/sd/pic/index.txt',num=100,interval=300,mode='period'):
                  global pic_num
                  global save_path
                  print('sensor_init & lcd')
                  pic_index=get_pic_key_index(ikey,file_index_path)
                  print(pic_index)
                  sensor_init()
                  lcd.init()
                  if mode=='period':
                      if interval 
微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon