基于视觉特征的图推理方法 Graph-Based Global Reasoning Networks
注意:
- Node不是类别数,只是将相似的像素聚合在一起,可以设置为16或者32,为经验值。
- 图神经网络不是用来做分类的(不是作为classifier),只是将feature map进行分组,分成几个node,然后学习了node之间的关系,最后再返回为feature map(可以理解为学习了node的上下文信息的feature map),图神经网络可以放在model中的任何位置,即插即用(如果用在网络的前端,则node数量要大一点,因为分辨率高,feature map较大,如果再网络高层,分辨率较小,则node数量少点),然后继续进行其他操作,最后再加classifier进行分类。
建图,坐标空间到交互空间
从坐标空间到交互空间,本质上还是建图:把pixel label的feature map 建成 group node的表征。
假设输入特征图为X∈
R
L
×
C
R^{L×C}
RL×C,其中L=H×W,将X映射为交互空间的表征V=f(X)∈
R
N
×
C
R^{N×C}
RN×C
巧妙:用1×1Conv去生成投影矩阵B(N×L)
本质上:表征V里面的第i个node:特征矩阵B里面的第i行
b
i
b_{i}
bi和特征图X做一个线性组合,最后求得每个node的一个表征。
图卷积进行推理
图卷积进行推理:建模任意区域之间的关系转换为学习交互空间中节点的交互
- A g A_{g} Ag:邻接矩阵
- V:图表征矩阵
- W g W_{g} Wg:图卷积可学习参数
从交互空间到坐标空间
将新的图表征反投影到坐标空间,使得整个GIoRe能够即插即用
加上X:残差连接,改善梯度传播,加速训练
具体实现框图
图卷积
通过用2个1×1卷积近似成图卷积
(a) step1:信息传播、step2:状态更新
(b) 拆分为两个1维卷积,step1:在channel label上做卷积,然后step2在channel label上做卷积
代码:GCN图卷积
import paddle
import paddle.fluid as fluid
from paddle.fluid.dygraph import Conv1D
from paddle.fluid.dygraph import BatchNorm
class GCN(fluid.dygraph.Layer):
# 在通道维度和节点维度 做1维卷积
def __init__(self, num_state, num_node, bias=False):
super(GCN, self).__init__()
self.conv1 = Conv1D(num_channels=num_node, num_filters=num_node, filter_size=1)
self.relu = BatchNorm(num_node, act='relu')
self.conv2 = Conv1D(num_channels=num_state, num_filters=num_state, filter_size=1, bias_attr=bias)
def forward(self, inputs):
# inputs为输入的feature map
# inputs.shape:(B,C,N) B为batch_size,C为channel,N为node数量
x = self.conv1(fluid.layers.transpose(inputs, perm=(0,2,1))) # BNC,做一维卷积在第二维上做,所以将node放在第二维,在node上做一维卷积
x = fluid.layers.transpose(x, perm=(0,2,1)) # BCN
x = x - inputs # 残差,效果会好点
x = self.relu(self.conv2(x)) # 在channel维度上做一维卷积
return x
1维卷积
一维卷积原图
一维卷积的kernel