使用官方图像分类例程时出现IndexError: index is out of bounds报错

Viewed 40

重现步骤
1.在在线训练平台训练了一个图像分类的模型
2.按照压缩包内嵌pdf文档操作
3.运行cls_image_1_2_2脚本或者cls_video_1_2_2脚本

期待结果和实际结果
期待结果:正确进行图像分类操作
实际结果:一运行就出现IndexError: index is out of bounds报错

软硬件版本信息
硬件:01studio k230开发板
镜像版本:micropython_v1.2.2-0-nncase_v2.9.0
ide版本:4.0.9

错误日志
IndexError: index is out of bounds

尝试解决过程
好像是cls_idx这个索引不大对,这个变量的值已经到几千了,我有六个分类组感觉应该在0-5才是合理的,报错的地方已在下面指出

补充材料
代码:

import gc
import os

import image
import nncase_runtime as nn
import ujson
import ulab.numpy as np
import utime
from libs.PipeLine import ScopedTiming

root_path = "/sdcard/mp_deployment_source/"  # root_path要以/结尾
config_path = root_path + "deploy_config.json"
image_path = root_path + "test.jpg"
deploy_conf = {}
debug_mode = 1


def read_img(img_path):
    img_data = image.Image(img_path)
    img_data_rgb888 = img_data.to_rgb888()
    img_hwc = img_data_rgb888.to_numpy_ref()
    shape = img_hwc.shape
    img_tmp = img_hwc.reshape((shape[0] * shape[1], shape[2]))
    img_tmp_trans = img_tmp.transpose()
    img_res = img_tmp_trans.copy()
    img_return = img_res.reshape((shape[2], shape[0], shape[1]))
    return img_return



def read_deploy_config(config_path):# 读取deploy_config.json文件
    with open(config_path, "r") as json_file:
        try:
            config = ujson.load(json_file)
        except ValueError as e:
            print("JSON 解析错误:", e)
    return config


def softmax(x):
    exp_x = np.exp(x - np.max(x))
    return exp_x / np.sum(exp_x)


def sigmoid(x):
    return 1 / (1 + np.exp(-x))


def classification():
    print("--------------start-----------------")
    # 使用json读取内容初始化部署变量
    deploy_conf = read_deploy_config(config_path)
    kmodel_name = deploy_conf["kmodel_path"]
    labels = deploy_conf["categories"]
    confidence_threshold = deploy_conf["confidence_threshold"]
    model_input_size = deploy_conf["img_size"]
    num_classes = deploy_conf["num_classes"]
    cls_idx = -1

    # ai2d输入输出初始化
    ai2d_input = read_img(image_path)
    ai2d_input_tensor = nn.from_numpy(ai2d_input)
    ai2d_input_shape = ai2d_input.shape
    data = np.ones((1, 3, model_input_size[1], model_input_size[0]), dtype=np.uint8)
    ai2d_output_tensor = nn.from_numpy(data)

    # 初始化kpu并加载模型
    kpu = nn.kpu()
    kpu.load_kmodel(root_path + kmodel_name)
    # 初始化ai2d
    ai2d = nn.ai2d()
    ai2d.set_dtype(nn.ai2d_format.NCHW_FMT, nn.ai2d_format.NCHW_FMT, np.uint8, np.uint8)
    ai2d.set_resize_param(True, nn.interp_method.tf_bilinear, nn.interp_mode.half_pixel)
    ai2d_builder = ai2d.build(
        [1, 3, ai2d_input_shape[1], ai2d_input_shape[2]], [1, 3, model_input_size[1], model_input_size[0]]
    )
    with ScopedTiming("total", debug_mode > 0):
        # 使用ai2d对输入进行预处理
        ai2d_builder.run(ai2d_input_tensor, ai2d_output_tensor)
        # 设置模型的输入tensor
        kpu.set_input_tensor(0, ai2d_output_tensor)
        # 模型推理
        kpu.run()
        # 获取模型输出
        results = []
        for i in range(kpu.outputs_size()):
            data = kpu.get_output_tensor(i)
            result = data.to_numpy()
            del data
            results.append(result)
        # 后处理并绘制结果保存图片
        if num_classes > 2:
            softmax_res = softmax(results[0][0])
            res_idx = np.argmax(softmax_res)
            if softmax_res[res_idx] > confidence_threshold:                #报错的地方
                cls_idx = res_idx
                print("classification result:", labels[res_idx])
                print("score", softmax_res[cls_idx])
                image_draw = image.Image(image_path).to_rgb565()
                image_draw.draw_string_advanced(
                    5,
                    5,
                    20,
                    "result:" + labels[cls_idx] + " score:" + str(round(softmax_res[cls_idx], 3)),
                    color=(0, 255, 0),
                )
                image_draw.compress_for_ide()
                image_draw.save(root_path + "cls_result.jpg")
            else:
                cls_idx = -1
        else:
            sigmoid_res = sigmoid(results[0][0][0])
            if sigmoid_res > confidence_threshold:
                cls_idx = 1
                print("classification result:", labels[cls_idx])
                print("score", sigmoid_res)
                image_draw = image.Image(image_path).to_rgb565()
                image_draw.draw_string_advanced(
                    5, 5, 20, "result:" + labels[cls_idx] + " score:" + str(round(sigmoid_res, 3)), color=(0, 255, 0)
                )
                image_draw.compress_for_ide()
                image_draw.save(root_path + "cls_result.jpg")
            else:
                cls_idx = 0
                print("classification result:", labels[cls_idx])
                print("score", 1 - sigmoid_res)
                image_draw = image.Image(image_path).to_rgb565()
                image_draw.draw_string_advanced(
                    5,
                    5,
                    20,
                    "result:" + labels[cls_idx] + " score:" + str(round(1 - sigmoid_res, 3)),
                    color=(0, 255, 0),
                )
                image_draw.compress_for_ide()
                image_draw.save(root_path + "cls_result.jpg")
    del ai2d_input_tensor
    del ai2d_output_tensor
    print("---------------end------------------")
    gc.collect()
    nn.shrink_memory_pool()


if __name__ == "__main__":
    classification()
2 Answers

打印num_classes和result.shape,看看输出维度是否能和类别数对上

好的,好像是模型有点问题,重新训练了一个模型,已经没问题了