• 如何高效扩展bool值Tensor的shape?
    问题:有一个Tensor(称为t0),shape为(1, 1),值为bool型(True或者False),现在想通过一个或多个算子把t0变成一个shape为(i, j, k)的Tensor,Tensor的值和t0的值完全相同(目的是把扩展shape后的Tensor传给select算子使用)。一种方案是利用BroadcastTo算子进行变换。另外想创建一个bool类型的Tensor和t0相乘,但是会报“两数相乘,至少有一个需要是int”。或者创建一个值全为1的Tensor和t0相乘,但是相乘的结果不是bool类型,传给select算子会报错(cast算子不能把tensor转成bool类型)。还有其它的方案吗?要求转换速度尽可能快,并且这个算子能转成OM格式。
  • [执行问题] modelarts上tacotron2遇到无法执行run_standalone_train.sh脚本的问题
    无论将生成好的hdf5数据文件放在哪个目录下,都会出现如上报错
  • [技术干货] 2022年12月份昇腾问题求助合计
    1:华为云上的ECS,AI加速型昇腾的为什么不给个好点的镜像?cid:link_0在modelaets上训练官方模型yolov5时,自定义数据集的路径找不到(确认过OBS路径没有错),怀疑是相对路径配置得不对cid:link_1在昇腾200加速模块上,sudo提权命令使用不了 cid:link_2Atlas 300推理卡(3010)调用acl_resource.init()报错507033 cid:link_3altas500华为库读取的图片转成opencv是多少字节cid:link_4altlas500如何读取h265的摄像头流cid:link_5“输入以下命令安装MindSpore 1.5.0版本”报错 cid:link_6使用MindSpore Profiler的官方例子时出现错误:mindspore.profiler.common.exceptions.exceptions.ProfilerFileNotFoundException:cid:link_7Mindspore 未适配模型cid:link_8batch_norm1dcid:link_911. 关于在mindspore中实现一些RL算法时遇到的问题 cid:link_10mindspore.dataset.vision的HWC2CHW算子问题 cid:link_11Yolov3-darknet53 在非GPU下的amp level cid:link_12atlas 200dk 上mindspore_server官方案例进行推理失败cid:link_13
  • [热门活动] MindSpore论坛报错活动第五期
    活动详情请移步到: MindSpore论坛报错活动第五期期待您的参与!!!
  • [推理] atlas 200dk 上mindspore_server官方案例进行推理失败
    新手上路,在atlas 200dk上安装了合设环境,然后安装了mindspore1.6, 验证案例已经成功跑通然后,我想要把PC机上的mindspore模型移植到atlas 200dk上推理通过查阅文档,发现可以使用mindspore_server进行(不确定可不可行,因为现在报错了)然后我开始跑官网的案例https://www.mindspore.cn/serving/docs/zh-CN/r1.6/serving_example.html然后报错了这个是为什么呢我的tensor_add.mindir是PC机(x86_64)mindspore1.6.2版本导出来的, atlas上为了和mindspore_server保持版本一致用了1.6.0,不知道有没有关系把mindir也附上
  • [知识分享] 网络fp32改fp16
    框架:MindSpore1.6硬件:Ascend我们在使用Ascend进行网络的训练时,可能由于种种原因导致使用一张卡不能进行正常的训练,而在这是我们手里只有一张Ascend卡时,下面这种方法或许可以帮到你。将网络结构由fp32改为fp16, 更改方法如下:只需要将网络中的每个算子按如上方式更改便可以实现由fp32到fp16的更改,这样做以后不仅可以使模型正常训练,也可以加快训练的速度,加快我们的速度。
  • [知识分享] 单卡正常运行,多卡加大batch后报错
    框架:MindSpore1.6硬件:Ascend单卡可以正常训练。8卡并行batch为1可以运行,batch加大为2后报如下错误经研究,发现是HCCL_CONNECT_TIMEOUT这个环境变量的问题,该环境变量的默认值是150,这样会导致8卡之间的同步时间过短,我们可以通过将该环境变量的值设大一点来解决这个问题,如下所示:
  • [经验分享] MindStudio模型推理场景精度比对全流程和结果分析
    视频案例,可以查看Bilibili MindStudio模型推理场景精度比对全流程和结果分析:【经验分享】MindStudio模型推理场景精度比对全流程和结果分析1、MindStudio介绍MindStudio提供在AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务,依靠模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio能够帮助您在一个工具上就能高效便捷地完成AI应用开发,MindStudio采用了插件化扩展机制,开发者可以通过开发插件来扩展已有功能。本实验使用的MindStudio版本为5.0.RC3,安装请参考MindStudio安装教程。2、交付件介绍(1)精度对比简介​ 在下面两种情况下,自有实现的算子在昇腾AI处理器上的运算结果与业界标准算子(如Caffe、ONNX、TensorFlow、PyTorch)的运算结果可能存在差异。在模型转换过程中对模型进行了优化,包括算子消除、算子融合、算子拆分,这些动作可能会造成自有实现的算子运算结果与业界标准算子(如Caffe、TensorFlow、ONNX)运算结果存在偏差。用户原始网络可以迁移到昇腾910 AI处理器上执行训练,网络迁移可能会造成自有实现的算子运算结果与用业界标准算子(如TensorFlow)运算结果存在偏差。(2)实现流程​ 为了帮助开发人员快速解决算子精度问题,需要提供自有实现的算子运算结果与业界标准算子运算结果之间进行精度差异对比的工具。​ MindStudio精度比对工具提供Tensor比对能力,包含余弦相似度、欧氏相对距离、绝对误差(最大绝对误差、平均绝对误差、均方根误差)、相对误差(最大相对误差、平均相对误差、累积相对误差)、KL散度、标准差算法比对维度。精度比对总体流程如下:(3)代码工程本实验基于MindStudio的代码工程结构如下所示。本实验基于MindStudio的代码工程结构如下所示。 ├── caffeResnet50_49048f18 │ ├── acl_net.py //离线模型推理脚本代码 │ ├── caffe_dump.py //原始模型推理脚本代码 │ ├── caffe_model //原始模型文件存储目录 │ │ ├── resnet50.caffemodel │ │ └── resnet50.prototxt │ ├── caffeResnet50.iml │ ├── constant.py //离线模型推理脚本工具脚本 │ ├── data //数据文件夹 │ │ └── img.png │ ├── dump //离线模型dump数据文件夹 │ ├── model //离线模型文件夹 │ │ └── resnet50.om │ ├── npy_dump //原始模型dump数据文件夹 │ ├── output //精度比对输出文件夹 │ │ └── 20221111205145 │ └── src │ └── acl.json //离线模型dump构造文件 (4)文章介绍​ 文章详细记录了如何使用MindStudio中的精度比对功能去进行推理场景下的模型的精度比对操作,包括原始第三方框架下模型的npy数据准备,离线模型的dump数据准备,精度比对以及分析。第三节介绍了MindStudio的昇腾App工程的创建。第四节介绍了推理场景下的数据准备。第五节介绍了精度比对和分析。第六节介绍了整个流程中遇到的问题和解决方案。第七节介绍MindStudio的更多的内容。3、App工程创建打开MindStudio进入算子工程创建界面首次登录MindStudio:在MindStudio欢迎界面中单击“New Project”,进入创建工程界面。非首次登录MindStudio:在顶部菜单栏中选择“File > New > Project...”,进入创建工程界面。创建App工程左侧导航栏选择“Ascend App”,如图所示,在右侧点击选择ACL Project(Python)工程。单击“Next”,在弹出的页面中,Project name那一行输入项目名称,然后点击Finish,既可完成工程的创建。单击“Finish”,完成应用工程的创建若工作窗口已打开其他工程,会出现如图所示提示。选择“This Window”,则直接在当前工作窗口打开新创建的工程。选择“New Window”,则新建一个工作窗口打开新创建的工程。 4、推理场景数据准备(1)准备Caffe模型npy数据文件MindStudio当前版本不提供Caffe模型numpy数据生成功能,请自行安装Caffe环境并提前准备Caffe原始数据“*.npy”文件。本文仅提供生成符合精度比对要求的numpy格式Caffe原始数据“*.npy”文件的样例参考。下面给出Resnet50原始模型dump数据的推理脚本代码。请参考表1的参数说明进行使用。​ 表1 原始模型推理脚本参数说明-wCaffe 权重文件路径,如'resnet50.caffemodel'-i, --input_bins模型推理输入bin文件或者图片文件路径,多个以;分隔,如'./a.bin;./img.png'-n, --input_names模型推理输入节点名称,多个以;分隔,如'graph_input_0:0; graph_input_1:0'-mCaffe 模型文件路径,如'resnet50.prototxt'-odump输出文件路径,如'./output_dir', 该路径需要用户自己创建脚本代码:# coding=utf-8 import caffe import sys import argparse import os import caffe.proto.caffe_pb2 as caffe_pb2 import google.protobuf.text_format import json import numpy as np import time TIME_LENGTH = 1000 FILE_PERMISSION_FLAG = 0o600 class CaffeProcess: def __init__(self): parse = argparse.ArgumentParser() parse.add_argument("-w", dest="weight_file_path", help="<Required> the caffe weight file path", required=False,default="caffe_model/resnet50.caffemodel") parse.add_argument("-m", dest="model_file_path", help="<Required> the caffe model file path", required=False,default="caffe_model/resnet50.prototxt") parse.add_argument("-o", dest="output_path", help="<Required> the output path", required=False,default="npy_dump") parse.add_argument("-i", "--input_bins", dest="input_bins", help="input_bins bins. e.g. './a.bin;./c.bin'", required=False,default="./data/img.png") parse.add_argument("-n", "--input_names", dest="input_names", help="input nodes name. e.g. 'graph_input_0:0;graph_input_0:1'", required=False,default="data:0") args, _ = parse.parse_known_args(sys.argv[1:]) self.weight_file_path = os.path.realpath(args.weight_file_path) self.model_file_path = os.path.realpath(args.model_file_path) self.input_bins = args.input_bins.split(";") self.input_names = args.input_names.split(";") self.output_path = os.path.realpath(args.output_path) self.net_param = None self.cur_layer_idx = -1 @staticmethod def _check_file_valid(path, is_file): if not os.path.exists(path): print('Error: The path "' + path + '" does not exist.') exit(-1) if is_file: if not os.path.isfile(path): print('Error: The path "' + path + '" is not a file.') exit(-1) else: if not os.path.isdir(path): print('Error: The path "' + path + '" is not a directory.') exit(-1) def _check_arguments_valid(self): self._check_file_valid(self.model_file_path, True) self._check_file_valid(self.weight_file_path, True) self._check_file_valid(self.output_path, False) for input_file in self.input_bins: self._check_file_valid(input_file, True) @staticmethod def calDataSize(shape): dataSize = 1 for dim in shape: dataSize *= dim return dataSize def _load_inputs(self, net): inputs_map = {} for layer_name, blob in net.blobs.items(): if layer_name in self.input_names: input_bin = np.fromfile( self.input_bins[self.input_names.index(layer_name)], np.float32) input_bin_shape = blob.data.shape if self.calDataSize(input_bin_shape) == self.calDataSize(input_bin.shape): input_bin = input_bin.reshape(input_bin_shape) else: print("Error: input node data size %d not match with input bin data size %d.", self.calDataSize( input_bin_shape), self.calDataSize(input_bin.shape)) exit(-1) inputs_map[layer_name] = input_bin return inputs_map def process(self): """ Function Description: process the caffe net, save result as dump data """ # check path valid self._check_arguments_valid() # load model and weight file net = caffe.Net(self.model_file_path, self.weight_file_path, caffe.TEST) inputs_map = self._load_inputs(net) for key, value in inputs_map.items(): net.blobs[key].data[...] = value # process net.forward() # read prototxt file net_param = caffe_pb2.NetParameter() with open(self.model_file_path, 'rb') as model_file: google.protobuf.text_format.Parse(model_file.read(), net_param) for layer in net_param.layer: name = layer.name.replace("/", "_").replace(".", "_") index = 0 for top in layer.top: data = net.blobs[top].data[...] file_name = name + "." + str(index) + "." + str( round(time.time() * 1000000)) + ".npy" output_dump_path = os.path.join(self.output_path, file_name) np.save(output_dump_path, data) os.chmod(output_dump_path, FILE_PERMISSION_FLAG) print('The dump data of "' + layer.name + '" has been saved to "' + output_dump_path + '".') index += 1 if __name__ == "__main__": caffe_process = CaffeProcess() caffe_process.process()说明:运行之前需要提前准备数据文件和模型文件,原始模型下载地址为:cid:link_3​ 数据图片下载地址为:https://gitee.com/link?target=https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/models/aclsample/dog1_1024_683.jpg远程安装好caffe的python3环境,在本地配置好安装的caffe的SDK。将上述代码拷贝到新建的python脚本中,右键点击运行该脚本,即可以在参数-o指定的路径下生成npy数据文件。生成的文件是以{op_name}.{output_index}.{timestamp}.npy形式命名。其中{op_name}为算子名称,{output_index}是算子的编号索引,{timestamp}是时间戳;设置numpy数据文件名包括output_index字段且值为0,确保转换生成的dump数据的output_index为0,否则无比对结果,原因是精度比对时默认从第一个output_index为0的数据开始。(2)准备离线模型dump数据通过MindStudio提供的dump功能,生成离线模型的dump数据,需要提前完成以下操作:完成Caffe、TensorFlow或ONNX模型的ATC模型转换,将原始模型转换为OM离线模型。详细介绍请参见模型转换。完成应用工程的开发、编译和运行,确保具备可执行的应用工程。详细介绍请参见应用开发。操作步骤如下:准备好离线模型,离线模型下载地址为:cid:link_3; 或者参考如下模型转换步骤进行模型转换(1) 在菜单栏选择“Ascend > Model Converter”。出现如下配置界面,参数配置参考MindStudio官网>用户指南>模型转换>操作步骤。(2) 单击“Next”,进入“Data Pre-Processing”配置数据预处理页签,界面参考如图所示。说明:数据预处理是昇腾AI处理器提供的硬件图像预处理模块,包括色域转换,图像归一化(减均值/乘系数)和抠图(指定抠图起始点,抠出神经网络需要大小的图片)等功能。只有当“Model Information”页签,“Input Nodes”参数中,输入节点的“Type”有配置为“Uint8”类型,“Data Pre-Processing”页签才可以配置该节点的数据预处理功能。如果模型有多个输入,每个输入节点都可以获取shape信息中的宽和高,并且“Input Nodes”参数中每个输入节点的“Type”都配置为“Uint8”,则“Data Pre-Processing”页签可以配置多个节点的数据预处理功能。(3) 单击“Next”,进入“Advanced Options Preview”高级选项配置页签,界面参考如图所示。(4) 单击Finish完成模型转换。在MindStudio界面下方,“Output”窗口会显示模型转换过程中的日志信息,如果提示“Model converted successfully”,则表示模型转换成功。准备好离线模型的推理代码。推理代码可以从cid:link_0中获取,或者直接拷贝下面代码。构造dump的.json配置,选择“Ascend > Dump Configuration”菜单,弹出“Select Offline Model”窗口,如图所示。注意:如果不知道自己本地同步到远程哪个路径下,可以点击Tools>Development>Configuration下查看。选择.om模型文件,单击“OK”,展示模型文件结构,设置dump开关。如图所示。它会在src目录下生成acl.json配置文件,通过修改窗口最右侧配置项,设置.om模型文件的dump配置项,会自动更新到acl.json文件中。(1) Dump Option:配置dump范围。ALL:所有算子开启dump。Several:自定义部分算子开启dump。选择该项后,需要右键单击待dump数据的算子并选择“Enable Dump”。None:所有算子不开启dump。(2) Dump Mode:dump数据模式。ALL:同时dump算子的输入、输出数据。Input:dump算子的输入数据。Output:dump算子的输出数据。(3) Dump Path:配置保存dump数据文件的路径,默认为:{project_path}/dump。如果Dump Path设置为其他路径,需要确保MindStudio安装用户对该路径具有读写权限。注意:该选项要选择远程的dump目录,当前版本mindstudio只支持选择本地的dump目录,如果不能选择远程dump目录,请自行在acl.json中配置。(4) AclConfig File:Acl配置文件,在dump操作中该文件保存算子的dump配置信息。一般路径为{project_path}/src/acl.json。请参考表2中的参数说明使用该脚本​ 表2 离线模型推理脚本参数说明--devicenpu设备编号。--model_path离线模型文件路径,到文件名层次。--images_path数据文件路径,到数据文件的文件夹层次。import argparse import numpy as np import acl import os from PIL import Image from constant import ACL_MEM_MALLOC_HUGE_FIRST, \ ACL_MEMCPY_HOST_TO_DEVICE, ACL_MEMCPY_DEVICE_TO_HOST, \ ACL_SUCCESS, IMG_EXT, NPY_FLOAT32 buffer_method = { "in": acl.mdl.get_input_size_by_index, "out": acl.mdl.get_output_size_by_index } def check_ret(message, ret): if ret != ACL_SUCCESS: raise Exception("{} failed ret={}" .format(message, ret)) class Net(object): def __init__(self, device_id, model_path): self.device_id = device_id # int self.model_path = model_path # string self.model_id = None # pointer self.context = None # pointer self.input_data = [] self.output_data = [] self.model_desc = None # pointer when using self.load_input_dataset = None self.load_output_dataset = None self.init_resource() def release_resource(self): print("Releasing resources stage:") ret = acl.mdl.unload(self.model_id) check_ret("acl.mdl.unload", ret) if self.model_desc: acl.mdl.destroy_desc(self.model_desc) self.model_desc = None while self.input_data: item = self.input_data.pop() ret = acl.rt.free(item["buffer"]) check_ret("acl.rt.free", ret) while self.output_data: item = self.output_data.pop() ret = acl.rt.free(item["buffer"]) check_ret("acl.rt.free", ret) if self.context: ret = acl.rt.destroy_context(self.context) check_ret("acl.rt.destroy_context", ret) self.context = None ret = acl.rt.reset_device(self.device_id) check_ret("acl.rt.reset_device", ret) ret = acl.finalize() check_ret("acl.finalize", ret) print('Resources released successfully.') def init_resource(self): print("init resource stage:") current_dir=os.path.dirname(os.path.abspath(__file__)) ret = acl.init(os.path.join(current_dir,"./src/acl.json")) check_ret("acl.init", ret) # ret = acl.mdl.init_dump() # check_ret("acl.init", ret) # ret = acl.mdl.set_dump(os.path.join(current_dir,"./src/acl.json")) # check_ret("acl.init", ret) ret = acl.rt.set_device(self.device_id) check_ret("acl.rt.set_device", ret) self.context, ret = acl.rt.create_context(self.device_id) check_ret("acl.rt.create_context", ret) # load_model self.model_id, ret = acl.mdl.load_from_file(self.model_path) check_ret("acl.mdl.load_from_file", ret) print("model_id:{}".format(self.model_id)) self.model_desc = acl.mdl.create_desc() self._get_model_info() print("init resource success") def _get_model_info(self,): ret = acl.mdl.get_desc(self.model_desc, self.model_id) check_ret("acl.mdl.get_desc", ret) input_size = acl.mdl.get_num_inputs(self.model_desc) output_size = acl.mdl.get_num_outputs(self.model_desc) self._gen_data_buffer(input_size, des="in") self._gen_data_buffer(output_size, des="out") def _gen_data_buffer(self, size, des): func = buffer_method[des] for i in range(size): # check temp_buffer dtype temp_buffer_size = func(self.model_desc, i) temp_buffer, ret = acl.rt.malloc(temp_buffer_size, ACL_MEM_MALLOC_HUGE_FIRST) check_ret("acl.rt.malloc", ret) if des == "in": self.input_data.append({"buffer": temp_buffer, "size": temp_buffer_size}) elif des == "out": self.output_data.append({"buffer": temp_buffer, "size": temp_buffer_size}) def _data_interaction(self, dataset, policy=ACL_MEMCPY_HOST_TO_DEVICE): temp_data_buffer = self.input_data \ if policy == ACL_MEMCPY_HOST_TO_DEVICE \ else self.output_data if len(dataset) == 0 and policy == ACL_MEMCPY_DEVICE_TO_HOST: for item in self.output_data: temp, ret = acl.rt.malloc_host(item["size"]) if ret != 0: raise Exception("can't malloc_host ret={}".format(ret)) dataset.append({"size": item["size"], "buffer": temp}) for i, item in enumerate(temp_data_buffer): if policy == ACL_MEMCPY_HOST_TO_DEVICE: if "bytes_to_ptr" in dir(acl.util): bytes_data = dataset[i].tobytes() ptr = acl.util.bytes_to_ptr(bytes_data) else: ptr = acl.util.numpy_to_ptr(dataset[i]) ret = acl.rt.memcpy(item["buffer"], item["size"], ptr, item["size"], policy) check_ret("acl.rt.memcpy", ret) else: ptr = dataset[i]["buffer"] ret = acl.rt.memcpy(ptr, item["size"], item["buffer"], item["size"], policy) check_ret("acl.rt.memcpy", ret) def _gen_dataset(self, type_str="input"): dataset = acl.mdl.create_dataset() temp_dataset = None if type_str == "in": self.load_input_dataset = dataset temp_dataset = self.input_data else: self.load_output_dataset = dataset temp_dataset = self.output_data for item in temp_dataset: data = acl.create_data_buffer(item["buffer"], item["size"]) _, ret = acl.mdl.add_dataset_buffer(dataset, data) if ret != ACL_SUCCESS: ret = acl.destroy_data_buffer(data) check_ret("acl.destroy_data_buffer", ret) def _data_from_host_to_device(self, images): print("data interaction from host to device") # copy images to device self._data_interaction(images, ACL_MEMCPY_HOST_TO_DEVICE) # load input data into model self._gen_dataset("in") # load output data into model self._gen_dataset("out") print("data interaction from host to device success") def _data_from_device_to_host(self): print("data interaction from device to host") res = [] # copy device to host self._data_interaction(res, ACL_MEMCPY_DEVICE_TO_HOST) print("data interaction from device to host success") result = self.get_result(res) self._print_result(result) # free host memory for item in res: ptr = item['buffer'] ret = acl.rt.free_host(ptr) check_ret('acl.rt.free_host', ret) def run(self, images): self._data_from_host_to_device(images) self.forward() self._data_from_device_to_host() def forward(self): print('execute stage:') ret = acl.mdl.execute(self.model_id, self.load_input_dataset, self.load_output_dataset) check_ret("acl.mdl.execute", ret) self._destroy_databuffer() print('execute stage success') def _print_result(self, result): vals = np.array(result).flatten() top_k = vals.argsort()[-1:-6:-1] print("======== top5 inference results: =============") for j in top_k: print("[%d]: %f" % (j, vals[j])) def _destroy_databuffer(self): for dataset in [self.load_input_dataset, self.load_output_dataset]: if not dataset: continue number = acl.mdl.get_dataset_num_buffers(dataset) for i in range(number): data_buf = acl.mdl.get_dataset_buffer(dataset, i) if data_buf: ret = acl.destroy_data_buffer(data_buf) check_ret("acl.destroy_data_buffer", ret) ret = acl.mdl.destroy_dataset(dataset) check_ret("acl.mdl.destroy_dataset", ret) def get_result(self, output_data): result = [] dims, ret = acl.mdl.get_cur_output_dims(self.model_desc, 0) check_ret("acl.mdl.get_cur_output_dims", ret) out_dim = dims['dims'] for temp in output_data: ptr = temp["buffer"] # 转化为float32类型的数据 if "ptr_to_bytes" in dir(acl.util): bytes_data = acl.util.ptr_to_bytes(ptr, temp["size"]) data = np.frombuffer(bytes_data, dtype=np.float32).reshape(tuple(out_dim)) else: data = acl.util.ptr_to_numpy(ptr, tuple(out_dim), NPY_FLOAT32) result.append(data) return result def transfer_pic(input_path): input_path = os.path.abspath(input_path) with Image.open(input_path) as image_file: image_file = image_file.resize((256, 256)) img = np.array(image_file) height = img.shape[0] width = img.shape[1] # 对图片进行切分,取中间区域 h_off = (height - 224) // 2 w_off = (width - 224) // 2 crop_img = img[h_off:height - h_off, w_off:width - w_off, :] # rgb to bgr,改变通道顺序 img = crop_img[:, :, ::-1] shape = img.shape img = img.astype("float16") img[:, :, 0] -= 104 img[:, :, 1] -= 117 img[:, :, 2] -= 123 img = img.reshape([1] + list(shape)) img = img.transpose([0, 3, 1, 2]) result = np.frombuffer(img.tobytes(), np.float16) return result if __name__ == '__main__': current_dir = os.path.dirname(os.path.abspath(__file__)) parser = argparse.ArgumentParser() parser.add_argument('--device', type=int, default=0) parser.add_argument('--model_path', type=str, default=os.path.join(current_dir, "./model/resnet50.om")) parser.add_argument('--images_path', type=str, default=os.path.join(current_dir, "./data")) args = parser.parse_args() print("Using device id:{}\nmodel path:{}\nimages path:{}" .format(args.device, args.model_path, args.images_path)) images_list = [os.path.join(args.images_path, img) for img in os.listdir(args.images_path) if os.path.splitext(img)[1] in IMG_EXT] net = Net(args.device, args.model_path) for image in images_list: print("images:{}".format(image)) img = transfer_pic(image) net.run([img]) # acl.mdl.finalize_dump() # net.run([img]) print("*****run finish******") net.release_resource() 说明:(1) 数据文件应该是与原始模型生成npy数据文件保持一致。(2) 如果是从gitee上下载的代码,需要修改acl.init()这行代码,在里面传入dump的配置参数.json文件。6.设置dump完成后,单击MindStudio界面“Run”菜单,重新编译和运行应用工程。工程运行完毕后,可以在{project_path}/dump路径下查看到生成的dump数据文件。生成的路径及格式说明:time/device_id/model_name/model_id/data_index/dump文件time:dump数据回传落盘时间。格式为:YYYYMMDDhhmmss。device_id:Device设备ID号。model_name:模型名称。model_id:模型ID号。data_index:针对每个Task ID执行的次数维护一个序号,从0开始计数,该Task每dump一次数据,序号递增1。dump文件:命名规则如{op_type}.{op_name}.{taskid}.{timestamp}。如果model_name、op_type、op_name出现了“.”、“/”、“\”、空格时,转换为下划线表示。5、精度比对及分析(1)全网精度比对操作步骤在MindStudio界面菜单栏选择“Ascend > Model Accuracy Analyzer > New Task”菜单,进入比对界面,如下图所示。参考表3配置好参数后点击Next下一步。进入到数据和模型的配置界面。 ​ 表3 精度比对New Task参数说明参数说明Run ModeRemote Run:远程运行。Local Run:本地运行。Windows使用场景下仅支持Remote Run,该参数不展示。Deployment运行配置,选择Remote Run模式时可见,必选配置。通过Deployment功能,详细请参见Deployment,可以将指定项目中的文件、文件夹同步到远程指定机器的指定目录。Remote Toolkit Path远端运行环境toolkit软件包安装路径,选择Remote Run模式时可见,必选配置。例如配置为${HOME}/Ascend/ascend-toolkit/xxx/toolkit。与Deployment参数为绑定关系,单击“Start”后参数值将被保存。再次配置时,如连接已配置过的Deployment,则参数自动填充,可手动修改。Environment Variables环境变量配置,选择Remote Run模式时可见,可以直接在框中输入,也可以单击后在弹窗内单击填写。可选配置,当Model File指定文件为离线模型文件(*.om)时,需要配置环境变量,否则工具将无法为离线模型文件(*.om)进行ATC转换导致比对失败。与Deployment参数为绑定关系,单击“Start”后参数值将被保存。再次配置时,如连接已配置过的Deployment,则参数自动填充,可手动修改。Output Path比对数据结果存放路径,必选配置。无论选择Remote Run模式还是Local Run模式,均需要指定为本端路径。默认路径为当前系统的用户目录。Analysis Mode精度比对分析模式,必选配置。可选择模式为:NPU vs NPU:表示两个比对文件均为昇腾AI处理器上运行生成的dump数据文件。此时Model File参数可选。一般用于分析开启和关闭融合规则时进行模型转换后的dump数据文件之间的精度差。模型转换开启和关闭融合规则的详细介绍请参见模型转换。NPU vs GPU/CPU:表示昇腾AI处理器上运行生成的dump数据文件与原始模型的npy文件进行比对。此时展示Framework必选参数。Framework比对数据所属的框架类型,必选配置。Analysis Mode为NPU vs GPU/CPU时可见。可选类型为:- TensorFlow:TensorFlow框架模型dump数据的精度比对,支持推理、训练场景,Model File参数必选。- ONNX:ONNX框架模型dump数据的精度比对,支持推理场景,Model File参数必选。- Caffe:Caffe框架模型dump数据的精度比对,支持推理场景,Model File参数必选。NPU Dump昇腾AI处理器上运行生成的dump数据文件目录,必选配置。在远端执行比对时(Remote Run),须指定远端设备上的dump数据文件目录。Model File模型文件或融合规则文件。Analysis Mode为NPU vs NPU时,进行离线模型转换开启算子融合功能前后的dump数据精度比对,需要指定开融合的算子映射文件(.json)或离线模型文件(*.om)和关融合的算子映射文件(.json)或离线模型文件(*.om)。Analysis Mode为NPU vs GPU/CPU时,根据Framework选择的框架类型选择不同的文件:l TensorFlow:推理场景选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om);训练场景选择计算图文件(*.txt)。l ONNX:选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om)。l Caffe:选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om)。l 具体选择文件请参见比对场景。Quantization Rule File(.json)量化算子映射关系文件(昇腾模型压缩输出的json文件),可选配置。仅Framework为Caffe时展示。Ground Truth原始模型的npy文件目录,必选配置。在远端执行比对时(Remote Run),须指定远端设备上的原始模型的npy文件目录。Algorithm比对算法维度。取值为:l Cosine Similarity:余弦相似度算法,默认勾选。l Relative Euclidean Distance:欧氏相对距离算法,默认勾选。l Absolute Error,绝对误差,默认勾选,此项执行的比对算法为:l Max Absolute Error:最大绝对误差。l Mean Absolute Error:平均绝对误差。l Root Mean Square Error:均方根误差。l Relative Error,相对误差,默认勾选,此项执行的比对算法为:l Max Relative Error:最大相对误差。l Mean Relative Error:平均相对误差。l Accumulated Relative Error:累积相对误差。l Kullback Leibler Divergence:KL散度算法,默认不勾选。l Standard Deviation:标准差算法,默认不勾选。l 与Customized Algorithm自定义算法之间至少勾选一种算法。Advance Options扩展选项。包括Customized Algorithm、Advisor和Operator Range。Customized Algorithm自定义算法文件路径。与Algorithm内置算法之间至少勾选一种算法。需用户自行准备自定义算法.py文件,所在目录格式为“algorithm”,指定该目录下的自定义算法.py文件,生成自定义算法。自定义算法.py文件相关要求参见《精度比对工具使用指南》附录中的“准备自定义算法.py文件”章节。Advisor专家系统分析开关,默认关闭。开启后会在完成整网比对后对比对结果进行专家系统分析并输出问题节点、问题类型和优化建议。详细介绍请参见比对结果专家建议。使用本功能前需要先执行*pip3* *install* ****pandas****命令安装pandas 1.3或更高版本依赖。与Operator Range无法同时开启。Operator Range设定算子比对范围。有两种设置方式:方式一:单击“Select”按钮,在弹出框内勾选需要比对的算子。方式二:根据Start、End、Step参数配置比对算子的范围。l start:第一个比对的算子,取值范围为[1, 参与计算的算子个数],默认值为1。l end:最后一个比对的算子,取值范围为-1或[start, 参与计算的算子个数],默认值为-1(动态获取网络模型中最后一个参与计算的算子)。l step:第start+stepn个比对的算子,step取值范围为[1, 参与计算的算子个数),默认值为1,n为从1开始的正整数。配置格式为:“start,end,step”。比如:-r 1,101,20,表示算子1,21,41,61,81,101的Tensor参与比对。不配置本参数时,比对网络模型中的所有参与计算的算子。配置本参数且Analysis Mode参数配置为NPU vs NPU时,需同时指定NPU Dump和Ground Truth的Model File分别指定开融合的算子映射文件(.json)或离线模型文件(.om)和关融合的算子映射文件(.json)或离线模型文件(*.om)。与Advisor无法同时开启。(2)全网比对结果分析上面步骤配置好参数后点击start即可以出现对比的结果界面。如下所示。图一 图二 图三 所示将Tensor比对结果界面分为四个区域分别进行介绍。其中1~4区域为整网比对结果。表4 整网比对结果说明区域区域名称说明1菜单栏从左到右分别为Open…、New Task、Refresh、Help四项功能。Open…为打开并展示比对结果csv文件;New Task为创建新的比对任务;Refresh用于读取并刷新File Manager中管理的文件;单击Help弹出小窗,可展示精度比对工具的使用限制(Restrictions)、使用建议、在线教程链接等。2File Manager,历史数据管理显示用户指定文件夹以及文件夹下生成的整网比对的csv文件以及显示通过Open…单独打开的csv文件;对文件夹和csv,提供历史数据管理功能,包括打开、删除、另存为;在文件夹处右键删除;在空白处右键创建新比对任务(New Task)、刷新(Refresh)和Open…(打开并展示比对结果csv文件)。3Model Accuracy Analysis,精度比对分析界面默认仅显示有结果的算子。可单击列名,进行排序;单击Show Invalid Data,可展示无法比对的数据,各列字段含义请参见表2。4Scatter Diagram,各项算法指标的散点分布图Show Model,比对模型可视化展示Scatter Diagram:横坐标表示算子的执行顺序,纵坐标为算法指标在对应Tensor上的实际取值。各字段含义请参见表3。Show Model:分别展示NPU和Ground Truth的模型图。详细介绍请参见表4。表5 比对结果字段说明字段说明Index网络模型中算子的ID。OpSequence算子运行的序列。全网层信息文件中算子的ID。仅配置“Operator Range”时展示。OpType算子类型。NPUDump表示NPU Dump模型的算子名。光标悬浮时,可显示具体算子所在的文件路径。DataType表示NPU Dump侧数据算子的数据类型。Addressdump tensor的虚拟内存地址。用于判断算子的内存问题。仅基于昇腾AI处理器运行生成的dump数据文件在整网比对时可提取该数据。GroundTruth表示Ground Truth模型的算子名。光标悬浮时,可显示具体算子所在的文件路径。DataType表示Ground Truth侧数据算子的数据类型。TensorIndex表示NPU Dump模型算子的input ID和output ID。Shape比对的Tensor的Shape。OverFlow溢出算子。显示YES表示该算子存在溢出;显示NO表示算子无溢出;显示NaN表示不做溢出检测。开启Advisor功能时展示,为比对结果专家建议的FP16溢出检测专家建议提供数据。CosineSimilarity进行余弦相似度算法比对出来的结果。取值范围为[-1,1],比对的结果如果越接近1,表示两者的值越相近,越接近-1意味着两者的值越相反。MaxAbsoluteError进行最大绝对误差算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。KullbackLeiblerDivergence进行KL散度算法比对出来的结果。取值范围为0到无穷大。KL散度越小,真实分布与近似分布之间的匹配越好。RootMeanSquareError表示均方根误差。取值范围为0到无穷大,MeanAbsoluteError趋于0,RootMeanSquareError趋于0,说明测量值与真实值越近似;MeanAbsoluteError趋于0,RootMeanSquareError越大,说明存在局部过大的异常值;MeanAbsoluteError越大,RootMeanSquareError等于或近似MeanAbsoluteError,说明整体偏差越集中;MeanAbsoluteError越大,RootMeanSquareError越大于MeanAbsoluteError,说明存在整体偏差,且整体偏差分布分散;不存在以上情况的例外情况,因为RMSE ≥ MAE恒成立。MaxRelativeError表示最大相对误差。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。RelativeEuclideanDistance进行欧氏相对距离算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。StandardDeviation进行标准差算法比对出来的结果。取值范围为0到无穷大。标准差越小,离散度越小,表明越接近平均值。该列显示NPU Dump和Ground Truth两组数据的均值和标准差,第一组展示NPU Dump模型dump数据的数值(均值;标准差),第二组展示Ground Truth模型dump数据的数值(均值;标准差)。AccumulatedRelativeError进行累积相对误差算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。MeanAbsoluteError表示平均绝对误差。取值范围为0到无穷大,MeanAbsoluteError趋于0,RootMeanSquareError趋于0,说明测量值与真实值越近似;MeanAbsoluteError趋于0,RootMeanSquareError越大,说明存在局部过大的异常值;MeanAbsoluteError越大,RootMeanSquareError等于或近似MeanAbsoluteError,说明整体偏差越集中;MeanAbsoluteError越大,RootMeanSquareError越大于MeanAbsoluteError,说明存在整体偏差,且整体偏差分布分散;不存在以上情况的例外情况,因为RMSE ≥ MAE恒成立。MeanRelativeError表示平均相对误差。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。CompareFailReason算子无法比对的原因。若余弦相似度为1,则查看该算子的输入或输出shape是否为空或全部为1,若为空或全部为1则算子的输入或输出为标量,提示:this tensor is scalar。注1:余弦相似度和KL散度比较结果为NaN,其他算法有比较数据,则表明左侧或右侧数据为0;KL散度比较结果为inf,表明右侧数据有一个为0;比对结果为nan,表示dump数据有nan。 注2:光标悬浮在表头可以看到对应的参数详细解释。 注3:若配置了自定义算法比对,则在比对结果的内置算法后增加对应自定义算法列。表6 散点分布图字段说明字段说明Algorithm选择展示对应比对算法结果的散点分布图,不支持展示StandardDeviation、KullbackLeiblerDivergence和AccumulatedRelativeError。Tensor过滤显示Input、Output结果散点分布图。Highlight对算子Tensor散点进行高亮。通过拖拉游标在对应算法指标的[min,max]间滑动来设置算法指标(纵坐标)的阈值,高于或等于阈值的点显示为蓝色,低于阈值的点显示为红色。如针对余弦相似度,图中设置阈值为0.98,小于0.98的算子Tensor被标记为红色。注1:光标移动到对应Tensor点上时,浮窗显示Tensor信息。信息包括:Index(Tensor对应算子的Index)、Op Name(算子名称)、Tensor Index(Tensor类型(input/output))以及Value(在当前算法维度下的Tensor数值)。注2:支持对散点图进行缩放。注3:指定区域3中的Tensor时,高亮对应Tensor点。表7 比对模型可视化展示字段说明字段说明NPU Model离线模型可视化。指定算子映射文件(.json)或离线模型文件(*.om)展示。训练场景下,若整网比对使用的Model File为计算图文件(*.txt),此处不支持展示模型图。Ground Truth Model原始模型可视化。指定原始模型文件展示。Input Model指定算子映射文件(.json)、离线模型文件(*.om)或原始模型文件。注:指定区域3中的Tensor时,高亮对应模型网络中的节点。在第一部分我们可以选择菜单,精度对比、历史等选项。我们可以从第二部分选择我们经过精度对比操作之后得到的不同的答案,并选择我们想要的内容来进行第三部分和第四部分的展示,在本次的实例当中我们只生成了一个模型的整网对比,所以只有一个对应的结果的文件,打开相应的文件夹,双击里面的csv文件,就可以呈现出我们本次模型的精度对比。精度对比页面第三部分看出我们的原模型和转换模型之间每个算子之间的结果的差距,并且也可以得到输入和输出的shape。在后面几栏的算子的精度的对比,我们可以根据不同的评判方法得出原算子和转化的算子之间经过运算之后得出的结果的相似程度来判断算子转化的优劣,我们根据后面几项的精度对比,从数据上可以看出精度正在下降,也意味着误差正在增加。随后也可观察4部分的散点图来观察从最开始的输入到最后的输出,经过每一个算子的计算,两模型之间的精度差距,我们可以看到余弦相似度的值有下降的趋势,且最后的结果接近于零,所以说两模型之间的误差在慢慢的增大。并且在第四部分还可以根据Algorithm选项选择不同的精度比较方法,比如说图1和图3选择的是余弦相似度和均方根误差来来展示精度的对比。在Tensor选项当中,我们可以选择input或者output选项来展示输入或者输出之间的精度对比。我们还可以选择第四部分的show model选项,即可以展示网络模型结构中算子之间的关系,也可以配合精度比对结果来定位具体算子的精度问题。(3)单算子精度比对操作步骤在刚刚的整网络分析界面下,点击下面的Operator Detail,出现如下界面。 对比操作。 (1)基于已经读取到的Tensor信息,通过Operator下拉框选择要比对的算子和对应Tensor(output/input)。 (2)通过Metric选择比对算子的Absolute Error(绝对误差)或Relative Error(相对误差)。 (3)配置输出该指标的TopN个Tensor元素(取值范围为[1,10000])。 (4)单击“Compare”按钮进行单算子比对。 (5)TopN结果显示请参见比对结果。 单算子比对界面说明。算子比对功能是在比对结果的基础上选择具体算子并根据需要指定参数进行比对的。界面展示为图5的6区域、7区域和8区域,如图5。详细介绍请参见表7表7 单算子比对结果说明区域说明5Operator Detail,单算子比对功能。下发单算子比对命令。具体操作请参见比对操作。6单算子比对TopN结果。各列字段解释请参见表8。7Cumulative Error,对于TopN Tensor元素,绘制的误差累积分布折线图。详细介绍请参见表8。比对结果。单算子比对结果界面展示为图5的7区域和8区域。详细介绍请参见表8。表8 比对结果字段说明字段说明6区域Index算子比对的条数。N C H W数据格式。NPUDumpNPU Dump侧算子的dump值。GroundTruthGround Truth侧算子的dump值。Absolute Error绝对误差,NPU Dump侧算子的dump值减Ground Truth侧算子的dump值取绝对值比对出来的结果。小数点后最多6位。Relative Error相对误差,Absolute Error值除以Ground Truth侧算子的dump值比对出来的结果。当Ground Truth侧算子的dump值为0时,该处显示为“-”。小数点后最多6位。7区域A % of tensor elements (B elements) have an absolute error greater than C.当前算子比对的所有tensor元素的绝对误差结果中有A %的tensor也就是B个元素的绝对误差超过了C。其中absolute error根据5区域配置的Metric取值变化可以为relative error;右侧滑块控制C的取值,范围由6区域AbsoluteError或RelativeError的最大最小值决定。误差累积分布折线图横坐标为6区域的AbsoluteError或RelativeError,取值范围由AbsoluteError或RelativeError的最大最小值决定;纵坐标为累积百分占比,含义为AbsoluteError或RelativeError到达某个阈值时,小于等于该阈值的所有tensor元素在整体tensor元素中的占比。注:光标移动到对应Tensor点上时,浮窗显示Tensor信息。信息包括:Index(算子比对的条数)、Absolute Error/Relative Error(绝对/相对误差)、Cumulative Percentage(累积百分占比)(4)对比结果专家建议FP16溢出检测 针对比对数据中数据类型为FP16的数据,进行溢出检测。如果存在溢出数据,输出专家建议。专家系统分析结果:Detection Type: FP16 overflowOperator Index: 228Expert Advice: Float16 data overflow occurs. Rectify the fault and perform comparison again.检测类型:FP16溢出检测Operator Index:228 专家建议:存在Float16数据溢出,请修正溢出问题,再进行比对。输入不一致检测 针对整网的输入数据进行检测,主要判断整网两批待比对数据的输入data是否一致。如果存在不一致问题(余弦相似度<0.99),输出专家建议。专家系统分析结果:Detection Type: Input inconsistentOperator Index: 0Expert Advice: The input data of NPUDump is inconsistent with that of GroundTruth. Use the same data or check the data preprocessing process.检测类型:输入不一致检测Operator Index:0 专家建议:NPUDump和GroundTruth间的输入数据不一致,请使用相同数据或者检查数据预处理流程。整网一致性检测(问题节点检测) 判断整网比对结果中,是否某层小于阈值,该层后续数据均小于阈值或最后一层小于阈值(余弦相似度<0.99),输出量化误差修正建议。专家系统分析结果:Detection Type: global consistencyOperator Index: 1174Expert Advice: The accuracy of some tensors is low, resulting in an unqualified final accuracy. This may be caused by quantization. Calibrate the data or contact Huawei for further diagnosis.检测类型:整网一致性检测Operator Index:1174专家建议:部分张量精度较低,且导致最终结果精度不达标;很可能由量化造成,请进行数据校准或者反馈给华为做进一步定位。整网一致性检测(单点误差检测) 判断整网比对结果中,是否某层小于阈值(余弦相似度<0.99),但最终结果符合精度要求,输出专家建议。专家系统分析结果:Detection Type: global consistencyOperator Index: 195Expert Advice: The accuracy of some tensors is low, while the final accuracy is qualified. This may be caused by Ascend internal optimization. Ignore or contact Huawei for further diagnosis.检测类型:整网一致性检测Operator Index:195专家建议:部分张量精度较低,但最终结果精度达标,可能由内部优化导致,请忽略或反馈给华为做进一步定位。整网一致性检测(一致性检测) 比对结果中的所有数据均符合精度要求,输出专家建议。专家系统分析结果:Detection Type: global consistencyOperator Index: NAExpert Advice: All data in the comparison result meets the accuracy requirements.If data accuracy of the model is still not up to standard in practical application, please check the post-processing process of model outputs.检测类型:整网一致性检测Operator Index:NA专家建议:比对结果中的所有数据均符合精度要求。如果模型实际应用中,精度依旧不达标,请排查输出数据的后处理流程。6、经验总结运行代码的时候,显示同步文件出现问题,如下。解决方法:远程python3运行环境中缺少google模块和protobuf==3.19.0模块,使用pip安装后再运行即可。 2. 单算子分析的时候,点击下面栏框显示不出来单算子分析的窗口。解决方法:确认没有报错信息的情况下,点击自己电脑的设置,调整显示屏分辨率或者缩放比例即可。Windows端的MindStudio中使用离线模型dump数据时,路径配置只能选择本地的路径,没有可选的远程路径。 解决方法:找到自己项目目录下的src/acl.json文件,手动修改JSON文件导出路径配置为远程目录的路径。配置好路径,但是运行的时候有时候会报错路径不存在。 解决方法:所有文件路径,请先确保本地存在相应路径,再同步到远程服务器中,有时候MindStudio不会自动生成路径,导致报错。7、关于MindStudio更多的内容 如果需要了解关于MindStudio更多的信息,请查阅昇腾社区中MindStudio的用户手册cid:link_4,里面有算子开发、模型开发等各种使用操作的详细介绍。 如果在使用MindStudio过程中遇到任何问题,也可以在昇腾社区中的昇腾论坛cid:link_12里进行提问,会有华为内部技术人员对其进行解答,如下图。
  • [经验分享] MindStudio模型推理场景精度比对全流程和结果分析
    视频案例,可以查看Bilibili MindStudio模型推理场景精度比对全流程和结果分析:【经验分享】MindStudio模型推理场景精度比对全流程和结果分析1、MindStudio介绍MindStudio提供在AI开发所需的一站式开发环境,支持模型开发、算子开发以及应用开发三个主流程中的开发任务,依靠模型可视化、算力测试、IDE本地仿真调试等功能,MindStudio能够帮助您在一个工具上就能高效便捷地完成AI应用开发,MindStudio采用了插件化扩展机制,开发者可以通过开发插件来扩展已有功能。本实验使用的MindStudio版本为5.0.RC3,安装请参考MindStudio安装教程。2、交付件介绍(1)精度对比简介​ 在下面两种情况下,自有实现的算子在昇腾AI处理器上的运算结果与业界标准算子(如Caffe、ONNX、TensorFlow、PyTorch)的运算结果可能存在差异。在模型转换过程中对模型进行了优化,包括算子消除、算子融合、算子拆分,这些动作可能会造成自有实现的算子运算结果与业界标准算子(如Caffe、TensorFlow、ONNX)运算结果存在偏差。用户原始网络可以迁移到昇腾910 AI处理器上执行训练,网络迁移可能会造成自有实现的算子运算结果与用业界标准算子(如TensorFlow)运算结果存在偏差。(2)实现流程​ 为了帮助开发人员快速解决算子精度问题,需要提供自有实现的算子运算结果与业界标准算子运算结果之间进行精度差异对比的工具。​ MindStudio精度比对工具提供Tensor比对能力,包含余弦相似度、欧氏相对距离、绝对误差(最大绝对误差、平均绝对误差、均方根误差)、相对误差(最大相对误差、平均相对误差、累积相对误差)、KL散度、标准差算法比对维度。精度比对总体流程如下:(3)代码工程本实验基于MindStudio的代码工程结构如下所示。本实验基于MindStudio的代码工程结构如下所示。 ├── caffeResnet50_49048f18 │ ├── acl_net.py //离线模型推理脚本代码 │ ├── caffe_dump.py //原始模型推理脚本代码 │ ├── caffe_model //原始模型文件存储目录 │ │ ├── resnet50.caffemodel │ │ └── resnet50.prototxt │ ├── caffeResnet50.iml │ ├── constant.py //离线模型推理脚本工具脚本 │ ├── data //数据文件夹 │ │ └── img.png │ ├── dump //离线模型dump数据文件夹 │ ├── model //离线模型文件夹 │ │ └── resnet50.om │ ├── npy_dump //原始模型dump数据文件夹 │ ├── output //精度比对输出文件夹 │ │ └── 20221111205145 │ └── src │ └── acl.json //离线模型dump构造文件 (4)文章介绍​ 文章详细记录了如何使用MindStudio中的精度比对功能去进行推理场景下的模型的精度比对操作,包括原始第三方框架下模型的npy数据准备,离线模型的dump数据准备,精度比对以及分析。第三节介绍了MindStudio的昇腾App工程的创建。第四节介绍了推理场景下的数据准备。第五节介绍了精度比对和分析。第六节介绍了整个流程中遇到的问题和解决方案。第七节介绍MindStudio的更多的内容。3、App工程创建打开MindStudio进入算子工程创建界面首次登录MindStudio:在MindStudio欢迎界面中单击“New Project”,进入创建工程界面。非首次登录MindStudio:在顶部菜单栏中选择“File > New > Project...”,进入创建工程界面。创建App工程左侧导航栏选择“Ascend App”,如图所示,在右侧点击选择ACL Project(Python)工程。单击“Next”,在弹出的页面中,Project name那一行输入项目名称,然后点击Finish,既可完成工程的创建。单击“Finish”,完成应用工程的创建若工作窗口已打开其他工程,会出现如图所示提示。选择“This Window”,则直接在当前工作窗口打开新创建的工程。选择“New Window”,则新建一个工作窗口打开新创建的工程。4、推理场景数据准备(1)准备Caffe模型npy数据文件MindStudio当前版本不提供Caffe模型numpy数据生成功能,请自行安装Caffe环境并提前准备Caffe原始数据“*.npy”文件。本文仅提供生成符合精度比对要求的numpy格式Caffe原始数据“*.npy”文件的样例参考。下面给出Resnet50原始模型dump数据的推理脚本代码。请参考表1的参数说明进行使用。​ 表1 原始模型推理脚本参数说明-wCaffe 权重文件路径,如'resnet50.caffemodel'-i, --input_bins模型推理输入bin文件或者图片文件路径,多个以;分隔,如'./a.bin;./img.png'-n, --input_names模型推理输入节点名称,多个以;分隔,如'graph_input_0:0; graph_input_1:0'-mCaffe 模型文件路径,如'resnet50.prototxt'-odump输出文件路径,如'./output_dir', 该路径需要用户自己创建脚本代码:# coding=utf-8 import caffe import sys import argparse import os import caffe.proto.caffe_pb2 as caffe_pb2 import google.protobuf.text_format import json import numpy as np import time TIME_LENGTH = 1000 FILE_PERMISSION_FLAG = 0o600 class CaffeProcess: def __init__(self): parse = argparse.ArgumentParser() parse.add_argument("-w", dest="weight_file_path", help="<Required> the caffe weight file path", required=False,default="caffe_model/resnet50.caffemodel") parse.add_argument("-m", dest="model_file_path", help="<Required> the caffe model file path", required=False,default="caffe_model/resnet50.prototxt") parse.add_argument("-o", dest="output_path", help="<Required> the output path", required=False,default="npy_dump") parse.add_argument("-i", "--input_bins", dest="input_bins", help="input_bins bins. e.g. './a.bin;./c.bin'", required=False,default="./data/img.png") parse.add_argument("-n", "--input_names", dest="input_names", help="input nodes name. e.g. 'graph_input_0:0;graph_input_0:1'", required=False,default="data:0") args, _ = parse.parse_known_args(sys.argv[1:]) self.weight_file_path = os.path.realpath(args.weight_file_path) self.model_file_path = os.path.realpath(args.model_file_path) self.input_bins = args.input_bins.split(";") self.input_names = args.input_names.split(";") self.output_path = os.path.realpath(args.output_path) self.net_param = None self.cur_layer_idx = -1 @staticmethod def _check_file_valid(path, is_file): if not os.path.exists(path): print('Error: The path "' + path + '" does not exist.') exit(-1) if is_file: if not os.path.isfile(path): print('Error: The path "' + path + '" is not a file.') exit(-1) else: if not os.path.isdir(path): print('Error: The path "' + path + '" is not a directory.') exit(-1) def _check_arguments_valid(self): self._check_file_valid(self.model_file_path, True) self._check_file_valid(self.weight_file_path, True) self._check_file_valid(self.output_path, False) for input_file in self.input_bins: self._check_file_valid(input_file, True) @staticmethod def calDataSize(shape): dataSize = 1 for dim in shape: dataSize *= dim return dataSize def _load_inputs(self, net): inputs_map = {} for layer_name, blob in net.blobs.items(): if layer_name in self.input_names: input_bin = np.fromfile( self.input_bins[self.input_names.index(layer_name)], np.float32) input_bin_shape = blob.data.shape if self.calDataSize(input_bin_shape) == self.calDataSize(input_bin.shape): input_bin = input_bin.reshape(input_bin_shape) else: print("Error: input node data size %d not match with input bin data size %d.", self.calDataSize( input_bin_shape), self.calDataSize(input_bin.shape)) exit(-1) inputs_map[layer_name] = input_bin return inputs_map def process(self): """ Function Description: process the caffe net, save result as dump data """ # check path valid self._check_arguments_valid() # load model and weight file net = caffe.Net(self.model_file_path, self.weight_file_path, caffe.TEST) inputs_map = self._load_inputs(net) for key, value in inputs_map.items(): net.blobs[key].data[...] = value # process net.forward() # read prototxt file net_param = caffe_pb2.NetParameter() with open(self.model_file_path, 'rb') as model_file: google.protobuf.text_format.Parse(model_file.read(), net_param) for layer in net_param.layer: name = layer.name.replace("/", "_").replace(".", "_") index = 0 for top in layer.top: data = net.blobs[top].data[...] file_name = name + "." + str(index) + "." + str( round(time.time() * 1000000)) + ".npy" output_dump_path = os.path.join(self.output_path, file_name) np.save(output_dump_path, data) os.chmod(output_dump_path, FILE_PERMISSION_FLAG) print('The dump data of "' + layer.name + '" has been saved to "' + output_dump_path + '".') index += 1 if __name__ == "__main__": caffe_process = CaffeProcess() caffe_process.process()说明:运行之前需要提前准备数据文件和模型文件,原始模型下载地址为:cid:link_3​ 数据图片下载地址为:https://gitee.com/link?target=https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/models/aclsample/dog1_1024_683.jpg远程安装好caffe的python3环境,在本地配置好安装的caffe的SDK。将上述代码拷贝到新建的python脚本中,右键点击运行该脚本,即可以在参数-o指定的路径下生成npy数据文件。生成的文件是以{op_name}.{output_index}.{timestamp}.npy形式命名。其中{op_name}为算子名称,{output_index}是算子的编号索引,{timestamp}是时间戳;设置numpy数据文件名包括output_index字段且值为0,确保转换生成的dump数据的output_index为0,否则无比对结果,原因是精度比对时默认从第一个output_index为0的数据开始。(2)准备离线模型dump数据通过MindStudio提供的dump功能,生成离线模型的dump数据,需要提前完成以下操作:完成Caffe、TensorFlow或ONNX模型的ATC模型转换,将原始模型转换为OM离线模型。详细介绍请参见模型转换。完成应用工程的开发、编译和运行,确保具备可执行的应用工程。详细介绍请参见应用开发。操作步骤如下:准备好离线模型,离线模型下载地址为:cid:link_3;或者参考如下模型转换步骤进行模型转换(1) 在菜单栏选择“Ascend > Model Converter”。出现如下配置界面,参数配置参考MindStudio官网>用户指南>模型转换>操作步骤。(2) 单击“Next”,进入“Data Pre-Processing”配置数据预处理页签,界面参考如图所示。说明:数据预处理是昇腾AI处理器提供的硬件图像预处理模块,包括色域转换,图像归一化(减均值/乘系数)和抠图(指定抠图起始点,抠出神经网络需要大小的图片)等功能。只有当“Model Information”页签,“Input Nodes”参数中,输入节点的“Type”有配置为“Uint8”类型,“Data Pre-Processing”页签才可以配置该节点的数据预处理功能。如果模型有多个输入,每个输入节点都可以获取shape信息中的宽和高,并且“Input Nodes”参数中每个输入节点的“Type”都配置为“Uint8”,则“Data Pre-Processing”页签可以配置多个节点的数据预处理功能。(3) 单击“Next”,进入“Advanced Options Preview”高级选项配置页签,界面参考如图所示。(4) 单击Finish完成模型转换。在MindStudio界面下方,“Output”窗口会显示模型转换过程中的日志信息,如果提示“Model converted successfully”,则表示模型转换成功。准备好离线模型的推理代码。推理代码可以从cid:link_0中获取,或者直接拷贝下面代码。构造dump的.json配置,选择“Ascend > Dump Configuration”菜单,弹出“Select Offline Model”窗口,如图所示。注意:如果不知道自己本地同步到远程哪个路径下,可以点击Tools>Development>Configuration下查看。选择.om模型文件,单击“OK”,展示模型文件结构,设置dump开关。如图所示。它会在src目录下生成acl.json配置文件,通过修改窗口最右侧配置项,设置.om模型文件的dump配置项,会自动更新到acl.json文件中。(1) Dump Option:配置dump范围。ALL:所有算子开启dump。Several:自定义部分算子开启dump。选择该项后,需要右键单击待dump数据的算子并选择“Enable Dump”。None:所有算子不开启dump。(2) Dump Mode:dump数据模式。ALL:同时dump算子的输入、输出数据。Input:dump算子的输入数据。Output:dump算子的输出数据。(3) Dump Path:配置保存dump数据文件的路径,默认为:{project_path}/dump。如果Dump Path设置为其他路径,需要确保MindStudio安装用户对该路径具有读写权限。注意:该选项要选择远程的dump目录,当前版本mindstudio只支持选择本地的dump目录,如果不能选择远程dump目录,请自行在acl.json中配置。(4) AclConfig File:Acl配置文件,在dump操作中该文件保存算子的dump配置信息。一般路径为{project_path}/src/acl.json。请参考表2中的参数说明使用该脚本​ 表2 离线模型推理脚本参数说明--devicenpu设备编号。--model_path离线模型文件路径,到文件名层次。--images_path数据文件路径,到数据文件的文件夹层次。import argparse import numpy as np import acl import os from PIL import Image from constant import ACL_MEM_MALLOC_HUGE_FIRST, \ ACL_MEMCPY_HOST_TO_DEVICE, ACL_MEMCPY_DEVICE_TO_HOST, \ ACL_SUCCESS, IMG_EXT, NPY_FLOAT32 buffer_method = { "in": acl.mdl.get_input_size_by_index, "out": acl.mdl.get_output_size_by_index } def check_ret(message, ret): if ret != ACL_SUCCESS: raise Exception("{} failed ret={}" .format(message, ret)) class Net(object): def __init__(self, device_id, model_path): self.device_id = device_id # int self.model_path = model_path # string self.model_id = None # pointer self.context = None # pointer self.input_data = [] self.output_data = [] self.model_desc = None # pointer when using self.load_input_dataset = None self.load_output_dataset = None self.init_resource() def release_resource(self): print("Releasing resources stage:") ret = acl.mdl.unload(self.model_id) check_ret("acl.mdl.unload", ret) if self.model_desc: acl.mdl.destroy_desc(self.model_desc) self.model_desc = None while self.input_data: item = self.input_data.pop() ret = acl.rt.free(item["buffer"]) check_ret("acl.rt.free", ret) while self.output_data: item = self.output_data.pop() ret = acl.rt.free(item["buffer"]) check_ret("acl.rt.free", ret) if self.context: ret = acl.rt.destroy_context(self.context) check_ret("acl.rt.destroy_context", ret) self.context = None ret = acl.rt.reset_device(self.device_id) check_ret("acl.rt.reset_device", ret) ret = acl.finalize() check_ret("acl.finalize", ret) print('Resources released successfully.') def init_resource(self): print("init resource stage:") current_dir=os.path.dirname(os.path.abspath(__file__)) ret = acl.init(os.path.join(current_dir,"./src/acl.json")) check_ret("acl.init", ret) # ret = acl.mdl.init_dump() # check_ret("acl.init", ret) # ret = acl.mdl.set_dump(os.path.join(current_dir,"./src/acl.json")) # check_ret("acl.init", ret) ret = acl.rt.set_device(self.device_id) check_ret("acl.rt.set_device", ret) self.context, ret = acl.rt.create_context(self.device_id) check_ret("acl.rt.create_context", ret) # load_model self.model_id, ret = acl.mdl.load_from_file(self.model_path) check_ret("acl.mdl.load_from_file", ret) print("model_id:{}".format(self.model_id)) self.model_desc = acl.mdl.create_desc() self._get_model_info() print("init resource success") def _get_model_info(self,): ret = acl.mdl.get_desc(self.model_desc, self.model_id) check_ret("acl.mdl.get_desc", ret) input_size = acl.mdl.get_num_inputs(self.model_desc) output_size = acl.mdl.get_num_outputs(self.model_desc) self._gen_data_buffer(input_size, des="in") self._gen_data_buffer(output_size, des="out") def _gen_data_buffer(self, size, des): func = buffer_method[des] for i in range(size): # check temp_buffer dtype temp_buffer_size = func(self.model_desc, i) temp_buffer, ret = acl.rt.malloc(temp_buffer_size, ACL_MEM_MALLOC_HUGE_FIRST) check_ret("acl.rt.malloc", ret) if des == "in": self.input_data.append({"buffer": temp_buffer, "size": temp_buffer_size}) elif des == "out": self.output_data.append({"buffer": temp_buffer, "size": temp_buffer_size}) def _data_interaction(self, dataset, policy=ACL_MEMCPY_HOST_TO_DEVICE): temp_data_buffer = self.input_data \ if policy == ACL_MEMCPY_HOST_TO_DEVICE \ else self.output_data if len(dataset) == 0 and policy == ACL_MEMCPY_DEVICE_TO_HOST: for item in self.output_data: temp, ret = acl.rt.malloc_host(item["size"]) if ret != 0: raise Exception("can't malloc_host ret={}".format(ret)) dataset.append({"size": item["size"], "buffer": temp}) for i, item in enumerate(temp_data_buffer): if policy == ACL_MEMCPY_HOST_TO_DEVICE: if "bytes_to_ptr" in dir(acl.util): bytes_data = dataset[i].tobytes() ptr = acl.util.bytes_to_ptr(bytes_data) else: ptr = acl.util.numpy_to_ptr(dataset[i]) ret = acl.rt.memcpy(item["buffer"], item["size"], ptr, item["size"], policy) check_ret("acl.rt.memcpy", ret) else: ptr = dataset[i]["buffer"] ret = acl.rt.memcpy(ptr, item["size"], item["buffer"], item["size"], policy) check_ret("acl.rt.memcpy", ret) def _gen_dataset(self, type_str="input"): dataset = acl.mdl.create_dataset() temp_dataset = None if type_str == "in": self.load_input_dataset = dataset temp_dataset = self.input_data else: self.load_output_dataset = dataset temp_dataset = self.output_data for item in temp_dataset: data = acl.create_data_buffer(item["buffer"], item["size"]) _, ret = acl.mdl.add_dataset_buffer(dataset, data) if ret != ACL_SUCCESS: ret = acl.destroy_data_buffer(data) check_ret("acl.destroy_data_buffer", ret) def _data_from_host_to_device(self, images): print("data interaction from host to device") # copy images to device self._data_interaction(images, ACL_MEMCPY_HOST_TO_DEVICE) # load input data into model self._gen_dataset("in") # load output data into model self._gen_dataset("out") print("data interaction from host to device success") def _data_from_device_to_host(self): print("data interaction from device to host") res = [] # copy device to host self._data_interaction(res, ACL_MEMCPY_DEVICE_TO_HOST) print("data interaction from device to host success") result = self.get_result(res) self._print_result(result) # free host memory for item in res: ptr = item['buffer'] ret = acl.rt.free_host(ptr) check_ret('acl.rt.free_host', ret) def run(self, images): self._data_from_host_to_device(images) self.forward() self._data_from_device_to_host() def forward(self): print('execute stage:') ret = acl.mdl.execute(self.model_id, self.load_input_dataset, self.load_output_dataset) check_ret("acl.mdl.execute", ret) self._destroy_databuffer() print('execute stage success') def _print_result(self, result): vals = np.array(result).flatten() top_k = vals.argsort()[-1:-6:-1] print("======== top5 inference results: =============") for j in top_k: print("[%d]: %f" % (j, vals[j])) def _destroy_databuffer(self): for dataset in [self.load_input_dataset, self.load_output_dataset]: if not dataset: continue number = acl.mdl.get_dataset_num_buffers(dataset) for i in range(number): data_buf = acl.mdl.get_dataset_buffer(dataset, i) if data_buf: ret = acl.destroy_data_buffer(data_buf) check_ret("acl.destroy_data_buffer", ret) ret = acl.mdl.destroy_dataset(dataset) check_ret("acl.mdl.destroy_dataset", ret) def get_result(self, output_data): result = [] dims, ret = acl.mdl.get_cur_output_dims(self.model_desc, 0) check_ret("acl.mdl.get_cur_output_dims", ret) out_dim = dims['dims'] for temp in output_data: ptr = temp["buffer"] # 转化为float32类型的数据 if "ptr_to_bytes" in dir(acl.util): bytes_data = acl.util.ptr_to_bytes(ptr, temp["size"]) data = np.frombuffer(bytes_data, dtype=np.float32).reshape(tuple(out_dim)) else: data = acl.util.ptr_to_numpy(ptr, tuple(out_dim), NPY_FLOAT32) result.append(data) return result def transfer_pic(input_path): input_path = os.path.abspath(input_path) with Image.open(input_path) as image_file: image_file = image_file.resize((256, 256)) img = np.array(image_file) height = img.shape[0] width = img.shape[1] # 对图片进行切分,取中间区域 h_off = (height - 224) // 2 w_off = (width - 224) // 2 crop_img = img[h_off:height - h_off, w_off:width - w_off, :] # rgb to bgr,改变通道顺序 img = crop_img[:, :, ::-1] shape = img.shape img = img.astype("float16") img[:, :, 0] -= 104 img[:, :, 1] -= 117 img[:, :, 2] -= 123 img = img.reshape([1] + list(shape)) img = img.transpose([0, 3, 1, 2]) result = np.frombuffer(img.tobytes(), np.float16) return result if __name__ == '__main__': current_dir = os.path.dirname(os.path.abspath(__file__)) parser = argparse.ArgumentParser() parser.add_argument('--device', type=int, default=0) parser.add_argument('--model_path', type=str, default=os.path.join(current_dir, "./model/resnet50.om")) parser.add_argument('--images_path', type=str, default=os.path.join(current_dir, "./data")) args = parser.parse_args() print("Using device id:{}\nmodel path:{}\nimages path:{}" .format(args.device, args.model_path, args.images_path)) images_list = [os.path.join(args.images_path, img) for img in os.listdir(args.images_path) if os.path.splitext(img)[1] in IMG_EXT] net = Net(args.device, args.model_path) for image in images_list: print("images:{}".format(image)) img = transfer_pic(image) net.run([img]) # acl.mdl.finalize_dump() # net.run([img]) print("*****run finish******") net.release_resource() 说明:(1) 数据文件应该是与原始模型生成npy数据文件保持一致。(2) 如果是从gitee上下载的代码,需要修改acl.init()这行代码,在里面传入dump的配置参数.json文件。6.设置dump完成后,单击MindStudio界面“Run”菜单,重新编译和运行应用工程。工程运行完毕后,可以在{project_path}/dump路径下查看到生成的dump数据文件。生成的路径及格式说明:time/device_id/model_name/model_id/data_index/dump文件time:dump数据回传落盘时间。格式为:YYYYMMDDhhmmss。device_id:Device设备ID号。model_name:模型名称。model_id:模型ID号。data_index:针对每个Task ID执行的次数维护一个序号,从0开始计数,该Task每dump一次数据,序号递增1。dump文件:命名规则如{op_type}.{op_name}.{taskid}.{timestamp}。如果model_name、op_type、op_name出现了“.”、“/”、“\”、空格时,转换为下划线表示。5、精度比对及分析(1)全网精度比对操作步骤在MindStudio界面菜单栏选择“Ascend > Model Accuracy Analyzer > New Task”菜单,进入比对界面,如下图所示。参考表3配置好参数后点击Next下一步。进入到数据和模型的配置界面。​ 表3 精度比对New Task参数说明参数说明Run ModeRemote Run:远程运行。Local Run:本地运行。Windows使用场景下仅支持Remote Run,该参数不展示。Deployment运行配置,选择Remote Run模式时可见,必选配置。通过Deployment功能,详细请参见Deployment,可以将指定项目中的文件、文件夹同步到远程指定机器的指定目录。Remote Toolkit Path远端运行环境toolkit软件包安装路径,选择Remote Run模式时可见,必选配置。例如配置为${HOME}/Ascend/ascend-toolkit/xxx/toolkit。与Deployment参数为绑定关系,单击“Start”后参数值将被保存。再次配置时,如连接已配置过的Deployment,则参数自动填充,可手动修改。Environment Variables环境变量配置,选择Remote Run模式时可见,可以直接在框中输入,也可以单击后在弹窗内单击填写。可选配置,当Model File指定文件为离线模型文件(*.om)时,需要配置环境变量,否则工具将无法为离线模型文件(*.om)进行ATC转换导致比对失败。与Deployment参数为绑定关系,单击“Start”后参数值将被保存。再次配置时,如连接已配置过的Deployment,则参数自动填充,可手动修改。Output Path比对数据结果存放路径,必选配置。无论选择Remote Run模式还是Local Run模式,均需要指定为本端路径。默认路径为当前系统的用户目录。Analysis Mode精度比对分析模式,必选配置。可选择模式为:NPU vs NPU:表示两个比对文件均为昇腾AI处理器上运行生成的dump数据文件。此时Model File参数可选。一般用于分析开启和关闭融合规则时进行模型转换后的dump数据文件之间的精度差。模型转换开启和关闭融合规则的详细介绍请参见模型转换。NPU vs GPU/CPU:表示昇腾AI处理器上运行生成的dump数据文件与原始模型的npy文件进行比对。此时展示Framework必选参数。Framework比对数据所属的框架类型,必选配置。Analysis Mode为NPU vs GPU/CPU时可见。可选类型为:- TensorFlow:TensorFlow框架模型dump数据的精度比对,支持推理、训练场景,Model File参数必选。- ONNX:ONNX框架模型dump数据的精度比对,支持推理场景,Model File参数必选。- Caffe:Caffe框架模型dump数据的精度比对,支持推理场景,Model File参数必选。NPU Dump昇腾AI处理器上运行生成的dump数据文件目录,必选配置。在远端执行比对时(Remote Run),须指定远端设备上的dump数据文件目录。Model File模型文件或融合规则文件。Analysis Mode为NPU vs NPU时,进行离线模型转换开启算子融合功能前后的dump数据精度比对,需要指定开融合的算子映射文件(.json)或离线模型文件(*.om)和关融合的算子映射文件(.json)或离线模型文件(*.om)。Analysis Mode为NPU vs GPU/CPU时,根据Framework选择的框架类型选择不同的文件:l TensorFlow:推理场景选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om);训练场景选择计算图文件(*.txt)。l ONNX:选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om)。l Caffe:选择昇腾模型压缩后的量化融合规则文件(json文件)或离线模型文件(*.om)。l 具体选择文件请参见比对场景。Quantization Rule File(.json)量化算子映射关系文件(昇腾模型压缩输出的json文件),可选配置。仅Framework为Caffe时展示。Ground Truth原始模型的npy文件目录,必选配置。在远端执行比对时(Remote Run),须指定远端设备上的原始模型的npy文件目录。Algorithm比对算法维度。取值为:l Cosine Similarity:余弦相似度算法,默认勾选。l Relative Euclidean Distance:欧氏相对距离算法,默认勾选。l Absolute Error,绝对误差,默认勾选,此项执行的比对算法为:l Max Absolute Error:最大绝对误差。l Mean Absolute Error:平均绝对误差。l Root Mean Square Error:均方根误差。l Relative Error,相对误差,默认勾选,此项执行的比对算法为:l Max Relative Error:最大相对误差。l Mean Relative Error:平均相对误差。l Accumulated Relative Error:累积相对误差。l Kullback Leibler Divergence:KL散度算法,默认不勾选。l Standard Deviation:标准差算法,默认不勾选。l 与Customized Algorithm自定义算法之间至少勾选一种算法。Advance Options扩展选项。包括Customized Algorithm、Advisor和Operator Range。Customized Algorithm自定义算法文件路径。与Algorithm内置算法之间至少勾选一种算法。需用户自行准备自定义算法.py文件,所在目录格式为“algorithm”,指定该目录下的自定义算法.py文件,生成自定义算法。自定义算法.py文件相关要求参见《精度比对工具使用指南》附录中的“准备自定义算法.py文件”章节。Advisor专家系统分析开关,默认关闭。开启后会在完成整网比对后对比对结果进行专家系统分析并输出问题节点、问题类型和优化建议。详细介绍请参见比对结果专家建议。使用本功能前需要先执行*pip3* *install* ****pandas****命令安装pandas 1.3或更高版本依赖。与Operator Range无法同时开启。Operator Range设定算子比对范围。有两种设置方式:方式一:单击“Select”按钮,在弹出框内勾选需要比对的算子。方式二:根据Start、End、Step参数配置比对算子的范围。l start:第一个比对的算子,取值范围为[1, 参与计算的算子个数],默认值为1。l end:最后一个比对的算子,取值范围为-1或[start, 参与计算的算子个数],默认值为-1(动态获取网络模型中最后一个参与计算的算子)。l step:第start+stepn个比对的算子,step取值范围为[1, 参与计算的算子个数),默认值为1,n为从1开始的正整数。配置格式为:“start,end,step”。比如:-r 1,101,20,表示算子1,21,41,61,81,101的Tensor参与比对。不配置本参数时,比对网络模型中的所有参与计算的算子。配置本参数且Analysis Mode参数配置为NPU vs NPU时,需同时指定NPU Dump和Ground Truth的Model File分别指定开融合的算子映射文件(.json)或离线模型文件(.om)和关融合的算子映射文件(.json)或离线模型文件(*.om)。与Advisor无法同时开启。(2)全网比对结果分析上面步骤配置好参数后点击start即可以出现对比的结果界面。如下所示。图一图二图三所示将Tensor比对结果界面分为四个区域分别进行介绍。其中1~4区域为整网比对结果。表4 整网比对结果说明区域区域名称说明1菜单栏从左到右分别为Open…、New Task、Refresh、Help四项功能。Open…为打开并展示比对结果csv文件;New Task为创建新的比对任务;Refresh用于读取并刷新File Manager中管理的文件;单击Help弹出小窗,可展示精度比对工具的使用限制(Restrictions)、使用建议、在线教程链接等。2File Manager,历史数据管理显示用户指定文件夹以及文件夹下生成的整网比对的csv文件以及显示通过Open…单独打开的csv文件;对文件夹和csv,提供历史数据管理功能,包括打开、删除、另存为;在文件夹处右键删除;在空白处右键创建新比对任务(New Task)、刷新(Refresh)和Open…(打开并展示比对结果csv文件)。3Model Accuracy Analysis,精度比对分析界面默认仅显示有结果的算子。可单击列名,进行排序;单击Show Invalid Data,可展示无法比对的数据,各列字段含义请参见表2。4Scatter Diagram,各项算法指标的散点分布图Show Model,比对模型可视化展示Scatter Diagram:横坐标表示算子的执行顺序,纵坐标为算法指标在对应Tensor上的实际取值。各字段含义请参见表3。Show Model:分别展示NPU和Ground Truth的模型图。详细介绍请参见表4。表5 比对结果字段说明字段说明Index网络模型中算子的ID。OpSequence算子运行的序列。全网层信息文件中算子的ID。仅配置“Operator Range”时展示。OpType算子类型。NPUDump表示NPU Dump模型的算子名。光标悬浮时,可显示具体算子所在的文件路径。DataType表示NPU Dump侧数据算子的数据类型。Addressdump tensor的虚拟内存地址。用于判断算子的内存问题。仅基于昇腾AI处理器运行生成的dump数据文件在整网比对时可提取该数据。GroundTruth表示Ground Truth模型的算子名。光标悬浮时,可显示具体算子所在的文件路径。DataType表示Ground Truth侧数据算子的数据类型。TensorIndex表示NPU Dump模型算子的input ID和output ID。Shape比对的Tensor的Shape。OverFlow溢出算子。显示YES表示该算子存在溢出;显示NO表示算子无溢出;显示NaN表示不做溢出检测。开启Advisor功能时展示,为比对结果专家建议的FP16溢出检测专家建议提供数据。CosineSimilarity进行余弦相似度算法比对出来的结果。取值范围为[-1,1],比对的结果如果越接近1,表示两者的值越相近,越接近-1意味着两者的值越相反。MaxAbsoluteError进行最大绝对误差算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。KullbackLeiblerDivergence进行KL散度算法比对出来的结果。取值范围为0到无穷大。KL散度越小,真实分布与近似分布之间的匹配越好。RootMeanSquareError表示均方根误差。取值范围为0到无穷大,MeanAbsoluteError趋于0,RootMeanSquareError趋于0,说明测量值与真实值越近似;MeanAbsoluteError趋于0,RootMeanSquareError越大,说明存在局部过大的异常值;MeanAbsoluteError越大,RootMeanSquareError等于或近似MeanAbsoluteError,说明整体偏差越集中;MeanAbsoluteError越大,RootMeanSquareError越大于MeanAbsoluteError,说明存在整体偏差,且整体偏差分布分散;不存在以上情况的例外情况,因为RMSE ≥ MAE恒成立。MaxRelativeError表示最大相对误差。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。RelativeEuclideanDistance进行欧氏相对距离算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。StandardDeviation进行标准差算法比对出来的结果。取值范围为0到无穷大。标准差越小,离散度越小,表明越接近平均值。该列显示NPU Dump和Ground Truth两组数据的均值和标准差,第一组展示NPU Dump模型dump数据的数值(均值;标准差),第二组展示Ground Truth模型dump数据的数值(均值;标准差)。AccumulatedRelativeError进行累积相对误差算法比对出来的结果。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。MeanAbsoluteError表示平均绝对误差。取值范围为0到无穷大,MeanAbsoluteError趋于0,RootMeanSquareError趋于0,说明测量值与真实值越近似;MeanAbsoluteError趋于0,RootMeanSquareError越大,说明存在局部过大的异常值;MeanAbsoluteError越大,RootMeanSquareError等于或近似MeanAbsoluteError,说明整体偏差越集中;MeanAbsoluteError越大,RootMeanSquareError越大于MeanAbsoluteError,说明存在整体偏差,且整体偏差分布分散;不存在以上情况的例外情况,因为RMSE ≥ MAE恒成立。MeanRelativeError表示平均相对误差。取值范围为0到无穷大,值越接近于0,表明越相近,值越大,表明差距越大。CompareFailReason算子无法比对的原因。若余弦相似度为1,则查看该算子的输入或输出shape是否为空或全部为1,若为空或全部为1则算子的输入或输出为标量,提示:this tensor is scalar。注1:余弦相似度和KL散度比较结果为NaN,其他算法有比较数据,则表明左侧或右侧数据为0;KL散度比较结果为inf,表明右侧数据有一个为0;比对结果为nan,表示dump数据有nan。 注2:光标悬浮在表头可以看到对应的参数详细解释。 注3:若配置了自定义算法比对,则在比对结果的内置算法后增加对应自定义算法列。表6 散点分布图字段说明字段说明Algorithm选择展示对应比对算法结果的散点分布图,不支持展示StandardDeviation、KullbackLeiblerDivergence和AccumulatedRelativeError。Tensor过滤显示Input、Output结果散点分布图。Highlight对算子Tensor散点进行高亮。通过拖拉游标在对应算法指标的[min,max]间滑动来设置算法指标(纵坐标)的阈值,高于或等于阈值的点显示为蓝色,低于阈值的点显示为红色。如针对余弦相似度,图中设置阈值为0.98,小于0.98的算子Tensor被标记为红色。注1:光标移动到对应Tensor点上时,浮窗显示Tensor信息。信息包括:Index(Tensor对应算子的Index)、Op Name(算子名称)、Tensor Index(Tensor类型(input/output))以及Value(在当前算法维度下的Tensor数值)。注2:支持对散点图进行缩放。注3:指定区域3中的Tensor时,高亮对应Tensor点。表7 比对模型可视化展示字段说明字段说明NPU Model离线模型可视化。指定算子映射文件(.json)或离线模型文件(*.om)展示。训练场景下,若整网比对使用的Model File为计算图文件(*.txt),此处不支持展示模型图。Ground Truth Model原始模型可视化。指定原始模型文件展示。Input Model指定算子映射文件(.json)、离线模型文件(*.om)或原始模型文件。注:指定区域3中的Tensor时,高亮对应模型网络中的节点。在第一部分我们可以选择菜单,精度对比、历史等选项。我们可以从第二部分选择我们经过精度对比操作之后得到的不同的答案,并选择我们想要的内容来进行第三部分和第四部分的展示,在本次的实例当中我们只生成了一个模型的整网对比,所以只有一个对应的结果的文件,打开相应的文件夹,双击里面的csv文件,就可以呈现出我们本次模型的精度对比。精度对比页面第三部分看出我们的原模型和转换模型之间每个算子之间的结果的差距,并且也可以得到输入和输出的shape。在后面几栏的算子的精度的对比,我们可以根据不同的评判方法得出原算子和转化的算子之间经过运算之后得出的结果的相似程度来判断算子转化的优劣,我们根据后面几项的精度对比,从数据上可以看出精度正在下降,也意味着误差正在增加。随后也可观察4部分的散点图来观察从最开始的输入到最后的输出,经过每一个算子的计算,两模型之间的精度差距,我们可以看到余弦相似度的值有下降的趋势,且最后的结果接近于零,所以说两模型之间的误差在慢慢的增大。并且在第四部分还可以根据Algorithm选项选择不同的精度比较方法,比如说图1和图3选择的是余弦相似度和均方根误差来来展示精度的对比。在Tensor选项当中,我们可以选择input或者output选项来展示输入或者输出之间的精度对比。我们还可以选择第四部分的show model选项,即可以展示网络模型结构中算子之间的关系,也可以配合精度比对结果来定位具体算子的精度问题。(3)单算子精度比对操作步骤在刚刚的整网络分析界面下,点击下面的Operator Detail,出现如下界面。对比操作。 (1)基于已经读取到的Tensor信息,通过Operator下拉框选择要比对的算子和对应Tensor(output/input)。 (2)通过Metric选择比对算子的Absolute Error(绝对误差)或Relative Error(相对误差)。 (3)配置输出该指标的TopN个Tensor元素(取值范围为[1,10000])。 (4)单击“Compare”按钮进行单算子比对。 TopN结果显示请参见比对结果。单算子比对界面说明。算子比对功能是在比对结果的基础上选择具体算子并根据需要指定参数进行比对的。界面展示为图5的6区域、7区域和8区域,如图5。详细介绍请参见表7表7 单算子比对结果说明区域说明5Operator Detail,单算子比对功能。下发单算子比对命令。具体操作请参见比对操作。6单算子比对TopN结果。各列字段解释请参见表8。7Cumulative Error,对于TopN Tensor元素,绘制的误差累积分布折线图。详细介绍请参见表8。比对结果。单算子比对结果界面展示为图5的7区域和8区域。详细介绍请参见表8。表8 比对结果字段说明字段说明6区域Index算子比对的条数。N C H W数据格式。NPUDumpNPU Dump侧算子的dump值。GroundTruthGround Truth侧算子的dump值。Absolute Error绝对误差,NPU Dump侧算子的dump值减Ground Truth侧算子的dump值取绝对值比对出来的结果。小数点后最多6位。Relative Error相对误差,Absolute Error值除以Ground Truth侧算子的dump值比对出来的结果。当Ground Truth侧算子的dump值为0时,该处显示为“-”。小数点后最多6位。7区域A % of tensor elements (B elements) have an absolute error greater than C.当前算子比对的所有tensor元素的绝对误差结果中有A %的tensor也就是B个元素的绝对误差超过了C。其中absolute error根据5区域配置的Metric取值变化可以为relative error;右侧滑块控制C的取值,范围由6区域AbsoluteError或RelativeError的最大最小值决定。误差累积分布折线图横坐标为6区域的AbsoluteError或RelativeError,取值范围由AbsoluteError或RelativeError的最大最小值决定;纵坐标为累积百分占比,含义为AbsoluteError或RelativeError到达某个阈值时,小于等于该阈值的所有tensor元素在整体tensor元素中的占比。注:光标移动到对应Tensor点上时,浮窗显示Tensor信息。信息包括:Index(算子比对的条数)、Absolute Error/Relative Error(绝对/相对误差)、Cumulative Percentage(累积百分占比)(4)对比结果专家建议FP16溢出检测 针对比对数据中数据类型为FP16的数据,进行溢出检测。如果存在溢出数据,输出专家建议。专家系统分析结果:Detection Type: FP16 overflowOperator Index: 228Expert Advice: Float16 data overflow occurs. Rectify the fault and perform comparison again.检测类型:FP16溢出检测Operator Index:228 专家建议:存在Float16数据溢出,请修正溢出问题,再进行比对。输入不一致检测 针对整网的输入数据进行检测,主要判断整网两批待比对数据的输入data是否一致。如果存在不一致问题(余弦相似度<0.99),输出专家建议。专家系统分析结果:Detection Type: Input inconsistentOperator Index: 0Expert Advice: The input data of NPUDump is inconsistent with that of GroundTruth. Use the same data or check the data preprocessing process.检测类型:输入不一致检测Operator Index:0 专家建议:NPUDump和GroundTruth间的输入数据不一致,请使用相同数据或者检查数据预处理流程。整网一致性检测(问题节点检测) 判断整网比对结果中,是否某层小于阈值,该层后续数据均小于阈值或最后一层小于阈值(余弦相似度<0.99),输出量化误差修正建议。专家系统分析结果:Detection Type: global consistencyOperator Index: 1174Expert Advice: The accuracy of some tensors is low, resulting in an unqualified final accuracy. This may be caused by quantization. Calibrate the data or contact Huawei for further diagnosis.检测类型:整网一致性检测Operator Index:1174专家建议:部分张量精度较低,且导致最终结果精度不达标;很可能由量化造成,请进行数据校准或者反馈给华为做进一步定位。整网一致性检测(单点误差检测) 判断整网比对结果中,是否某层小于阈值(余弦相似度<0.99),但最终结果符合精度要求,输出专家建议。专家系统分析结果:Detection Type: global consistencyOperator Index: 195Expert Advice: The accuracy of some tensors is low, while the final accuracy is qualified. This may be caused by Ascend internal optimization. Ignore or contact Huawei for further diagnosis.检测类型:整网一致性检测Operator Index:195专家建议:部分张量精度较低,但最终结果精度达标,可能由内部优化导致,请忽略或反馈给华为做进一步定位。整网一致性检测(一致性检测) 比对结果中的所有数据均符合精度要求,输出专家建议。专家系统分析结果:Detection Type: global consistencyOperator Index: NAExpert Advice: All data in the comparison result meets the accuracy requirements.If data accuracy of the model is still not up to standard in practical application, please check the post-processing process of model outputs.检测类型:整网一致性检测Operator Index:NA专家建议:比对结果中的所有数据均符合精度要求。如果模型实际应用中,精度依旧不达标,请排查输出数据的后处理流程。6、经验总结运行代码的时候,显示同步文件出现问题,如下。解决方法:远程python3运行环境中缺少google模块和protobuf==3.19.0模块,使用pip安装后再运行即可。 2. 单算子分析的时候,点击下面栏框显示不出来单算子分析的窗口。解决方法:确认没有报错信息的情况下,点击自己电脑的设置,调整显示屏分辨率或者缩放比例即可。Windows端的MindStudio中使用离线模型dump数据时,路径配置只能选择本地的路径,没有可选的远程路径。 解决方法:找到自己项目目录下的src/acl.json文件,手动修改JSON文件导出路径配置为远程目录的路径。配置好路径,但是运行的时候有时候会报错路径不存在。 解决方法:所有文件路径,请先确保本地存在相应路径,再同步到远程服务器中,有时候MindStudio不会自动生成路径,导致报错。7、关于MindStudio更多的内容 如果需要了解关于MindStudio更多的信息,请查阅昇腾社区中MindStudio的用户手册cid:link_4,里面有算子开发、模型开发等各种使用操作的详细介绍。 如果在使用MindStudio过程中遇到任何问题,也可以在昇腾社区中的昇腾论坛cid:link_12里进行提问,会有华为内部技术人员对其进行解答,如下图。
  • [热门活动] MindSpore论坛技术干货迁移活动:让干货再飞一次
    奖励规则​转载不同数量的个人技术干货,领取不同的奖品!·转载数量:3~5篇​·转载数量:6~10篇·转载数量:10篇以上可获得100元京东自营自选。活动时间2022年12月15日——2023年01月05日参与方式1、打开在旧论坛中的账号,截图展示账号中‘我的论坛’的信息,并截图。2、在新论坛中注册账号,请把新账号昵称和旧账号昵称设置成一致哦!3、将旧帐号中的‘技术干货’帖子转发在新论坛中。4、将截图和新发布的帖子链接回复在本活动帖下方即可。注意事项1、请勿盗用他人截图、内容等,一经发现无效参与。2、请勿在本帖下方刷帖,否则做无效处理。3、一个账号只可以参与一次。4、最终解释权归MindSpore团队所有。
  • [公告] MindSpore论坛报错活动第四期获奖名单
    第四期任务的获奖用户是:lipf702@qq.com8714604@qq.com1152040573@qq.com497776945@qq.com我们将以2335846400@qq.com的邮箱联系您,还请关注邮箱信息哦!
  • [MindX SDK] 视频伪装物体检测参考设计案例
    视频伪装物体检测1 介绍基于 MindX SDK 实现 SLT-Net 模型的推理,在 MoCA-Mask 数据集上 Sm 达到大于 0.6。输入连续几帧伪装物体的视频序列,输出伪装物体掩膜 Mask 图。1.1 支持的产品支持昇腾310芯片1.2 支持的版本支持的SDK版本:SDK3.0 RC2版本号查询方法,在Atlas产品环境下,运行命令:npu-smi info1.3 软件方案介绍本方案中,先通过 torch2onnx.py 脚本将 PyTorch 版本的伪装视频物体检测模型 SLT-Net 转换为 onnx 模型;然后通过 inference.py 脚本调用晟腾om模型,将输入视频帧进行图像处理,最终生成视频伪装物体的掩膜 Mask 图。1.4 代码目录结构与说明本sample工程名称为 VCOD_SLTNet,工程目录如下图所示:──VCOD_SLTNet ├── flowchart.jpeg ├── inference.py # 推理文件 ├── torch2onnx.py # 模型转换脚本 └── README.md本项目的代码地址为:cid:link_21.5 技术实现流程图图1 视频伪装物体检测流程图1.6 特性及适用场景对于伪装视频数据的分割任务均适用,输入视频需要转换为图片序列输入到模型中,具体可以参考 MoCA 数据格式与目录结构(如下所示),详见 SLT-Net 与 MoCA 数据集主页。--data └── TestDataset_per_sq # 测试数据集 ├── flower_crab_spider_1 # 不同场景 ├── GT # Ground Truth ├── 00000.png ├── ..... └── Imgs # 输入图片序列 ├── 00000.jpg ├── ..... ......2 环境依赖环境依赖软件和版本如下表:软件名称版本MindX SDKmxVision-3.0.RC2Python3.9.2CANN5.1RC2PyTorch1.12.1numpy1.21.5imageio2.22.3Pillow9.3.0cv24.5.5timm0.4.12tqdm4.64.13. 数据准备3.1 准备相关文件1、SLT-Net代码包准备点击访问 SLT-Net 并下载 SLT-Net-master.zip 代码压缩包,上传服务器并解压得到“SLT-Net-master”目录及文件;2、SLT-Net模型文件准备方法一:通过访问 SLT-Net 模型官方链接 下载模型压缩包 (注意,需要访问 Google Drive ),解压后将 Net_epoch_MoCA_short_term_pseudo.pth 模型拷贝至 SLT-Net-master 目录下;方法二:下载 models.zip 备份模型压缩包 并解压获得 sltnet.pth、sltnet.onnx、sltnet.om 三个模型文件,将 sltnet.pth 模型拷贝至 SLT-Net-master 目录下3、数据集准备通过访问MoCA官方链接下载 MoCA_Video 数据集,或者通过数据集备份链接来下载 MoCA_Video.zip 数据集压缩包并解压;3.2 模型转换1、SLT-Net代码预处理进入 SLT-Net-master/lib 目录下,对 __init__.py、short_term_model.py、pvtv2_afterTEM.py三个文件做以下修改:1)__init__.py文件注释如下:from .short_term_model import VideoModel as VideoModel_pvtv2 # from .long_term_model import VideoModel as VideoModel_long_term注:因为长期模型依赖 CUDA,并且需要在 CUDA 平台进行编译,而本项目基于 MindX SDK 实现,因此使用短期模型。并且,短期模型的评价指标满足预期。2)修改 short_term_model.py 文件中,如下代码行:修改def forward(self, x): image1, image2, image3 = x[:, :3], x[:, 3:6], x[:, 6:] # 替换之前的 image1, image2, image3 = x[0],x[1],x[2] fmap1=self.backbone.feat_net(image1) fmap2=self.backbone.feat_net(image2) fmap3=self.backbone.feat_net(image3)修改 def __init__(self, args): super(ImageModel, self).__init__() self.args = args # self.backbone = Network(pvtv2_pretrained=self.args.pvtv2_pretrained, imgsize=self.args.trainsize) self.backbone = Network(pvtv2_pretrained=self.args.pvtv2_pretrained, imgsize=352) # 指定图片大小 .... # self.backbone = Network(pvtv2_pretrained=False, imgsize=self.args.trainsize) self.backbone = Network(pvtv2_pretrained=False, imgsize=352) # 指定图片大小 if self.args.pretrained_cod10k is not None: self.load_backbone(self.args.pretrained_cod10k )删除if self.args.pretrained_cod10k is not None: self.load_backbone(self.args.pretrained_cod10k )3)pvtv2_afterTEM.py 文件注释如下:from timm.models import create_model #from mmseg.models import build_segmentor #from mmcv import ConfigDict import pdb修改“SLT-Net-master/mypath.py”文件如下:elif dataset == 'MoCA': return './dataset/MoCA-Mask/' # 将此处路径修改指定为“MoCA_Video”目录的相对路径可参考已经完成修改的 SLT_Net_MindXsdk_torch,也可直接使用该项目进行下面的 onnx 模型转换操作,替代以上步骤。2、模型转换步骤一、pth模型转onnx模型将 VCOD_SLTNet 代码包中的 torch2onnx.py 脚本拷贝至 SLT-Net-master 目录下,并在 SLT-Net-master 目录下执行以下命令将 pth 模型转换成 onnx 模型:python torch2onnx.py --pth_path ${pth模型文件路径} --onnx_path ./sltnet.onnx参数说明:pth_path:pth模型文件名称及所在路径onnx_path:生成输出的onnx模型文件注意,timm 的版本为 0.4.12,其他版本可能有兼容性问题。步骤二、简化onnx文件(可选操作)python -m onnxsim --input-shape="1,9,352,352" --dynamic-input-shape sltnet.onnx sltnet_sim.onnx步骤三、onnx模型转om模型atc --framework=5 --model=sltnet.onnx --output=sltnet --input_shape="image:1,9,352,352" --soc_version=Ascend310 --log=error注意:若想使用转换好的onnx模型或om模型,可通过下载 models.zip备份模型压缩包 解压获得转换好的 onnx 模型或 om 模型。pth模型转onnx模型,onnx模型转om模型,均可能花费约1小时左右,视不同运行环境而定。如无报错,请耐心等待。4. 运行推理使用如下命令,运行 inference.py 脚本:python inference.py --datapath ${MoCA_Video数据集路径} --save_root ./results/ --om_path ./sltnet.om --testsize 352 --device_id 0参数说明:datapath:下载数据以后,目录中 TestDataset_per_sq 的上一级目录,save_root:结果保存路径om_path:om 模型路径testsize:图片 resize 的大小,当前固定为 352device_id:设备编号注意,该脚本无需放入修改的 SLT-Net 目录,在任意位置均可执行,只需设置好上述参数即可。运行输出如下: 0%| | 0/713 [00:00<?, ?it/s]> ./results/arctic_fox/Pred/00000.png 0%|▏ | 1/713 [00:00<10:31, 1.13it/s]> ./results/arctic_fox/Pred/00005.png 0%|▎ | 2/713 [00:01<09:01, 1.31it/s]> ./results/arctic_fox/Pred/00010.png 0%|▍ | 3/713 [00:02<08:30, 1.39it/s]> ./results/arctic_fox/Pred/00015.png 1%|▌ | 4/713 [00:02<08:13, 1.44it/s]> ./results/arctic_fox/Pred/00020.png将展示剩余运行时间以及生成图片的路径。5. 精度评估点击访问 SLT_Net_MindXsdk_torch 并下载 SLT_Net_MindXsdk_torch-master.zip 代码压缩包,上传服务器并解压获得 SLT_Net_MindXsdk_torch-master 目录及相关文件;进入 SLT_Net_MindXsdk_torch-master 目录,修改 eval_python/run_eval.py 脚本中的 gt_dir 为本地的 MoCA_Video/TestDataset_per_sq/ 目录的绝对路径,pred_dir 为预测结果目录的绝对路径,并执行以下命令进行精度评估:python eval_python/run_eval.py完成评估后的结果如下:{'Smeasure': 0.6539, 'wFmeasure': 0.3245, 'MAE': 0.0161, 'adpEm': 0.6329, 'meanEm': 0.7229, 'maxEm': 0.7554, 'adpFm': 0.3025, 'meanFm': 0.3577, 'maxFm': 0.3738}评测结果高于交付所要求的 Smeasure 0.6 的指标。注:评估还可参考基于 基于 MATLAB 的 SLT-Net 的评测代码或参考基于 Python 的 PySODEvalToolkit 的评测代码。
  • [执行问题] 关于在mindspore中实现一些RL算法时遇到的问题
    在mindspore中实现一些RL算法时,我首先需要让模型前向计算得到某个action,再让环境执行action得到reward计算loss。由于该环境比较复杂,我无法将其纳入计算图中,导致我无法构建grad_fn。请问在这种情况下如何计算梯度?
  • [公告] MindSpore论坛报错活动第三期获奖名单
    第三期任务的获奖用户是:756625088@qq.com8714604@qq.com461084847@qq.com497776945@qq.com我们将以2335846400@qq.com的邮箱联系您!第四期正在活动中哦,欢迎参与MindSpore论坛报错活动第四期!
  • [问题求助] 在modelaets上训练官方模型yolov5时,自定义数据集的路径找不到(确认过OBS路径没有错),怀疑是相对路径配置得不对
    loading annotations into memory...Traceback (most recent call last):File "/home/ma-user/modelarts/user-job-dir/yolo/code/yolov5/train_start.py", line 153, inrun_train()File "/home/ma-user/modelarts/user-job-dir/yolo/code/yolov5/model_utils/moxing_adapter.py", line 167, in wrapped_funcrun_func(*args, **kwargs)File "/home/ma-user/modelarts/user-job-dir/yolo/code/yolov5/train_start.py", line 103, in run_trainrank=config.rank, config=config)File "/home/ma-user/modelarts/user-job-dir/yolo/code/yolov5/src/yolo_dataset.py", line 240, in create_yolo_datasetremove_images_without_annotations=remove_empty_anno, is_training=is_training)File "/home/ma-user/modelarts/user-job-dir/yolo/code/yolov5/src/yolo_dataset.py", line 62, in __init__self.coco = COCO(ann_file)File "/home/ma-user/anaconda/lib/python3.7/site-packages/pycocotools/coco.py", line 84, in __init__dataset = json.load(open(annotation_file, 'r'))FileNotFoundError: [Errno 2] No such file or directory: '/dataset/YOLOv5/annotations/train.json'
总条数:3176 到第
上滑加载中