This repository is a compact reference implementation of the model and optimization mechanism described in:
M. S. Lee, D. H. Kim, and Y.-S. Choi, "Enhancing EEG-Based Emotion Recognition Using Sparse Dynamic Graph CNN With ℓ₂,₁-Norm", IEEE Sensors Journal, vol. 25, no. 22, 2025. DOI: 10.1109/JSEN.2025.3616343.
The release intentionally contains no EEG data, preprocessing pipeline, trained weights, experiment logs, or reported results. It is meant to show the model architecture and the forward-backward training mechanism in a reusable, dataset-independent form; it is not an end-to-end benchmark reproduction. Benchmark metrics and evaluation pipelines are also intentionally omitted.
An EEG sample is represented as a graph with electrodes as nodes and a
learnable nonnegative adjacency matrix W. The initial graph is symmetric and
can be constructed from electrode coordinates with a thresholded Gaussian
kernel:
W_ij = exp(-dist(i,j)^2 / (2 theta^2)) if dist(i,j) <= tau
0 otherwise
W_ii = 0
The network applies a Chebyshev graph convolution, ReLU, dropout, a 1 x 1
convolution, and two fully connected layers. Its composite objective is
cross_entropy + alpha * ||network parameters||_2 + beta * ||W||_2,1,
where ||W||_2,1 is the sum of the ℓ₂ norms of the rows of W. The smooth part
is updated with gradient descent. Momentum is disabled so the subsequent
proximal operation uses the same scalar step size as Algorithm 1. The nonsmooth
graph penalty is handled after every optimizer step using row-wise group
soft-thresholding:
w_i <- max(1 - learning_rate * beta / ||w_i||_2, 0) * w_i
W <- max(W, 0)
Consequently, an entire row can become exactly zero, functionally suppressing one EEG channel's outgoing graph connections.
The complete off-diagonal edge set is retained during training so connections initialized to zero can become active. During evaluation, exact-zero edges are removed before graph convolution, so learned sparsity also reduces message passing work.
The coordinate-based initial graph is undirected. The paper's row-wise ℓ₂,₁ proximal update is applied exactly and does not include a projection back onto the set of symmetric matrices. Therefore, the learned adjacency is not forced to remain symmetric. A zero row represents suppression of a channel's outgoing connections; it should not be interpreted as guaranteed simultaneous removal of the corresponding column. This implementation choice follows the stated optimization steps rather than adding an undocumented symmetry projection.
Python 3.10 or later is required.
python -m venv .venv
source .venv/bin/activate
pip install -e .For tests, install the development extra:
pip install -e ".[dev]"
pytestThe example uses random tensors and does not download any data:
python examples/train_synthetic.py --epochs 3The model expects a batch tensor shaped [batch, electrodes, features] and
zero-based class labels:
import torch
from torch.utils.data import DataLoader, TensorDataset
from sparse_dgcnn import (
SparseDGCNN,
TrainingConfig,
fit,
gaussian_adjacency,
make_optimizer,
)
# Replace this with coordinates in the same order as the feature channels.
positions = torch.randn(62, 3)
initial_adjacency = gaussian_adjacency(positions, tau=10.0, theta=5.0)
model = SparseDGCNN(
in_channels=5,
hidden_channels=5,
out_channels=5,
num_classes=3,
initial_adjacency=initial_adjacency,
chebyshev_order=3,
)
# Replace these tensors with precomputed DE, PSD, or other node features.
x = torch.randn(256, 62, 5)
y = torch.randint(0, 3, (256,))
loader = DataLoader(TensorDataset(x, y), batch_size=64, shuffle=True)
config = TrainingConfig(learning_rate=1e-3, alpha=5e-4, beta=1e-2)
optimizer = make_optimizer(model, config)
history = fit(model, loader, optimizer, config, epochs=10)The paper's reported settings use 62 EEG channels, Chebyshev order K=3,
learning_rate=0.001, alpha=0.0005, beta=0.01, theta=5, and tau=10.
Feature extraction and train/test partitioning remain the caller's
responsibility.
The original experiments used an Adam-based implementation. This compact reference defaults to plain gradient descent so its adjacency update is the standard forward-backward splitting operation written in Algorithm 1. Results can therefore differ from the paper's reported experiments.
src/sparse_dgcnn/graph.py Gaussian graph initialization
src/sparse_dgcnn/model.py Sparse DGCNN architecture and proximal operator
src/sparse_dgcnn/training.py Composite loss, training loop, and early stopping
examples/ Data-free runnable example
tests/ Shape and optimization smoke tests
Code is released under the MIT License. The paper and datasets retain their respective copyrights and licenses.