最近在研究图卷积神经网络,看到许多学者都描述它为“能挖掘非欧几里得空间特征”会比“仅能挖掘欧几里得空间特征”的传统CNN网络表现好,但是实际用起来发现它的收敛甚至都是个问题....
我是用GCN去做航迹的分类与预测
CNN训练一阵子就能达到比较好的表现,但是GCN训练一阵子误差依然非常大
然后我分析了下图卷积操作的函数
self.w1 = pyg_nn.dense.linear.Linear(in_channels, out_channels, weight_initializer='glorot', bias=bias)
self.w2 = pyg_nn.dense.linear.Linear(in_channels, out_channels, weight_initializer='glorot', bias=bias)
def forward(self, x, edge_index, edge_weight):
# 对自身节点进行特征映射
wh_1 = self.w1(x)
# 获取邻居特征
x_j = x[edge_index[0]]
x_j = scatter(src=x_j, index=edge_index[1], dim=0, reduce='sum')
# 对邻居节点进行特征映射
wh_2 = self.w2(x_j)
wh = wh_1
# wh = wh_1 + wh_2
return wh
我一开始觉得是图卷积的问题,就是问题出在x_j = scatter(src=x_j)上,把邻居节点特征和节点自身特征求和很容易把自身特征埋没?即便用加权好像也不会有什么改变? 实验结果也证明,如果 wh = wh_1,相当于不做图卷积,直接用全连接神经网络,效果很好,这个时候严格意义上来讲整个网络虽然是在PyG的架构上搭建的,输入输出都是图的形式,但是网络的操作和图无关了。
如果是wh = wh_2,或者正常的wh = wh_1+wh_2收敛到最后loss值依然很大
wh = wh_1时loss曲线图:
wh = wh_1+wh_2时loss曲线图:
后来仔细一想,CNN也是一个卷积核,卷过的地方按卷积核数值加权求和,那就不是图卷积上的事。
分析
突然想到,图卷积时求和是不是不太行,求平均才比较符合常理?
求和数值大于节点原来特征数值几倍,这很可能影响模型了解节点特征。实验结果也表明,在图卷积是求和的情况下,节点与邻居节点的关系阶数越高训练效果越差,如果节点只与周围1阶节点有关系,训练效果会更好些。
x_j = scatter(src=x_j, index=edge_index[1], dim=0, reduce='mean')
wh = wh_1+wh_2时loss曲线图:
总结
图卷积操作的模型对训练效果影响挺大的....虽然改成了平均,但是效果还是不如CNN,有待进一步研究分析...