Convolutional neural networks on graph with fast localized spectral filtering 代码修改

  • Defferrard 及其团队,在NIPS.2016的上的文章 《Convolutional neural networks on graph with fast localized spectral fiftering》是学习GCN的入门必读文章。文章的核心要点是将谱域GCN的卷积核,使用chebyshev多项式截断,然后经过迭代,绕开了原有对Laplacian的特征分解所需要的大量计算。因此计算复杂度大量下降,加快了卷积的过程。
  • 本文针对原文代码,在读入数据时,每个节点仅仅可以读取一个像素值的情况进行修改,以便其可以读入更长的一维向量文中第四部分(Numerical experiments),给出了对于传统图像(欧式数据)转化成graph,这种非欧数据的做法以验证自身提出对GCN改进的有效性。在著名“Hello world”数据集上MNIST上进行了实验。其做法如下:
  • 首先,将28x28像素的图像中的每一个像素点,视作graph中的一个节点/顶点(vertex),节点之间的edges的定义来自像素点之间任意两点的欧氏距离,但取前8个最小距离的像素点作为节点的邻接节点(neighborhood)。从这里也能观察出,实际上某一节点的邻接节点,也就是它的八邻域而已,这点和CNN的卷积核(3x3)是相同的作用。有了节点和边(edge)的定义,因此也能很快求得graph的Adjacency matrix和Degress matrix,二者相减即可得到Laplacian。graph定义完毕。(值得注意的是graph的节点由于进行了图粗化,因此得到的Laplacian并不是784x784,而是粗化到了928x928,因此后面输入的数据相应也进行了粗化,不再是784长的像素值,而是928长度的,见下图)
def grid_graph(m, corners=False):
    z = graph.grid(m)  # 产生一个28*28网格的每个点的坐标
    dist, idx = graph.distance_sklearn_metrics(z, k=FLAGS.number_edges, metric=FLAGS.metric)
    A = graph.adjacency(dist, idx)

    # Connections are only vertical or horizontal on the grid. 网格上的连接只有水平或者垂直
    # Corner vertices are connected to 2 neightbors only. 转角处的顶点只与两个邻接点连接
    if corners:
        import scipy.sparse
        A = A.toarray()
        A[A < A.max() / 1.5] = 0
        A = scipy.sparse.csr_matrix(A)
        print('{} edges'.format(A.nnz))

    print("{} > {} edges".format(A.nnz // 2, FLAGS.number_edges * m ** 2 // 2))
    return A
  • 其次,文中也提到了GSP(graph signal processing)的问题,但是在原文代码中,每个节点读入的是其像素值。这也就是说,graph上的每个节点上的signal仅仅是一个数值而已,这限制了特征提取。
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets(FLAGS.dir_data, one_hot=False)

train_data = mnist.train.images.astype(np.float32)
val_data = mnist.validation.images.astype(np.float32)
test_data = mnist.test.images.astype(np.float32)
train_labels = mnist.train.labels
val_labels = mnist.validation.labels
test_labels = mnist.test.labels

t_start = time.process_time()
train_data = coarsening.perm_data(train_data, perm)
val_data = coarsening.perm_data(val_data, perm)
test_data = coarsening.perm_data(test_data, perm)

可见到L[0]的shape并不是784x784,而是928x928
训练数据也变成了928

  • 图中所示。signal中的值为像素值,对应了定义的graph上vertex的signal。但是一个节点就一个数值实在是难受的一批。

  • 如何将signal信号变长,以适应节点有更好的特征,方便我们从数据中获得信息,减少信息丢失。如下图,我们需要的graph的样子。

带有节点信号的graph

  • 其中红色表示节点间的相互连接,也就是我们得到的邻接矩阵,蓝色竖条为节点signal(这张图上的信号长度各不相同,本博客所针对的是长度相同的信号)。

具体修改工程如下:
1.将model,继承做法去除,直接合并成新的类(neu_gcn)
2.修改model中self.fit()方法 tf的placeholder加一维
3.修改_inference 以适用读入的三维数据的情况(NxMxFin N为batch_size M为节点数量 Fin为signal长度)
4.修改了源码的mnist部分 换用了ABIDE数据(871x116x116),自闭症数据,有871个被试,每个被试拥有116x116的标准脑网络矩阵。另有标准脑脑区位置坐标以便生成连接矩阵。
5.修改了其他辅助函数,删除了本代码没有使用的函数,重写了utils.py和graph.py
详细内容参考,我的github:https://github.com/leesendy/neu_gcn

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值