极市平台比赛使用经验交流&问题请教

相信所有人都清楚,做这个比赛的第一步就是跑通流程。本人菜鸡以一枚,挣扎许久,在考虑要不要放弃。但是实话说,白白浪费了几周的时间总是有一些不甘心,所以写下这篇经验博客。如果有幸大家在我的基础上帮我解决了问题,是共赢。万一问题解决不了,我也认了,能给大家一点点帮助,也算我这几周没有白费。。(哭辽真的。。。)因为我目前做的是手绘图像识别,所以就以这个为例讲一下本人一点经验。

step1:训练

注意我们这篇博客的目的是先跑通平台,所以一切步骤从简,模型就用resnet18即可。

1.确保训练代码没有问题。在本地先跑通一个模型,跑一个epoch 并保存模型参数。注意:确定模型weight保存在/project/train/models。

2.训练模型。提交训练任务,进行训练,1个epoch很快可以训练完。这时候我们可以在训练任务栏看到保存的模型。

step2:测试

为了顺利运行测试任务,我们首先得保证测试代码在本地是畅通的。

1.模型转换,本人直接交出自己的convert_model.sh。

source /opt/snpe/snpe_venv/bin/activate
# step 0:prepare 
pip install onnx
pip install protobuf --upgrade
pip install opencv-python

# step 1:to_onnx 
python3.6 /usr/local/ev_sdk/src/to_onnx.py

# step 2:generate file_list.txt
mkdir /usr/local/ev_sdk/pic
mkdir /usr/local/ev_sdk/raw
wget -O /usr/local/ev_sdk/pic/0.jpg https://www.baidu.com/img/bd_logo1.png
python /usr/local/ev_sdk/src/create_raws.py -i /usr/local/ev_sdk/pic -d /usr/local/ev_sdk/raw -s 224
python /usr/local/ev_sdk/src/create_list.py -i /usr/local/ev_sdk/raw -e *.raw

# step 3:generate dlc
snpe-onnx-to-dlc --input_network /usr/local/ev_sdk/model/model.onnx --output_path /usr/local/ev_sdk/model/model.dlc -d input 1,3,224,224 && echo "snpe-onx-to-dlc done"
snpe-dlc-quantize --input_dlc /usr/local/ev_sdk/model/model.dlc --output_dlc /usr/local/ev_sdk/model/model_quantized.dlc --input_list /usr/local/ev_sdk/model/file_list.txt --input_dlc --enable_htp && echo 'snpe-dlc-quantize done'
rm /usr/local/ev_sdk/model/model.dlc

step 0: 安装一下包

step 1:我的代码是用pytorch写的,要先转为onnx才可以转为dlc。所以写了一个转onnx的python代码。(仅供参考)

在本地测试的时候,我是把本地训练产生的模型直接copy到ev_sdk/model文件夹下了。

import torch
import torch.onnx
from models import ResNet
# device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = ResNet(model_name="resnet18")
pthfile = r'/usr/local/ev_sdk/model/version_1_fold_0_best.pth'
model.load_state_dict(torch.load(pthfile,map_location=torch.device('cpu'))['state_dict'])
dummy_input1 = torch.randn(1,3,224,224)
input_names = [ "input"]
output_names = [ "output1" ]
torch.onnx.export(model, dummy_input1,"/usr/local/ev_sdk/model/model.onnx", verbose=True,input_names=input_names,output_names=output_names)

step 2:生成file_list。大家可以在step 3 中看到,有一个参数是--input_list ,我们这一步就是为其生成一个文件。

大家可以看到我先建了一个文件夹,一个是pic,一个是raw。

然后下载了一张图片到pic文件夹中。为什么下载而不用/home/data/里面的图片呢?是因为平台在执行测试任务的时候没有/home/data 这个文件夹,用不了啊。我随便下了一张进行测试(是度娘的logo)。

接下来执行create_raws.py(这个是从/opt/snpe/models/Inception v3/scripts/ 里copy过来的),它的目的是将参数(-i)这个文件夹里面的内容转换为 (.raw)文件并输出到参数(-d)文件夹,参数-s是指你要将图片resize的大小,要跟你模型的输入大小匹配。 大家可以根据需要对代码进行修改,保证raw文件的维度正确。

最后一步就是运行create_list.py(跟create_raws.py同一个位置copy过来的)将raw文件夹里面内容生成一个file_list文件,这个文件的内容是.raw文件的绝对路径。参数-i 就是说raw文件保存的位置,参数-e是指具体的文件类型,这个参数的默认值是.jpg。

step 3:生成dlc 

有一个要注意的点是这个-d参数它的输出是 两个值,一个是输入节点名称,一个是大小。输入节点名称要跟onnx的一样,然后确保输入的大小正确(pytorch是NCHW)。

2.编写ji.py

这就是我出问题的部分了,朋友们~

step 1:我的第一个版本是这样的:

from __future__ import print_function
import logging as log
import json
import torch
import cv2
import numpy as np
from model import *
log.basicConfig(level = log.DEBUG)
f = open("./class.txt")
label_id_map = {}
for line in f.readlines():
    line = line.strip().split(",")
    label_id_map[int(line[0])] = line[1]
logging.info(label_id_map)
    
def init():
    save_model = "/usr/local/ev_sdk/model/laji_1.pth"
    if not os.path.isfile(save_model):
        log.error(f"{model_pb_path} does not exist")
        
    model = ResNet(model_name="resnet18",pretrained = False)
    log.info('Initializing model...')
    model.load_state_dict(torch.load(save_model)['state_dict'])
    model = model.cuda()
    return model

def process_image(net,input_image,args=None):
    img = cv2.resize(input_image,(256,256)).astype(np.float32)
    img = img.transpose(2,0,1)
    img = cv2.normalize(img,None)
    img = torch.tensor([img]).cuda()
    output = net(img)
    data = {'class':label_id_map[int(output[0])]}
    return json.dumps(data, indent=4)

在平台测试的时候只用了两个积分,用的gpu,所以性能分低。我当时在想为啥我dlc转换成功了,为啥不用呢????

后来我后知后觉觉得好像是我自己生成了但自己没写代码用它。

于是我开始想怎么把它用起来,出了第二个版本。

step 2: 尝试用dlc

def init():
    os.system("bash /usr/local/ev_sdk/src/convert_model.sh")
    path = "/usr/local/ev_sdk/src"
    if not os.path.exists(os.path.join(path,"pic")):
        os.makedirs(os.path.join(path,"pic"))
    if not os.path.exists(os.path.join(path,"raw")):
        os.makedirs(os.path.join(path,"raw"))
    if not os.path.exists(os.path.join(path,"output")):
        os.makedirs(os.path.join(path,"output"))
    save_model = "/usr/local/ev_sdk/model/model_quantized.dlc"
    return save_model

def process_image(save_model,input_image,args=None):

    cv2.imwrite("/usr/local/ev_sdk/src/pic/0.jpg",input_image)
    convert_img("/usr/local/ev_sdk/src/pic/","/usr/local/ev_sdk/src/raw/",224,RESIZE_METHOD_BILINEAR)

    cmd = ['snpe-net-run',
               '--input_list', "/usr/local/ev_sdk/src/input_list.txt",
               '--container',"/usr/local/ev_sdk/model/model_quantized.dlc",
                '--output_dir',"/usr/local/ev_sdk/src/output"]
    # '--output_dir',"/usr/local/ev_sdk/src/output","--use_dsp","--platform_options", "unsignedPD:ON"]
    subprocess.call(cmd)
    # assert os.path.exists("/usr/local/ev_sdk/src/output/Result_0/output1.raw")
    float_array = np.fromfile("/usr/local/ev_sdk/src/output/Result_0/output1.raw", dtype=np.float32)  ## 读取这个文件内容
    max_prob = max(float_array)
    max_prob_index = np.where(float_array == max_prob)[0][0]
    data = {'class':label_id_map[max_prob_index]}
    return json.dumps(data, indent=4)

if __name__ == '__main__':
    """Test python api
    """
    # img = cv2.imread('/usr/local/ev_sdk/data/dog.jpg')
    img = np.random.randn(224,224,3)
    predictor = init()
    result = process_image(predictor, img)
    logging.info(result) 

重点是执行了snpe-net-run,它的输入是一个list文件,里面是raw文件的路径,container是模型位置,output_dir是输出文件的位置。最后从输出文件里读取结果。

这个版本测试一次消耗了100个积分,并且成绩跟上一个版本完全一样,用的gpu。

然后我尝试给它加参数 --use_dsp,但是测试结果如下:就是说平台不支持dsp。这就是我的问题所在!!!!

The selected runtime is not available on this platform. Continue anyway to observe the failure at network creation time.
error_code=500; error_message=Target runtime is not available. error_code=500; error_message=Target runtime is not available. 
No viable runtimes available.; error_component=Host Runtime; line_no=423; thread_id=140447590590208; error_component=Host Runtime; line_no=263; thread_id=140448895645632

编者按:在写这个博客前,我也很犹豫。最终我还是决定写下来,因为大家跟我双赢是我赚了,没有人帮我的话我也不损失啥,毕竟菜鸡走投无路已经打算放弃了。 当然,我还是希望结果是好的菜鸡哭泣。。。。期待跟大家交流(救我!)

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

!!!!!新更新内容:ji.py不需要调用.dlc,生成的dlc是系统自动调用的。

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值