V831本地训练详解及踩坑指南

V831本地训练

  • 下载源码
  • 配置环境
  • nncn模型转换工具
  • 照片拍摄
  • 制作数据集
  • 训练
  • 模型转换
  • 模型部署
  • 提示:看这篇文章前最好先看一遍官方说明,v831的配置只要不是我这种倒霉蛋,一般都是很好配置的,跟着官方文档就能配好

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

    下载源码

    官方网址非常慢要翻墙

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

    配置环境

    推荐先搞anaconda,搞个虚拟环境,养成好习惯

    1. python版本3.6以上的应该都可以,以下的没测试过,我最后使用的是3.9的,可以考虑3.8,印象里3.8配置的最快,资源包搜索的很快且安装后面2个包没有小插曲.
    2. pytorch安装,30系显卡选11以上的
    3. pip3 install torchsummary pycocotools opencv-python opencv-contrib-python

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

    nncn模型转换工具

    直接区官网教程里安装吧

    编译完之后如果在任意目录下运行:

    onnx2ncnn
    

    如果报错找不到命令.
    这边提供3个方法
    1.想办法把官网的教程里加路径的搞懂,反正我没看懂也没实践出来
    2.直接把要转换的文件丢到和onnx2ncnn可执行文件同一个目录下

    onnx2ncnn可执行文件目录
    也就是对应的这个目录下打开终端输入

    ./onnx2ncnn 需要转换的yolo模型.onnx  转换出来的你想要的文件名.param  转换出来的你想要的文件名.bin
    

    3.直接把onnx2ncnn这个可执行文件cp到/usr/bin里(推荐)
    这种方法好处是简单除暴,也不需要在环境变量中加新的环境变量.在当前目录输入

    sudo cp onnx2ncnn /usr/bin
    

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

    照片拍摄

    因为我有01家的k210,上面有按键,所以可以按键拍摄,如果是官方的k210,可以采用1s1次自动拍摄,或者用杜邦线一次次短路按键脚口来拍照
    ps1:我这个代码会报错,但是不管三七二十一,上电后掉电重启一次,就可以用
    ps2:关于摄像头方向和lcd方向的技巧:先调整到开发板怎么转,lcd显示都是符合人的主观的,之后每转90°拍一张照片.
    然后掉电把sd卡取下,看一下4张图里有一张图是真正正着的,这样就确定了应该怎么拿'照相机'
    

    拍照代码

    #要注意照片实际效果和LCD的显示,多试几次,通过更改sensor.set_vflip(1) 和lcd.rotation(0),甚至还有镜像等
    
    import sensor, lcd, utime
    from Maix import GPIO
    from fpioa_manager import fm
    
    #注册KEY的外部IO
    fm.register(16, fm.fpioa.GPIOHS0, force=True)
    
    #构建KEY对象
    KEY=GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)
    
    #摄像头初始化
    sensor.reset() # Initialize the camera sensor.
    sensor.set_pixformat(sensor.RGB565) # or sensor.GRAYSCALE
    sensor.set_framesize(sensor.QVGA) # or sensor.QVGA (or others)
    sensor.skip_frames(30) # Let new settings take affect.
    sensor.set_windowing((224,224))  # 设置图片大小为224*224(训练需要224的图片,提前转换好)
    sensor.set_vflip(1)    #摄像头后置模式(0或1)
    
    #LCD初始化
    lcd.init()
    lcd.rotation(0)  # 屏幕旋转(0~3)
    
    key_node = 0  #按键标志位
    name_num = 0  #照片名字
    
    ##############################################
    #  按键和其回调函数
    ##############################################
    def fun(KEY):
        global key_node
        utime.sleep_ms(10) #消除抖动
        if KEY.value()==0: #确认按键被按下
            key_node = 1
    
    #开启中断,下降沿触发
    KEY.irq(fun, GPIO.IRQ_FALLING)
    
    while True:
    
        lcd.display(sensor.snapshot()) # LCD实时显示
    
        if key_node==1: #按键被按下
            key_node = 0 #清空按键标志位
    
            #拍照并保存,保存文件用时间来命名。
            lcd.display(sensor.snapshot().save("/sd/"+str(name_num)+".jpg"))
            name_num=name_num+1 #名字编码加1
    
            print("Done! Reset the camera to see the saved image.")
    
            #延时0.5秒,观看拍摄图片
            utime.sleep_ms(500)
    

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

    制作数据集

    labelimg下载网上资料很多,这里不多说了.
    小tip:左边有个标注模式选择一定要选PascalVOC模式.view菜单栏里有自动保存模式,A上一张,D下一张,W开始标注,右边点击使用预设标签,我这边标的是冰墩墩就叫bdd了.

    标注完之后
    1.来到v831_yolo-master/data/custom/annotations_cache里把所有文件删了,这是缓存数据,如果同一批数据集可以不删,但是如果换数据集了要删除
    2.退回到Annotations里放入刚刚标注好的xml文件
    3.往JPEGImages里放入图片
    4.进入ImageSets/Main
    在这个目录制作一个python脚本(代码内容在下方),并运行:

    python auto_create.py --first 0 --finish 304 --interval 9
    

    PS:如果没有用我的拍照代码,train.txt和val.txt请自行制作

    第一个参数是第一张图片,如果使用我上面的拍照代码,那就是从0 开始
    我拍了305张,最后一张是304,所以第二个参数填304,验证集一般取10%左右,第三个参数我填9
    之后会生成一个train.txt和val.txt

    # coding=utf-8
    
    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument('--first', default=0, type=int, help='第一个数据集的名字')
    parser.add_argument('--finish', default=10, type=int, help='最后一个数据集的名字')
    parser.add_argument('--interval',default=5, type=int, help='间隔多少采集一个作为一个验证集')
                  
    arg = parser.parse_args()
    
    start = arg.first
    last = arg.finish
    interval = arg.interval
    
    t = open('train.txt','w')
    v = open('val.txt','w')
    
    train_number = 0
    val_number = 0
    
    
    for i in range(start,last+1):
     if i % interval == 0:
      val_number+=1
      v.write(str(i)+'\n')
     else:
      train_number+=1
      t.write(str(i)+'\n')
    
    print('start:%d\nfinish:%d\ntrain_number:%d\nval_number:%d\n'%(start,last,train_number,val_number))
    
    
    
    1. 修改配置
      修改 data/custom.py 中的 CUSTOM_CLASSES 变量为正确的 labels
    # CUSTOM_CLASSES = [
    #     "mouse",
    #     "sipeed_logo"
    # ]
    
    CUSTOM_CLASSES = [
        "bdd"
    ]
    

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

    训练

    正常人弄完就可以开始训练了,并且一般训练了就出结果了
    在v831_yolo-master下输入

    python3 train.py -d custom --cuda -v slim_yolo_v2 -hr -ms
    

    然后等待训练结束就可以在/v831_yolo-master/weights/custom下找到练出来的参数了
    但是我一直有问题,如果你也有问题,可以看看我改的内容.

    我一共改了3个地方


    第二张图这里本来是32,我是3070,改为了16,再垃圾点的算力改为8就差不多了

    第三张图片默认是10,要改为比config.py的max_epoch大才能完成全部训练.
    不知道哪里出的问题,一进入检查就报错,但是我确定我的数据集,环境配置是没什么问题的,估计是什么很坑人的坑了,所以我直接不进行检查了

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

    模型转换

    python3 test.py -d custom -v slim_yolo_v2 --trained_model weights/custom/slim_yolo_v2/slim_yolo_v2_260.pth --visual_threshold 0.3 -size 224 --export
    

    运行导出模型命令后会在 out 目录下生成
    那么这一步如果出现报错

    那就跳回到nncn模型转换工具,只要你的转换工具安装没问题,那就可以用我的方法

    加工完之后还要再加工一次变成awnn
    进入maixhub
    工具箱里的模型转换,选择NCNN,RGB,然后按照要求打包文件,上传
    要求如下:
    也就是2个由转换工具转换出来的bin和param文件加上一个验证数据集,这个数据集从训练的图片里选或者再拍摄一些,当然要确保拍摄手法一致,大约50张.
    然后进行压缩,压完上传,进行转换.转换完之后下载下来的文件中有bin和param就是我们需要的模型了.
    ##############################################################################################################

    模型部署

    按照历程去模型部署,官网代码我这里也贴出来把

    from maix import nn, display, camera, image
    from root.classes_label import labels    #分类标签,根据个人需求自行替换
    import time
    
    model = {
        "param": "/root/restnet18_int8.param",        #模型文件,需要替换成自己训练的模型路劲
        "bin": "/root/restnet18_int8.bin"
    }
    options = {
        "model_type":  "awnn",
        "inputs": {
            "input0": (224, 224, 3)
        },
        "outputs": {
            "output0": (1, 1, len(labels))           
        },
        "first_layer_conv_no_pad": False,
        "mean": [127.5, 127.5, 127.5],
        "norm": [0.00784313725490196, 0.00784313725490196, 0.00784313725490196],
    }
    
    print("-- load model:", model)
    m = nn.load(model, opt=options)
    print("-- load ok")
    
    while True:
        img = camera.capture()
        AI_img = img.copy().resize(224, 224)
        t = time.time()
        out,  = m.forward(AI_img, quantize=True)
        t = time.time() - t
        print("-- forward time: {}s".format(t))
        msg = "{}%: {}".format(int(out.max() * 10), labels[out.argmax()])
        print(msg)
        img.draw_string(0, 0, msg, color = (255, 0, 0))
        display.show(img)
    
    
    物联沃分享整理
    物联沃-IOTWORD物联网 » V831本地训练详解及踩坑指南

    发表评论