点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

英国机器视觉会议(BMVC)大约两周前在英国卡迪夫结束,是计算机视觉和模式识别领域的顶级会议之一,具有28%的竞争接受率。与其他人相比,这是一个小活动,所以你有足够的时间在会议上走来走去,和论文讲述者一对一的交流,我觉得这大有裨益。

我在会议上展示了一份关于分层多图网络图像分类的工作,在林晓、穆罕默德·艾默尔(主页)和我的博士顾问格雷厄姆·泰勒的监督下,我在SRI国际公司实习期间主要在上面工作。

在本文中,我们基本上试图回答以下问题:“我们能比卷积神经网络做得更好吗?”。 在这里,我讨论这个问题,并通过结果支持我的论点。 我还将引导您使用PyTorch从PASCAL VOC 2012的整个管道前进,获取单个图像。

这篇文章的完整代码在我的[Github笔记本](https://github.com/bknyaz/bmvc_2019)上。应该很容易地对其进行调整,以对整个PASCAL数据集进行训练和验证。

那么,为什么我们要比ConvNets做得更好?他们在许多任务上都胜过人类吗?

例如,您可以说图像分类是解决的任务。 好吧,就ImageNet而言,是的。 但是,尽管ImageNet做出了巨大贡献,但这是一个奇怪的任务。 您为什么要区分数百种狗? 因此,结果是我们成功地建立了模型,但是无法区分稍微旋转的狗和猫。 幸运的是,我们现在有了ImageNet-C和其他类似的基准,表明我们离解决它还很遥远。

相关任务(例如对象检测)中出现的另一个未解决的问题是在非常大的图像(例如4000×3000)上进行训练,例如Katharopoulos&Fleuret(ICML,2019)和Ramapuram等人解决了这个问题。 (BMVC,2019)。 多亏了后者,我现在知道如果海报的背景是黑色的,那么很有可能来自Apple。 我也应该保留一些颜色!

因此,也许我们需要不同于卷积神经网络的东西?也许我们应该从一开始就使用具有更好属性的模型,而不是不断修补其错误。

我们认为这种模型可以是图神经网络(GNN):一种可以从图结构数据中学习的神经网络。 GNN具有一些吸引人的属性。 例如,与ConvNets相比,GNN本质上是旋转和平移不变的,因为在图形中根本没有旋转或平移的概念,即没有左右,在某种意义上只有“邻居”(Khasanova和Frossard, ICML,2017)。 因此,人们多年来一直试图解决的使ConvNet更好地推广到不同的轮换的问题可以通过GNN自动解决!

关于从大图像中学习,如何从图像中提取超像素并将低维输入输入到GNN而不是将下采样(例如224×224)图像输入到ConvNet? 与双线性插值相比,超像素似乎是对图像进行下采样的一种更好的方法,因为超像素通常通过保持对象之间的边界来保留很多语义。 借助ConvNet,我们无法直接从这种输入中学习,但是,有一些很好的提议建议利用它们(Kwak等人,AAAI,2017)。

因此,GNN听起来很棒!让我们看看它在实践中的表现。 但是不好了!基于(Kipf&Welling,ICLR,2017)的基准GNN在PASCAL上仅达到19.2%(平均平均精度或mAP),而在每一层中具有相同数量的层和滤波器的ConvNet为32.7%我们提出了一些改进措施,最终击败了ConvNet!

1. 层次图

在ConvNets中,图像的层次结构是通过池化层隐式建模的。 在GNN中,您至少可以通过两种方式实现这一目标。 首先,您可以使用类似于ConvNets的池化方法,但是对于图而言,定义一种快速且良好的池化方法确实具有挑战性。 相反,我们可以计算多个比例的超像素,并通过将它们与较大的父超像素对应来合并超像素。 但是,由于某些原因,这种合并在我们的案例中效果不佳(我仍然认为效果很好)。 因此,我们改为在输入级别对层次结构建模。 特别是,我们将所有比例的超像素组合成一个集合,并基于语义分割中常用的基于联合的交集(IoU)计算层次关系。

基于该原理,我在下面的代码中构建了层次图。 我还构建了空间图的多尺度版本,但它仅编码空间关系,而IoU应该更好地编码分层关系。 例如,使用IoU,我们可以在远程子节点之间创建快捷方式,即连接两个空间上相距较远但属于同一父节点(例如汽车)的小超像素(例如车轮),如上图所示。

实际上,层次图将mAP提升到31.7%,使其比ConvNet仅低1%,而可训练参数却减少了4倍!如果仅使用空间多尺度图,则结果将比本文中探讨的要差得多。

def compute_iou_binary(seg1, seg2):inters = float(np.count_nonzero(seg1 & seg2))#区域可以预先计算seg1_area = float(np.count_nonzero(seg1))seg2_area = float(np.count_nonzero(seg2))return inters / (seg1_area + seg2_area - inters)def hierarchical_graph(masks_multiscale, n_sp_actual, knn_graph=32):n_sp_total = np.sum(n_sp_actual)A = np.zeros((n_sp_total, n_sp_total))for level1, masks1 in enumerate(masks_multiscale):for level2, masks2 in enumerate(masks_multiscale[level1+1:]):for i, mask1 in enumerate(masks1):for j, mask2 in enumerate(masks2):A[np.sum(n_sp_actual[:level1], dtype=np.int) + i, np.sum(n_sp_actual[:level2+level1+1], dtype=np.int) + j] = compute_iou_binary(mask1, mask2)sparsify_graph(A, knn_graph)return A + A.Tn_sp_actual = []
avg_values_multiscale, coord_multiscale, masks_multiscale = [], [], []# Scales [1000, 300, 150, 75, 21, 7] ]在论文中
for i, (name, sp) in enumerate(zip(['children', 'parents', 'grandparents'], [1000, 300, 21])):superpixels = slic(img, n_segments=sp)n_sp_actual.append(len(np.unique(superpixels)))avg_values_, coord_, masks_ = superpixel_features(img, superpixels)avg_values_multiscale.append(avg_values_)coord_multiscale.append(coord_)masks_multiscale.append(masks_)A_spatial_multiscale = spatial_graph(np.concatenate(coord_multiscale), img.shape[:2], knn_graph=knn_graph)
A_hier = hierarchical_graph(masks_multiscale, n_sp_actual, knn_graph=None)

很棒!我们还可以做些什么来进一步改善结果?

2.易学的关系

到目前为止,如果我们可视化滤波器,它们将看起来非常原始(就像高斯一样)。有关更多详细信息,请参见我的[GNN教程](https://medium.com/@BorisAKnyazev/tutorial-on-graph-neural-networks-for-computer-vision-and-beyond-part-1-3d9fada3b80d)。我们想学习一些类似于ConvNets的边缘检测器,因为效果很好。但是事实证明,使用GNN来学习它们非常困难。为此,我们基本上需要根据坐标之间的差异在超像素之间生成边缘。这样,我们将使GNN能够理解坐标系(旋转,平移)。我们将使用在PyTorch中定义的2层神经网络,如下所示:

pred_edge = nn.Sequential(nn.Linear(2, 32),nn.ReLU(True),nn.Linear(32, L))

其中L是预测边数或滤波器数,例如下面的图表中的4。
我们限制滤波器仅根据 |(x₁,y₁) - (x₂,y₂)|之间的绝对差而不是原始值来学习边缘,从而使滤波器变得对称。 这限制了滤波器的容量,但是它仍然比我们的基准GCN使用的简单高斯滤波器好得多。

在我的[Jupyter笔记本](https://github.com/bknyaz/bmvc_2019/blob/master/bmvc_2019.ipynb)中,我创建了一个LearnableGraph类,该类实现了在给定节点坐标(或任何其他特征)和空间图的情况下预测边缘的逻辑。 后者用于在每个节点周围定义一个小的局部邻域,以避免预测所有可能的节点对的边缘,因为它昂贵且连接非常远的超像素没有多大意义。

下面,我将训练有素的pred_edge函数可视化。 为此,我假设在其中应用卷积的索引为1的当前节点位于坐标系(x₁,y₁)= 0的中心。 然后,我简单地采样其他节点的坐标(x₂,y₂),并将其输入给pred_edge。 颜色显示边缘的强度取决于与中心节点的距离。

学习到的图也非常强大,但是计算量较大,如果我们生成非常稀疏的图,则可以忽略不计。32.3%的结果仅比ConvNet低0.4%,如果我们生成更多的过滤器,则可以轻松地改善它!

3. 多尺度GNN

现在,我们有了三个图:空间图,层次图和学习图。 具有空间或层次图的单个图卷积层仅允许特征在“第一邻居”内传播。 在我们的例子中,邻居是软性定义的,因为我们使用高斯来定义层次图的空间图和IoU。 (Defferrard等。 NIPS(2016))提出了一种多尺度(multihop)图卷积算法,该算法将K-hop邻域内的特征聚合在一起并近似谱图卷积。 有关此方法的详细说明,请参见我的[其他文章](https://towardsdatascience.com/tutorial-on-graph-neural-networks-for-computer-vision-and-beyond-part-2-be6d71d70f49)。 对于我们的空间图,它实质上对应于使用多个不同宽度的高斯。 对于分层图,我们可以通过这种方式在远程子节点之间创建K-hop快捷方式。 对于学习的图,此方法将创建可视化的学习过滤器的多个比例。

使用多尺度图卷积,在我的GraphLayerMultiscale类中实现,结果证明是非常重要的,它使我们的性能比基准卷积神经网络高出0.3%!

4. 以低成本改善关系类型的融合

到目前为止,为了从我们的三个图中学习,我们使用了标准的级联方法。 但是,这种方法有两个问题。 首先,这种融合算子的可训练参数的数量是线性的。 输入和输出要素的维数,比例(K)和关系类型的数量,因此,如果我们一次增加两个或多个这些参数,它的确会快速增长。 其次,我们尝试融合的关系类型可以具有非常不同的性质,并占据流形的非常不同的子空间。 为了同时解决这两个问题,我们提出了类似于(Knyazev等人,NeurIPS-W,2018)的可学习的预测。 通过这种方式,我们将线性相关性解耦,与串联相比,参数数量减少了2-3倍。 此外,可学习的投影变换了多关系特征,因此它们应占据流形的附近子空间,从而促进信息从一种关系传播到另一种关系。

通过使用在下面的GraphLayerFusion类中实现的拟议融合方法,我们将ConvNet击败了达到了34.5%提升1.8%,而参数却减少了2倍! 对于最初对图像的空间结构一无所知的模型,除了以超像素编码的信息外,还给人留下了深刻的印象。 探索其他融合方法(例如这种方法)以获得更好的结果将很有趣。

class GraphLayerFusion(GraphLayerMultiscale):def __init__(self,in_features,out_features,K,fusion='pc',n_hidden=64,bnorm=True,activation=nn.ReLU(True),n_relations=1):super(GraphLayerFusion, self).__init__(in_features, out_features, K, bnorm, activation, n_relations)self.fusion = fusionif self.fusion == 'cp':fc = [nn.Linear(in_features * K * n_relations, n_hidden), nn.ReLU(True), nn.Linear(n_hidden, out_features)]else:if self.fusion == 'pc':fc = [nn.Linear(n_hidden * n_relations, out_features)]elif self.fusion == 'sum':fc = [nn.Linear(n_hidden, out_features)]else:raise NotImplementedError('cp, pc or sum is expected. Use GraphLayer for the baseline concatenation fusion')self.proj = nn.ModuleList([nn.Sequential(nn.Linear(in_features * K, n_hidden), nn.Tanh()) for rel in range(n_relations)])  # projection layers followed by nonlinearityif bnorm:fc.append(BatchNorm1d_GNN(out_features))if activation is not None:fc.append(activation)self.fc = nn.Sequential(*fc)def relation_fusion(self, x, A):B, N = x.shape[:2]for rel in range(self.n_relations):y = self.chebyshev_basis(A[:, :, :, rel], x, self.K).view(B, N, -1)  # B,N,K,Cif self.fusion in ['pc', 'sum']:y = self.proj[rel](y)  # projection if self.fusion == 'sum':y_out = y if rel == 0 else y_out + ycontinue# for CP and PCif rel == 0:y_out = []y_out.append(y)  y = self.fc(y_out if self.fusion == 'sum' else (torch.cat(y_out, 2)))  # B,N,Freturn y

结语

事实证明,有了多关系图网络和一些技巧,我们可以比卷积神经网络做得更好!
不幸的是,在改进GNN的过程中,我们逐渐失去了不变性。例如,旋转图像后,超像素的形状可能会发生变化,而我们用于节点特征以改善模型的超像素坐标也使其健壮性降低。
尽管如此,我们的工作只是迈向更好的图像推理模型的一小步,并且我们证明了GNN可以为一个有希望的方向铺平道路。
有关实现的详细信息,请参阅我在Github上的[笔记本](https://github.com/bknyaz/bmvc_2019)。
我还高度推荐Matthias Fey的硕士论文,其中包含与非常相关的主题相关的[代码](https://github.com/rusty1s/embedded_gcnn)。

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

GNN|如何做的比卷积神经网络更好?相关推荐

  1. 【Pytorch神经网络理论篇】 25 基于谱域图神经网络GNN:基础知识+GNN功能+矩阵基础+图卷积神经网络+拉普拉斯矩阵

    图神经网络(Graph Neural Network,GNN)是一类能够从图结构数据中学习特征规律的神经网络,是解决图结构数据(非欧氏空间数据)机器学习问题的最重要的技术. 1 图神经网络的基础知识 ...

  2. 第二课.图卷积神经网络

    目录 卷积神经网络 图卷积神经网络 GNN数据集 图的表示 GCN GNN的基准化:Benchmarking Graph Neural Networks 卷积神经网络 在计算机视觉中,卷积网络是一种高 ...

  3. 如果卷积神经网络存在根本性的缺陷,你会怎么看?

    作者 | Ben Dickson 译者 | 香槟超新星 经过一段漫长时期的沉寂之后,人工智能正在进入一个蓬勃发展的新时期,这主要得益于深度学习和人工神经网络近年来取得的长足发展.更准确地说,人们对深度 ...

  4. 深度学习笔记 第四门课 卷积神经网络 第二周 深度卷积网络:实例探究

    本文是吴恩达老师的深度学习课程[1]笔记部分. 作者:黄海广[2] 主要编写人员:黄海广.林兴木(第四所有底稿,第五课第一二周,第三周前三节).祝彦森:(第三课所有底稿).贺志尧(第五课第三周底稿). ...

  5. python识别人脸多种属性_人脸检测及识别python实现系列(4)——卷积神经网络(CNN)入门...

    人脸检测及识别python实现系列(4)--卷积神经网络(CNN)入门 上篇博文我们准备好了2000张训练数据,接下来的几节我们将详细讲述如何利用这些数据训练我们的识别模型.前面说过,原博文给出的训练 ...

  6. python卷积神经网络cnn的训练算法_【深度学习系列】卷积神经网络CNN原理详解(一)——基本原理...

    上篇文章我们给出了用paddlepaddle来做手写数字识别的示例,并对网络结构进行到了调整,提高了识别的精度.有的同学表示不是很理解原理,为什么传统的机器学习算法,简单的神经网络(如多层感知机)都可 ...

  7. python神经网络构建图_如何用卷积神经网络构建图像?

    原标题:如何用卷积神经网络构建图像? 原标题 |Everything you need to know to master Convolutional Neural Networks 作者 | Tir ...

  8. 卷积神经网络(CNN)的参数优化方法

    积神经网络的参数优化方法--调整网络结构是关键!!!你只需不停增加层,直到测试误差不再减少. 著名: 本文是从 Michael Nielsen的电子书Neural Network and Deep L ...

  9. NNDL 实验六 卷积神经网络(5)使用预训练resnet18实现CIFAR-10分类

    目录 5.5实践:基于ResNet18网络完成图像分类任务 5.5.1数据处理 5.5.1.1数据集介绍 5.5.1.2 数据读取 5.5.1.2 数据集划分 5.5.2模型构建 5.5.2.1使用R ...

最新文章

  1. Nginx 内置 命令启动,停止和重新加载Nginx
  2. java mysql 文本导入数据语句_Java利用MYSQL LOAD DATA LOCAL INFILE实现大批量导入数据到MySQL...
  3. iOS-----使用NSURLConnection
  4. workman php教程_workerman搭建websocket入门教程,简单实用
  5. 安卓手机浏览器_chrome浏览器插件安卓下载-chrome apk手机版下载v4.8.2安卓版
  6. Ubuntu 16.04上安装Code::Blocks
  7. WAN killer
  8. Docsify 侧边栏 : 自动生成sidebar与子目录sidebar
  9. Low Power概念介绍Level Shifter
  10. java soapui 发送xml_javawebservice 中用soapui发送请求由于出现异常错误, 无法创建 SOAP 消息: XML 读进程错误...
  11. 小白自学c51笔记之数码管1——D74HC245和D74HC138
  12. 益寿延年,这13种食物真是宝,能延寿10年,赶紧收藏!
  13. 湖北计算机专业不错的学校,计算机专业大学TOP10排名,湖北一所大学上榜,这个地方占了四所...
  14. Mysql 常用函数(40)- time_to_sec 函数
  15. windows下通过关键字批量删除远程k8s下deployment及pods
  16. 护眼台灯国家标准是什么?国aa和国a台灯区别大吗
  17. 组合保险策略及相应模拟测算工具----Discrete Hedging: Guaranteed CPPI Structures
  18. IMS 紧急服务相关概念
  19. Python药店销售数据分析
  20. php导出cvs文件英文自动分割,导出csv_php导出csv文件函数

热门文章

  1. 全球计算机视觉顶会CVPR 2020论文出炉:腾讯优图17篇论文入选
  2. ICLR 2020论文投稿2600篇,GNN、BERT、Transformer领跑热门研究方向
  3. 这可能是Python面向对象编程的最佳实践
  4. 高效读CV论文法则:先在GitHub上立Flag!| 资源
  5. 如何使用TensorFlow中的Dataset API
  6. 程序员转型AI,这里有最全的机器学习介绍+应用实例
  7. 技术详解 | 如何用GAN实现阴影检测和阴影去除?
  8. Spring IoC是如何进行依赖注入的
  9. 老弟,你连HTTPS 原理都不懂,还给我讲“中间人攻击”,逗我吗...
  10. 千万不要一辈子靠技术生存