论文代码复现之AutoSAM (Xinrong Hu version)

论文:https://arxiv.org/abs/2306.13731

代码:https://github.com/xhu248/AutoSAM/

我需要先复现AutoSAM,然后再在GlaS数据集上测试一下。这个代码个人感觉还是相当工整规范的,文件夹层次也比较清晰,值得学习。可惜就是readme介绍页面步骤太过省略,对新手不太友好。此外,代码好像还有一些bug,比如args的下划线和减号在代码里有些错误,和下文对应不上。这个代码里没有提供训练好的权重文件,因此必须得自己从头训练(当然也可以管作者发邮件要,但是我用不上ACDC这个数据集,只用来调试,之后会换成别的数据集)。本着改动越少越好的原则,我准备直接上来就试一下AutoSAM在单GPU上能否运行起来。

第一步:配置Python和PyTorch环境(成功)

第二步:下载SAM权重文件并放到指定位置

注意权重文件要放在代码根目录下,但我这个人最忌讳的就是数据集和checkpoint乱放,我要通过建立软连接来建立链接(建立软链接不会占用额外的空间,并且使得结构更加清晰,代码也能够正常运行,下文的downloads-AutoSAM...是我自己的目录,请修改为你自己的路径):

ln -s ../downloads-AutoSAM/SAM-checkpoints/sam_vit_b_01ec64.pth ./sam_vit_b_01ec64.pth
ln -s ../downloads-AutoSAM/SAM-checkpoints/sam_vit_l_0b3195.pth ./sam_vit_l_0b3195.pth
ln -s ../downloads-AutoSAM/SAM-checkpoints/sam_vit_h_4b8939.pth ./sam_vit_h_4b8939.pth

第三步:下载ACDC数据集(成功)

放在任意位置都行,后面会使用命令行里的args让你提供存放位置。

第四步:运行代码

不使用微调CNN解码器,直接微调AutoSAM。作者提供了一个多GPU同时调试AutoSAM,虽然快,但是代码好像有bug并且我没看懂。代码为:

python scripts/main_autosam_seg.py --src_dir ${ACDC_folder} \ --data_dir ${ACDC_folder}/imgs/ --save_dir ./${output_dir}  \ --b 4 --dataset ACDC --gpu ${gpu} \ --fold ${fold} --tr_size ${tr_size}  --model_type ${model_type} --num_classes 4

对于gpu设置,在这个项目里表示指定某一个具体的GPU训练,也就是如果设置了使用某个GPU训练,那么就不能多GPU同时训练了,对应代码里的:

if args.gpu is not None:
    warnings.warn('You have chosen a specific GPU. This will completely '
                  'disable data parallelism.')

此外,指令中这个fold应该是取第几折。我将splits.pkl打印出来,发现有5折,其中选中部分为一折。既然有五折,那么fold取值为0/1/2/3/4中任意一个。

${tr_size}在Github上写的解释是“你训练的量是多少”,对应到论文里,论文里的volumn取3或者取5。不过进入到代码里就会发现tr_size并没有用到,所以训练时就不考虑这个了。model_type就是vit_b vit_l vit_h三选一,其中vit_b表示该图像编码器基于ViT架构,并且编码器的体量(大小或者复杂度)是base的,vit_l表示large,vit_h表示huge,其对应的文件大小也是逐渐增加的。其中ViT_h最好,而ViT_b占用资源更少,适用范围更广。但在此处我打算先尝试一下ViT_l(不过由于vit_l是默认的,其实不设置也行)。

对于我来说,我需要执行的具体代码为(到后面需要改batch_size并且更改成vit_b):

CUDA_VISIBLE_DEVICES=7 python scripts/main_autosam_seg.py --src_dir ../downloads-AutoSAM/ACDC-dataset/ --data_dir ../downloads-AutoSAM/ACDC-dataset/imgs/ --save_dir output_acdc_vit_l --b 4 --dataset ACDC --gpu 0 --fold 0 --model_type vit_l --num_classes 4

要求安装nibabel,其原因是要最后处理为nii文件,其实我并不需要处理那个文件,但是为了代码完整性,勉为其难的先装一下吧:

pip install nibabel -i https://pypi.tuna.tsinghua.edu.cn/simple

还要安装tensorboard!!!太好了,我喜欢看tensorboard的图像!!!

pip install tensorboard -i https://pypi.tuna.tsinghua.edu.cn/simple

还要安装six,batchgenerators,SimpleITK,medpy。

遇到报错:

Traceback (most recent call last):
  File "scripts/main_autosam_seg.py", line 35, in <module>
    from dataset import generate_dataset, generate_test_loader
  File "./main-AutoSAM/dataset/__init__.py", line 3, in <module>
    from .utils import *
  File "./main-AutoSAM/dataset/utils.py", line 5, in <module>
    from dataset.SliceLoader import SliceDataset
ModuleNotFoundError: No module named 'dataset.SliceLoader'

别慌,查看源码发现这个dataset.SliceLoader根本用不到,可能是作者重构代码时忘了改了,注释掉./dataset/utils.py第5行代码即可。

在一块16GB 3090上就能运行真的很诱人,我在Tesla T4 16GB上尝试运行,当batch_size=4时不成功,调整batch_size=2,能完美运行,其显存占用为7782/15109MB,可见当batch_size=4时会报错,但是其实就差一点点,为啥非和我较这个几百MB的真呢,batch_size=4不香吗,真无语。即最后的指令为:

CUDA_VISIBLE_DEVICES=7 python scripts/main_autosam_seg.py --src_dir ../downloads-AutoSAM/ACDC-dataset/ --data_dir ../downloads-AutoSAM/ACDC-dataset/imgs/ --save_dir output_acdc_vit_b --b 2 --dataset ACDC --gpu 0 --fold 0 --model_type vit_b --num_classes 4

既然batch_size=2的时候vit_b可以跑,batch_size=4的时候谁都别想跑,那我再试试batch_size=2的时候的vit_l和vit_h吧:

CUDA_VISIBLE_DEVICES=8 nohup python scripts/main_autosam_seg.py --src_dir ../downloads-AutoSAM/ACDC-dataset/ --data_dir ../downloads-AutoSAM/ACDC-dataset/imgs/ --save_dir output_acdc_vit_l --b 2 --dataset ACDC --gpu 0 --fold 0 --model_type vit_l --num_classes 4 >nohup_l.out 2>&1 &

CUDA_VISIBLE_DEVICES=9 python scripts/main_autosam_seg.py --src_dir ../downloads-AutoSAM/ACDC-dataset/ --data_dir ../downloads-AutoSAM/ACDC-dataset/imgs/ --save_dir output_acdc_vit_h --b 2 --dataset ACDC --gpu 0 --fold 0 --model_type vit_h --num_classes 4

想想还是不费那功夫了,因为我最后想跑的数据集也不是它,先把vit_b的流程跑通再说。

在运行vit_b的时候发现报错:

AttributeError: module 'numpy' has no attribute 'bool'.
`np.bool` was a deprecated alias for the builtin `bool`. To avoid this error in existing code, use `bool` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.bool_` here.
The aliases was originally deprecated in NumPy 1.20; for more details and guidance see the original release note at:
    https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
但实际上这个报错是程序调用了medpy,而medpy中的代码包含numpy.bool,导致报错。解决方式有二:降低numpy版本到1.20以下;或者将np.bool改为np.bool_(参考:AttributeError: module ‘numpy‘ has no attribute ‘bool‘._attributeerror: module 'numpy' has no attribute 'b-CSDN博客)。经过调试,应当选择后者,即修改medpy代码。原因是选择前者会发现引入了包不匹配:

ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
nibabel 5.2.0 requires numpy>=1.20, but you have numpy 1.19.5 which is incompatible.
scikit-image 0.21.0 requires numpy>=1.21.1, but you have numpy 1.19.5 which is incompatible.

所以还是修改medpy代码就好:

vim /usr/local/anaconda3/envs/xxx/lib/python3.8/site-packages/medpy/metric/binary.py,在第1200行和下面那行的bool后面加个下划线,进入vim后先按下G能够定位到末尾,再往上翻会更快。

AttributeError: module ‘numpy‘ has no attribute ‘bool‘._attributeerror: module 'numpy' has no attribute 'b-CSDN博客

代码成功运行,最后若干行的输出结果如图所示。

此外,在save_dir里有若干文件:

回到代码进行对应发现:infer里面是若干经过模型推理的nii文件,label是与infer对应的标注nii文件,tensorboard0文件夹对应的是训练曲线,dice_pre.txt里的结果就是前文最后的输出日志结果。

events.out.tfevents的可视化:

tensorboard --logdir=D:\..\output_acdc_vit_b --port=8008

D:\xxx是events.out.tfevents文件所在的文件目录;--port=8008 是开启可视化的“地址”,修改 --port= 后面的数字可以同时可视化多个不同的events.out.tfevents文件。

以上就是AutoSAM的源代码运行,能够成功跑通。但是查看效果就发现并不是很好,有点差的离谱,可能和调参也有关系吧。但是看了下本身论文的结果,也不是很靠谱的样子。接下来将看看其他SAM相关的对GlaS腺体分割数据集进行有效适配的论文并进行复现。

未完待续

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值