讲解基于图神经网络的情绪识别深度学习模型DGCNN(附基础原理讲解和代码讲解)

T. Song, W. Zheng, P. Song and Z. Cui, “EEG Emotion Recognition Using Dynamical Graph Convolutional Neural Networks,” in IEEE Transactions on Affective Computing, vol. 11, no. 3, pp. 532-541, 1 July-Sept. 2020, doi: 10.1109/TAFFC.2018.2817622.

Dynamical graph convolutional neural networks (DGCNN) 是一种基于图神经网络的EEG情绪识别模型,引用量截至2024年7月达到了1000+,模型较为简单,所以适合以此了解图神经网络。

DGCNN的模型结构

DGCNN的代码参考以下链接:

什么是Chebynet?

频谱图理论 (Spectral Graph Theory) 是用线性代数概念(如特征向量和特征值理论)研究图的性质。
(想要简单了解频谱图理论可以参考这个视频。)

DGCNN的基础是Chebynet。Chebynet是一种频谱图神经网络(Spectral GNNs) 在频谱域中操作,具体指的是在图的拉普拉斯矩阵上应用卷积算子。

图的拉普拉斯矩阵

A A A 是邻接矩阵, D D D 是度矩阵。 L L L 是拉普拉斯矩阵,假定它是对称的:
L = D − A L=D-A L=DA
L L L 通过 SVD(奇异值分解)获得 U U U 中的特征向量和特征值。
L = U Λ U T L=UΛU^T L=UΛUT
传统频谱滤波器:图上的频谱卷积可以定义为节点信号 x ∈ R N x ∈ R^N xRN 与在傅里叶域中的卷积滤波器 g θ = diag ⁡ ( θ ) g_θ = \operatorname{diag}(θ) gθ=diag(θ) 的乘积,其中 θ \theta θ 是滤波器的编号。
g θ ⋆ x = U g θ U T x g_\theta \star \mathbf{x}=U g_\theta U^T \mathbf{x} gθx=UgθUTx
U T x U^T\mathbf{x} U

### DGCNN模型PyTorch实现 DGCNN(Dynamic Graph Convolutional Neural Networks)是一种用于点云数据处理的有效方法。以下是基于PyTorch框架复现DGCNN模型的核心思路代码示例。 #### 1. 数据预处理 为了构建动态图卷积层,通常需要计算输入点之间的k近邻关系并提取局部特征。这一步可以通过`scipy.spatial.KDTree`或其他库完成[^1]。 ```python import numpy as np from scipy.spatial import KDTree def knn(x, k): """ 计算每一点的K近邻 """ inner = -2 * torch.matmul(x.transpose(2, 1), x) xx = torch.sum(x ** 2, dim=1, keepdim=True) pairwise_distance = -xx - inner - xx.transpose(2, 1) idx = pairwise_distance.topk(k=k, dim=-1)[1] # (batch_size, num_points, k) return idx ``` #### 2. 动态图卷积模块 动态图卷积通过聚合邻居节点的信息来增强局部特征表示能力。以下是一个简单的动态图卷积实现: ```python import torch.nn.functional as F from torch_geometric.nn import EdgeConv class DynamicEdgeConv(EdgeConv): def __init__(self, nn, aggr='max', k=20): super(DynamicEdgeConv, self).__init__(nn, aggr) self.k = k def forward(self, x, batch=None): edge_index = knn(x, self.k).contiguous() # 使用上述定义的knn函数 return super().forward(x, edge_index) ``` #### 3. 整体网络架构 完整的DGCNN模型由多个动态图卷积层组成,并最终连接全连接层进行分类或回归任务。 ```python import torch.nn as nn class DGCNN(nn.Module): def __init__(self, output_channels=40, k=20): super(DGCNN, self).__init__() self.conv1 = DynamicEdgeConv(nn.Sequential( nn.Conv2d(6, 64, kernel_size=1, bias=False), nn.BatchNorm2d(64), nn.LeakyReLU(negative_slope=0.2)), k=k) self.conv2 = DynamicEdgeConv(nn.Sequential( nn.Conv2d(64*2, 64, kernel_size=1, bias=False), nn.BatchNorm2d(64), nn.LeakyReLU(negative_slope=0.2)), k=k) self.fc1 = nn.Linear(1024, 512, bias=False) self.bn1 = nn.BatchNorm1d(512) self.drop1 = nn.Dropout(p=0.5) self.fc2 = nn.Linear(512, 256, bias=False) self.bn2 = nn.BatchNorm1d(256) self.drop2 = nn.Dropout(p=0.5) self.fc3 = nn.Linear(256, output_channels) def forward(self, x): batch_size = x.size(0) x = get_graph_feature(x) # 提取局部特征 x1 = self.conv1(x) x2 = self.conv2(x1) x = torch.cat((x1.max(dim=-1, keepdim=False)[0], x2.max(dim=-1, keepdim=False)[0]), dim=1) x = F.adaptive_max_pool1d(x, 1).view(batch_size, -1) x = F.leaky_relu(self.bn1(self.fc1(x)), negative_slope=0.2) x = self.drop1(x) x = F.leaky_relu(self.bn2(self.fc2(x)), negative_slope=0.2) x = self.drop2(x) x = self.fc3(x) return x ``` #### TensorFlow 实现注意事项 虽然本回答主要关注于PyTorch实现,但在TensorFlow中也可以采用类似的逻辑。需要注意的是,TensorFlow中的操作可能更依赖于静态图模式下的自定义梯度计算[^2]。 --- ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值