论文代码复现之OEEM (Online Easy Example Mining)

本文详细描述了如何在虚拟环境中训练和优化一个名为OEEM的模型,涉及数据下载、权重管理、分类网络和分割模型的训练,以及伪掩码生成和模型测试。作者分享了训练参数调整和遇到的问题,但最终的性能指标与论文有所差距,有待进一步探究。
摘要由CSDN通过智能技术生成

论文链接:https://arxiv.org/abs/2206.06665
代码链接:https://github.com/xmed-lab/OEEM

第一步:新建虚拟环境

第二步:下载百度网盘资源,包括数据集及权重,并建立软连接

此处建议将原有权重文件复制一份做备份,因为新生成的权重文件可能会覆盖掉原始的文件。这里需要注意的是,classification的weights和segmentation的weights是link到同一个地方的,这是没有问题的。

第三步:训练

1、训练分类网络

python classification/train.py -d 0 -m res38d

其中d是device的意思,如果想使用第5 6 7号GPU,则代码为:

CUDA_VISIBLE_DEVICES=5,6,7 python classification/train.py -d 0 1 2 -m res38d

而不建议使用:

python classification/train.py -d 5 6 7 -m res38d

默认是batch_size=20, epoch=20,一个epoch大约8分钟,根据实际GPU使用情况可以适当增大batch_size,我将batch_size设置为64,即在命令行添加-b 64(我这里batch_size最多设置64,再多就报错内存不够了)。如果是在后台执行命令,可以执行:

CUDA_VISIBLE_DEVICES=5,6,7 nohup python classification/train.py -d 0 1 2 -m res38d -b 64 >cls_train.log 2>&1 &

运行完后去./classification/result查看train_loss和valid_iou两个图像,发现20个epoch没收敛啊,还能变得更好,因此再试个120个epoch的:

CUDA_VISIBLE_DEVICES=0,1,2,3,4,5 nohup python classification/train.py -d 0 1 2 3 4 5 -m res38d -b 64 -test_every 2 -epoch 120 >cls_train.log 2>&1 &

这里虽然提供了测试图像,但是我更希望写入tensorboard的summary_writer里生成events.out.tfevents文件,下次看的时候改一下代码。与此同时,运行完后再./classification/weights文件夹下面会有res38d_best.pth和res38d_last.pth。如果你直接用res38d的话,这两个新生成的pth会覆盖掉官方提供的pth。因为这里的weights文件夹和下载权重资源的路径在之前通过命令行link到一起了。

2、生成伪掩码(对我而言这是非常重要的一步!)

CUDA_VISIBLE_DEVICES=8,9 python classification/prepare_seg_inputs.py -batch 512 -d 0 1 -ckpt res38d_best_240221

这里虽然可以用多个GPU并行训练,但是实际上只有一个GPU在工作,不需要用多个GPU。这个步骤耗时约3.5小时。代码分为两部分:代码最后两行之前执行情况是会在classification/res38d_best_240221_train_pseudo_mask文件夹下生成9703个伪掩码npy文件;而代码最后两行执行glas_join_crops_back()函数,是将npy文件整合成png伪彩图。在执行结束后全部npy文件都将被删除!可以看到该函数调用的是./classification/utils/pyutils.py下的相应函数。如果想保留npy文件,可以将该函数最后的os.remove换成os.move,将其移动到某个文件夹下即可。此外,通过观察代码可以发现,这里的ckpt只需要输入文件名,与classification/weights下的pth文件名一致即可,不要写完整路径。官方提供了res38d_best和res38d_last两个版本。而res38d是一阶段分类网络初始化权重,并不是推理时所用的权重。

3、将生成的伪掩码切成patch(只有一行进度条)

python segmentation/tools/crop_img_and_gt.py segmentation/glas/images classification/res38d_240221_best_train_pseudo_mask segmentation/glas

执行结束后会在segmentation/glas文件夹下生成img_train_256_192和pesudo_train_256_192两个文件夹,文件夹里存放着对应的patch文件。这个步骤生成的图片看起来都是黑色的,需要额外进行颜色变换。

4、训练分割模型

cd segmentation
bash tools/dist_train.sh configs/pspnet_oeem/pspnet_wres38-d8_10k_histo.py 1 runs/oeem

提示没有安装pydensecrf库,网上说python版本大于3.5不能直接安装。执行:

pip install git+https://github.com/lucasb-eyer/pydensecrf.git 

完美运行!另外,据说执行:conda install -c conda-forge pydensecrf也是可以的,但是我这里不行,是服务器本身的问题。

运行报错:

text, _ = FormatCode(text, style_config=yapf_style, verify=True)

TypeError: FormatCode() got an unexpected keyword argument 'verify'

解决办法:最新的yapf=0.40.2,重新安装yapf=0.40.1即可。感谢大哥:mmdetection 报错 TypeError: FormatCode() got an unexpected keyword argument ‘verify‘-CSDN博客

debug后即可完美运行,默认迭代次数是10000轮,平均3分钟迭代100轮,全部运行需要5个小时。

不过命令行中的“1”对应使用1块GPU,我肯定希望多运行,因此执行代码:

CUDA_VISIBLE_DEVICES=2,3,4,5,6 nohup bash tools/dist_train.sh configs/pspnet_oeem/pspnet_wres38-d8_10k_histo.py 5 runs/oeem >seg_train.log 2>&1 &

上述代码执行后,在某个时刻报错:

WARNING:torch.distributed.elastic.agent.server.api:Received 1 death signal, shutting down workers
...

raise SignalException(f"Process {os.getpid()} got signal: {sigval}", sigval=sigval)
torch.distributed.elastic.multiprocessing.api.SignalException: Process 32664 got signal: 1
网上看可能和nohup有关,解决方法未知,先不探索了,找个电脑后台挂着,先把程序跑完吧。

第四步:测试

1、测试分割模型

cd segmentation
bash tools/dist_test.sh configs/pspnet_oeem/pspnet_wres38-d8_10k_histo_test.py runs/oeem/[name of best ckpt] 1

将[name of best ckpt]替换为iter_10000.pth,也可以换成官方在weight里提供的res38d_oeem_release.pth。即:

bash tools/dist_test.sh configs/pspnet_oeem/pspnet_wres38-d8_10k_histo_test.py weights/res38d_oeem_release.pth 1

最后一个gpu数量为1时,日志为:

2024-02-28 22:09:24,175 - mmseg - INFO - Loaded 924 images
load checkpoint from local path: runs/oeem/iter_10000.pth
[                                                  ] 3/924, 0.1 task/s, elapsed: 48s, ETA: 14584s

最后一个gpu数量为6时,日志为:

[                                                  ] 18/924, 0.3 task/s, elapsed: 53s, ETA:  2646s

最后一个gpu数量为10时,日志为:

[                                                 ] 30/924, 0.5 task/s, elapsed: 59s, ETA:  1746s
改gpu数量后,推理剩余时间确实有变快,没人用gpu的时候最好把gpu都用上,会省很多时间。不过实话实说,在测试中这个推理的步骤耗时实在太多了,虽然GPU利用率是满的,但是推理速度实在太慢了,0.5task/s,这个真太慢了。而且这还是第一步,后面还有一步merge。隔壁的真AutoSAM算法已经能推理很多张图了,这里还没推理完,而且隔壁只需要一个GPU,这个多GPU才能快点。除非有好的方法把推理速度提升上去,否则这个方法根本不可能落地应用。

之后会得出推理结果

per class results:
Class                  IoU        Acc
0                    72.44      93.24
1                    64.93      69.58
Summary:
Scope                 mIoU       mAcc       aAcc
global               68.68      81.41      81.75

此步会在glas/test_patches里生成很多npy文件,便于下一步整合。

2、整合patches并评估

python tools/merge_patches.py glas/test_patches glas/test_wsi 2

对应代码可以看出,后三个arguments分别是输入文件夹、输出文件夹、分类类别数。因此此步会在glas/test_wsi文件夹下生成若干图。

python tools/count_miou.py glas/test_wsi glas/gt_val 2

对应代码可以看出,后三个arguments分别是预测文件夹、标注ground truth文件夹、分类类别数。此步仅输出mIoU和dice。

mIoU 0.6855933256228037, dice 0.8134741817033315

代码基本没变,可以跑通,但是我最终输出的mIoU和dice与论文中的还是有不小差距,尚不知道问题出在哪里。

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值