From 7eb0c7fb38234f6b049b157517d5bcce6ff5f6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 07:33:20 +0000 Subject: [PATCH 01/40] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20Segformer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ACL_PyTorch/contrib/cv/segmentation/Segformer/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/.keep diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/.keep b/ACL_PyTorch/contrib/cv/segmentation/Segformer/.keep new file mode 100644 index 0000000000..e69de29bb2 -- Gitee From 9805ed8fc941b1f638f655b31f00cd34cd735539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 07:40:43 +0000 Subject: [PATCH 02/40] update --- .../Segformer/Segformer_postprocess.py | 238 ++++++++++++++++++ .../Segformer/Segformer_preprocess.py | 84 +++++++ .../contrib/cv/segmentation/Segformer/env.sh | 9 + .../cv/segmentation/Segformer/get_info.py | 62 +++++ 4 files changed, 393 insertions(+) create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/env.sh create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py new file mode 100644 index 0000000000..fc1726ec82 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py @@ -0,0 +1,238 @@ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import torch +import argparse +import os +from PIL import Image + + +class gtFineFile(object): + """ + directory: path to gtFine + suffix: suffix of the gtFine + return path List of gtFine files + """ + def __init__(self, directory, suffix='_gtFine_labelTrainIds.png'): + gtFine_list = [] + # file_count = 0 # 记录找到的后缀为 _gtFine_labelTrainIds.png 的文件总数 + for root, dirs, files in os.walk(directory): + for special_file in files: + if special_file.endswith(suffix): + gtFine_list.append(os.path.join(root, special_file)) + # file_count += 1 + # print("Found gtFine files:", os.path.join(root, special_file)) + # print("total count of gtFine files is:", file_count) + self.gtFine_list = gtFine_list + + def get_file(self, filename): + """ return file path list """ + for file in self.gtFine_list: + if file.endswith(filename): + return file + + +def intersect_and_union(pred_label, + label, + num_classes, + ignore_index, + label_map=dict(), + reduce_zero_label=False): + """Calculate intersection and Union. + + Args: + pred_label (ndarray | str): Prediction segmentation map + or predict result filename. + label (ndarray): Ground truth segmentation map. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + label_map (dict): Mapping old labels to new labels. The parameter will + work only when label is str. Default: dict(). + reduce_zero_label (bool): Wether ignore zero label. The parameter will + work only when label is str. Default: False. + + Returns: + torch.Tensor: The intersection of prediction and ground truth + histogram on all classes. + torch.Tensor: The union of prediction and ground truth histogram on + all classes. + torch.Tensor: The prediction histogram on all classes. + torch.Tensor: The ground truth histogram on all classes. + """ + + if isinstance(pred_label, str): + pred_label = torch.from_numpy(np.load(pred_label)) + else: + pred_label = torch.from_numpy((pred_label)) + + label = torch.from_numpy(label) + + if label_map is not None: + for old_id, new_id in label_map.items(): + label[label == old_id] = new_id + if reduce_zero_label: + label[label == 0] = 255 + label = label - 1 + label[label == 254] = 255 + + mask = (label != ignore_index) + pred_label = pred_label[mask] + label = label[mask] + + intersect = pred_label[pred_label == label] + area_intersect = torch.histc( + intersect.float(), bins=(num_classes), min=0, max=num_classes - 1) + area_pred_label = torch.histc( + pred_label.float(), bins=(num_classes), min=0, max=num_classes - 1) + area_label = torch.histc( + label.float(), bins=(num_classes), min=0, max=num_classes - 1) + area_union = area_pred_label + area_label - area_intersect + return [area_intersect, area_union, area_pred_label, area_label] + + +class IntersectAndUnion(object): + """Calculate Total Intersection and Union. + + Args: + results (list[ndarray] | list[str]): List of prediction segmentation + maps or list of prediction result filenames. + gt_seg_maps (list[ndarray] | list[str]): list of ground truth + segmentation maps or list of label filenames. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + label_map (dict): Mapping old labels to new labels. Default: dict(). + reduce_zero_label (bool): Whether ignore zero label. Default: False. + + Returns: + IoU + Acc + """ + + def __init__(self, num_classes, ignore_index, label_map=dict(), reduce_zero_label=False): + self.num_classes = num_classes + self.ignore_index = ignore_index + self.label_map = label_map + self.reduce_zero_label = reduce_zero_label + self.total_area_intersect = torch.zeros((num_classes,), dtype=torch.float64) + self.total_area_union = torch.zeros((num_classes,), dtype=torch.float64) + self.total_area_pred_label = torch.zeros((num_classes,), dtype=torch.float64) + self.total_area_label = torch.zeros((num_classes,), dtype=torch.float64) + + def update(self, output, gt_seg_map): + """ update """ + [area_intersect, area_union, area_pred_label, area_label] = \ + intersect_and_union( + output, gt_seg_map, self.num_classes, self.ignore_index, + self.label_map, self.reduce_zero_label) + self.total_area_intersect += area_intersect.to(torch.float64) + self.total_area_union += area_union.to(torch.float64) + self.total_area_pred_label += area_pred_label.to(torch.float64) + self.total_area_label += area_label.to(torch.float64) + + def get(self): + """ get result """ + iou = self.total_area_intersect / self.total_area_union + acc = self.total_area_intersect / self.total_area_label + all_acc = self.total_area_intersect.sum() / self.total_area_label.sum() + mIoU = np.round(np.nanmean(iou) * 100, 2) + aAcc = np.round(np.nanmean(all_acc) * 100, 2) + return {'aAcc': aAcc, 'mIoU': mIoU} + + +def eval_metrics(output_path, + gt_path, + out_suffix='_leftImg8bit_output_0.bin', + gt_suffix='_gtFine_labelTrainIds.png', + result_path='./postprocess_result', + num_classes=19, + ignore_index=255, + label_map=None, + reduce_zero_label=False): + """Calculate evaluation metrics + Args: + results (list[ndarray] | list[str]): List of prediction segmentation + maps or list of prediction result filenames. + gt_seg_maps (list[ndarray] | list[str]): list of ground truth + segmentation maps or list of label filenames. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + metrics (list[str] | str): Metrics to be evaluated, 'mIoU' and 'mDice'. + nan_to_num (int, optional): If specified, NaN values will be replaced + by the numbers defined by the user. Default: None. + label_map (dict): Mapping old labels to new labels. Default: dict(). + reduce_zero_label (bool): Wether ignore zero label. Default: False. + Returns: + float: Overall accuracy on all images. + ndarray: Per category accuracy, shape (num_classes, ). + ndarray: Per category evaluation metrics, shape (num_classes, ). + """ + + # initial metric + metric = IntersectAndUnion(num_classes, ignore_index, label_map, reduce_zero_label) + + # initial gtFine files list + fileFinder = gtFineFile(gt_path) + + for root, dirs, files in os.walk(output_path): + files = [file for file in files if str(file).endswith('bin')] # 找到 bin 文件,形成列表赋给 files + len = str(files.__len__()) # bin 文件总数 + for i, output_name in enumerate(files): + if not str(output_name).endswith('bin'): # 跳过非 bin 文件 + continue + print('Segformer metric [' + str(i + 1) + '/' + len + '] on process: ' + output_name) # 当前进度 + # 将 output_name 中的字符串 out_suffix 替换成 gt_suffix + seg_map_name = str(output_name).replace(out_suffix, gt_suffix) + # print("output_name :", output_name) + # print("seg_map_name :", seg_map_name) + seg_map_path = fileFinder.get_file(seg_map_name) # 从 gtFineFile 类对象中获取文件对应路径 + if seg_map_name is not None: + seg_map = Image.open(seg_map_path) + seg_map = np.array(seg_map, dtype=np.uint8) + + output_path = os.path.realpath(os.path.join(root, output_name)) + output = np.fromfile(output_path, dtype=np.uint64).reshape(1024, 2048) + output = output.astype(np.uint8) + metric.update(output, seg_map) + else: + print("[ERROR] " + seg_map_name + " not find, check the file or make sure --out_suffix") + + # get result + result = metric.get() + print(result) + with open(result_path + '.txt', 'w') as f: + f.write('aAcc: {}\n'.format(result['aAcc'])) + f.write('mIoU: {}\n'.format(result['mIoU'])) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser('mIoU calculate') + parser.add_argument('--output_path', default="./result", + help='path to om/onnx output file, default ./result') + parser.add_argument('--gt_path', default="/opt/npu/cityscapes/gtFine/val", + help='path to gtFine/val, default /opt/npu/cityscapes/gtFine/val') + parser.add_argument('--out_suffix', default="_leftImg8bit_output_0.bin", + help='suffix of the om/onnx output, default "_leftImg8bit_output_0.bin"') + parser.add_argument('--result_path', default="./postprocess_result", + help='path to save the script result, default ./postprocess_result.txt') + + args = parser.parse_args() + + output_path = os.path.realpath(args.output_path) + gt_path = os.path.realpath(args.gt_path) + out_suffix = args.out_suffix + result_path = os.path.realpath(args.result_path) + print("output_path :", output_path) + print("gt_path :", gt_path) + eval_metrics(output_path, gt_path, out_suffix = out_suffix, result_path = result_path) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py new file mode 100644 index 0000000000..004626848b --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py @@ -0,0 +1,84 @@ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os +import cv2 +import numpy as np +from torchvision import transforms + + +class Normalize(object): + def __init__(self, mean, std, to_rgb=True): + self.mean = np.array(mean, dtype=np.float32) + self.std = np.array(std, dtype=np.float32) + self.to_rgb = to_rgb + + def __call__(self, img): + img = img.copy().astype(np.float32) + # cv2 inplace normalization does not accept uint8 + assert img.dtype != np.uint8 + mean = np.float64(self.mean.reshape(1, -1)) + stdinv = 1 / np.float64(self.std.reshape(1, -1)) + if self.to_rgb: + cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) # inplace + cv2.subtract(img, mean, img) # inplace + cv2.multiply(img, stdinv, img) # inplace + return img + + +def preprocess(src_path, save_path): + preprocess = transforms.Compose([ + Normalize(mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True), + transforms.ToTensor(), + ]) + + root = src_path + + def _scandir(dir_path, suffix, recursive): + for entry in os.scandir(dir_path): + if not entry.name.startswith('.') and entry.is_file(): + rel_path = os.path.relpath(entry.path, root) + if suffix is None or rel_path.endswith(suffix): + yield rel_path + elif recursive and os.path.isdir(entry.path): + # scan recursively if entry.path is a directory + yield from _scandir( + entry.path, suffix=suffix, recursive=recursive) + + in_files = _scandir(src_path, '_leftImg8bit.png', True) + if not os.path.exists(save_path): + os.makedirs(save_path) + + i = 0 + for file in in_files: + i = i + 1 + print(file, "====", i) + input_image = cv2.imread(src_path + '/' + file) + input_tensor = preprocess(input_image) + # print(file.split('/')[-1].split('.')[0]) + # print(input_tensor) + img = np.array(input_tensor).astype(np.float32) + # print(img.shape) + img.tofile(os.path.join(save_path, file.split('/')[-1].split('.')[0] + ".bin")) + + +if __name__ == '__main__': + if len(sys.argv) < 3: + raise Exception("usage: python xxx.py [src_path] [save_path]") + src_path = sys.argv[1] + save_path = sys.argv[2] + src_path = os.path.realpath(src_path) + save_path = os.path.realpath(save_path) + preprocess(src_path, save_path) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/env.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/env.sh new file mode 100644 index 0000000000..1c7c13700a --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/env.sh @@ -0,0 +1,9 @@ +# env.sh + +source /usr/local/Ascend/ascend-toolkit/set_env.sh + +# 将atc日志打印到屏幕 +export ASCEND_SLOG_PRINT_TO_STDOUT=0 + +# 设置日志级别 +export ASCEND_GLOBAL_LOG_LEVEL=0 # debug 0 --> info 1 --> warning 2 --> error 3 diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py new file mode 100644 index 0000000000..84a8405444 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py @@ -0,0 +1,62 @@ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License.s + +import os +import sys +import cv2 +from glob import glob + + +def get_bin_info(file_path, info_name, width, height): + bin_images = glob(os.path.join(file_path, '*.bin')) + with open(info_name, 'w') as file: + for index, img in enumerate(bin_images): + content = ' '.join([str(index), img, width, height]) + file.write(content) + file.write('\n') + + +def get_jpg_info(file_path, info_name): + extensions = ['jpg', 'jpeg', 'JPG', 'JPEG'] + image_names = [] + for extension in extensions: + image_names.append(glob(os.path.join(file_path, '*.' + extension))) + with open(info_name, 'w') as file: + for image_name in image_names: + if len(image_name) == 0: + continue + else: + for index, img in enumerate(image_name): + img_cv = cv2.imread(img) + shape = img_cv.shape + width, height = shape[1], shape[0] + content = ' '.join([str(index), img, str(width), str(height)]) + file.write(content) + file.write('\n') + + +if __name__ == '__main__': + file_type = sys.argv[1] + file_path = sys.argv[2] + info_name = sys.argv[3] + if file_type == 'bin': + width = sys.argv[4] + height = sys.argv[5] + assert len(sys.argv) == 6, 'The number of input parameters must be equal to 5' + get_bin_info(file_path, info_name, width, height) + elif file_type == 'jpg': + assert len(sys.argv) == 4, 'The number of input parameters must be equal to 3' + get_jpg_info(file_path, info_name) + +# python get_info.py bin ./prep_dataset ./prep_bin.info 640 640 \ No newline at end of file -- Gitee From 3d97b71160a99a70b2af67b5be0b795a6b6d75ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 07:40:56 +0000 Subject: [PATCH 03/40] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20AC?= =?UTF-8?q?L=5FPyTorch/contrib/cv/segmentation/Segformer/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ACL_PyTorch/contrib/cv/segmentation/Segformer/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/.keep diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/.keep b/ACL_PyTorch/contrib/cv/segmentation/Segformer/.keep deleted file mode 100644 index e69de29bb2..0000000000 -- Gitee From 8827c9b0cc2c3f7c4c1f1d81e0efb5f117438dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 08:01:10 +0000 Subject: [PATCH 04/40] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20AC?= =?UTF-8?q?L=5FPyTorch/contrib/cv/segmentation/Segformer/Segformer=5Fprepr?= =?UTF-8?q?ocess.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Segformer/Segformer_preprocess.py | 84 ------------------- 1 file changed, 84 deletions(-) delete mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py deleted file mode 100644 index 004626848b..0000000000 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys -import os -import cv2 -import numpy as np -from torchvision import transforms - - -class Normalize(object): - def __init__(self, mean, std, to_rgb=True): - self.mean = np.array(mean, dtype=np.float32) - self.std = np.array(std, dtype=np.float32) - self.to_rgb = to_rgb - - def __call__(self, img): - img = img.copy().astype(np.float32) - # cv2 inplace normalization does not accept uint8 - assert img.dtype != np.uint8 - mean = np.float64(self.mean.reshape(1, -1)) - stdinv = 1 / np.float64(self.std.reshape(1, -1)) - if self.to_rgb: - cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) # inplace - cv2.subtract(img, mean, img) # inplace - cv2.multiply(img, stdinv, img) # inplace - return img - - -def preprocess(src_path, save_path): - preprocess = transforms.Compose([ - Normalize(mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True), - transforms.ToTensor(), - ]) - - root = src_path - - def _scandir(dir_path, suffix, recursive): - for entry in os.scandir(dir_path): - if not entry.name.startswith('.') and entry.is_file(): - rel_path = os.path.relpath(entry.path, root) - if suffix is None or rel_path.endswith(suffix): - yield rel_path - elif recursive and os.path.isdir(entry.path): - # scan recursively if entry.path is a directory - yield from _scandir( - entry.path, suffix=suffix, recursive=recursive) - - in_files = _scandir(src_path, '_leftImg8bit.png', True) - if not os.path.exists(save_path): - os.makedirs(save_path) - - i = 0 - for file in in_files: - i = i + 1 - print(file, "====", i) - input_image = cv2.imread(src_path + '/' + file) - input_tensor = preprocess(input_image) - # print(file.split('/')[-1].split('.')[0]) - # print(input_tensor) - img = np.array(input_tensor).astype(np.float32) - # print(img.shape) - img.tofile(os.path.join(save_path, file.split('/')[-1].split('.')[0] + ".bin")) - - -if __name__ == '__main__': - if len(sys.argv) < 3: - raise Exception("usage: python xxx.py [src_path] [save_path]") - src_path = sys.argv[1] - save_path = sys.argv[2] - src_path = os.path.realpath(src_path) - save_path = os.path.realpath(save_path) - preprocess(src_path, save_path) -- Gitee From a6fd74d2a4f10d8a6642172c8b4689b5a76dabf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 08:01:22 +0000 Subject: [PATCH 05/40] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20AC?= =?UTF-8?q?L=5FPyTorch/contrib/cv/segmentation/Segformer/Segformer=5Fpostp?= =?UTF-8?q?rocess.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Segformer/Segformer_postprocess.py | 238 ------------------ 1 file changed, 238 deletions(-) delete mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py deleted file mode 100644 index fc1726ec82..0000000000 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py +++ /dev/null @@ -1,238 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import numpy as np -import torch -import argparse -import os -from PIL import Image - - -class gtFineFile(object): - """ - directory: path to gtFine - suffix: suffix of the gtFine - return path List of gtFine files - """ - def __init__(self, directory, suffix='_gtFine_labelTrainIds.png'): - gtFine_list = [] - # file_count = 0 # 记录找到的后缀为 _gtFine_labelTrainIds.png 的文件总数 - for root, dirs, files in os.walk(directory): - for special_file in files: - if special_file.endswith(suffix): - gtFine_list.append(os.path.join(root, special_file)) - # file_count += 1 - # print("Found gtFine files:", os.path.join(root, special_file)) - # print("total count of gtFine files is:", file_count) - self.gtFine_list = gtFine_list - - def get_file(self, filename): - """ return file path list """ - for file in self.gtFine_list: - if file.endswith(filename): - return file - - -def intersect_and_union(pred_label, - label, - num_classes, - ignore_index, - label_map=dict(), - reduce_zero_label=False): - """Calculate intersection and Union. - - Args: - pred_label (ndarray | str): Prediction segmentation map - or predict result filename. - label (ndarray): Ground truth segmentation map. - num_classes (int): Number of categories. - ignore_index (int): Index that will be ignored in evaluation. - label_map (dict): Mapping old labels to new labels. The parameter will - work only when label is str. Default: dict(). - reduce_zero_label (bool): Wether ignore zero label. The parameter will - work only when label is str. Default: False. - - Returns: - torch.Tensor: The intersection of prediction and ground truth - histogram on all classes. - torch.Tensor: The union of prediction and ground truth histogram on - all classes. - torch.Tensor: The prediction histogram on all classes. - torch.Tensor: The ground truth histogram on all classes. - """ - - if isinstance(pred_label, str): - pred_label = torch.from_numpy(np.load(pred_label)) - else: - pred_label = torch.from_numpy((pred_label)) - - label = torch.from_numpy(label) - - if label_map is not None: - for old_id, new_id in label_map.items(): - label[label == old_id] = new_id - if reduce_zero_label: - label[label == 0] = 255 - label = label - 1 - label[label == 254] = 255 - - mask = (label != ignore_index) - pred_label = pred_label[mask] - label = label[mask] - - intersect = pred_label[pred_label == label] - area_intersect = torch.histc( - intersect.float(), bins=(num_classes), min=0, max=num_classes - 1) - area_pred_label = torch.histc( - pred_label.float(), bins=(num_classes), min=0, max=num_classes - 1) - area_label = torch.histc( - label.float(), bins=(num_classes), min=0, max=num_classes - 1) - area_union = area_pred_label + area_label - area_intersect - return [area_intersect, area_union, area_pred_label, area_label] - - -class IntersectAndUnion(object): - """Calculate Total Intersection and Union. - - Args: - results (list[ndarray] | list[str]): List of prediction segmentation - maps or list of prediction result filenames. - gt_seg_maps (list[ndarray] | list[str]): list of ground truth - segmentation maps or list of label filenames. - num_classes (int): Number of categories. - ignore_index (int): Index that will be ignored in evaluation. - label_map (dict): Mapping old labels to new labels. Default: dict(). - reduce_zero_label (bool): Whether ignore zero label. Default: False. - - Returns: - IoU - Acc - """ - - def __init__(self, num_classes, ignore_index, label_map=dict(), reduce_zero_label=False): - self.num_classes = num_classes - self.ignore_index = ignore_index - self.label_map = label_map - self.reduce_zero_label = reduce_zero_label - self.total_area_intersect = torch.zeros((num_classes,), dtype=torch.float64) - self.total_area_union = torch.zeros((num_classes,), dtype=torch.float64) - self.total_area_pred_label = torch.zeros((num_classes,), dtype=torch.float64) - self.total_area_label = torch.zeros((num_classes,), dtype=torch.float64) - - def update(self, output, gt_seg_map): - """ update """ - [area_intersect, area_union, area_pred_label, area_label] = \ - intersect_and_union( - output, gt_seg_map, self.num_classes, self.ignore_index, - self.label_map, self.reduce_zero_label) - self.total_area_intersect += area_intersect.to(torch.float64) - self.total_area_union += area_union.to(torch.float64) - self.total_area_pred_label += area_pred_label.to(torch.float64) - self.total_area_label += area_label.to(torch.float64) - - def get(self): - """ get result """ - iou = self.total_area_intersect / self.total_area_union - acc = self.total_area_intersect / self.total_area_label - all_acc = self.total_area_intersect.sum() / self.total_area_label.sum() - mIoU = np.round(np.nanmean(iou) * 100, 2) - aAcc = np.round(np.nanmean(all_acc) * 100, 2) - return {'aAcc': aAcc, 'mIoU': mIoU} - - -def eval_metrics(output_path, - gt_path, - out_suffix='_leftImg8bit_output_0.bin', - gt_suffix='_gtFine_labelTrainIds.png', - result_path='./postprocess_result', - num_classes=19, - ignore_index=255, - label_map=None, - reduce_zero_label=False): - """Calculate evaluation metrics - Args: - results (list[ndarray] | list[str]): List of prediction segmentation - maps or list of prediction result filenames. - gt_seg_maps (list[ndarray] | list[str]): list of ground truth - segmentation maps or list of label filenames. - num_classes (int): Number of categories. - ignore_index (int): Index that will be ignored in evaluation. - metrics (list[str] | str): Metrics to be evaluated, 'mIoU' and 'mDice'. - nan_to_num (int, optional): If specified, NaN values will be replaced - by the numbers defined by the user. Default: None. - label_map (dict): Mapping old labels to new labels. Default: dict(). - reduce_zero_label (bool): Wether ignore zero label. Default: False. - Returns: - float: Overall accuracy on all images. - ndarray: Per category accuracy, shape (num_classes, ). - ndarray: Per category evaluation metrics, shape (num_classes, ). - """ - - # initial metric - metric = IntersectAndUnion(num_classes, ignore_index, label_map, reduce_zero_label) - - # initial gtFine files list - fileFinder = gtFineFile(gt_path) - - for root, dirs, files in os.walk(output_path): - files = [file for file in files if str(file).endswith('bin')] # 找到 bin 文件,形成列表赋给 files - len = str(files.__len__()) # bin 文件总数 - for i, output_name in enumerate(files): - if not str(output_name).endswith('bin'): # 跳过非 bin 文件 - continue - print('Segformer metric [' + str(i + 1) + '/' + len + '] on process: ' + output_name) # 当前进度 - # 将 output_name 中的字符串 out_suffix 替换成 gt_suffix - seg_map_name = str(output_name).replace(out_suffix, gt_suffix) - # print("output_name :", output_name) - # print("seg_map_name :", seg_map_name) - seg_map_path = fileFinder.get_file(seg_map_name) # 从 gtFineFile 类对象中获取文件对应路径 - if seg_map_name is not None: - seg_map = Image.open(seg_map_path) - seg_map = np.array(seg_map, dtype=np.uint8) - - output_path = os.path.realpath(os.path.join(root, output_name)) - output = np.fromfile(output_path, dtype=np.uint64).reshape(1024, 2048) - output = output.astype(np.uint8) - metric.update(output, seg_map) - else: - print("[ERROR] " + seg_map_name + " not find, check the file or make sure --out_suffix") - - # get result - result = metric.get() - print(result) - with open(result_path + '.txt', 'w') as f: - f.write('aAcc: {}\n'.format(result['aAcc'])) - f.write('mIoU: {}\n'.format(result['mIoU'])) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser('mIoU calculate') - parser.add_argument('--output_path', default="./result", - help='path to om/onnx output file, default ./result') - parser.add_argument('--gt_path', default="/opt/npu/cityscapes/gtFine/val", - help='path to gtFine/val, default /opt/npu/cityscapes/gtFine/val') - parser.add_argument('--out_suffix', default="_leftImg8bit_output_0.bin", - help='suffix of the om/onnx output, default "_leftImg8bit_output_0.bin"') - parser.add_argument('--result_path', default="./postprocess_result", - help='path to save the script result, default ./postprocess_result.txt') - - args = parser.parse_args() - - output_path = os.path.realpath(args.output_path) - gt_path = os.path.realpath(args.gt_path) - out_suffix = args.out_suffix - result_path = os.path.realpath(args.result_path) - print("output_path :", output_path) - print("gt_path :", gt_path) - eval_metrics(output_path, gt_path, out_suffix = out_suffix, result_path = result_path) -- Gitee From b2bdca55e7a31e775b603bcdf954dd2e8fcfc98d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 08:01:49 +0000 Subject: [PATCH 06/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py. --- ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py index 84a8405444..dbd364055d 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py @@ -1,4 +1,4 @@ -# Copyright 2021 Huawei Technologies Co., Ltd +# Copyright 2022 Huawei Technologies Co., Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -59,4 +59,4 @@ if __name__ == '__main__': assert len(sys.argv) == 4, 'The number of input parameters must be equal to 3' get_jpg_info(file_path, info_name) -# python get_info.py bin ./prep_dataset ./prep_bin.info 640 640 \ No newline at end of file +# python get_info.py bin ./prep_dataset ./prep_bin.info 1024 2048 \ No newline at end of file -- Gitee From eeb714189760ebeaa398e1b4182aa72df5610d67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 08:02:14 +0000 Subject: [PATCH 07/40] update --- .../Segformer/Segformer_postprocess.py | 234 ++++++++++++++++++ .../Segformer/Segformer_preprocess.py | 84 +++++++ .../segmentation/Segformer/requirements.txt | 7 + 3 files changed, 325 insertions(+) create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/requirements.txt diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py new file mode 100644 index 0000000000..be0ea03149 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py @@ -0,0 +1,234 @@ +# Copyright 2022 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import torch +import argparse +import os +from PIL import Image + + +class gtFineFile(object): + """ + directory: path to gtFine + suffix: suffix of the gtFine + return path List of gtFine files + """ + def __init__(self, directory, suffix='_gtFine_labelTrainIds.png'): + gtFine_list = [] + for root, dirs, files in os.walk(directory): + for special_file in files: + if special_file.endswith(suffix): + gtFine_list.append(os.path.join(root, special_file)) + # print("Found gtFine files:", os.path.join(root, special_file)) + self.gtFine_list = gtFine_list + + def get_file(self, filename): + """ return file path list """ + for file in self.gtFine_list: + if file.endswith(filename): + return file + + +def intersect_and_union(pred_label, + label, + num_classes, + ignore_index, + label_map=dict(), + reduce_zero_label=False): + """Calculate intersection and Union. + + Args: + pred_label (ndarray | str): Prediction segmentation map + or predict result filename. + label (ndarray): Ground truth segmentation map. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + label_map (dict): Mapping old labels to new labels. The parameter will + work only when label is str. Default: dict(). + reduce_zero_label (bool): Wether ignore zero label. The parameter will + work only when label is str. Default: False. + + Returns: + torch.Tensor: The intersection of prediction and ground truth + histogram on all classes. + torch.Tensor: The union of prediction and ground truth histogram on + all classes. + torch.Tensor: The prediction histogram on all classes. + torch.Tensor: The ground truth histogram on all classes. + """ + + if isinstance(pred_label, str): + pred_label = torch.from_numpy(np.load(pred_label)) + else: + pred_label = torch.from_numpy((pred_label)) + + label = torch.from_numpy(label) + + if label_map is not None: + for old_id, new_id in label_map.items(): + label[label == old_id] = new_id + if reduce_zero_label: + label[label == 0] = 255 + label = label - 1 + label[label == 254] = 255 + + mask = (label != ignore_index) + pred_label = pred_label[mask] + label = label[mask] + + intersect = pred_label[pred_label == label] + area_intersect = torch.histc( + intersect.float(), bins=(num_classes), min=0, max=num_classes - 1) + area_pred_label = torch.histc( + pred_label.float(), bins=(num_classes), min=0, max=num_classes - 1) + area_label = torch.histc( + label.float(), bins=(num_classes), min=0, max=num_classes - 1) + area_union = area_pred_label + area_label - area_intersect + return [area_intersect, area_union, area_pred_label, area_label] + + +class IntersectAndUnion(object): + """Calculate Total Intersection and Union. + + Args: + results (list[ndarray] | list[str]): List of prediction segmentation + maps or list of prediction result filenames. + gt_seg_maps (list[ndarray] | list[str]): list of ground truth + segmentation maps or list of label filenames. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + label_map (dict): Mapping old labels to new labels. Default: dict(). + reduce_zero_label (bool): Whether ignore zero label. Default: False. + + Returns: + IoU + Acc + """ + + def __init__(self, num_classes, ignore_index, label_map=dict(), reduce_zero_label=False): + self.num_classes = num_classes + self.ignore_index = ignore_index + self.label_map = label_map + self.reduce_zero_label = reduce_zero_label + self.total_area_intersect = torch.zeros((num_classes,), dtype=torch.float64) + self.total_area_union = torch.zeros((num_classes,), dtype=torch.float64) + self.total_area_pred_label = torch.zeros((num_classes,), dtype=torch.float64) + self.total_area_label = torch.zeros((num_classes,), dtype=torch.float64) + + def update(self, output, gt_seg_map): + """ update """ + [area_intersect, area_union, area_pred_label, area_label] = \ + intersect_and_union( + output, gt_seg_map, self.num_classes, self.ignore_index, + self.label_map, self.reduce_zero_label) + self.total_area_intersect += area_intersect.to(torch.float64) + self.total_area_union += area_union.to(torch.float64) + self.total_area_pred_label += area_pred_label.to(torch.float64) + self.total_area_label += area_label.to(torch.float64) + + def get(self): + """ get result """ + iou = self.total_area_intersect / self.total_area_union + acc = self.total_area_intersect / self.total_area_label + all_acc = self.total_area_intersect.sum() / self.total_area_label.sum() + mIoU = np.round(np.nanmean(iou) * 100, 2) + aAcc = np.round(np.nanmean(all_acc) * 100, 2) + return {'aAcc': aAcc, 'mIoU': mIoU} + + +def eval_metrics(output_path, + gt_path, + out_suffix='_leftImg8bit_output_0.bin', + gt_suffix='_gtFine_labelTrainIds.png', + result_path='./postprocess_result', + num_classes=19, + ignore_index=255, + label_map=None, + reduce_zero_label=False): + """Calculate evaluation metrics + Args: + results (list[ndarray] | list[str]): List of prediction segmentation + maps or list of prediction result filenames. + gt_seg_maps (list[ndarray] | list[str]): list of ground truth + segmentation maps or list of label filenames. + num_classes (int): Number of categories. + ignore_index (int): Index that will be ignored in evaluation. + metrics (list[str] | str): Metrics to be evaluated, 'mIoU' and 'mDice'. + nan_to_num (int, optional): If specified, NaN values will be replaced + by the numbers defined by the user. Default: None. + label_map (dict): Mapping old labels to new labels. Default: dict(). + reduce_zero_label (bool): Wether ignore zero label. Default: False. + Returns: + float: Overall accuracy on all images. + ndarray: Per category accuracy, shape (num_classes, ). + ndarray: Per category evaluation metrics, shape (num_classes, ). + """ + + # initial metric + metric = IntersectAndUnion(num_classes, ignore_index, label_map, reduce_zero_label) + + # initial gtFine files list + fileFinder = gtFineFile(gt_path) + + for root, dirs, files in os.walk(output_path): + files = [file for file in files if str(file).endswith('bin')] + len = str(files.__len__()) + for i, output_name in enumerate(files): + if not str(output_name).endswith('bin'): + continue + print('Segformer metric [' + str(i + 1) + '/' + len + '] on process: ' + output_name) + seg_map_name = str(output_name).replace(out_suffix, gt_suffix) + # print("output_name :", output_name) + # print("seg_map_name :", seg_map_name) + seg_map_path = fileFinder.get_file(seg_map_name) + if seg_map_name is not None: + seg_map = Image.open(seg_map_path) + seg_map = np.array(seg_map, dtype=np.uint8) + + output_path = os.path.realpath(os.path.join(root, output_name)) + output = np.fromfile(output_path, dtype=np.uint64).reshape(1024, 2048) + output = output.astype(np.uint8) + metric.update(output, seg_map) + else: + print("[ERROR] " + seg_map_name + " not find, check the file or make sure --out_suffix") + + # get result + result = metric.get() + print(result) + with open(result_path + '.txt', 'w') as f: + f.write('aAcc: {}\n'.format(result['aAcc'])) + f.write('mIoU: {}\n'.format(result['mIoU'])) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser('mIoU calculate') + parser.add_argument('--output_path', default="./result", + help='path to om/onnx output file, default ./result') + parser.add_argument('--gt_path', default="/opt/npu/cityscapes/gtFine/val", + help='path to gtFine/val, default /opt/npu/cityscapes/gtFine/val') + parser.add_argument('--out_suffix', default="_leftImg8bit_output_0.bin", + help='suffix of the om/onnx output, default "_leftImg8bit_output_0.bin"') + parser.add_argument('--result_path', default="./postprocess_result", + help='path to save the script result, default ./postprocess_result.txt') + + args = parser.parse_args() + + output_path = os.path.realpath(args.output_path) + gt_path = os.path.realpath(args.gt_path) + out_suffix = args.out_suffix + result_path = os.path.realpath(args.result_path) + print("output_path :", output_path) + print("gt_path :", gt_path) + eval_metrics(output_path, gt_path, out_suffix = out_suffix, result_path = result_path) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py new file mode 100644 index 0000000000..e04c524321 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py @@ -0,0 +1,84 @@ +# Copyright 2022 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os +import cv2 +import numpy as np +from torchvision import transforms + + +class Normalize(object): + def __init__(self, mean, std, to_rgb=True): + self.mean = np.array(mean, dtype=np.float32) + self.std = np.array(std, dtype=np.float32) + self.to_rgb = to_rgb + + def __call__(self, img): + img = img.copy().astype(np.float32) + # cv2 inplace normalization does not accept uint8 + assert img.dtype != np.uint8 + mean = np.float64(self.mean.reshape(1, -1)) + stdinv = 1 / np.float64(self.std.reshape(1, -1)) + if self.to_rgb: + cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) + cv2.subtract(img, mean, img) + cv2.multiply(img, stdinv, img) + return img + + +def preprocess(src_path, save_path): + preprocess = transforms.Compose([ + Normalize(mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True), + transforms.ToTensor(), + ]) + + root = src_path + + def _scandir(dir_path, suffix, recursive): + for entry in os.scandir(dir_path): + if not entry.name.startswith('.') and entry.is_file(): + rel_path = os.path.relpath(entry.path, root) + if suffix is None or rel_path.endswith(suffix): + yield rel_path + elif recursive and os.path.isdir(entry.path): + # scan recursively if entry.path is a directory + yield from _scandir( + entry.path, suffix=suffix, recursive=recursive) + + in_files = _scandir(src_path, '_leftImg8bit.png', True) + if not os.path.exists(save_path): + os.makedirs(save_path) + + i = 0 + for file in in_files: + i = i + 1 + print(file, "====", i) + input_image = cv2.imread(src_path + '/' + file) + input_tensor = preprocess(input_image) + # print(file.split('/')[-1].split('.')[0]) + # print(input_tensor) + img = np.array(input_tensor).astype(np.float32) + # print(img.shape) + img.tofile(os.path.join(save_path, file.split('/')[-1].split('.')[0] + ".bin")) + + +if __name__ == '__main__': + if len(sys.argv) < 3: + raise Exception("usage: python xxx.py [src_path] [save_path]") + src_path = sys.argv[1] + save_path = sys.argv[2] + src_path = os.path.realpath(src_path) + save_path = os.path.realpath(save_path) + preprocess(src_path, save_path) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/requirements.txt b/ACL_PyTorch/contrib/cv/segmentation/Segformer/requirements.txt new file mode 100644 index 0000000000..9961216403 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/requirements.txt @@ -0,0 +1,7 @@ +numpy == 1.21.5 +torch == 1.7.1 +torchvision == 0.8.2 +onnx == 1.10.1 +onnxruntime == 1.7.2 +onnx-simplifier == 0.3.8 +opencv-python == 4.5.5.64 -- Gitee From 29dfcdfb4941ffed8cf1ad824930978710d9ecc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 08:21:29 +0000 Subject: [PATCH 08/40] add ACL_PyTorch/contrib/cv/segmentation/Segformer/modelzoo_level.txt. --- .../contrib/cv/segmentation/Segformer/modelzoo_level.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/modelzoo_level.txt diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/modelzoo_level.txt b/ACL_PyTorch/contrib/cv/segmentation/Segformer/modelzoo_level.txt new file mode 100644 index 0000000000..405b26618a --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/modelzoo_level.txt @@ -0,0 +1,3 @@ +FuncStatus:OK +PerfStatus:POK +PrecisionStatus:OK \ No newline at end of file -- Gitee From 00fb112e49d474030a7bafdff5f2bf4727d313b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 08:37:59 +0000 Subject: [PATCH 09/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/modelzoo_level.txt. --- .../contrib/cv/segmentation/Segformer/modelzoo_level.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/modelzoo_level.txt b/ACL_PyTorch/contrib/cv/segmentation/Segformer/modelzoo_level.txt index 405b26618a..d2a4478db7 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/modelzoo_level.txt +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/modelzoo_level.txt @@ -1,3 +1,4 @@ FuncStatus:OK PerfStatus:POK -PrecisionStatus:OK \ No newline at end of file +PrecisionStatus:OK +ModelConvert:OK \ No newline at end of file -- Gitee From 0e63c8db88c2ef3cb5957748df29ceda6d6bc1f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 10:28:50 +0000 Subject: [PATCH 10/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/requirements.txt. --- ACL_PyTorch/contrib/cv/segmentation/Segformer/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/requirements.txt b/ACL_PyTorch/contrib/cv/segmentation/Segformer/requirements.txt index 9961216403..f34142973f 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/requirements.txt +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/requirements.txt @@ -5,3 +5,4 @@ onnx == 1.10.1 onnxruntime == 1.7.2 onnx-simplifier == 0.3.8 opencv-python == 4.5.5.64 +mmcv-full == 1.4.8 \ No newline at end of file -- Gitee From 1e8cedc78e343e59ac0add44002af11bd0b87a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 11:07:57 +0000 Subject: [PATCH 11/40] update --- .../cv/segmentation/Segformer/README.md | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md new file mode 100644 index 0000000000..18cf164a69 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md @@ -0,0 +1,107 @@ +## Segformer 模型离线推理指导 + +### 一、环境准备 + +1. 安装依赖 + +``` +pip install -r requirements.txt +``` + +  + +2. 获取开源模型代码仓 + +``` +git clone https://github.com/open-mmlab/mmsegmentation.git +cd mmsegmentation +python setup.py develop +``` + +  + +### 二、转 ONNX + +1. 进入 mmsegmentation/configs 目录下 [segformer](https://github.com/open-mmlab/mmsegmentation/tree/master/configs/segformer) +2. 下载 Cityscapes 栏第一行 model 权重文件 +3. 将权重文件 segformer_mit-b0_8x1_1024x1024_160k_cityscapes_20211208_101857-e7f88502.pth 放到当前工作目录 +4. 执行转 ONNX 脚本 + ``` + python mmsegmentation/tools/pytorch2onnx.py \ + mmsegmentation/configs/segformer/segformer_mit-b0_8x1_1024x1024_160k_cityscapes.py \ + --checkpoint ./segformer_mit-b0_8x1_1024x1024_160k_cityscapes_20211208_101857-e7f88502.pth \ + --output-file segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs.onnx \ + --shape 1024 2048 \ + --verify \ + --dynamic-export + ``` +5. 使用 onnx-simplifier 简化 onnx 模型 + ``` + python -m onnxsim --input-shape="1,3,1024,2048" --dynamic-input-shape segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs.onnx segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx + ``` + +  + +### 三、转 OM + +``` +source env.sh + +# 生成的 onnx 模型为动态 batch size,通过调整参数 --input_shape 的第一个参数修改生成的 om 模型的 batch size +atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --output=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim --input_format=NCHW --input_shape="input:1,3,1024,2048" --soc_version=Ascend310 --log=debug +``` + +  + +### 四、数据集预处理 + +1. 将数据集存放到指定目录 + 获取 cityscapes 数据集,解压存放到 /opt/npu/ 文件夹内 + +  + +2. 执行数据预处理脚本 + ``` + python ./Segformer_preprocess.py /opt/npu/cityscapes/leftImg8bit/val /opt/npu/prep_dataset + ``` + 处理后的 bin 文件放到 /opt/npu/prep_dataset 位置 + +  + +3. 生成 info 文件 + ``` + python ./get_info.py bin /opt/npu/prep_dataset ./prep_bin.info 1024 2048 + ``` + 生成的 info 文件保存到当前工作目录下 + +  + +### 五、离线推理 + +1. 准备 msame 推理工具 + 将 msame 文件放到当前工作目录 + (chmod +x msame 添加访问权限) + +  + +2. 推理时,使用 npu-smi info 命令查看 device 是否在运行其它推理任务,提前确保 device 空闲 + ``` + ./msame --model "./segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim.om" --input "/opt/npu/prep_dataset" --output "./msame_result" --outfmt BIN + ``` + 生成的结果文件存放到当前目录下的 msame_result 文件夹内 + +  + +3. 执行数据后处理脚本 + ``` + # 根据生成的结果文件名,完善以下命令中的 ${NAME} 信息 + python ./cityscapes_Segformer_postprocess.py --output_path=./msame_result/${NAME} --gt_path=/opt/npu/cityscapes/gtFine/val + ``` + +  + +**精度评测结果:** + +| 模型 | pth精度 | 离线推理精度 | +| ---------- | ----------- | --------------- | +| Segformer bs1 | mIoU = 76.54 | mIoU = 76.53 | -- Gitee From f77d6233f53472accaf8f29a5e7fd06e0b274948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 11:20:56 +0000 Subject: [PATCH 12/40] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ACL_PyTorch/contrib/cv/segmentation/Segformer/test/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/test/.keep diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/.keep b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/.keep new file mode 100644 index 0000000000..e69de29bb2 -- Gitee From 5924ee6aea2aeffe2f1f2d121ba4bb8d80d9ceee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 11:21:15 +0000 Subject: [PATCH 13/40] update --- .../cv/segmentation/Segformer/test/pth2om.sh | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh new file mode 100644 index 0000000000..ac7c9d23d6 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh @@ -0,0 +1,33 @@ +# pytorch to onnx +python mmsegmentation/tools/pytorch2onnx.py \ + mmsegmentation/configs/segformer/segformer_mit-b0_8x1_1024x1024_160k_cityscapes.py \ + --checkpoint ./segformer_mit-b0_8x1_1024x1024_160k_cityscapes_20211208_101857-e7f88502.pth \ + --output-file segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs.onnx \ + --shape 1024 2048 \ + --verify \ + --dynamic-export + +if [ $? != 0 ]; then + echo "fail!" + exit -1 +fi + +# simplify onnx model +python -m onnxsim --input-shape="1,3,1024,2048" --dynamic-input-shape segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs.onnx segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx + +if [ $? != 0 ]; then + echo "fail!" + exit -1 +fi + +# onnx to om +source env.sh + +# Segformer bs1 +atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --output=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim --input_format=NCHW --input_shape="input:1,3,1024,2048" --soc_version=Ascend310 --log=debug + +if [ -f "segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim.om" ] ; then + echo "success" +else + echo "fail!" +fi -- Gitee From 90f929c7d4eeeb075fffc32770ff3a17f6659064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 11:21:20 +0000 Subject: [PATCH 14/40] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20AC?= =?UTF-8?q?L=5FPyTorch/contrib/cv/segmentation/Segformer/test/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ACL_PyTorch/contrib/cv/segmentation/Segformer/test/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/test/.keep diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/.keep b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/.keep deleted file mode 100644 index e69de29bb2..0000000000 -- Gitee From b532a2d101b425aa6504e34d2fb6db4bbffc41a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 12:38:27 +0000 Subject: [PATCH 15/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md. --- ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md index 18cf164a69..6cf59d227f 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md @@ -102,6 +102,6 @@ atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic **精度评测结果:** -| 模型 | pth精度 | 离线推理精度 | -| ---------- | ----------- | --------------- | -| Segformer bs1 | mIoU = 76.54 | mIoU = 76.53 | +| 模型 | 官网精度 | 310 精度 | T4 性能 | 310 性能 | +| ------- | ------- | -------- | -------- | -------- | +| Segformer bs1 | mIoU = 76.54 | mIoU = 76.53 | 8.861 fps | 5.587 fps | -- Gitee From b7eeaea37675615a9ddca48a60cbaac1f8e9d869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 12:57:13 +0000 Subject: [PATCH 16/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md. --- ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md index 6cf59d227f..e9c1fec416 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md @@ -102,6 +102,6 @@ atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic **精度评测结果:** -| 模型 | 官网精度 | 310 精度 | T4 性能 | 310 性能 | +| 模型 | 官网精度 | 710 精度 | T4 性能 | 710 性能 | | ------- | ------- | -------- | -------- | -------- | | Segformer bs1 | mIoU = 76.54 | mIoU = 76.53 | 8.861 fps | 5.587 fps | -- Gitee From 0b4e74c1650f1ab0f1f9205df2d45ab3ff609cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Thu, 19 May 2022 12:58:32 +0000 Subject: [PATCH 17/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md. --- ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md index e9c1fec416..aced2be915 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md @@ -48,7 +48,7 @@ python setup.py develop source env.sh # 生成的 onnx 模型为动态 batch size,通过调整参数 --input_shape 的第一个参数修改生成的 om 模型的 batch size -atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --output=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim --input_format=NCHW --input_shape="input:1,3,1024,2048" --soc_version=Ascend310 --log=debug +atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --output=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim --input_format=NCHW --input_shape="input:1,3,1024,2048" --soc_version=Ascend710 --log=debug ```   -- Gitee From 52feba29a2bf927c0177cf9766e131e374ef1e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Sun, 22 May 2022 10:38:04 +0000 Subject: [PATCH 18/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md. --- ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md index aced2be915..adb8948ffb 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md @@ -95,7 +95,7 @@ atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic 3. 执行数据后处理脚本 ``` # 根据生成的结果文件名,完善以下命令中的 ${NAME} 信息 - python ./cityscapes_Segformer_postprocess.py --output_path=./msame_result/${NAME} --gt_path=/opt/npu/cityscapes/gtFine/val + python ./Segformer_postprocess.py --output_path=./msame_result/${NAME} --gt_path=/opt/npu/cityscapes/gtFine/val ```   -- Gitee From adc5cf120aadd1ec32c6ae439c2d7f486214bc93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Tue, 24 May 2022 15:23:29 +0000 Subject: [PATCH 19/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md. --- ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md index adb8948ffb..554e6c559b 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md @@ -94,8 +94,7 @@ atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic 3. 执行数据后处理脚本 ``` - # 根据生成的结果文件名,完善以下命令中的 ${NAME} 信息 - python ./Segformer_postprocess.py --output_path=./msame_result/${NAME} --gt_path=/opt/npu/cityscapes/gtFine/val + bash Segformer_postprocess.sh ```   -- Gitee From 97ec6600026b27e803032dc05a2a0ae206dd8c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Tue, 24 May 2022 15:24:34 +0000 Subject: [PATCH 20/40] update --- .../segmentation/Segformer/Segformer_postprocess.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.sh diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.sh new file mode 100644 index 0000000000..704569a8c3 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# get the file name +Folder="msame_result" +for file in ${Folder}/* +do + filename=`basename $file` +done + +# postprocess +python ./Segformer_postprocess.py --output_path=./msame_result/${filename} --gt_path=/opt/npu/cityscapes/gtFine/val \ No newline at end of file -- Gitee From ec6cf46eb8cbc729e49cd70d75d8acd5f27e4700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Tue, 24 May 2022 16:06:45 +0000 Subject: [PATCH 21/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh. --- .../contrib/cv/segmentation/Segformer/test/pth2om.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh index ac7c9d23d6..ac289ff394 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh @@ -1,3 +1,5 @@ +#!/bin/bash + # pytorch to onnx python mmsegmentation/tools/pytorch2onnx.py \ mmsegmentation/configs/segformer/segformer_mit-b0_8x1_1024x1024_160k_cityscapes.py \ @@ -24,10 +26,10 @@ fi source env.sh # Segformer bs1 -atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --output=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim --input_format=NCHW --input_shape="input:1,3,1024,2048" --soc_version=Ascend310 --log=debug +atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --output=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim --input_format=NCHW --input_shape="input:1,3,1024,2048" --soc_version=Ascend710 --log=debug if [ -f "segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim.om" ] ; then - echo "success" + echo "pth2om success" else echo "fail!" fi -- Gitee From 76d1f7648a501a54c5e741dd4c84ba82343c6435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Tue, 24 May 2022 16:09:42 +0000 Subject: [PATCH 22/40] update --- .../Segformer/test/eval_acc_perf.sh | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh new file mode 100644 index 0000000000..29b182a9c7 --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +datasets_path="/opt/npu/cityscapes" + +for para in $* +do + if [[ $para == --datasets_path* ]]; then + datasets_path=`echo ${para#*=}` + fi +done + +# preprocess +rm -rf /opt/npu/prep_dataset +python ./Segformer_preprocess.py ${datasets_path}/leftImg8bit/val /opt/npu/prep_dataset + +if [ $? != 0 ]; then + echo "fail!" + exit -1 +else + echo "========== preprocess finished ==========" +fi + +# get .info +python ./get_info.py bin /opt/npu/prep_dataset ./prep_bin.info 1024 2048 + +if [ $? != 0 ]; then + echo "fail!" + exit -1 +else + echo "========== get info finished ==========" +fi + +source env.sh + +rm -rf ./msame_result +./msame --model "./segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim.om" --input "/opt/npu/prep_dataset" --output "./msame_result" --outfmt BIN + +# get the result_file name +Folder="msame_result" +for file in ${Folder}/* +do + filename=`basename $file` +done + +# postprocess +python ./Segformer_postprocess.py --output_path=./msame_result/${filename} --gt_path=/opt/npu/cityscapes/gtFine/val + +if [ $? != 0 ]; then + echo "fail!" + exit -1 +else + echo "success" +fi \ No newline at end of file -- Gitee From ab272aa21e9d724273f5dd098568536e3a5181ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Wed, 25 May 2022 07:34:50 +0000 Subject: [PATCH 23/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py. --- .../cv/segmentation/Segformer/get_info.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py index dbd364055d..bffc36b4e2 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py @@ -18,21 +18,21 @@ import cv2 from glob import glob -def get_bin_info(file_path, info_name, width, height): - bin_images = glob(os.path.join(file_path, '*.bin')) - with open(info_name, 'w') as file: +def get_bin_info(_file_path, _info_name, _width, _height): + bin_images = glob(os.path.join(_file_path, '*.bin')) + with open(_info_name, 'w') as f: for index, img in enumerate(bin_images): - content = ' '.join([str(index), img, width, height]) - file.write(content) - file.write('\n') + content = ' '.join([str(index), img, _width, _height]) + f.write(content) + f.write('\n') -def get_jpg_info(file_path, info_name): +def get_jpg_info(_file_path, _info_name): extensions = ['jpg', 'jpeg', 'JPG', 'JPEG'] image_names = [] for extension in extensions: - image_names.append(glob(os.path.join(file_path, '*.' + extension))) - with open(info_name, 'w') as file: + image_names.append(glob(os.path.join(_file_path, '*.' + extension))) + with open(_info_name, 'w') as f: for image_name in image_names: if len(image_name) == 0: continue @@ -42,8 +42,8 @@ def get_jpg_info(file_path, info_name): shape = img_cv.shape width, height = shape[1], shape[0] content = ' '.join([str(index), img, str(width), str(height)]) - file.write(content) - file.write('\n') + f.write(content) + f.write('\n') if __name__ == '__main__': -- Gitee From 192ec5317c1f4a2da57aa3105446755873c1690e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Wed, 25 May 2022 07:48:19 +0000 Subject: [PATCH 24/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py. --- ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py index bffc36b4e2..b5108c5c53 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py @@ -40,8 +40,8 @@ def get_jpg_info(_file_path, _info_name): for index, img in enumerate(image_name): img_cv = cv2.imread(img) shape = img_cv.shape - width, height = shape[1], shape[0] - content = ' '.join([str(index), img, str(width), str(height)]) + _width, _height = shape[1], shape[0] + content = ' '.join([str(index), img, str(_width), str(_height)]) f.write(content) f.write('\n') -- Gitee From de663398ad07856050021e47932edd5e7034c74c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Wed, 25 May 2022 08:25:35 +0000 Subject: [PATCH 25/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py. --- .../Segformer/Segformer_postprocess.py | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py index be0ea03149..a572285818 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py @@ -36,16 +36,16 @@ class gtFineFile(object): def get_file(self, filename): """ return file path list """ - for file in self.gtFine_list: - if file.endswith(filename): - return file + for f in self.gtFine_list: + if f.endswith(filename): + return f def intersect_and_union(pred_label, label, num_classes, ignore_index, - label_map=dict(), + label_map={}, reduce_zero_label=False): """Calculate intersection and Union. @@ -56,7 +56,7 @@ def intersect_and_union(pred_label, num_classes (int): Number of categories. ignore_index (int): Index that will be ignored in evaluation. label_map (dict): Mapping old labels to new labels. The parameter will - work only when label is str. Default: dict(). + work only when label is str. Default: {}. reduce_zero_label (bool): Wether ignore zero label. The parameter will work only when label is str. Default: False. @@ -117,7 +117,7 @@ class IntersectAndUnion(object): Acc """ - def __init__(self, num_classes, ignore_index, label_map=dict(), reduce_zero_label=False): + def __init__(self, num_classes, ignore_index, label_map={}, reduce_zero_label=False): self.num_classes = num_classes self.ignore_index = ignore_index self.label_map = label_map @@ -148,11 +148,11 @@ class IntersectAndUnion(object): return {'aAcc': aAcc, 'mIoU': mIoU} -def eval_metrics(output_path, - gt_path, - out_suffix='_leftImg8bit_output_0.bin', - gt_suffix='_gtFine_labelTrainIds.png', - result_path='./postprocess_result', +def eval_metrics(_output_path, + _gt_path, + _out_suffix='_leftImg8bit_output_0.bin', + _gt_suffix='_gtFine_labelTrainIds.png', + _result_path='./postprocess_result', num_classes=19, ignore_index=255, label_map=None, @@ -180,16 +180,16 @@ def eval_metrics(output_path, metric = IntersectAndUnion(num_classes, ignore_index, label_map, reduce_zero_label) # initial gtFine files list - fileFinder = gtFineFile(gt_path) + fileFinder = gtFineFile(_gt_path) - for root, dirs, files in os.walk(output_path): - files = [file for file in files if str(file).endswith('bin')] - len = str(files.__len__()) + for root, dirs, files in os.walk(_output_path): + files = [f for f in files if str(f).endswith('bin')] + length = str(files.__len__()) for i, output_name in enumerate(files): if not str(output_name).endswith('bin'): continue - print('Segformer metric [' + str(i + 1) + '/' + len + '] on process: ' + output_name) - seg_map_name = str(output_name).replace(out_suffix, gt_suffix) + print('Segformer metric [' + str(i + 1) + '/' + length + '] on process: ' + output_name) + seg_map_name = str(output_name).replace(_out_suffix, _gt_suffix) # print("output_name :", output_name) # print("seg_map_name :", seg_map_name) seg_map_path = fileFinder.get_file(seg_map_name) @@ -197,8 +197,8 @@ def eval_metrics(output_path, seg_map = Image.open(seg_map_path) seg_map = np.array(seg_map, dtype=np.uint8) - output_path = os.path.realpath(os.path.join(root, output_name)) - output = np.fromfile(output_path, dtype=np.uint64).reshape(1024, 2048) + _output_path = os.path.realpath(os.path.join(root, output_name)) + output = np.fromfile(_output_path, dtype=np.uint64).reshape(1024, 2048) output = output.astype(np.uint8) metric.update(output, seg_map) else: @@ -207,7 +207,7 @@ def eval_metrics(output_path, # get result result = metric.get() print(result) - with open(result_path + '.txt', 'w') as f: + with open(_result_path + '.txt', 'w') as f: f.write('aAcc: {}\n'.format(result['aAcc'])) f.write('mIoU: {}\n'.format(result['mIoU'])) -- Gitee From b27c3aa218ce088668e77597bf5079e82e169971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Wed, 25 May 2022 08:36:17 +0000 Subject: [PATCH 26/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py. --- .../contrib/cv/segmentation/Segformer/Segformer_preprocess.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py index e04c524321..1e16ec18fd 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py @@ -54,8 +54,7 @@ def preprocess(src_path, save_path): yield rel_path elif recursive and os.path.isdir(entry.path): # scan recursively if entry.path is a directory - yield from _scandir( - entry.path, suffix=suffix, recursive=recursive) + yield from _scandir(entry.path, suffix=suffix, recursive=recursive) in_files = _scandir(src_path, '_leftImg8bit.png', True) if not os.path.exists(save_path): -- Gitee From 89c86f4f8630cc670a72a0687fb6da65b64bb212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Wed, 25 May 2022 08:42:23 +0000 Subject: [PATCH 27/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py. --- .../cv/segmentation/Segformer/Segformer_postprocess.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py index a572285818..04e59e87be 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py @@ -45,7 +45,7 @@ def intersect_and_union(pred_label, label, num_classes, ignore_index, - label_map={}, + label_map=dict(), reduce_zero_label=False): """Calculate intersection and Union. @@ -117,7 +117,7 @@ class IntersectAndUnion(object): Acc """ - def __init__(self, num_classes, ignore_index, label_map={}, reduce_zero_label=False): + def __init__(self, num_classes, ignore_index, label_map=dict(), reduce_zero_label=False): self.num_classes = num_classes self.ignore_index = ignore_index self.label_map = label_map @@ -231,4 +231,4 @@ if __name__ == '__main__': result_path = os.path.realpath(args.result_path) print("output_path :", output_path) print("gt_path :", gt_path) - eval_metrics(output_path, gt_path, out_suffix = out_suffix, result_path = result_path) + eval_metrics(_output_path = output_path, _gt_path = gt_path, _out_suffix = out_suffix, _result_path = result_path) -- Gitee From bd85d4176bb422977323c3d39cd1a2815a9364a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Wed, 25 May 2022 13:16:22 +0000 Subject: [PATCH 28/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py. --- .../segmentation/Segformer/Segformer_postprocess.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py index 04e59e87be..76f5287031 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py @@ -45,7 +45,7 @@ def intersect_and_union(pred_label, label, num_classes, ignore_index, - label_map=dict(), + label_map, reduce_zero_label=False): """Calculate intersection and Union. @@ -55,8 +55,8 @@ def intersect_and_union(pred_label, label (ndarray): Ground truth segmentation map. num_classes (int): Number of categories. ignore_index (int): Index that will be ignored in evaluation. - label_map (dict): Mapping old labels to new labels. The parameter will - work only when label is str. Default: {}. + label_map : Mapping old labels to new labels. The parameter will + work only when label is str. reduce_zero_label (bool): Wether ignore zero label. The parameter will work only when label is str. Default: False. @@ -109,7 +109,7 @@ class IntersectAndUnion(object): segmentation maps or list of label filenames. num_classes (int): Number of categories. ignore_index (int): Index that will be ignored in evaluation. - label_map (dict): Mapping old labels to new labels. Default: dict(). + label_map : Mapping old labels to new labels. reduce_zero_label (bool): Whether ignore zero label. Default: False. Returns: @@ -117,7 +117,7 @@ class IntersectAndUnion(object): Acc """ - def __init__(self, num_classes, ignore_index, label_map=dict(), reduce_zero_label=False): + def __init__(self, num_classes, ignore_index, label_map, reduce_zero_label=False): self.num_classes = num_classes self.ignore_index = ignore_index self.label_map = label_map @@ -177,6 +177,7 @@ def eval_metrics(_output_path, """ # initial metric + label_map = dict() metric = IntersectAndUnion(num_classes, ignore_index, label_map, reduce_zero_label) # initial gtFine files list -- Gitee From 573ef14e1d8b21087258cbb347ba17fd7db28534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Fri, 27 May 2022 16:24:54 +0000 Subject: [PATCH 29/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py. --- .../contrib/cv/segmentation/Segformer/Segformer_postprocess.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py index 76f5287031..d4c9a08408 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py @@ -191,8 +191,6 @@ def eval_metrics(_output_path, continue print('Segformer metric [' + str(i + 1) + '/' + length + '] on process: ' + output_name) seg_map_name = str(output_name).replace(_out_suffix, _gt_suffix) - # print("output_name :", output_name) - # print("seg_map_name :", seg_map_name) seg_map_path = fileFinder.get_file(seg_map_name) if seg_map_name is not None: seg_map = Image.open(seg_map_path) -- Gitee From 03b728a571b3fd61137e0b53ea9273d74d5817e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Fri, 27 May 2022 16:25:36 +0000 Subject: [PATCH 30/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py. --- .../contrib/cv/segmentation/Segformer/Segformer_preprocess.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py index 1e16ec18fd..8a26ab9157 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_preprocess.py @@ -66,10 +66,7 @@ def preprocess(src_path, save_path): print(file, "====", i) input_image = cv2.imread(src_path + '/' + file) input_tensor = preprocess(input_image) - # print(file.split('/')[-1].split('.')[0]) - # print(input_tensor) img = np.array(input_tensor).astype(np.float32) - # print(img.shape) img.tofile(os.path.join(save_path, file.split('/')[-1].split('.')[0] + ".bin")) -- Gitee From 29919e7f5e34aa363546ee5282f7e96a3190c1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Sat, 28 May 2022 10:05:54 +0000 Subject: [PATCH 31/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md. --- ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md index 554e6c559b..54c373e856 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/README.md @@ -2,6 +2,8 @@ ### 一、环境准备 +环境: CANN 5.1.rc1 + 1. 安装依赖 ``` @@ -45,7 +47,8 @@ python setup.py develop ### 三、转 OM ``` -source env.sh +# 设置环境变量 +source /usr/local/Ascend/ascend-toolkit/set_env.sh # 生成的 onnx 模型为动态 batch size,通过调整参数 --input_shape 的第一个参数修改生成的 om 模型的 batch size atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --output=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim --input_format=NCHW --input_shape="input:1,3,1024,2048" --soc_version=Ascend710 --log=debug -- Gitee From 5c044c8ac701789eaebbbfb3b11b2ee65a74fb81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Sat, 28 May 2022 10:08:17 +0000 Subject: [PATCH 32/40] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20AC?= =?UTF-8?q?L=5FPyTorch/contrib/cv/segmentation/Segformer/env.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ACL_PyTorch/contrib/cv/segmentation/Segformer/env.sh | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/env.sh diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/env.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/env.sh deleted file mode 100644 index 1c7c13700a..0000000000 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/env.sh +++ /dev/null @@ -1,9 +0,0 @@ -# env.sh - -source /usr/local/Ascend/ascend-toolkit/set_env.sh - -# 将atc日志打印到屏幕 -export ASCEND_SLOG_PRINT_TO_STDOUT=0 - -# 设置日志级别 -export ASCEND_GLOBAL_LOG_LEVEL=0 # debug 0 --> info 1 --> warning 2 --> error 3 -- Gitee From 2748ffd2cffabd0991af9b4a4fd72da9e5f7e28c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Sat, 28 May 2022 10:09:30 +0000 Subject: [PATCH 33/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh. --- .../contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh index 29b182a9c7..86062e98cc 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh @@ -30,7 +30,7 @@ else echo "========== get info finished ==========" fi -source env.sh +source /usr/local/Ascend/ascend-toolkit/set_env.sh rm -rf ./msame_result ./msame --model "./segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim.om" --input "/opt/npu/prep_dataset" --output "./msame_result" --outfmt BIN -- Gitee From 18666e5db471af29c4ad5b5b4a78450f5228ddd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Sat, 28 May 2022 10:10:18 +0000 Subject: [PATCH 34/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh. --- ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh index ac289ff394..07600db2d1 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh @@ -23,7 +23,7 @@ if [ $? != 0 ]; then fi # onnx to om -source env.sh +source /usr/local/Ascend/ascend-toolkit/set_env.sh # Segformer bs1 atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --output=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim --input_format=NCHW --input_shape="input:1,3,1024,2048" --soc_version=Ascend710 --log=debug -- Gitee From c21cd9db214777fe684db99e00a0f0c0361eeacd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Sat, 28 May 2022 10:16:04 +0000 Subject: [PATCH 35/40] update --- .../cv/segmentation/Segformer/test/perf_g.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/test/perf_g.sh diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/perf_g.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/perf_g.sh new file mode 100644 index 0000000000..0298c5360f --- /dev/null +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/perf_g.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +trtexec --onnx=./segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --fp16 --shapes=input:1x3x1024x2048 --workspace=15000 --threads > Segformer.log + +perf_str=`grep "GPU.* mean.*ms$" Segformer.log` + +if [ -n "$perf_str" ]; then + perf_num=`echo $perf_str | awk -F' ' '{print $16}'` +else + perf_str=`grep "mean.*ms$" deeplabv3_bs1.log` + perf_num=`echo $perf_str | awk -F' ' '{print $4}'` +fi +awk 'BEGIN{printf "bs1 fps:%.3f\n", 1000*1/('$perf_num'/1)}' -- Gitee From 1b4fdd77b09c91136c9f1fac266ff25287ffbbaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Sat, 28 May 2022 10:36:09 +0000 Subject: [PATCH 36/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py. --- .../Segformer/Segformer_postprocess.py | 65 ++----------------- 1 file changed, 4 insertions(+), 61 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py index d4c9a08408..950d90fbca 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py @@ -16,10 +16,11 @@ import numpy as np import torch import argparse import os +from mmsegmentation.mmseg.core.evaluation import metrics from PIL import Image -class gtFineFile(object): +class GtFine_File(object): """ directory: path to gtFine suffix: suffix of the gtFine @@ -41,64 +42,6 @@ class gtFineFile(object): return f -def intersect_and_union(pred_label, - label, - num_classes, - ignore_index, - label_map, - reduce_zero_label=False): - """Calculate intersection and Union. - - Args: - pred_label (ndarray | str): Prediction segmentation map - or predict result filename. - label (ndarray): Ground truth segmentation map. - num_classes (int): Number of categories. - ignore_index (int): Index that will be ignored in evaluation. - label_map : Mapping old labels to new labels. The parameter will - work only when label is str. - reduce_zero_label (bool): Wether ignore zero label. The parameter will - work only when label is str. Default: False. - - Returns: - torch.Tensor: The intersection of prediction and ground truth - histogram on all classes. - torch.Tensor: The union of prediction and ground truth histogram on - all classes. - torch.Tensor: The prediction histogram on all classes. - torch.Tensor: The ground truth histogram on all classes. - """ - - if isinstance(pred_label, str): - pred_label = torch.from_numpy(np.load(pred_label)) - else: - pred_label = torch.from_numpy((pred_label)) - - label = torch.from_numpy(label) - - if label_map is not None: - for old_id, new_id in label_map.items(): - label[label == old_id] = new_id - if reduce_zero_label: - label[label == 0] = 255 - label = label - 1 - label[label == 254] = 255 - - mask = (label != ignore_index) - pred_label = pred_label[mask] - label = label[mask] - - intersect = pred_label[pred_label == label] - area_intersect = torch.histc( - intersect.float(), bins=(num_classes), min=0, max=num_classes - 1) - area_pred_label = torch.histc( - pred_label.float(), bins=(num_classes), min=0, max=num_classes - 1) - area_label = torch.histc( - label.float(), bins=(num_classes), min=0, max=num_classes - 1) - area_union = area_pred_label + area_label - area_intersect - return [area_intersect, area_union, area_pred_label, area_label] - - class IntersectAndUnion(object): """Calculate Total Intersection and Union. @@ -130,7 +73,7 @@ class IntersectAndUnion(object): def update(self, output, gt_seg_map): """ update """ [area_intersect, area_union, area_pred_label, area_label] = \ - intersect_and_union( + metrics.intersect_and_union( output, gt_seg_map, self.num_classes, self.ignore_index, self.label_map, self.reduce_zero_label) self.total_area_intersect += area_intersect.to(torch.float64) @@ -181,7 +124,7 @@ def eval_metrics(_output_path, metric = IntersectAndUnion(num_classes, ignore_index, label_map, reduce_zero_label) # initial gtFine files list - fileFinder = gtFineFile(_gt_path) + fileFinder = GtFine_File(_gt_path) for root, dirs, files in os.walk(_output_path): files = [f for f in files if str(f).endswith('bin')] -- Gitee From 5e00ae4d67e334c14624ebbebf2aa47658e1c2fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Sat, 28 May 2022 10:38:51 +0000 Subject: [PATCH 37/40] update ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py. --- .../cv/segmentation/Segformer/Segformer_postprocess.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py index 950d90fbca..126d420207 100644 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py +++ b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.py @@ -20,7 +20,7 @@ from mmsegmentation.mmseg.core.evaluation import metrics from PIL import Image -class GtFine_File(object): +class GtFineFile(object): """ directory: path to gtFine suffix: suffix of the gtFine @@ -124,7 +124,7 @@ def eval_metrics(_output_path, metric = IntersectAndUnion(num_classes, ignore_index, label_map, reduce_zero_label) # initial gtFine files list - fileFinder = GtFine_File(_gt_path) + fileFinder = GtFineFile(_gt_path) for root, dirs, files in os.walk(_output_path): files = [f for f in files if str(f).endswith('bin')] -- Gitee From 25b5166896715d288d83d637145726310607cc43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Tue, 12 Jul 2022 02:21:14 +0000 Subject: [PATCH 38/40] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20AC?= =?UTF-8?q?L=5FPyTorch/contrib/cv/segmentation/Segformer/get=5Finfo.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cv/segmentation/Segformer/get_info.py | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py b/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py deleted file mode 100644 index b5108c5c53..0000000000 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/get_info.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2022 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License.s - -import os -import sys -import cv2 -from glob import glob - - -def get_bin_info(_file_path, _info_name, _width, _height): - bin_images = glob(os.path.join(_file_path, '*.bin')) - with open(_info_name, 'w') as f: - for index, img in enumerate(bin_images): - content = ' '.join([str(index), img, _width, _height]) - f.write(content) - f.write('\n') - - -def get_jpg_info(_file_path, _info_name): - extensions = ['jpg', 'jpeg', 'JPG', 'JPEG'] - image_names = [] - for extension in extensions: - image_names.append(glob(os.path.join(_file_path, '*.' + extension))) - with open(_info_name, 'w') as f: - for image_name in image_names: - if len(image_name) == 0: - continue - else: - for index, img in enumerate(image_name): - img_cv = cv2.imread(img) - shape = img_cv.shape - _width, _height = shape[1], shape[0] - content = ' '.join([str(index), img, str(_width), str(_height)]) - f.write(content) - f.write('\n') - - -if __name__ == '__main__': - file_type = sys.argv[1] - file_path = sys.argv[2] - info_name = sys.argv[3] - if file_type == 'bin': - width = sys.argv[4] - height = sys.argv[5] - assert len(sys.argv) == 6, 'The number of input parameters must be equal to 5' - get_bin_info(file_path, info_name, width, height) - elif file_type == 'jpg': - assert len(sys.argv) == 4, 'The number of input parameters must be equal to 3' - get_jpg_info(file_path, info_name) - -# python get_info.py bin ./prep_dataset ./prep_bin.info 1024 2048 \ No newline at end of file -- Gitee From ca9b7688cc10b169ce4d44a9c9cc7a20595c86f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Fri, 15 Jul 2022 07:20:50 +0000 Subject: [PATCH 39/40] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20AC?= =?UTF-8?q?L=5FPyTorch/contrib/cv/segmentation/Segformer/test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Segformer/test/eval_acc_perf.sh | 53 ------------------- .../cv/segmentation/Segformer/test/perf_g.sh | 13 ----- .../cv/segmentation/Segformer/test/pth2om.sh | 35 ------------ 3 files changed, 101 deletions(-) delete mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh delete mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/test/perf_g.sh delete mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh deleted file mode 100644 index 86062e98cc..0000000000 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/eval_acc_perf.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - -datasets_path="/opt/npu/cityscapes" - -for para in $* -do - if [[ $para == --datasets_path* ]]; then - datasets_path=`echo ${para#*=}` - fi -done - -# preprocess -rm -rf /opt/npu/prep_dataset -python ./Segformer_preprocess.py ${datasets_path}/leftImg8bit/val /opt/npu/prep_dataset - -if [ $? != 0 ]; then - echo "fail!" - exit -1 -else - echo "========== preprocess finished ==========" -fi - -# get .info -python ./get_info.py bin /opt/npu/prep_dataset ./prep_bin.info 1024 2048 - -if [ $? != 0 ]; then - echo "fail!" - exit -1 -else - echo "========== get info finished ==========" -fi - -source /usr/local/Ascend/ascend-toolkit/set_env.sh - -rm -rf ./msame_result -./msame --model "./segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim.om" --input "/opt/npu/prep_dataset" --output "./msame_result" --outfmt BIN - -# get the result_file name -Folder="msame_result" -for file in ${Folder}/* -do - filename=`basename $file` -done - -# postprocess -python ./Segformer_postprocess.py --output_path=./msame_result/${filename} --gt_path=/opt/npu/cityscapes/gtFine/val - -if [ $? != 0 ]; then - echo "fail!" - exit -1 -else - echo "success" -fi \ No newline at end of file diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/perf_g.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/perf_g.sh deleted file mode 100644 index 0298c5360f..0000000000 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/perf_g.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -trtexec --onnx=./segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --fp16 --shapes=input:1x3x1024x2048 --workspace=15000 --threads > Segformer.log - -perf_str=`grep "GPU.* mean.*ms$" Segformer.log` - -if [ -n "$perf_str" ]; then - perf_num=`echo $perf_str | awk -F' ' '{print $16}'` -else - perf_str=`grep "mean.*ms$" deeplabv3_bs1.log` - perf_num=`echo $perf_str | awk -F' ' '{print $4}'` -fi -awk 'BEGIN{printf "bs1 fps:%.3f\n", 1000*1/('$perf_num'/1)}' diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh deleted file mode 100644 index 07600db2d1..0000000000 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/test/pth2om.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -# pytorch to onnx -python mmsegmentation/tools/pytorch2onnx.py \ - mmsegmentation/configs/segformer/segformer_mit-b0_8x1_1024x1024_160k_cityscapes.py \ - --checkpoint ./segformer_mit-b0_8x1_1024x1024_160k_cityscapes_20211208_101857-e7f88502.pth \ - --output-file segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs.onnx \ - --shape 1024 2048 \ - --verify \ - --dynamic-export - -if [ $? != 0 ]; then - echo "fail!" - exit -1 -fi - -# simplify onnx model -python -m onnxsim --input-shape="1,3,1024,2048" --dynamic-input-shape segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs.onnx segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx - -if [ $? != 0 ]; then - echo "fail!" - exit -1 -fi - -# onnx to om -source /usr/local/Ascend/ascend-toolkit/set_env.sh - -# Segformer bs1 -atc --framework=5 --model=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_dynamic_bs_sim.onnx --output=segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim --input_format=NCHW --input_shape="input:1,3,1024,2048" --soc_version=Ascend710 --log=debug - -if [ -f "segformer_mit-b0_8x1_1024x1024_160k_cityscapes_bs1_sim.om" ] ; then - echo "pth2om success" -else - echo "fail!" -fi -- Gitee From 33c1faad494776a82522c4971fc38f5e40b92224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E5=AE=B6=E7=86=99?= <10509124+Yawning_x@user.noreply.gitee.com> Date: Fri, 15 Jul 2022 07:57:29 +0000 Subject: [PATCH 40/40] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20AC?= =?UTF-8?q?L=5FPyTorch/contrib/cv/segmentation/Segformer/Segformer=5Fpostp?= =?UTF-8?q?rocess.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../segmentation/Segformer/Segformer_postprocess.sh | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.sh diff --git a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.sh b/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.sh deleted file mode 100644 index 704569a8c3..0000000000 --- a/ACL_PyTorch/contrib/cv/segmentation/Segformer/Segformer_postprocess.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -# get the file name -Folder="msame_result" -for file in ${Folder}/* -do - filename=`basename $file` -done - -# postprocess -python ./Segformer_postprocess.py --output_path=./msame_result/${filename} --gt_path=/opt/npu/cityscapes/gtFine/val \ No newline at end of file -- Gitee