无规则采集器列表算法(【无监督语义分割】*敏*感*词*:作者算法)

优采云 发布时间: 2022-01-13 09:05

  无规则采集器列表算法(【无监督语义分割】*敏*感*词*:作者算法)

  煎饼不是水果:【无监督语义分割】InfoSeg: Unsupervised Semantic Image Segmentation with Mutual Information Maximization

  以上内容于2021-10-10更新。我觉得上面的文章相当于下面描述的文章的升级版。

  在使用无监督分割可以搜索到的GitHub代码中,最受关注的是这个项目→Unsupervised Image Segmentation by Backpropagation - Asako Kanezaki Kanazaki Asako(东京大学)- GitHub,作者在PyTorch中实现的代码。

  基于作者论文的算法,我成功复现了作者的算法,我也把代码放到了Github↑上,我复现的代码可以使用更短的运行时间(作者用图30秒,我用5秒),并达到同样的Split效果。

  直接用图片展示算法的效果↓

  这些改进并不是因为我的代码写得有多好,而是因为原作者没有很好地实现她的算法,如下图:

  第一行是无监督语义分割的输入图像;第二行是作者放在GitHub上的展示图片;第三行是我在本地电脑上运行作者的源代码得到的结果;第四行是基于作者的作者。论文的算法是用 PyTorch 复现的。原作者使用了随机颜色,但为了美观,我随机计算了同一语义标签的平均颜色作为着色。

  

  无监督语义分割结果

  注意:第 3 列第 2 行中的两只狼被分成不同的颜色(蓝色和*敏*感*词*),这是一个偶然的结果。事实上,这个算法不能做Instance Segmentation。第三列,第 3 行,下面是我自己转载的图片:可以看出两只狼被分配了相同的标签。

  用GIF*敏*感*词*感性的讲解算法原理↓

  该算法一遍又一遍地迭代以将相同的标签分配给具有相似语义的像素(出于美学原因,我选择了随机颜色匹配的不愉快结果,在免费在线 gif 网站 中生成 - 在 ezgif 上生成 gif:

  

  珊瑚珊瑚

  

  Woof Husky下面会正式介绍算法更新日志(文章看起来很长,其实是图片。在文末评论区回复问题)

  2019-06-19 第一版,添加橙猫橙图,添加算法缺点章节

  2019-06-21 修改compantness -> n_segments 并在评论区回复问题

  2019-12-20 点赞和私信的人突然多了?原来是被专栏选中的,所以我更新了一些东西:添加了说明论文中的Conv2D + BN + ReLU部分BN应该放在ReLU之前。修改了文章基于评论和私信,增加了关于医学影像的讨论0.算法主体内容理解代码提高优化效果算法缺点附录末尾文章在评论区回复问题1. 算法主体

  个人觉得原论文的算法不好看,在保持算法不变的情况下修改了。原创PDF在这里,其中的算法1如下。

  ———————————————————————————————————————

  算法:无监督图像分割

  ———————————————————————————————————————

  进入:

  

  输入 RGB 图像

  输出:

  

  输出语义分割的结果图像

  

  初始化神经网络,保持每一层的方差和均值

  

  图像的初步聚类

  

  迭代 T 次

  

  使用卷积网络获取特征图

  

  根据特征图,值最大的是对应像素的标签

  

  经典语义分割的聚类结果

  

  计算每个集群中出现次数最多的类别

  

  将此簇中的所有像素记录为该类别

  

  计算损失函数(softmax有中文名称:归一化索引)

  

  使用随机梯度下降更新参数——————————————————————————————————————————

  在,

  

  ,作者使用全卷积网络接受输入图像完成特征提取。该网络由三层卷积网络组成,如下:

  

  

  作者论文中的图1,我们可以看到这里的两只狼被分配了同一个标签(都是绿色的)

  其中,原作者使用2D Conv + ReLU + Batch Norm的做法是不合适的,应该改为Conv2D + BN + ReLU。具体解释见文末附录《Batch normalization Batch Norm 应该在 ReLU 之前》

  在,

  

  (原文为GetSuperPixels,使用的是slic算法),即使用经典的机器学习无监督语义分割算法对输入图像进行预分类,如Python的skimage.segmentation中的多种算法,如使用的slic算法由原作者撰写,我推荐使用 felzenszwalb 算法。值得注意的是,在作者的原创代码中,slic算法选择了一个比较极端的参数。选择这个极端参数是有原因的:

  

  原代码为slic选择了一个极端参数n_segments=1000

  在slic算法中,当分区数n_segments越高时,算法对输入图像的划分越多:

  由于具有相同语义的像素通常存在于图像中的连续区域中,因此可以推断位置相似的像素属于相同语义的概率很高。因此,在预分类中,我们给相邻像素分配相同的语义标签2.算法理解:

  首先,使用经典的机器学习算法对输入图像进行“预分类”:调整算法参数,为语义信息明显相同的小区域分配相同的语义标签。由于具有相同语义的像素通常存在于图像的连续区域中,我们可以假设具有接近颜色、接近纹理和接近位置的像素可以被分配相同的语义标签。

  然后使用深度学习结合自动编码器结构对输入图像进行分类。分类的目标是使输出的语义分割结果尽可能接近“预分类”的结果。训练收敛。

  最后,深度学习的语义分割结果会在符合“预分类结果”的基础上,合并具有相同语义信息的小块,得到大块。

  我个人的理解是:在整个无监督语义分割任务中,深度学习(神经网络)的任务就是对经典机器学习无监督语义分割的细粒度预分类结果进行处理。并且在迭代中,小块逐渐融合,最终得到符合人类期望的语义分割结果。

  

  橘猫,无监督语义分割1、2、4、8、16、32、64、128次迭代的结果

  大家可以观察我之前发布的gif图,可以看到:语义信息相似的小块会在迭代前期被合并;在迭代后期,只剩下2~8个语义标签。有一种树状的分类方法(类似于物种的进化树),比较自然,比如各种类型的草、虎纹在迭代合并中很好区分和优先排序。需要改进的地方,比如“虎而不橙”的虎尾、虎眼,在迭代中被错误地赋予了与“草”相同的标签,这不是我们希望看到的结果。(我也想到了一些改进方法,这里不再展开)

  

  在作者的原创代码中,网络使用随机梯度下降(SGD)进行训练,学习率选择0.1(默认值为0.001),使得以前的迭代中,该算法非常快速地合并像素。

  3. 代码改进(只为了运行效率,缩短运行时间,不改主算法)

  详情见文末附录:《为什么我推荐使用felz算法而不是slic算法?》

  4. 优化结果(128次迭代,40秒→4秒)

  由于修改了代码,用更少的迭代就可以达到同样的效果,所以耗时不到4秒。

  测试用图片

  

  修改(魔术修改)后,不仅缩短了时间消耗,而且图像分割的质量也有所提高。下面是我从法国自动化研究所卫星图像数据集Inria Aerial Image,1000x1000的卫星图像数据集的bellingham_x.tif中随机截取的一张图片,图片包括树林、草地、道路、建筑物和一个湖(绿色),里面有cosplay草右下角。

  

  对于这个更大的图像 1000x1000:

  原代码迭代 128 次,耗时 3 分钟(不计算 PyTorch 初始化所用的 15 秒):

  我修改后的代码也迭代了 128 次,耗时 8 秒(PyTorch 初始化耗时 15 秒):

  5. 算法缺点(不够健壮,缺乏限制)

  首先,这个算法不够鲁棒,算法受参数影响很大(包括梯度下降法的参数,以及机器学习预分类算法的参数),以及算法随机重启的结果会有所不同。为了展示这个缺点,我做了《橘猫看橘子》:(@cm cm 问:这个方案能不能分老虎和橘子?答:有时可以,有时不能,这就是算法的缺点.)

  

  右上角,我通过PS阈值筛选证明:橙色和图中橘猫的颜色范围是一致的。以下三行是我随机调整参数后得到的不同结果。

  结果图中,橘猫的橙色比橘猫的颜色浅,因为橘猫在计算平均像素的时候,黑色的条纹也收录在了计算中。并不是橘猫和橘猫不同。我专门用PS来证明两个橘子是一样的——橘猫的平均颜色比结果图中的橙色要浅,因为橘猫的平均颜色中含有黑色虎纹。深度学习可以区分橘子和橘猫。很大的原因是卷积网络可以更好地感知纹理的差异,而不是仅仅依靠颜色进行分类。

  二是算法不够成熟。随着迭代,算法会逐渐合并各个分区。然而,算法中没有设置限制来禁止神经网络合并小区域。

  浅草,暗草,枯草,,,,虎尾,虎眼,,虎纹,虎皮

  

  橙色猫图,迭代2次

  黑草、浅草、尾虎尾、、、虎皮(橙)、虎皮(白)

  

  橘猫图,迭代3次

  深草,浅草(+部分老虎),老虎(大部分)

  

  橘猫图,迭代5次

  在作者自己的原创代码中,当语义分割的类别数下降到 3 或 4 时,算法终止。如果去掉训练限制,当整幅图像归为同一类别时,损失降为0。原文设计的损失函数不能限制神经网络机会主义地输出只收录一个类别的结果。这意味着在训练网络时,随机重启可能会得到截然不同的结果,我在运行原创代码时也注意到了这一点。由于没有“一类”的限制,所以这个神经网络的参数个数应该足够少(足够浅,足够窄),这样的设计太容易过拟合(不解决这个问题,模型的提升会是极其有限)。

  (我也想到了一些改进的方法,就是用普通的机器学习语义分割算法得到一些必须属于不同语义的标签。作为对“一类”的限制,这里就不展开了)

  6. 文末附录《Batch Normalization Batch Norm 应该在 ReLU 之前》

  作者论文中的图1,它使用了原作者使用的2D Conv + ReLU + Batch Norm。这种做法不合适,应该改成Conv2D + BN + ReLU

  一般在深度学习图像领域,我们会将批归一化层Batch Normalization放在激活函数ReLU前面,使得输入到ReLU的图像接近正态分布N(0, 1).如果将输入归一化归一化操作后的张量转化为梯度变化点为0的激活函数(比如这里使用的ReLU),那么这个激活函数的非线性特性就会被充分发挥出来,构造的loss函数会变得更流畅,可能是因为原论文的作者没有做图像,所以她用错了,我帮她改正为Conv2D + BN + ReLU。

  要详细了解为什么使用 Conv2D + BN + ReLU,可以阅读这篇论文:Batch Normalization is a Cause of Adversarial Vulnerability。ArXiv。2019 年 5 月。以此类推,如果一定要用Sigmoid作为激活函数,那么在前面使用Batch Normalization之后,需要将0.0到0.5的均值相加,然后输入Sigmoid就会更合适。下图来自纸图。2.

  

  批量标准化是对抗性漏洞的一个原因。图 2 “为什么我推荐使用 felz 算法而不是 slic 算法?”

  在预分类阶段,需要进行细粒度的分类,并分离出足够多的区域(确保分类的地方被分类,神经网络可以帮助它在不应该分类的地方合并),以使最终结果更准确。如果类别太多,算法需要更多的迭代。使用felz算法而不是slic算法是因为它可以用更少的区域命中更多的“正确边界”,并且felz分隔的边界更准确。无论是选择felz算法还是slic算法,当划分足够多的区域时,对精度影响不大,但迭代次数差别很大。先说一下图片:

  

  第一行,预分类结果,第二行,用PS差值表示我们想要得到的区域划分方案。

  第一列使用slic算法,分区数为n_segments=1000。可以看出,虽然区域很多,但虎尾与草的距离并不是很好。第二列使用的slic算法,分区数n_segments=100,没有达到我们想要得到的分类边界。

  下面是一个带有合适参数的预分类算法(比较felz和slic算法)

  

  slic,边框条纹不够细。而felz算法,它甚至把每一条虎纹都分离出来,这也是我推荐这个算法的原因之一。

  “费尔兹算法”

  Efficient Graph-Based Image Segmentation - Felzenszwalb (MIT) 2004. Graph-Based Semantic Segmentation。格式塔运动(Holistic Psychology/Gestalt Psychology)认为人类根据事物的整体性做出判断。Felz 算法定义了一种方法,该方法使用基于图形的表示来定义两个区域的边界(定义谓词)。尽管这种方法会做出贪婪的决定,但它仍然会产生满足全局属性的结果。

  翻译自 felz 论文的引言部分。

  “切片算法”

  SLIC 超像素与最先进的超像素方法的比较。2012. 省略,在作者论文的算法描述中,原代码中出现的SuperPixel也出现在了这篇论文中。大胆吐槽,上面的felz算法是2004年的,slic算法是2012年的,但是slic的标题里有State-of-the-Art?如果你没有达到全面的超越,不要说。要想戴上王冠,就必须承受它的重量。

  《性能提升与GPU》

  因为代码是单线程的,花在CPU上的时间越少,GPU的利用率就越高。所以即使我为了美学计算了所有类中像素的平均颜色,但时间仍然比原创代码短。无论是运行速度还是分割精度,我认为算法还有很大的提升空间。

  

  上面是修改后的代码,GPU利用率30~40%,下面是原代码,GPU利用率10~20%,全部使用RTX2080Ti运行。欢迎评论,如有错误,请多多交流6. 回复评论区问题@cm cm 问:这个设计是不是训练和推理不可知论?每次分割图像时,网络的权重是否会重新训练?

  答:“是的,训练的过程就是推理”。该算法与风格迁移的初始版本相同,通过对单个图像进行训练来获得最终结果。在李飞飞等人的实时风格迁移出来之前,风格迁移的结果是“训练”出来的,训练得到的网络参数无法保存在其他图片上使用。所以这个算法还不够成熟(我很想把它改成实时的)。

  @一Seconemeow想:flez,然后用平均颜色给像素上色(并计算方差),然后Kmean(k=4),感觉200毫秒能得到比这里展示的分割效果好很多的,还没用过神经网络。(感谢他的建议)...我用flez加yuv空间平均颜色加minibatchkmean做了150ms(cpu)和你差不多的结果。虎皮没有任何问题, ...(详见评论部分)

  A:在法国机器学习库 sklearn 中已经有类似的算法,Region Adjacency Graph (RAG) 和合并颜色相似的区域。后来我用了 flez 算法加上 yuv 空间的平均颜色加上 mini-batch + K-mean 的方案。我认为这确实是可行的。有机会我会试试,但是基于同色分类的算法确实是毫秒级的。级算法。但是,前面提到的这种算法存在以下问题:

  该算法对机器学习语义分割聚类的预分类结果敏感,需要找到合适的预分类参数。平均色法无法将“黑虎纹”与“橙虎皮”结合起来(见草丛中的橙猫)。平均颜色将错误地合并不同但具有相似平均颜色的区域。仅仅依靠颜色是不够的,纹理的感知还需要深度学习。

  问题3相关的gif:RAG算法中使用的阈值从4逐渐增大到128以下,在阈值为32时得到了比较好的结果。

  

  使用 slic 算法 (n_segments=2048, compactness=16, max_iter=8) # 分隔更多区域

  使用 slic 算法 (n_segments=2048, compactness=16, max_iter=8) # 分隔更多区域

  

  使用slic算法(n_segments=128, compactness=16, max_iter=8) # 分隔合适的区域

  与问题1相关的图片:左图和右图服从均值为128,方差为16的正态分布,右图的每一行使用一个排序。以服从相同的分布

  

  但是对于两张不同纹理的图片,很明显,如果只使用每个区域的均值和方差,下面的两个区域是无法用任何聚类算法分开的。

  

  左:白噪声;右:渐变

  此外,还可以通过计算特征矩(measure Moments)、SSIM等方法来区分上述两个区域。但是这些方法都要求要比较的两个对象必须具有相同的区域形状(例如,长宽相同的矩形,相同大小的圆形),并且每个只能比较两个对象,所以比较部分在该算法,其复杂度将超过 O(n*log(n))。

  @Anonymous:关于在医学图像上使用这个算法,可以吗?(问这个问题的人很多,请不要私信,私信的讨论过程帮不了别人,请留言)

  这是一种不需要训练数据的单帧图片无监督方案,其训练阶段是推理过程。仅当根本没有数据时才应选择此方法。同等条件下,数据越多越好。

  参考^无监督图像分割。ICASSP。2018 ^机器学习无监督语义分割 SLIC 超像素与最先进的超像素方法相比,TPAMI,201 年 5 月2.^机器学习无监督语义分割高效的基于图的图像分割。IJCV。2004~pff/papers/seg-ijcv.pdf 法国自动化研究所卫星图像数据集(其实是航拍的Aerial Image) 为什么要把BN层放在ReLU前面?批量标准化是计算机视觉和模式识别对抗性漏洞会议的一个原因。IEEE。1997 使用特征向量进行分割:统一。国际刑事*敏*感*词*。1999.实时风格迁移和超分辨率的感知损失。约翰逊。ECCV。2016OpenCV 简历2.

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线