MTCNN + MobileFaceNet 部署到 K210、YOLOv3-Tiny + ArcFace 部署到 K210

三、MTCNN + MobileFaceNet 部署到 K210 的完整步骤

1. 模型准备与优化
(1) MTCNN 模型适配 KPU
  • 步骤 1:获取 TensorFlow 版 MTCNN
     

    BASH

    git clone https://github.com/ipazc/mtcnn
    # 提取 PNet/RNet/ONet 的 .pb 模型
    python mtcnn/export_models.py
     

  • 步骤 2:转换为 TFLite 格式
     

    PYTHON

    import tensorflow as tf

    # 转换 PNet
    converter = tf.lite.TFLiteConverter.from_saved_model("mtcnn/pnet/")
    converter.optimizations = [tf.lite.Optimize.DEFAULT]
    tflite_pnet = converter.convert()
    open("pnet.tflite", "wb").write(tflite_pnet)

     

    关键调整
    • 固定输入尺寸(如 320x240),删除动态 ResizeBilinear 层。
    • 确保所有卷积层满足 KPU 限制(kernel=1x1/3x3stride=1/2)。
(2) MobileFaceNet 量化校准
  • 步骤 1:导出 Keras 模型为 TFLite
     

    PYTHON

    model = keras.models.load_model("mobilefacenet.h5")
    converter = tf.lite.TFLiteConverter.from_keras_model(model)
    converter.optimizations = [tf.lite.Optimize.DEFAULT]
    converter.representative_dataset = calibration_data_gen  # 提供 100 张校准图片
    tflite_model = converter.convert()
    open("mobilefacenet_int8.tflite", "wb").write(tflite_model)

  • 步骤 2:验证量化精度损失
    使用 LFW 数据集测试量化后模型,确保准确率下降不超过 2%。
2. 使用 nncase 编译为 K210 模型
 

BASH

# 编译 PNet
ncc -i tflite -o k210model --dataset calibration_images/ --postprocess 0to1 pnet.tflite pnet.kmodel

# 编译 MobileFaceNet
ncc -i tflite -o k210model --dataset faces_emore/ --weights-bits 8 mobilefacenet_int8.tflite mobilefacenet.kmodel

 

3. K210 端部署代码
 

PYTHON

# K210 MicroPython 代码(精简版)
import sensor, image, time
from nncase import runtime

# 初始化摄像头
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)  # 320x240

# 加载模型
pnet = runtime.Kpu()
pnet.load_kmodel('/sd/pnet.kmodel')
mobilefacenet = runtime.Kpu()
mobilefacenet.load_kmodel('/sd/mobilefacenet.kmodel')

while True:
    img = sensor.snapshot()
    # PNet 检测
    pnet_input = img.resize(160, 120).pix_to_ai()
    pnet.run(pnet_input)
    boxes = pnet.get_outputs()[0]  # 解析输出边界框
    
    for box in boxes:
        # 裁剪人脸并缩放到 112x112
        face = img.crop(box).resize(112, 112)
        face_ai = face.pix_to_ai()
        # MobileFaceNet 提取特征
        mobilefacenet.run(face_ai)
        embedding = mobilefacenet.get_outputs()[0]
        # 比对数据库(需提前存储注册特征)
        min_dist = 1.0
        for db_emb in database:
            dist = sum((embedding[i] - db_emb[i])**2 for i in range(128))**0.5
            if dist < min_dist:
                min_dist = dist
        if min_dist < 0.5:  # 阈值根据场景调整
            img.draw_rectangle(box, color=(0, 255, 0))

 

4. KPU 适配关键操作
  • 内存优化
    • 使用 runtime.Kpu.alloc_input() 和 runtime.Kpu.alloc_output() 复用内存缓冲区。
    • 限制并发模型数量(K210 内存仅 6MB,同时加载多个模型需分时加载)。
  • 算子替换
    • 将 MobileFaceNet 中的 GlobalAveragePooling2D 替换为 AveragePooling2D(pool_size=(7,7))
    • 确保所有 Conv2D 的 padding 为 same 且输入尺寸为偶数。

四、YOLOv3-Tiny + ArcFace 部署到 K210 的完整步骤

1. 模型训练与优化
(1) YOLOv3-Tiny 适配 KPU
  • 步骤 1:训练 TensorFlow 版 YOLOv3-Tiny
     

    BASH

    git clone https://github.com/zzh8829/yolov3-tf2
    python train.py --model yolov3-tiny --dataset widerface/ --weights yolov3-tiny.conv.15

  • 步骤 2:简化模型结构
    • 删除 ResizeNearestNeighbor 上采样层,改用 Conv2DTranspose(需 KPU 支持)。
    • 限制输入尺寸为 320x240(K210 最大支持分辨率)。
(2) ArcFace 特征提取模型量化
  • 步骤 1:转换 PyTorch 模型为 ONNX
     

    PYTHON

    import torch
    from models.arcface import ArcFace

    model = ArcFace(pretrained=True)
    dummy_input = torch.randn(1, 3, 112, 112)
    torch.onnx.export(model, dummy_input, "arcface.onnx", opset_version=11)

     

  • 步骤 2:ONNX 转 TFLite
     

    BASH

    pip install onnx-tf
    onnx-tf convert -i arcface.onnx -o arcface_tf
    tflite_convert --saved_model_dir arcface_tf --output_file arcface.tflite

2. nncase 编译与优化
 

BASH

# 编译 YOLOv3-Tiny
ncc -i tflite -o k210model --dataset calibration_images/ yolov3-tiny.tflite yolov3-tiny.kmodel

# 编译 ArcFace
ncc -i tflite -o k210model --postprocess n1to1 --weights-bits 8 arcface.tflite arcface.kmodel


 

3. K210 端部署代码
 

PYTHON

# K210 MicroPython 代码(关键逻辑)
import nncase, sensor, image

# 初始化模型
yolo = nncase.RuntimeKpu()
yolo.load_kmodel('/sd/yolov3-tiny.kmodel')
arcface = nncase.RuntimeKpu()
arcface.load_kmodel('/sd/arcface.kmodel')

while True:
    img = sensor.snapshot().resize(320, 240)
    # YOLO 推理
    yolo_input = img.pix_to_ai()
    yolo.run(yolo_input)
    dets = parse_yolo_output(yolo.get_outputs())  # 自定义解析函数
    
    for det in dets:
        face = img.crop(det['bbox']).resize(112, 112)
        # ArcFace 特征提取
        face_ai = face.pix_to_ai().transpose([2, 0, 1])  # HWC→CHW
        arcface.run(face_ai)
        embedding = arcface.get_outputs()[0]
        # 特征比对(Faiss 需预编译为 K210 兼容格式)
        match_id = faiss_search(embedding, database)
        if match_id != -1:
            img.draw_string(10, 10, f"ID: {match_id}", color=(255, 0, 0))

 

显示全部 (27)

4. KPU 适配关键操作
  • YOLOv3-Tiny 优化
    • 替换 LeakyReLU 为 ReLU(KPU 不支持 LeakyReLU 硬件加速)。
    • 确保所有 Conv2D 的 stride=1/2,输入尺寸为偶数。
  • ArcFace 调整
    • 使用 --postprocess n1to1 参数匹配模型输入归一化范围([-1,1])。
    • 将 Bottleneck 结构中的 Flatten 替换为 GlobalAveragePooling2D

五、总结与建议

  • 路径选择:将 nncase 工具链放在无空格路径(如 /opt/nncase),并确保 bin 加入 PATH。
  • 模型设计铁律
    • 输入尺寸 ≤ 320x240,输出 ≥ 4x4。
    • 仅使用 KPU 支持的算子(如 Conv3x3/1x1、ReLU)。
  • 性能压榨技巧
    • 使用 ncc 的 --weights-bits 8 和 --channelwise-output 降低内存占用。
    • 启用 nncase.RuntimeTensor 内存池复用,减少碎片
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值