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可执行文件同一个目录下

V831本地训练,小白超详细,奇葩踩坑之路_第1张图片
也就是对应的这个目录下打开终端输入

./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了.
V831本地训练,小白超详细,奇葩踩坑之路_第2张图片
标注完之后
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个地方
V831本地训练,小白超详细,奇葩踩坑之路_第3张图片
在这里插入图片描述
第二张图这里本来是32,我是3070,改为了16,再垃圾点的算力改为8就差不多了
在这里插入图片描述
第三张图片默认是10,要改为比config.py的max_epoch大才能完成全部训练.
不知道哪里出的问题,一进入检查就报错,但是我确定我的数据集,环境配置是没什么问题的,估计是什么很坑人的坑了,所以我直接不进行检查了
V831本地训练,小白超详细,奇葩踩坑之路_第4张图片

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

模型转换

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 目录下生成
那么这一步如果出现报错
V831本地训练,小白超详细,奇葩踩坑之路_第5张图片

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

加工完之后还要再加工一次变成awnn
进入maixhub
工具箱里的模型转换,选择NCNN,RGB,然后按照要求打包文件,上传
要求如下:V831本地训练,小白超详细,奇葩踩坑之路_第6张图片
也就是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)

你可能感兴趣的:(python,深度学习,开发语言)