K210学习笔记(十一)——MaixHub在线训练模型(旧版在线炼丹)

文章目录
前言一、MaixHub功能介绍二、Maixhub模型训练使用方法三、图片采集四、标注数据集(目标分类跳过这一步)五、打包数据集六、上传数据集进行训练总结

前言
个人觉得K210与openmv最大的区别就是可以跑模型了,虽然不能跑yolov5得这类大型模型,但是还是可以使用一些yolov2、Mobilenet V1等轻量化模型。
一、MaixHub功能介绍
想要训练一个可用得模型,奈何电脑显卡不给力,没关系,我们可以使用Spieed的MaixHub模型在线训练来训练模型。Maixhub 模型训练平台帮助大家快速训练想要的 AI模型, 不需要任何训练环境搭建和代码运行, 只需要选择训练类型,上传(标注)数据集, Maixhub就会自动进行训练,训练结束后下载即可。 MaixHub目前有两种训练: 1、目标分类 识别图片所属的种类,只是识别出图片的种类,并没有显示识别物体的坐标(没有框出来),比如: 2、目标检测 既能识别出物体,又能将识别到的物体的坐标输出出来(框出来),比如:
二、Maixhub模型训练使用方法
首先要确定自己需要训练那种模型,如果只是要识别出物体,那就先目标分类,如果既要识别出物体类别,还要输出识别到的物体坐标,那就选择目标检测。 确定分类。 包括分类数量, 具体分类。 比如这里以识别红色小球和玩具为例: 所以共两个分类: ball 和 toy, 我们也称之为标签(label), 注意!!! 分类名(标签/label)只能使用英文字符和下划线
确定分辨率:以下为Maixhub目前支持的分辨率,其它分辨率将会训练失败(使用推荐分辨率识别准确率更高):
目标分类: 224×224(推荐)
目标检测: 224×224(推荐), 240×240
确定采集数据集数量:另外也要满足 Maixhub 的要求:
目标分类: 每类图片数量不低于40张,比如采集 200 张
目标检测: 每类图片数量不低于100张, 比如采集200张 上限为2000张
最后要注意上传的zip文件不能超过20MiB
三、图片采集
采集图片有以下几种方式: 1、使用开发板采集到SD卡, 直接采集成需要的分辨率 (推荐) 2、使用现成的图片, 使用预处理工具处理成需要的分辨率, 注意, 处理完后一定要手动检查数据是否符合要求, 不然可能影响训练精准度 3、手机拍照, 然后使用预处理工具处理成需要的分辨率, 注意, 处理完后一定要手动检查数据是否符合要求, 不然可能影响训练精准度
使用开发板进行数据采集 因为之前已经了解了MAIX BIT的拍照原理,所以这里我们主要是用开发板来采集图片。 使用这个脚本来进行采集图片
#根据你的开发板修改摄像头和屏幕配置, 比如lcd.rotation
#准备一张支持 SPI 模式的 SD 卡, 分区为 MBR (msdos), 格式化为 FAT32
#将目录下的boot.py文件拷贝到 SD 卡根目录
#开发板断电, 将SD卡插入开发板
#开发板上电, 程序会自动创建一个目录cap_images_1, 下次上电会创建cap_images_2, 这样就避免了覆盖
#采集一个分类的图片 按开发板上的boot按键,然后松开按键来采集一张图片, 这会将图片保存到cap_images_1/0/0.jpg, 采集的图片的名字会自动增长, 比如0.jpg 1.jpg …
#长按boot按键切换类别目录 这会创建一个新目录,比如cap_images_1/1/, 后面采集的图片都会被保存到这个新的目录, 比如cap_images_1/1/0.jpg
#开发板断电,取出SD卡插到电脑, 打开文件管理器就可以看到采集的图片了
import sensor, lcd
from Maix import GPIO
from fpioa_manager import fm
from board import board_info
import os, sys
import time
import image

#### image size ####
set_windowing = (224, 224)

#### sensor config ####

sensor.reset(freq=22000000, dual_buff=False)
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA) # 320×240
try:
sensor.set_jb_quality(95) # for IDE display quality
except Exception:
pass # no IDE support
if set_windowing:
sensor.set_windowing(set_windowing)

sensor.skip_frames()

#### lcd config ####
lcd.init(type=1, freq=15000000)
lcd.rotation(2)

#### boot key ####
boot_pin = 16 # board_info.BOOT_KEY
fm.register(boot_pin, fm.fpioa.GPIOHS0)
key = GPIO(GPIO.GPIOHS0, GPIO.PULL_UP)

######################################################

#### main ####
def capture_main(key):
def draw_string(img, x, y, text, color, scale, bg=None , full_w = False):
if bg:
if full_w:
full_w = img.width()
else:
full_w = len(text)*8*scale+4
img.draw_rectangle(x-2,y-2, full_w, 16*scale, fill=True, color=bg)
img = img.draw_string(x, y, text, color=color,scale=scale)
return img

def del_all_images():
os.chdir("/sd")
images_dir = "cap_images"
if images_dir in os.listdir():
os.chdir(images_dir)
types = os.listdir()
for t in types:
os.chdir(t)
files = os.listdir()
for f in files:
os.remove(f)
os.chdir("..")
os.rmdir(t)
os.chdir("..")
os.rmdir(images_dir)

# del_all_images()
os.chdir("/sd")
dirs = os.listdir()
images_dir = "cap_images"
last_dir = 0
for d in dirs:
if d.startswith(images_dir):
if len(d) > 11:
n = int(d[11:])
if n > last_dir:
last_dir = n
images_dir = "{}_{}".format(images_dir, last_dir+1)
print("save to ", images_dir)
if images_dir in os.listdir():
img = image.Image()
img = draw_string(img, 2, 200, "please del cap_images dir", color=lcd.WHITE,scale=1, bg=lcd.RED)
lcd.display(img)
sys.exit(1)
os.mkdir(images_dir)
last_cap_time = 0
last_btn_status = 1
save_dir = 0
save_count = 0
os.mkdir("{}/{}".format(images_dir, save_dir))
while(True):
img0 = sensor.snapshot()
if set_windowing:
img = image.Image()
img = img.draw_image(img0, (img.width() – set_windowing[0])//2, img.height() – set_windowing[1])
else:
img = img0.copy()
# img = img.resize(320, 240)
if key.value() == 0:
time.sleep_ms(30)
if key.value() == 0 and (last_btn_status == 1) and (time.ticks_ms() – last_cap_time > 500):
last_btn_status = 0
last_cap_time = time.ticks_ms()
else:
if time.ticks_ms() – last_cap_time > 5000:
img = draw_string(img, 2, 200, "release to change type", color=lcd.WHITE,scale=1, bg=lcd.RED)
else:
img = draw_string(img, 2, 200, "release to capture", color=lcd.WHITE,scale=1, bg=lcd.RED)
if time.ticks_ms() – last_cap_time > 2000:
img = draw_string(img, 2, 160, "keep push to change type", color=lcd.WHITE,scale=1, bg=lcd.RED)
else:
time.sleep_ms(30)
if key.value() == 1 and (last_btn_status == 0):
if time.ticks_ms() – last_cap_time > 5000:
img = draw_string(img, 2, 200, "change object type", color=lcd.WHITE,scale=1, bg=lcd.RED)
lcd.display(img)
time.sleep_ms(1000)
save_dir += 1
save_count = 0
dir_name = "{}/{}".format(images_dir, save_dir)
os.mkdir(dir_name)
else:
draw_string(img, 2, 200, "capture image {}".format(save_count), color=lcd.WHITE,scale=1, bg=lcd.RED)
lcd.display(img)
f_name = "{}/{}/{}.jpg".format(images_dir, save_dir, save_count)
img0.save(f_name, quality=95)
save_count += 1
last_btn_status = 1
img = draw_string(img, 2, 0, "will save to {}/{}/{}.jpg".format(images_dir, save_dir, save_count), color=lcd.WHITE,scale=1, bg=lcd.RED, full_w=True)
lcd.display(img)
del img
del img0

def main():
try:
capture_main(key)
except Exception as e:
print("error:", e)
import uio
s = uio.StringIO()
sys.print_exception(e, s)
s = s.getvalue()
img = image.Image()
img.draw_string(0, 0, s)
lcd.display(img)
main()

采集好图片后,将SD卡中的图片拷贝到电脑, 整理成下面的目录结构, 所有图片的分辨率为224×224
四、标注数据集(目标分类跳过这一步)
注意: 一定要先保证分辨率正确, 再标注 有两种标注方式,一种是vott(击这里下载),另一种是labelimg(点击这里下载 )。这里我标注主要是用labelimg进行标注(注意:labelimg的路径不能有中文,不然会闪退)。 保存后会生成xml格式的文件(即PascalVOC格式),每张图对应一个xml文件。完成后目录结构和文件如下: 或者两级目录
五、打包数据集
将前面处理好的数据集进行打包, 使用zip压缩,暂不支持其它格式, 而且文件不要超过20MiB。 目标分类: 一个文件夹一个分类, 分类名(标签/label)就是文件夹名
目标检测: labelimg 的输出zip文件结构,新建了一个labels.txt, 输入标记的标签, 每行一个(这是必须的, 否则数据无效), 比如这里: 然后目录结构如下 或者两级labelimg输出
六、上传数据集进行训练
如果进度一直是0%可以刷新一下,训练完成后点击Download就可以下载训练文件。 下载文件是一个zip压缩文件, 解压后仔细阅读README.txt,使用了中英文对使用方法进行了说明,默认是在有最新版固件的情况下, 将结果文件全部拷贝到SD卡根目录, 断电插入开发板, 然后上电就可以运行了。(注意:提交数据集格式一定要争取,不然会报错不能训练)
总结
以上就是MaixHub在线训练模型大致过程,整体下来还是比较简单的,建议是先进行一次物体分类的训练再进行物体检测的训练。 常见问题: 1、物体分类训练完成后运行训练文件,发现识别到了物体,但是显示的是其它物体的名称,这个时候可以更改boot.py里面的labels的顺序。
labels = ["Recyclable_waste_out", "Other_waste", "Kitchen_waste", "Hazardous_waste_out"]

2、…有待补充…来源:纸箱里的猫咪

物联沃分享整理
物联沃-IOTWORD物联网 » K210学习笔记(十一)——MaixHub在线训练模型(旧版在线炼丹)

发表评论