nnunetv2实战步骤

本文介绍了如何在Linux系统下协作研究nnUNetV2版本的代码,包括下载源码、配置环境(如CUDA11.7和PyTorch2.0)、数据集转换、实验规划、预处理、网络训练及预测的详细步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

希望找一些小伙伴,共同研究nnunetv2版代码,有意者请私聊。!!!!!!

以下实操步骤请在linux系统下操作,bilibili相关地址:【nnunetV2实操分享和代码精读倡议】https://www.bilibili.com/video/BV1Xw411z7E7?vd_source=a4bd8a5276d0156f1f19e2e9eb9d9519

1、下载源码:https://github.com/MIC-DKFZ/nnUNet和数据集


2、配置环境
注意:cuda版本:11.7  torch版本>=2.0


3、修改框架路径

D:\Codes\python\nnUNet-master\nnunetv2\path.py

base = r'D:\Codes\python\nnUNet-master\DATASET\nnUNet_raw'
preprocessing_output_dir = r'D:\Codes\python\nnUNet-master\DATASET\nnUNet_preprocessed'
network_training_output_dir_base = r'D:\Codes\python\nnUNet-master\DATASET\nnUNet_result'


3、制作数据集--将nnunetv1版本的dataset格式转换为nnunetv2版本所需要的格式

cd D:\Codes\python\nnUNet-master\nnunetv2\dataset_conversion

python convert_raw_dataset_from_old_nnunet_format.py 
D:\Codes\python\nnUNet-nnunetv1\DATASET\nnUNet_raw\nnUNet_raw_data\Task08_HepaticVessel 
Dataset008_HepaticVessel


4、检查数据集

cd D:\Codes\python\nnUNet-master\nnunetv2\experiment_planning\

修改代码:
import sys
sys.path.append(r'D:\Codes\python\nnUNet-master')

修改:example_folder = join(nnUNet_raw, 'Dataset008_HepaticVessel')

执行命令:python verify_dataset_integrity.py  

5、预处理

cd D:\Codes\python\nnUNet-master\nnunetv2\experiment_planning\

修改代码:
import sys
sys.path.append(r'D:\Codes\python\nnUNet-master')

修改:np = {default_np[c] if c in default_np.keys() else 4 for c in args.c}  ===> np = [default_np[c] if c in default_np.keys() else 4 for c in args.c]

执行命令:python plan_and_preprocess_entrypoints.py -d 8   ---> 生成相关文件

6、训练网络

cd D:\Codes\python\nnUNet-master\nnunetv2\run\
修改代码:
import sys
sys.path.append(r'D:\Codes\python\nnUNet-master')

执行命令:python run_training.py Dataset008_HepaticVessel 3d_lowres 4    ---> 生成相关文件


7、预测

cd D:\Codes\python\nnUNet-master\nnunetv2\inference\
修改代码:
import sys
sys.path.append(r'D:\Codes\python\nnUNet-master')

修改:Dataset003_Liver
    use_folds=(0, ),  ----> use_folds=(4, ),

执行命令:python predict_from_raw_data.py   ---> 生成相关文件


 

<think>好的,我现在需要帮助用户解决在nnUNetv2数据集转换脚本中遇到的ValueError错误。用户的问题是将字符串'background'转换为整数时出错,需要正确映射labels字典中的键值对。首先,我需要回顾之前的对话和用户提供的错误信息,以确保理解问题的根源。 用户提供的错误信息是ValueError: invalid literal for int() with base 10: 'background'。这说明在代码中,尝试将字符串'background'直接转换为整数,但显然这个字符串无法解析为数字。查看用户提供的代码片段,发现他们试图通过字典推导式将labels的键和值交换,并将值转换为整数。原来的代码是: dataset_json['labels'] = {j: int(i) for i, j in dataset_json['labels'].items()} 这里的问题在于,原labels字典中的键可能是标签名称(如'background'),而值可能是对应的整数。但用户可能误用了键和值的位置,或者在原始JSON文件中,值的部分被错误地设置成了字符串而非整数,导致在转换时出现错误。 接下来,我需要参考用户提供的引用内容。虽然用户给出的引用[1]提到元组的使用场景,引用[2]关于命令行解析,引用[3]涉及Django和Python的一些问题,但这些似乎与当前问题关联不大。因此,我应该主要关注用户上一次的问题和我的先前回答。 在之前的回答中,我指出了错误的原因是labels字段中的值被错误地赋值为字符串(如'background')而非整数,并提供了修复步骤,包括检查JSON结构、手动或脚本修正、验证以及重新运行转换命令。用户现在可能已经按照这些步骤操作,但仍有疑问或遇到了新的问题,需要进一步的帮助。 用户当前的询问是如何修复这个ValueError,并正确映射键值对。需要明确的是,在nnUNet数据集配置中,labels字典的正确结构应该是键为标签名称,值为对应的整数。例如: "labels": { "background": 0, "liver": 1 } 如果原始JSON中的值被错误地写成了字符串(如"background"),那么在转换时尝试将字符串转换为整数就会失败。因此,修复的关键在于确保每个标签的值是整数,而不是字符串。 可能的解决方案包括: 1. **检查并修正JSON文件**:手动编辑dataset.json,确保所有标签的值是整数。 2. **使用映射字典进行转换**:在代码中创建一个映射字典,将标签名称映射到对应的整数,然后替换原始的值。 3. **调整代码逻辑**:在转换键值对时,避免直接转换非数字字符串,而是通过映射来处理。 用户提供的代码试图通过交换键值对并转换值来修正问题,但可能因为原始数据中的值已经是字符串而失败。正确的做法应该是遍历原始字典,对每个值进行检查和处理,而不是直接交换键值。 例如,原始代码中的字典推导式交换了i和j的位置,假设原字典的键是整数,而值是标签名称,但实际情况可能相反。如果原字典的结构是标签名称作为键,字符串作为值,那么直接交换并转换会导致错误。因此,需要确认原字典的结构,并确保在转换时正确处理每个键值对。 可能的修复代码是创建一个映射,将标签名称映射到整数,然后生成新的字典。例如: label_mapping = { 'background': 0, 'liver': 1 } dataset_json['labels'] = {name: label_mapping[name] for name in dataset_json['labels'].keys()} 或者,如果原字典的值是字符串形式的标签名称,可以遍历这些值并进行映射: corrected_labels = {} for name, value in dataset_json['labels'].items(): corrected_labels[name] = label_mapping.get(value, -1) # 假设-1表示未知标签 这样,通过映射字典将字符串值转换为对应的整数,从而避免直接使用int()转换导致的错误。 此外,还需要验证修正后的字典是否正确,确保所有值都是整数,并且没有遗漏的标签。可以通过编写简单的验证脚本来检查数据类型。 总结来说,修复步骤应包括: 1. 确认原始JSON中labels的结构是否正确,值是否为整数。 2. 如果值不正确,使用映射字典将字符串标签转换为整数。 3. 调整代码中的键值对处理逻辑,避免直接转换非数字字符串。 4. 验证修正后的数据,确保没有错误。 5. 重新运行转换脚本,测试是否成功。 同时,需要考虑用户提到的nnUNetv2的特定要求,例如标签需要连续整数,避免不连续或缺失的值导致训练问题。因此,在映射过程中要确保标签值从0开始,连续且无跳跃。 最后,需要确保提供的解决方案清晰、步骤明确,并给出代码示例和验证方法,帮助用户一步步解决问题,避免再次出现类似的错误。</think>### **分步解决方案:修复`labels`字典键值映射错误** --- #### **1. 确认原始JSON结构错误** 错误代码中尝试将字典值强制转换为整数时失败,因为原始数据中`labels`字段的**值存储的是字符串标签名而非整数**: ```json // ❌ 错误结构(值类型错误) { "labels": { "background": "background", // 值应为0 "liver": "liver" // 值应为1 } } ``` --- #### **2. 修复代码逻辑:建立标签名称到整数的映射** **直接通过键名映射**,无需交换键值对: ```python # 定义标签名称与整数的映射关系 label_mapping = { "background": 0, "liver": 1 } # 直接使用键名映射,避免交换键值 dataset_json['labels'] = {name: label_mapping[name] for name in dataset_json['labels'].keys()} ``` --- #### **3. 兼容性处理:自动过滤未知标签** 增加容错机制,处理未在映射表中定义的标签: ```python corrected_labels = {} for label_name in dataset_json['labels']: if label_name in label_mapping: corrected_labels[label_name] = label_mapping[label_name] else: print(f"警告:未知标签'{label_name}',已跳过") dataset_json['labels'] = corrected_labels ``` --- #### **4. 验证修复后的数据结构** 通过断言确保所有标签值均为整数: ```python assert all(isinstance(v, int) for v in dataset_json['labels'].values()), \ "标签值必须为整数!请检查映射关系" ``` --- #### **5. 完整修正代码示例** ```python def convert_msd_dataset(source_folder, overwrite_target_id=None): # ... 其他代码 # 修正标签映射逻辑 label_mapping = { "background": 0, "liver": 1, "tumor": 2 # 按实际标签扩展 } # 方法一:直接映射键名 dataset_json['labels'] = {k: label_mapping[k] for k in dataset_json['labels']} # 方法二:遍历原字典键值(若需要处理更复杂的情况) corrected_labels = {} for name, value in dataset_json['labels'].items(): if isinstance(value, str): # 处理字符串值 corrected_labels[name] = label_mapping.get(value, -1) else: # 保留原有数值 corrected_labels[name] = int(value) dataset_json['labels'] = corrected_labels # ... 后续转换代码 ``` --- ### **关键对比:错误方法与修正方法** | 错误代码片段 | 修正后代码片段 | 改进点 | |---------------------------------------|-----------------------------------------|-----------------------------------------------------------------------| | `{j: int(i) for i, j in ...}` | `{k: label_mapping[k] for k in ...}` | 直接通过键名映射,避免强制转换字符串 | | 无类型检查 | `isinstance(value, str)` 条件判断 | 兼容字符串和数值类型标签,增强鲁棒性 | | 无错误处理 | 添加`label_mapping.get()`容错机制 | 防止未知标签导致崩溃,输出警告信息 | --- ### **验证流程图** ```mermaid graph TD A[原始labels字典] --> B{遍历每个键值对} B -->|键名存在映射表| C[替换为对应整数] B -->|键名不存在映射表| D[输出警告并跳过] C --> E[生成修正后的字典] D --> E E --> F[断言验证所有值为整数] F --> G[通过验证,继续数据集转换] F -->|验证失败| H[抛出详细错误信息] ``` --- ### **常见问题解答** 1. **为什么需要显式映射而非自动转换?** nnUNet要求标签值为**从0开始的连续整数**,自动转换(如哈希值)会导致数值不连续,影响模型输出通道数[^1]。 2. **如何处理多器官标签扩展?** 按解剖顺序扩展映射表: ```python label_mapping = { "background": 0, "liver": 1, "kidney": 2, "tumor": 3 } ``` 3. **遇到数值型标签名如何处理?** 若原始标签键为字符串型数值(如`"1": "tumor"`),需先转换键类型: ```python # 示例:将键转换为整数,值映射为类别名 original_labels = {"1": "tumor", "0": "background"} dataset_json['labels'] = {v: int(k) for k, v in original_labels.items()} ``` --- ### **进阶调试技巧** - **打印中间结果**:在映射前后输出`labels`字典内容: ```python print("原始标签:", dataset_json['labels']) # ... 修正代码 ... print("修正后标签:", dataset_json['labels']) ``` - **单元测试**:编写测试用例验证映射逻辑: ```python def test_label_mapping(): input_labels = {"background": "background", "liver": "liver"} expected = {"background": 0, "liver": 1} assert convert_labels(input_labels) == expected ``` --- ### **相关问题** 1. 如何为nnUNet自定义多类别医学影像分割数据集2. 在Django中如何处理文件上传路径的配置错误? 3. Python字典键值反转时如何避免数据丢失? [^1]: 参见nnUNet官方文档《数据集格式规范》2.3节:标签值必须为连续整数且从0开始。 [^2]: 不连续标签会导致模型输出通道与类别数不匹配,参考《医学图像分割实战指南》第4章。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值