目录
1、代码地址:
论文地址:[1802.10349] Learning to Adapt Structured Output Space for Semantic Segmentation (arxiv.org)
网络上关于论文的有很多笔记,先阅读内容,配合代码学习。我看了代码基本不用改,但是代码还是有难度的,第一次用pytorch,其实是看不太懂的,如果只是复现的话走一遍就可以了。
2、调试。
我的服务器上可以跑通的环境配置为:pytorch1.8
conda install pytorch torchvision torchaudio cudatoolkit=11.1 -c pytorch -c nvidia
这个环境还是要根据自己的卡来定,我当时本来随便选择的1.4,以为版本够高能适配,但都会出现问题,”CUDA error: no kernel image is available for execution on the device” 或者“cuDNN error: CUDNN_STATUS_EXECUTION_FAILED”。弄了好久好生气,最后用了上面那句代码解决了。
readme里面给的环境是0.4,太古旧了,不一定和显卡配套。
3、数据集。
配置好环境,要放置数据集,格式为:
4、训练。
nohup python train_gta2cityscapes_multi.py --snapshot-dir ./snapshots/GTA2Cityscapes_multi \--lambda-seg 0.1 \--lambda-adv-target1 0.0002 --lambda-adv-target2 0.001 &
5、测试
主要参照readme文件
python evaluate_cityscapes.py --restore-from ./snapshots/GTA2Cityscapes_multi/GTA5_150000.pth
测试预训练模型:
python evaluate_cityscapes.py --restore-from ./model/GTA2Cityscapes_multi-ed35151c.pth
6、计算miou
python compute_iou.py 参数1 参数2
参数1是cityscape的gtfine文件的地址
参数2是/result/cityscapes/
7、结果
原图
论文作者预训练模型结果
我的迭代15万次的结果,还是有缺陷,下面那块的车头的奔驰车标识别失败,轮廓粗糙,
问题出在哪了,是仅仅是迭代次数不够还是其他问题,我还要有空去研究一下。心累。over。
![](https://i-blog.csdnimg.cn/blog_migrate/65b3f8966503fba5332bc59670055fb6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1f20978912d747cfe80a492e3893eed2.png)
8、结果补充:
上次训练了15万的迭代,发现奔驰车标不能很好的识别。因此修改代码,载入训练15万次的模型,在此基础增加了10万次,一共25万次的迭代,结果如下。(还是前面的原图)
和预训练模型做出的结果相比较的话,还是有一些瑕疵的,不过最主要的问题(就是车标的问题)已经解决了。
目前看来,25万次的迭代还是不够的,因为我看到LOSS并没有收敛,其次这个结果也很一般。
计算了miou:
下一步计划:
因为论文提出了好几种,single-level with LS-GAN、muti-level、single-level。但是论文阅读时间过于久远,所以下来看看论文中这三种有什么区别。
2022年5月23日补充:
1.复现实验迭代次数在26w次时达到了40以上,实现了比较好的复现效果。
multi-level指的是在outspace最后两层上进行两次DA,Single-level指的是一个DA。
2.补充讲解:
常用的语义分割一般是由两部分组成:一部分是特征提取器,比如可以用Resnet系列,或者VGG系列来提取图片的特征;二是分类器,将前面提取的特征送入到分类器里面(分类器比较常见的是PSP,或者DA分割里面最常用的 DeepLab V2里的ASPP)。通过把特征提取提到的特征送入到判别器里面,进而来完成整个DA。
为什么把特征送入判别器能完成DA呢?从判别器的作用上,我们可以来理解这个问题。
训练判别器,就能让它区分输入进来的图片到底是真还是假。在这个过程中,需要用判别器区分输入的特征是源域还是目标域。得到一个能够区分特征是源域和目标域的判别器之后,固定判别的参数不变,去训练分割网络的特征提取器。如何训练呢:让这个特征提取器来混淆这个判别器。
那么特征提取器又怎么来混淆判别器呢?无论是提取源域还是目标域的特征,都要把这两个特征的分布对齐,这样的话就相当于把这两个域的特征,使这个判别器区分不出来,那么就完成了“混淆”的任务。一旦完成了“混淆”任务,就说明特征提取器提取到了这个“域不变”的信息。
这里的output space就是,语音分割网络输出的结果经过softmax之后,变成了一个概率的东西,我们称这个概率为output space,
此论文的作者认为直接用特征做对抗是不好的,不如用output space概率来做对抗,为什么呢?因为作者认为,在原本,就比如分类里面,大家都是用特征来做的,但是分割是不一样的。因为分割的高维度特征,就是你前面的特征部分,是一个非常长的向量,比如Resnet101的最后一层,它的特征长度2048维的,如此高维度特征,编码的信息当然更加复杂。但是对于语义分割,可能这些复杂信息并不是有用的。这是作者的一个观点。
作者的另一个观点是,语义分割的输出的结果虽然是低维度的,即output space这个概率,实际上只有类别数的这样的一个维度,就是假如类别数c的话,它这个概率对于每个像素点就是c*1的一个向量。虽然是低维度空间,但是一整个图片的输出,实际上包含了场景、布局以及上下文这些丰富的信息。本论文作者认为不管图片来自于源域还是目标域,分割出来的结果在空间上,应该是具有非常强的相似性的。因为不管是仿真数据还是模拟数据,同样都是在做的分割任务上。如上图,其源域和目标域都是针对于自动驾驶来做的。很明显的一个观点是,中间大部分可能是路,上面一般是天,然后左右可能是建筑。这种场景上的分布是有非常强的相似性的,因此作者认为直接使用低维度的这个概率,就是softmax输出来进行对抗就能取得一个非常好的效果。
基于以上两个insight,作者就设计直接把概率放到判别器里面。训练的过程实际上和GAN是一样的,只不过不再是把特征传入判别器里面,而是把最终输出的概率传到判别器里面。
参考: