PySODEvalToolkit 使用笔记

news2024/10/6 0:26:50

1. 克隆仓库

首先,克隆PySODEvalToolkit仓库到你的本地机器:

git clone https://github.com/lartpang/PySODEvalToolkit.git

2. 创建虚拟环境

cd PySODEvalToolkit
conda create -n pysodeval python=3.7

3. 安装依赖

pip install -r requirements.txt

4. 放置要参与评估的数据

在 PySODEvalToolkit 目录下创建 Data 文件夹,如下图所示,在其中创建要评估测试的数据集文件夹,这里我创建了 2 个 CHAMELEON 和 COD10K,然后 Test/GT/ 下面放的是 Ground Truth 二值图,Test/Mask/ 下面放的是模型预测的 mask 二值图

PySODEvalToolkit/
├── Data/
│   ├── CHAMELEON/
│   │   ├── Test/
│   │   │   ├── GT/
│   │   │   └── Mask/
│   ├── COD10K/
│   │   ├── Test/
│   │   │   ├── GT/
│   │   │   └── Mask/
│   
├── config_dataset_json_example.json
├── config_method_json_example.json
├── eval.py

5. 修改数据配置文件

config_dataset_json_example.jsonconfig_method_json_example.json 这两个文件,

config_dataset_json_example.json 里对不同数据集的ground truth图像进行配置
config_method_json_example.json 里是模型在不同数据集上预测的mask图像进行配置

修改 config_dataset_json_example.json

以 CHAMELEON 为例,在配置文件中添加如下内容,实际只读取 “mask” 部分的内容,“prefix” 是 Data/CHAMELEON/Test/GT/ 中所有图像文件名的共同前缀,“suffix” 则是共同后缀

  "CHAMELEON": {
    "image": {
      "path": "Data/CHAMELEON/Test/GT", 
      "prefix": "animal-",
      "suffix": ".png"
    },
    "mask": {
      "path": "Data/CHAMELEON/Test/GT",
      "prefix": "animal-",
      "suffix": ".png"
    }
  }

修改 config_method_json_example.json

只评估 CHAMELEON 数据集的话,修改后的 config_method_json_example.json 文件内容如下,删除了 Method1,Method2,Method3,因为这里我只评估 SINetV2 这种方法在 CHAMELEON 数据集上的预测结果,如果要评估该方法在其他数据集上的预测结果,在该方法对应的方括号内按照 “CHAMELEON” 找猫画虎添加配置信息即可。
这里注意,新建"Method4",里面的名字替换成你要测试的模型方法,例如我要测SINetV2_2022,需要把 “Method4” 改成 “SINetV2_2022”,不然后面会报错。

{
  "Method4": {
    "CHAMELEON": {
      "path": "Data/CHAMELEON/Test/Mask",
      "prefix": "animal-",
      "suffix": ".png"
    }
  }
}

正确的:

{
  "SINetV2_2022": {
    "CHAMELEON": {
      "path": "Data/CHAMELEON/Test/Mask",
      "prefix": "animal-",
      "suffix": ".png"
    }
  }
}

6. 修改 yaml 文件 和 alias_for_plotting.json

alias_for_plotting.json 照猫画虎修改,添加 dataset 和 method

{
  "dataset": {
    "Name_In_Json": "Name_In_SubFigure",
    "NJUD": "NJUD",
    "NLPR": "NLPR",
    "DUTRGBD": "DUTRGBD",
    "STEREO1000": "SETERE",
    "RGBD135": "RGBD135",
    "SSD": "SSD",
    "SIP": "SIP",
    "CHAMELEON": "CHAMELEON"
  },
  "method": {
    "Name_In_Json": "Name_In_Legend",
    "GateNet_2020": "GateNet",
    "MINet_R50_2020": "MINet",
    "SINetV2_2022": "SINetV2"
  }
}

converter_config.yaml 照猫画虎添加

dataset_names: [
    'NJUD',
    'NLPR',
    'SIP',
    'STEREO1000',
    'SSD',
    'LFSD',
    'RGBD135',
    'DUTRGBD',
    'COD10K',
    'CHAMELEON' // 添加测试数据集
]

# 使用单引号保证不被转义
method_names: {
    '2020-ECCV-DANetV19': 'DANet$_{20}$',
    '2020-ECCV-HDFNetR50': 'HDFNet$_{20}$',
    '2022-AAAI-SSLSOD-ImageNet': 'SSLSOD$_{22}$',
    '2022-TPAMI-SINetV2': 'SINetV2$_{22}$', // 添加了这一行
}

# 使用单引号保证不被转义
metric_names: {
    'sm': '$S_{m}~\uparrow$',
    'wfm': '$F^{\omega}_{\beta}~\uparrow$',
    'mae': '$MAE~\downarrow$',
    'adpf': '$F^{adp}_{\beta}~\uparrow$',
    'avgf': '$F^{avg}_{\beta}~\uparrow$',
    'maxf': '$F^{max}_{\beta}~\uparrow$',
    'adpe': '$E^{adp}_{m}~\uparrow$',
    'avge': '$E^{avg}_{m}~\uparrow$',
    'maxe': '$E^{max}_{m}~\uparrow$',
}

rgbd_aliases.yaml 照猫画虎添加

dataset: {
    "NJUD": "NJUD",
    "NLPR": "NLPR",
    "SIP": "SIP",
    "STEREO1000": "STEREO1000",
    "RGBD135": "RGBD135",
    "SSD": "SSD",
    "LFSD": "LFSD",
    "DUTRGBD": "DUTRGBD",
    "CHAMELEON": "CHAMELEON"
}

method: {
    '2020-ECCV-DANetV19': 'DANet$_{20}$',
    '2020-ECCV-HDFNetR50': 'HDFNet$_{20}$',
    '2022-AAAI-SSLSOD-ImageNet': 'SSLSOD$_{22}$',
    '2022-TPAMI-SINetV2': 'SINetV2$_{22}$'
}

7. 检测修改后的配置文件是否有问题

在修改完数据集配置文件和方法配置文件后,执行这个命令检查

python tools/check_path.py -m examples/config_method_json_example.json -d examples/config_dataset_json_example.json

如果正确配置的话会打印

examples/config_method_json_example.json &
 examples/config_dataset_json_example.json 基本正常

如果未正确配置的话,会打印错误信息,
根据错误信息调试,如果提示 Data/CHAMELEON/Test/GT/ 和 Data/CHAMELEON/Test/Mask 文件名不匹配的话,首先检查这两个路径下的文件数量是否相同,前缀名和后缀名是否全部相同且json文件中是否正确配置。

如果确保Data/CHAMELEON/Test/GT/ 和 Data/CHAMELEON/Test/Mask 文件名是匹配的且json文件中也正确配置了,此时需要检查 check_path.py 文件中解析文件名的逻辑是否有问题,大概率是这里出错了,修改 check_path.py 添加调试打印信息根据输出进行排查。

8. 运行评估

运行评估脚本以计算评估指标和生成可视化图表:

python eval.py \
    --dataset-json config_dataset_json_example.json \
    --method-json config_method_json_example.json \
    --metric-npy output/metrics.npy \
    --curves-npy output/curves.npy \
    --record-txt output/results.txt \
    --record-xlsx output/results.xlsx \
    --num-workers 4 \
    --num-bits 3 \
    --metric-names sm wfm mae fmeasure em \
    --include-datasets datasettobeevaled \
    --include-methods yourmethod

参数解释

  • --dataset-json:数据集配置文件的路径。
  • --method-json:方法配置文件的路径,可以指定多个文件。
  • --metric-npy:用于保存评估指标结果的.npy文件路径。
  • --curves-npy:用于保存曲线结果的.npy文件路径。
  • --record-txt:用于保存评估结果的.txt文件路径。
  • --record-xlsx:用于保存评估结果的.xlsx文件路径。
  • --num-workers:用于多线程或多进程的工作线程数,默认值为4。
  • --num-bits:结果显示的小数位数,默认值为3。
  • --metric-names:要计算的评估指标的名称列表。
  • --include-datasets:要评估的特定数据集的名称。
  • --include-methods:要评估的特定方法的名称。

执行命令时 --num-workers--num-bits 可以省略,

然后我实际执行的eval命令语句是:

python eval.py --dataset-json examples/config_dataset_json_example.json 
--method-json examples/config_method_json_example.json 
--metric-npy output/metrics.npy 
--curves-npy output/curves.npy 
--record-txt output/results.txt 
--record-xlsx output/results.xlsx 
--metric-names sm wfm mae fmeasure em precision recall 
--include-datasets CHAMELEON 
--include-methods SINetV2_2022

执行该命令后评估的结果会自动创建并保存到这个目录下 PySODEvalToolkit/output ,可以看到,命令在 metric-names 中添加了 precision recall 指标,对SINetV2_2022 模型方法在 CHAMELEON 数据集的结果进行评估,如果要对多种模型方法在多个数据集的结果进行评估,空格并列添加就行,这里 --include-methods 中的方法名来自于 alias_for_plotting.json 中。

解释输出结果

运行脚本后,你将在指定的输出路径中找到结果文件:

  • metrics.npy:包含计算的评估指标结果的numpy数组。
  • curves.npy:包含生成的曲线结果的numpy数组。
  • results.txt:包含评估结果的文本文件。
  • results.xlsx:包含评估结果的Excel文件。

这些文件将详细记录你的模型在 CHAMELEON 数据集上的性能,包括各种评估指标和可视化曲线。

9. 绘制曲线图

plot.py 脚本用于绘制评估曲线,例如 Fm 曲线和 PR 曲线。该脚本通过读取保存的 .npy 文件中的曲线数据,并使用指定的样式配置文件生成图像。

使用方法

参数说明
  • --alias-yaml:数据集和方法别名的 YAML 文件。
  • --style-cfg:用于绘制曲线的 YAML 配置文件。
  • --curves-npys:保存曲线结果的 .npy 文件。
  • --our-methods:我们的方法的名称,用于突出显示。
  • --num-rows:子图的行数。
  • --num-col-legend:图例的列数。
  • --mode:绘图模式,可以是 prfmem
  • --separated-legend:使用分离的图例。
  • --sharey:使用共享的 y 轴。
  • --save-name:导出文件路径。
示例用法

绘制的命令

python plot.py --style-cfg examples/single_row_style.yml 
--num-rows 1 
--curves-npys output/curves.npy
--mode em 
--save-name output/simple_curve_em 
--alias-yaml examples/rgbd_aliases.yaml

例如 output/simple_curve_em 会在 output 目录下生成 simple_curve_em.pdf 文件,该文件打开就是绘制的曲线图

参数详细说明

  • --curves-npys:指定一个或多个保存曲线结果的 .npy 文件,这些文件包含了曲线的数据。
  • --style-cfg:指定用于绘图的样式配置文件,包含了 matplotlib 的配置,例如图例位置、字体大小等。
  • --num-rows:指定生成图像的行数。
  • --num-col-legend:指定图例的列数。
  • --mode:指定绘图的模式,有三种选择:
    • pr:绘制 Precision-Recall 曲线。
    • fm:绘制 F-measure 曲线。
    • em:绘制 E-measure 曲线。
  • --separated-legend:如果设置了这个选项,将使用分离的图例。
  • --sharey:如果设置了这个选项,将使用共享的 y 轴。
  • --save-name:指定保存图像的文件路径。

draw_curves 的使用

脚本的核心功能由 draw_curves.draw_curves 实现。以下是该函数的参数:

  • mode:绘图模式 (prfmem)。
  • axes_setting:不同曲线的绘图配置。
  • curves_npy_path:包含曲线数据的 .npy 文件路径。
  • row_num:子图的行数。
  • method_aliases:方法的别名。
  • dataset_aliases:数据集的别名。
  • style_cfg:样式配置文件路径。
  • ncol_of_legend:图例的列数。
  • separated_legend:是否使用分离的图例。
  • sharey:是否使用共享的 y 轴。
  • our_methods:需要高亮显示的方法。
  • save_name:保存图像的文件路径。

配置文件示例

single_row_style.yml 配置文件可能如下:

savefig.format: "png"
savefig.dpi: 300
savefig.bbox: "tight"
savefig.pad_inches: 0.1
axes.labelsize: 12
axes.titlesize: 14
xtick.labelsize: 10
ytick.labelsize: 10
legend.fontsize: 10

绘制图像的步骤

  1. 确保已经生成了包含曲线数据的 .npy 文件。
  2. 准备好样式配置文件,例如 single_row_style.yml
  3. 运行 plot.py,指定必要的参数。

总结

plot.py 脚本通过读取 .npy 文件中的曲线数据,并使用指定的样式配置文件生成图像。用户可以通过不同的参数控制生成图像的样式、子图的布局以及图例的配置。使用示例命令可以帮助用户快速上手绘制评估曲线。

10. 查看结果

评估结果和可视化图表将保存在配置文件中指定的save_dir目录中。

出现的问题

在修改完数据集配置文件和方法配置文件后,执行这个命令

python tools/check_path.py -m examples/config_method_json_example.json -d examples/config_dataset_json_example.json

出错提示:

(pysodeval) root@autodl-container-d9084da129-76991c4d:~/PySODEvalToolkit# python tools/check_path.py -m examples/config_method_json_example.json -d examples/config_dataset_json_example.json
Checking for Method1 ...
Traceback (most recent call last):
  File "tools/check_path.py", line 30, in <module>
    dataset_mask_info = datasets_info[dataset_name]["mask"]
KeyError: 'PASCAL-S'

解决方法:
在 examples/config_dataset_json_example.json 中添加

  "PASCAL-S": {
    "image": {
      "path": "Path_Of_RGBDSOD_Datasets/PASCAL-S/Image",
      "suffix": ".jpg"
    },
    "mask": {
      "path": "Path_Of_RGBDSOD_Datasets/PASCAL-S/Mask",
      "suffix": ".png"
    }
  },
  "ECSSD": {
    "image": {
      "path": "Path_Of_RGBDSOD_Datasets/ECSSD/Image",
      "suffix": ".jpg"
    },
    "mask": {
      "path": "Path_Of_RGBDSOD_Datasets/ECSSD/Mask",
      "suffix": ".png"
    }
  },
  "HKU-IS": {
    "image": {
      "path": "Path_Of_RGBDSOD_Datasets/HKU-IS/Image",
      "suffix": ".jpg"
    },
    "mask": {
      "path": "Path_Of_RGBDSOD_Datasets/HKU-IS/Mask",
      "suffix": ".png"
    }
  },
  "DUT-OMRON": {
    "image": {
      "path": "Path_Of_RGBDSOD_Datasets/DUT-OMRON/Image",
      "suffix": ".jpg"
    },
    "mask": {
      "path": "Path_Of_RGBDSOD_Datasets/DUT-OMRON/Mask",
      "suffix": ".png"
    }
  },
  "DUTS-TE": {
    "image": {
      "path": "Path_Of_RGBDSOD_Datasets/DUTS-TE/Image",
      "suffix": ".jpg"
    },
    "mask": {
      "path": "Path_Of_RGBDSOD_Datasets/DUTS-TE/Mask",
      "suffix": ".png"
    }
  }

之后重新执行,又出错:

Checking for Method1 ...
Checking for Method2 ...
Checking for Method3 ...
Checking for Method4 ...
Path_Of_Method1/PASCAL-S/DGRL 不存在
Path_Of_Method1/ECSSD/DGRL 不存在
Path_Of_Method1/HKU-IS/DGRL 不存在
Path_Of_Method1/DUT-OMRON/DGRL 不存在
Path_Of_Method1/DUTS-TE/DGRL 不存在
Path_Of_Method2/pascal 不存在
Path_Of_Method2/ecssd 不存在
Path_Of_Method2/hku 不存在
Path_Of_Method2/duto 不存在
Path_Of_Method2/dut_te 不存在
Path_Of_Method3/pascal 不存在
Path_Of_Method3/ecssd 不存在
Path_Of_Method3/hku 不存在
Path_Of_Method3/duto 不存在
Path_Of_Method3/dut_te 不存在
Data/COD10K/Test/Mask 中数据名字与真值 Data/COD10K/Test/GT 不匹配

解决办法:

把config_method_json_example.json下面这段代码删除掉可以解决掉不存在的报错,但是仍然存在数据名字不匹配的错误,

  "Method1": {
    "PASCAL-S": {
      "path": "Path_Of_Method1/PASCAL-S/DGRL",
      "prefix": "some_method_prefix",
      "suffix": ".png"
    },
    "ECSSD": {
      "path": "Path_Of_Method1/ECSSD/DGRL",
      "prefix": "some_method_prefix",
      "suffix": ".png"
    },
    "HKU-IS": {
      "path": "Path_Of_Method1/HKU-IS/DGRL",
      "prefix": "some_method_prefix",
      "suffix": ".png"
    },
    "DUT-OMRON": {
      "path": "Path_Of_Method1/DUT-OMRON/DGRL",
      "prefix": "some_method_prefix",
      "suffix": ".png"
    },
    "DUTS-TE": {
      "path": "Path_Of_Method1/DUTS-TE/DGRL",
      "suffix": ".png"
    }
  },
  "Method2": {
    "PASCAL-S": {
      "path": "Path_Of_Method2/pascal",
      "prefix": "pascal_",
      "suffix": ".png"
    },
    "ECSSD": {
      "path": "Path_Of_Method2/ecssd",
      "prefix": "ecssd_",
      "suffix": ".png"
    },
    "HKU-IS": {
      "path": "Path_Of_Method2/hku",
      "prefix": "hku_",
      "suffix": ".png"
    },
    "DUT-OMRON": {
      "path": "Path_Of_Method2/duto",
      "prefix": "duto_",
      "suffix": ".png"
    },
    "DUTS-TE": {
      "path": "Path_Of_Method2/dut_te",
      "prefix": "dut_te_",
      "suffix": ".png"
    }
  },
  "Method3": {
    "PASCAL-S": {
      "path": "Path_Of_Method3/pascal",
      "prefix": "pascal_",
      "suffix": "_fused_sod.png"
    },
    "ECSSD": {
      "path": "Path_Of_Method3/ecssd",
      "prefix": "ecssd_",
      "suffix": "_fused_sod.png"
    },
    "HKU-IS": {
      "path": "Path_Of_Method3/hku",
      "prefix": "hku_",
      "suffix": "_fused_sod.png"
    },
    "DUT-OMRON": {
      "path": "Path_Of_Method3/duto",
      "prefix": "duto_",
      "suffix": "_fused_sod.png"
    },
    "DUTS-TE": {
      "path": "Path_Of_Method3/dut_te",
      "prefix": "dut_te_",
      "suffix": "_fused_sod.png"
    }
  },

数据名字不匹配的错误原因是 check_path.py 文件中解析文件名的逻辑有问题:
修改后增加了打印调试信息的 check_path.py 代码:

# -*- coding: utf-8 -*-

import argparse
import json
import os
from collections import OrderedDict

parser = argparse.ArgumentParser(description="A simple tool for checking your json config file.")
parser.add_argument(
    "-m", "--method-jsons", nargs="+", required=True, help="The json file about all methods."
)
parser.add_argument(
    "-d", "--dataset-jsons", nargs="+", required=True, help="The json file about all datasets."
)
args = parser.parse_args()

for method_json, dataset_json in zip(args.method_jsons, args.dataset_jsons):
    with open(method_json, encoding="utf-8", mode="r") as f:
        methods_info = json.load(f, object_hook=OrderedDict)  # 有序载入
    with open(dataset_json, encoding="utf-8", mode="r") as f:
        datasets_info = json.load(f, object_hook=OrderedDict)  # 有序载入

    total_msgs = []
    for method_name, method_info in methods_info.items():
        print(f"Checking for {method_name} ...")
        for dataset_name, results_info in method_info.items():
            if results_info is None:
                continue

            dataset_mask_info = datasets_info[dataset_name]["mask"]
            mask_path = dataset_mask_info["path"]
            mask_suffix = dataset_mask_info["suffix"]

            dir_path = results_info["path"]
            file_prefix = results_info.get("prefix", "")
            file_suffix = results_info["suffix"]

            if not os.path.exists(dir_path):
                total_msgs.append(f"{dir_path} 不存在")
                continue
            elif not os.path.isdir(dir_path):
                total_msgs.append(f"{dir_path} 不是正常的文件夹路径")
                continue
            else:
                pred_names = [
                    name[len(file_prefix):-len(file_suffix)]
                    for name in os.listdir(dir_path)
                    if name.startswith(file_prefix) and name.endswith(file_suffix)
                ]
                if len(pred_names) == 0:
                    total_msgs.append(f"{dir_path} 中不包含前缀为 {file_prefix} 且后缀为 {file_suffix} 的文件")
                    continue

            mask_names = [
                name[len(file_prefix):-len(mask_suffix)]
                for name in os.listdir(mask_path)
                if name.endswith(mask_suffix)
            ]

            # 调试输出
            print(f"Prefix: {file_prefix}")
            print(f"Suffix: {file_suffix}")
            print(f"Prediction names in {dir_path}: {pred_names}")
            print(f"Ground truth mask names in {mask_path}: {mask_names}")

            pred_names_set = set(pred_names)
            mask_names_set = set(mask_names)

            intersection_names = pred_names_set.intersection(mask_names_set)
            if len(intersection_names) == 0:
                total_msgs.append(f"{dir_path} 中数据名字与真值 {mask_path} 不匹配")
            elif len(intersection_names) != len(mask_names):
                difference_names = mask_names_set.difference(pred_names_set)
                total_msgs.append(
                    f"{dir_path} 中数据({len(pred_names_set)})与真值({len(mask_names_set)})不一致: {difference_names}"
                )

    if total_msgs:
        print(*total_msgs, sep="\n")
    else:
        print(f"{method_json} & {dataset_json} 基本正常")

重新检查配置文件后输出如下:

Checking for Method4 ...
Prefix: animal-
Suffix: .png
Prediction names in Data/CHAMELEON/Test/Mask: ['1', '10', '11', '12', 
'13', '14', '15', '16', '17', '18', '19', '2', '20', '21', '22', '23', 
'24', '25', '26', '27', '28', '29', '3', '30', '31', '32', '33', '34', 
'35', '36', '37', '38', '39', '4', '40', '41', '42', '43', '44', '45',
 '46', '47', '48', '49', '5', '50', '51', '52', '53', '54', '55',
  '56', '57', '58', '59', '6', '60', '61', '62', '63', '64', '65',
   '66', '67', '68', '69', '7', '70', '71', '72', '73', '74', '75',
    '76', '8', '9']
Ground truth mask names in Data/CHAMELEON/Test/GT: ['1', '10', '11',
 '12', '13', '14', '15', '16', '17', '18', '19', '2', '20', '21',
  '22', '23', '24', '25', '26', '27', '28', '29', '3', '30', '31',
   '32', '33', '34', '35', '36', '37', '38', '39', '4', '40', '41', 
   '42', '43', '44', '45', '46', '47', '48', '49', '5', '50', '51',
    '52', '53', '54', '55', '56', '57', '58', '59', '6', '60', '61',
     '62', '63', '64', '65', '66', '67', '68', '69', '7', '70', '71',
      '72', '73', '74', '75', '76', '8', '9']
examples/config_method_json_example.json &
 examples/config_dataset_json_example.json 基本正常

可以看到此时对比两个路径下文件名信息是匹配的。

绘制pr曲线时

Traceback (most recent call last):
  File "plot.py", line 139, in <module>
    main(args)
  File "plot.py", line 133, in main
    save_name=args.save_name,
  File "/root/PySODEvalToolkit/metrics/draw_curves.py", line 71, in draw_curves
    raise ValueError(f"{x} must be contained in\n{dataset_names_from_npy}")
ValueError: NJUD must be contained in
['CHAMELEON', 'CAMO', 'COD10K']

原因是 rgbd_aliases.yaml 中的数据集需要删掉这样部分,因为 plot.py 脚本尝试绘制的曲线数据集包含 NJUD,但实际提供的 .npy 文件中只有 CHAMELEON、CAMO 和 COD10K。删除掉 rgbd_aliases.yaml 中下面这些数据集

    "NJUD": "NJUD",
    "NLPR": "NLPR",
    "SIP": "SIP",
    "STEREO1000": "STEREO1000",
    "RGBD135": "RGBD135",
    "SSD": "SSD",
    "LFSD": "LFSD",
    "DUTRGBD": "DUTRGBD",

绘制的曲线是空白

首先确保 output/curves.npy 文件中确实包含了正确的数据。可以使用以下代码来查看 .npy 文件的内容:

在 PySODEvalToolkit 目录下创建一个 check_nyp.py 文件然后执行该脚本查看输出的数据

import numpy as np

data = np.load('output/curves.npy', allow_pickle=True).item()
print(data)

排查了半天才发现是 alias_for_plotting.json 和 rgbd_aliases.yaml 中 method 配置不匹配导致 提供的 method_aliases 中的方法别名与 curves.npy 文件中的方法名称不匹配。因为别名不匹配,target_unique_method_names 为空,所以没有绘制任何曲线。为了解决这个问题,首先确保 method_aliases 中的方法别名与 curves.npy 中的方法名称一致。修改如下

alias_for_plotting.json

{
  "dataset": {
    "Name_In_Json": "Name_In_SubFigure",
    "NJUD": "NJUD",
    "NLPR": "NLPR",
    "DUTRGBD": "DUTRGBD",
    "STEREO1000": "SETERE",
    "RGBD135": "RGBD135",
    "SSD": "SSD",
    "SIP": "SIP",
    "CAMO": "CAMO",
    "CHAMELEON": "CHAMELEON",
    "COD10K": "COD10K"
  },
  "method": {
    "Name_In_Json": "Name_In_Legend",
    "GateNet_2020": "GateNet",
    "MINet_R50_2020": "MINet",
    "SINetV2_2022": "SINetV2"
  }
}

rgbd_aliases.yaml

dataset: {
    "CAMO": "CAMO",
    "CHAMELEON": "CHAMELEON",
    "COD10K": "COD10K"
}

method: {
    '2020-ECCV-DANetV19': 'DANet$_{20}$',
    '2020-ECCV-HDFNetR50': 'HDFNet$_{20}$',
    '2022-AAAI-SSLSOD-ImageNet': 'SSLSOD$_{22}$',
    'SINetV2_2022': 'SINetV2'
}

然后执行 plot 就可以得到绘制的非空白曲线了!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1688517.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文心一言 VS 讯飞星火 VS chatgpt (266)-- 算法导论20.2 1题

一、写出 PROTO-vEB-MAXIMUM 和 PROTO-vEB-PREDECESSOR 过程的伪代码。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 首先&#xff0c;让我们明确一下 PROTO-vEB-MAXIMUM 和 PROTO-vEB-PREDECESSOR 这两个过程是在介绍van Emde Boas树&#xff08;简称vEB树&a…

Vue - JavaScript基础学习

一、语言概述 JavaScript 中的类型应该包括这些&#xff1a; 1.数字&#xff08;默认双精度区别于Java&#xff09; console.log(3 / 2); // 1.5,not 1 console.log(Math.floor(3 / 2)); // 10.1 0.2 0.30000000000000004NaN&#xff08;Not a Number&#x…

深入用户内心:设计师如何通过可用性测试洞察用户需求

可用性测试是指让用户体验产品的原型或成品。设计师通过观察和分析用户的使用行为和感受&#xff0c;进一步合理地改进产品的设计方法。你可能会想知道我们可以用什么方法来测试可用性&#xff1f;随着互联网行业的快速迭代更新&#xff0c;可用性测试衍生出了许多类型和方法。…

Packet Tracer-HSRP+DHCPv4+VLAN间路由+以太通道综合实验

实验拓扑&#xff1a; 实验内容&#xff1a; VLAN及VLAN间路由的配置&#xff0c;以太通道的配置&#xff0c;STP的根调整&#xff0c;DHCPv4的配置&#xff0c;首跳冗余HSRP的配置。 实验最终结果&#xff1a; PC可以自动获取到DHCP-Server分配的IP地址&#xff0c;实现首跳…

【人工智能】模型性能评估

模型性能衡量介绍 混淆矩阵 混淆矩阵(Confusion Matrix&#xff09; TP(真阳性)&#xff1a;预测为阳性&#xff0c;且预测正确。 TN(真阴性)&#xff1a;预测为阴性&#xff0c;且预测正确。 FP(伪阳性)&#xff1a;预测为阳性&#xff0c;但预测错误&#xff0c;又称型一误…

widedeep模型简介

wide&deep模型 1.简介2.原理2.1 网络结构 3. 稀疏密集特征4.API和子类方式实现 1.简介 Wide and deep 模型是 TensorFlow 在 2016 年 6 月左右发布的一类用于分类和回归的模型&#xff0c;并应用到了 Google Play 的应用推荐中。wide and deep 模型的核心思想是结合线性模…

VBA_MF系列技术资料1-615

MF系列VBA技术资料1-615 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff0c;并结合自己的经验总结了这份MF系列VBA技术综合资料&#xff0c;而且开放源码&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-0…

Ubuntu切换内核版本

#安装内核安装工具 sudo apt-get install software-properties-common sudo add-apt-repository ppa:cappelikan/ppa sudo apt-get update sudo apt-get install mainline#安装指定内核版本(有些版本并不能安装成功) mainline install 5.14.10#更新GRUB配置 sudo update-grub#查…

go mod模式下,import gitlab中的项目

背景 为了go项目能够尽可能复用代码&#xff0c;把一些公用的工具类&#xff0c;公用的方法等放到共用包里统一管理。把共用包放到gitlab的私有仓库中。 遇到的问题 通过https方式&#xff0c;执行go get报了错误。 通过ssh方式&#xff0c;执行go get报了错误。 修改配置&am…

Joomla 3.7.0 (CVE-2017-8917) SQL注入漏洞环境

1 漏洞概述 Joomla是一个基于PHP的内容管理系统&#xff08;CMS&#xff09;&#xff0c;广泛应用于各类网站。2017年&#xff0c;Joomla 3.7.0版本被发现存在SQL注入漏洞&#xff08;CVE-2017-8917&#xff09;&#xff0c;攻击者可以利用该漏洞对数据库进行未授权查询或操作…

副业树洞聊天项目/树洞倾诉/陪陪系统源码/树洞源码下载搭建

随着社会的发展和人们生活水平的提高&#xff0c;越来越多的人在面临心理压力、情感困扰或生活困境时&#xff0c;需要一个可以宣泄、倾诉和寻求支持的平台。而传统的人际交往方式往往会遇到难以排解的问题&#xff0c;比如担心被他人知晓自己的隐私等&#xff0c;这就导致了人…

鸿蒙系统和安卓系统通过termux搭建Linux系统—Centos

目录 1. 前言 2. 效果图展示 3. 安装termux 4. 安装Centos系统 4.1 更换源 4.2 拉取镜像 4.3 启动centos 5.结尾 1. 前言 大家好&#xff0c;我是jiaoxingk 今天这篇文章让你能够在手机或者平板上使用Linux-Centos系统 让你随时随地都能操作命令行进行装13 2. 效果图展示…

【科普知识】伺服电机中的内置制动器

在工业自动化和机器人技术快速发展的今天&#xff0c;伺服电机作为核心驱动元件&#xff0c;其性能与功能直接影响整个系统的运行效率与稳定性。 近年来&#xff0c;一体化伺服电机技术不断融合创新&#xff0c;并逐步加入了许多新的硬件和软件的功能&#xff0c;为工业自动化领…

全域外卖是谁创办的公司?

全域外卖是谁创办的公司&#xff1f;这个问题是抽象的。正确的问法应该是全域外卖是谁研发的系统。 在了解全域外卖系统前&#xff0c;我们首先要了解什么是全域外卖&#xff0c;什么是全域团购。全域指的是多平台。当然这个平台是越多越好。实际上也可以理解为聚合外卖、聚合…

图数据库助力供应链柔性升级

导读 当今市场环境受短视频等流媒体影响&#xff0c;任何风险事件在社交网络中传播速度极其迅速&#xff0c;留给企业的反应时间按分秒计&#xff0c;传统供应链的年度计划面对剧烈变化的市场环境已失去意义。此外&#xff0c;受近年局势动荡的影响&#xff0c;市场需求和供应…

Unity 资源 之 限时免费的Lowpoly农场动物,等你来领!

Unity资源 之 Lowpoly farm animals 农村动物 前言资源包内容领取兑换码 前言 Unity 资源商店为大家带来了一份特别的惊喜——限时免费的农场动物资源&#xff01;这是一个充满趣味和实用性的资源包。 资源包内容 在这个资源包中&#xff0c;你可以找到丰富多样的低地养殖动物…

VScode代码片段自动转图标

注&#xff1a;在VScode编辑器中&#xff0c;编辑html、vue等文件时&#xff0c;特定代码片段&#xff08;token/xxx’等&#xff09;自动转图标显示&#xff0c;按住“ctrl鼠标左键”还可跳转“https://icones.js.org/collections”&#xff0c;个人感觉干扰代码编写&#xff…

VMware 安装Windows 7 SP1

1.下载镜像 迅雷&#xff1a;ed2k://|file|cn_windows_7_enterprise_with_sp1_x64_dvd_u_677685.iso|3265574912|E9DB2607EA3B3540F3FE2E388F8C53C4|/ 2.安装过程 自定义名字&#xff0c;点击【浏览】自定义安装路径 点击【浏览】&#xff0c;选择下载镜像的路径 结束啦~ Win…

详解http协议

什么是HTTP协议 定义 Http协议即超文本传送协议 (HTTP-Hypertext transfer protocol) 。 它定义了浏览器&#xff08;即万维网客户进程&#xff09;怎样向万维网服务器请求万维网文档&#xff0c;以及服务器怎样把文档传送给浏览器。从层次的角度看&#xff0c;HTTP是面向&am…

记录一个写SpringBoot中Hive数据可以正常提取但无法存到MySQL的bug

【背景】 我正在用SpringBoot框架写一个数据治理项目&#xff0c;目前所处阶段是将hive和hdfs中的元数据提取出来&#xff0c;存储到MySQL中&#xff0c;我的hive和hdfs上的数据存储在三台Linux服务器上&#xff08;hadoop102-104&#xff09;&#xff0c;MySQL在我本地Window…