关于GCN和CNN中耦合聚集与解耦合的理解

1.序言

最近读论文看到很多论文提到了耦合与解耦合的概念,实在不懂,就细细看了一下,下面是我的理解,如有不对欢迎指出。本文参考论文:

Cheng K, Zhang Y, Cao C, et al. Decoupling gcn with dropgraph module for skeleton-based action recognition[C]//Computer Vision–ECCV 2020: 16th European Conference, Glasgow, UK, August 23–28, 2020, Proceedings, Part XXIV 16. Springer International Publishing, 2020: 536-553.

2.GCN中的耦合聚集

关于GCN的过程理解可以参考我的博客 清晰图解,一图看懂图卷积GCN、时空图卷积ST-GCN ;在GCN中,我们可以看到特征之间的计算是通过邻接矩阵来实现的,所有的通道都使用同一个邻接矩阵,即对于所有的特征,都使用同一种模式加到一个节点上。如下图所示:绿色的块代表邻接矩阵,蓝色的代表输入特征,将特征分解成不同通道的话,每一个通道都使用同一个邻接矩阵。这被称为GCN的耦合聚集(coupling aggregation

论文原话:特征X的所有通道共享一个邻接矩阵A(用相同的颜色绘制),这意味着所有通道共享相同的聚合内核。我们称之为耦合聚集。现有的基于GCN的骨架动作识别方法都采用了耦合聚合,如ST-GCN 、非局部自适应GCN 、AS-GCN 、Directed-GNN。我们统称它们为耦合图卷积。

在这里插入图片描述

3.CNN中的解耦合

首先我们要弄懂一个逻辑,对于一个3通道的RGB图像而言,用5个3×3的卷积核去卷,卷积的参数为5×3×3×3,即5个卷积核,3个原通道,3×3的卷积参数,这说明:对于CNN而言,每个通道的卷积核参数是不一样的,3*3的卷积核在第一层通道卷完后,再以不同的9个参数卷第二层第三层,然后将三层相同位置的值相加,得到最终的一层输出,这样再叠加5次,得到最后的5个通道输出。我们验证一下:
在这里插入图片描述
可以看到,对于2个通道的输入(为了与后面的3×3卷积参数分开特地设置维度为2)而言,卷积核的参数为5×2×3×3

注意这里只讨论了weights,对于bias每个滤波器只有一个,如这里我们用5个卷积核去卷(out_channels = 5,也就是filter = 5),就有五个bias,对于其中一个filter而言,先将原来输入的所有通道都乘上对应的weights然后按通道相加,给结果加上一个bias成为该卷积核最后的卷积输出。

对于CNN而言,卷积核的参数相当于之前的邻接矩阵,表示特征怎样聚合在一起。那么,对于一个输入图像而言,每个通道都有不同的卷积参数,最后叠加在一起,如下图所示,不同的颜色代表不同的通道参数不一致,C为输入通道, C ′ C^{'} C为输出通道,即卷积核个数。每个通道都有不同的参数,这被称为解耦聚集(decoupling aggregation

在这里插入图片描述

论文原话:CNN是GCN的灵感来源,它不采用耦合聚合。如上图所示,不同的通道具有独立的空间聚集核,以不同的颜色显示。我们称这种机制为解耦聚合。解耦聚集机制可以大大提高空间聚集能力,这对于CNN的成功至关重要。

该论文认为GCN只使用相同的邻接矩阵不利于模型学习,因此以CNN的解耦合为灵感修改了GCN的邻接矩阵。
如下图所示:
在这里插入图片描述

4.联系方式

有问题欢迎联系:1759412770@qq.com,尽量发邮件

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
好的,以下是一个简单的GCNCNN相结的图像识别代码: ```python import tensorflow as tf from tensorflow.keras import layers # GCN layer class GraphConvolution(layers.Layer): def __init__(self, units): super(GraphConvolution, self).__init__() self.units = units def build(self, input_shape): self.kernel = self.add_weight("kernel", shape=[int(input_shape[-1]), self.units], initializer="glorot_uniform", trainable=True) self.bias = self.add_weight("bias", shape=[self.units], initializer="zeros", trainable=True) def call(self, inputs, adj_matrix): x = tf.matmul(inputs, self.kernel) x = tf.matmul(adj_matrix, x) return tf.nn.bias_add(x, self.bias) # GCN model class GCN(tf.keras.Model): def __init__(self, num_classes): super(GCN, self).__init__() self.conv1 = GraphConvolution(16) self.conv2 = GraphConvolution(num_classes) def call(self, inputs, adj_matrix): x = self.conv1(inputs, adj_matrix) x = tf.nn.relu(x) x = self.conv2(x, adj_matrix) return tf.nn.softmax(x) # CNN model class CNN(tf.keras.Model): def __init__(self, num_classes): super(CNN, self).__init__() self.conv1 = layers.Conv2D(32, (3, 3), activation='relu') self.pool1 = layers.MaxPooling2D((2, 2)) self.conv2 = layers.Conv2D(64, (3, 3), activation='relu') self.pool2 = layers.MaxPooling2D((2, 2)) self.conv3 = layers.Conv2D(64, (3, 3), activation='relu') self.flatten = layers.Flatten() self.fc1 = layers.Dense(64, activation='relu') self.fc2 = layers.Dense(num_classes, activation='softmax') def call(self, inputs): x = self.conv1(inputs) x = self.pool1(x) x = self.conv2(x) x = self.pool2(x) x = self.conv3(x) x = self.flatten(x) x = self.fc1(x) return self.fc2(x) # GCN-CNN model class GCN_CNN(tf.keras.Model): def __init__(self, num_classes, gcn_units): super(GCN_CNN, self).__init__() self.gcn = GCN(gcn_units) self.cnn = CNN(num_classes) def call(self, inputs, adj_matrix): x = self.gcn(inputs, adj_matrix) x = tf.expand_dims(x, axis=-1) return self.cnn(x) # Train the model gcn_cnn_model = GCN_CNN(num_classes=10, gcn_units=16) gcn_cnn_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) gcn_cnn_model.fit(train_images, train_labels, epochs=10, validation_data=(test_images, test_labels)) ``` 在这个代码,我们首先定义了一个GCN层和一个GCN模型,用于处理图像的特征。然后我们定义了一个CNN模型,用于处理图像的像素。最后,我们定义了一个GCN-CNN模型,将GCN模型和CNN模型连接在一起,用于图像识别。 在训练模型时,我们使用了图像数据和邻接矩阵,同时使用了交叉熵作为损失函数和Adam优化器进行优化。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锌a

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值