U-Mamba复现中遇到的问题及解决方法
1. 环境安装
1.1. 出错步骤1:创建umamba虚拟环境出错
解决方案在我的另一篇文章中
1.2. 出错步骤2:安装pytorch出错
1.3. 出错步骤3:安装casual-conv1d出错
错误1:
首先尝试了第一种解决方法:使用git clone直接将causal-conv1d clone过来
但是出错:(后来发现前面加上一个sudo就行)
后尝试第二种解决方法:直接从github上将项目下载到本地,再将项目发到服务器上再进行安装,但是用WinScp发文件的时候告诉我权限不够了…遂放弃
第三种解决方法:
conda install -c "nvidia/label/cuda-11.7.0" cuda-nvcc//这里是根据自己的cuda版本进行安装的
conda install packaging
pip install -i https://pypi.mirrors.ustc.edu.cn/simple causal-conv1d==1.1.1//这里用中科大的源,因为我自己用清华源的时候会Timeout,但每个人情况可能不同哪个能用就用哪个
成功安装(Building wheel for mamba_ssm的时间会比较长,安装mamba_ssm的时等待时间也要等较长时间)
- 注意:安装的mamba_ssm的版本一定要和casual-conv1d的版本相同,
要安装mamba_ssm==1.1.1
版本,否则后面运行时会报错(另一定要注意是安装mamba_ssm不是mamba!!!)
2. 运行:
2.1. 数据集预处理
nnUnet有严格的数据集结构要求,按照以下步骤制作自定义数据集:
-
在umamba下有一个文件夹data,初始只包含了
nnUNet_raw
文件夹,其中包含了作者在文章中使用的四个数据集(只有数据集名字,其中并没有图像)
-
从作者提供的网盘中下载数据集,这里使用的是Dataset_703,下载后包含了以下几个文件:
-
在data文件夹下创建三个文件夹,分别为
nnUNet_results、nnUNet_raw、nnUNet_preprocessed
-
配置环境变量
export nnUNet_results="/app/data/nnUNet_results"
export nnUNet_preprocessed="/app/data/nnUNet_raw"
export nnUNet_raw="/app/data/nnUNet_raw"
- 文章作者提供的数据集已经经过初步的处理的,所以不需要进行数据转换,只需要进行预处理即可:
nnUNetv2_plan_and_preprocess -d 703(这里根据自己的数据集名称进行修改DATASET_ID) -verify_dataset_integrity -c 2d(如果是3d图像,修改为3d即可)
开始处理:
2.2. 训练
nnUNet_n_proc_DA=0 CUDA_VISIBLE_DEVICES=0 nnUNetv2_train Dataset703_NeurIPSCell 2d all -tr nnUNetTrainerUMambaEnc -device cuda
2.2.1. 问题一
在docker容器中运行的,首先报错:
ImportError: libGL.so.1: cannot open shared object file: No such file or dir
解决方法:需要更新apt,安装libgl1-mesa-glx
apt update
apt install libgl1-mesa-glx
2.2.2. 问题二
在docker容器中运行老是能碰到奇奇怪怪的问题,这次是:RuntimeError: One or more background workers are no longer alive. Exiting. Please check the print statements above for the actual error message
最后在nnUnet的issues中找到了解决方法:https://github.com/MIC-DKFZ/nnUNet/issues/1343
nnUNet_n_proc_DA=0 CUDA_VISIBLE_DEVICES=0 nnUNetv2_train Dataset703_NeurIPSCell 2d all -tr nnUNetTrainerUMambaEnc -device cuda
2.2.3. 问题三
ausal_conv1d_fwd(): incompatible function arguments. The following argument types are supported:
1.(arg0: torch.Tensor, arg1: torch.Tensor, arg2: Optional[torch.Tensor], arg3: Optional[torch.Tensor], arg4: bool) -> torch.Tensor
解决方法:将mamba-ssm版本换成1.1.1版本,pip install mamba-ssm=1.1.1
开始训练啦:
显存占用大约为15G:
训练出的checkpoints在data/nnUNet_results
中
3. 测试
nnUNetv2_predict -i INPUT_FOLDER -o OUTPUT_FOLDER -d DATASET_ID -c CONFIGURATION -f all -tr nnUNetTrainerUMambaEnc --disable_tta
CONFIGURATION的内容是2d或者3d_fullres
-tr这里是训练时用的trianer,要和训练时保持一致
3.1. 问题一和二
Error: mkl-service + Intel® MKL: MKL_THREADING_LAYER=INTEL is incompatible with libgomp-a34b3233.so.1 library.Try to import numpy first or set the threading layer accordingly. Set MKL_SERVICE_FORCE_INTEL to force it.
参考这个方法MKL_THREADING_LAYER=INTEL is incompatible with libgomp.so.1 library
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
再解决这个问题:RuntimeError: Background workers died. Look for the error message further up! If there is none then your RAM was full and the worker was killed by the OS. Use fewer workers or get more RAM in that case!
参考nnUNet中的issues:Background workers died.
设置-nnp(Number of processes used for preprocessing. More is not always better. Beware of ’ 'out-of-RAM issues)和-nps('Number of processes used for segmentation export. More is not always better. Beware of ''out-of-RAM issues)都为1。
最后的测试代码为:
CUDA_VISIBLE_DEVICES=0 nnUNetv2_predict -i /app/data/nnUNet_raw/Dataset703_NeurIPSCell/imagesVal/ -o /app/result/ -d 703 -c 2d -f all -tr nnUNetTrainerUMambaEnc --disable_tta -npp 1 -nps 1
3.2. 生成的测试图像全黑
因为它的mask是归一化后用0-1保存的,所以把图像乘以255就可以了
from PIL import Image
import numpy as np
import os
# 定义源图像文件夹和目标文件夹路径
source_folder = 'E:\\Umamba\\Dataset703_NeurIPSCell\\result' # 源文件夹
target_folder = 'E:\\Umamba\\Dataset703_NeurIPSCell\\results' # 输出/目标文件夹
# 如果目标文件夹不存在,则创建它
if not os.path.exists(target_folder):
os.makedirs(target_folder)
for file_name in os.listdir(source_folder):
if file_name.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tif', '.tiff')):
# 构建源文件和目标文件的完整路径
source_path = os.path.join(source_folder, file_name)
target_path = os.path.join(target_folder, file_name)
# 打开和处理图像
img = Image.open(source_path)
img_array = np.array(img)
img_array = (img_array * 255).astype(np.uint8)
img_modified = Image.fromarray(img_array)
# 保存修改后的图像到目标文件夹
img_modified.save(target_path)
print("所有图像已处理完毕,并保存到:", target_folder)