RMETNet: A cross-subject motor imagery EEG signal classification model based on TSLANet and riemannian geometry features.
The 5 matches · 1 of them tie a paragraph to a whole file, not to given lines: a weak match, whose lines are not tinted
- [1] § Methodology › TSLANet module ↔ tools/VisualizationTech.py, lines 113–156 · score 0.57 · Power Spectral Density, PSD, adaptive
- [2] § Experimental setup › Datasets ↔ bciciv2a/general_processor.py, lines 199–218 · score 0.56 · notch filter, band pass, BCICIV2a
- [3] § Experimental setup › Datasets ↔ bciciv2a/general_processor_BCICIV.py, lines 103–122 · score 0.56 · notch filter, band pass, BCICIV2a
- [4] § Methodology › TSLANet module ↔ bciciv2a/MIBCICIV2a_mat_generate_TE.py, the whole file · a weak match · score 0.55 · Power Spectral Density, PSD, channel
- [5] § Experimental setup › Data preprocessing and division ↔ bciciv2a/LoaderBCICIV2a.py, lines 235–311 · score 0.53 · Riemannian alignment, Covariance matrices, LOSO, raw, training
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
Python · 345 lines · 15 KB · no license · 1 match
- # -*- coding: utf-8 -*-
- """
- Created on Mon Sep 2, 18:17:29 2019
- @author: JIAN
- """
- import torch
- import numpy as np
- import torch.optim as optim
- import matplotlib.pyplot as plt
- from matplotlib.collections import LineCollection
- from scipy.integrate import simps
- from mne.time_frequency import psd_array_multitaper
- import matplotlib.gridspec as gridspec
- # from CompactCNN import CompactCNN
- from EEGConformerG4 import Conformer
- from bciciv2a.LoaderBCICIV2a import BCICIV2Amatdataloader2D
- from bciciv2a.general_processor_BCICIV_mat_TE import Utils as UtilsmatTE
- plt.rcParams.update({'font.size': 12})
- torch.cuda.empty_cache()
- torch.manual_seed(0)
- class FeatureVis:
- def __init__(self, model):
- self.model = model
- self.model.eval()
- def generate_heatmap(self, allsignals, sampleidx, subid, samplelabel, multichannelsignal, likelihood):
- """
- input:
- allsignals: all the signals in the batch 每个batch中的所有信号
- sampleidx: the index of the sample 样本索引
- subid: the ID of the subject 被试编号
- samplelabel: the ground truth label of the sample 样本的标签
- multichannelsignal: the signals from all channels for the sample 样本全部通道的信号
- likelihood: the likelihood of the sample to be classified into alert and drowsy state
- 样本被分为警觉和嗜睡状态的可能性,原文中的任务为识别司机驾驶是否为 清醒 还是 昏昏欲睡
- 那么我们自己的任务为4分类 左 右 脚 舌
- """
- # 相关性谁大选谁(对于二分类来说)
- # if likelihood[0] > likelihood[1]:
- # state = 0
- # else:
- # state = 1
- # 得到最大的类别的位置,后边能用到
- likelihoodlist = likelihood.tolist()
- state = likelihoodlist.index(max(likelihoodlist))
- if samplelabel == 0:
- labelstr = 'Left'
- elif samplelabel == 1:
- labelstr = 'Right'
- elif samplelabel == 2:
- labelstr = 'Foot'
- else:
- labelstr = 'Tongue'
- # 画布宽度为14英寸 高度为6英寸
- fig = plt.figure(figsize=(28, 12))
- # 顶部中央放置一个标签
- fig.suptitle('Subject:' + str(int(subid)) + ' ' + 'Label:' + labelstr
- + ' $P_{Left}=$' + str(round(likelihood[0], 2))
- + ' $P_{Right}=$' + str(round(likelihood[1], 2))
- + ' $P_{Foot}=$' + str(round(likelihood[2], 2))
- + ' $P_{Tongue}=$' + str(round(likelihood[3], 2))
- ) # , fontsize=12)
- # devide the figure layout
- # 创建一个grid网格图形,2列3行,可以存放多个子图
- gridlayout = gridspec.GridSpec(ncols=2, nrows=3, figure=fig, wspace=0.2, hspace=0.5)
- # 在网格中创建一个子图,占据前两行,第一列的位置
- axis0 = fig.add_subplot(gridlayout[0:2, 0])
- # 占据第三行
- axis1 = fig.add_subplot(gridlayout[2, 0])
- # 占据前三行,第二列
- axis2 = fig.add_subplot(gridlayout[0:3, 1])
- # do some preparations 准备一下
- # 获得某个样本的信号
- rawsignal = allsignals[sampleidx].cpu().detach().numpy().squeeze()
- # 通道数
- channelnum = multichannelsignal.shape[0]
- # 样本长度
- samplelength = multichannelsignal.shape[1]
- # 信号中的最大值
- maxvalue = np.max(np.abs(rawsignal))
- # 卷积核长度
- convkernelLength = self.model.kernelLength
- # calculate the heatmap for the sample 为样本计算热力图
- # 通过model也就是自定义的网路,以此运行里面的结构来计算 conv batch 最后激活函数
- # 计算了所有的信号
- source = self.model.conv(allsignals)
- source = self.model.batch(source)
- source = torch.nn.ELU()(source)
- # 得到运行结束后的激活结果 取出其中特定的一个信号
- activations = source[sampleidx].cpu().detach().numpy().squeeze()
- # 得到最大的类别(也就是训练出来的类别)的权重
- weights = self.model.fc.weight[state].cpu().detach().numpy().squeeze()
- # 得到cam Class Activation Mapping 计算激活后的结果与权重的乘积
- cam = np.matmul(weights, activations)
- # 得到长度为samplelength的零元素数组 热力图
- heatmap = np.zeros(samplelength)
- # 计算卷积长度一半
- halfkerlength = int(convkernelLength / 2)
- # 首先这个CAM的内容(权重*运行结果)放入到热力图当中 [32:(1000 - 32 + 1)] 这个长度应该是网络训练后自动计算好的
- heatmap[halfkerlength:(samplelength - halfkerlength + 1)] = cam
- # 将热力图前边和后边空缺部分填充:空缺为头或尾的平均值
- for i in range(halfkerlength - 1):
- heatmap[i] = heatmap[halfkerlength] * i / (halfkerlength - 1)
- for i in range((samplelength - halfkerlength), samplelength):
- heatmap[i] = heatmap[halfkerlength] * (samplelength - halfkerlength + 1 - i) / halfkerlength
- # 将热力图标准化
- heatmap = (heatmap - np.mean(heatmap)) / np.sqrt(np.sum(heatmap ** 2) / samplelength)
- # calculate the band power components
- # 计算多窗功率谱密度,psd,返回存储的频率值 freqs, 输入时域信号,自适应选择带宽
- psd, freqs = psd_array_multitaper(rawsignal, 250, adaptive=True, normalization='full', verbose=0)
- freq_res = freqs[1] - freqs[0] # 计算出频率间隔,这里应该都是相同的
- bandpowers = np.zeros(4)
- # 产生一个bool数组,每个元素对应频率是否在范围[1, 4]内,可以用作筛选Alpha波段
- idx_band = np.logical_and(freqs >= 1, freqs <= 4)
- # 计算特定频率范围内的频带功率,并将结果存储在bandpowers当中
- bandpowers[0] = simps(psd[idx_band], dx=freq_res)
- idx_band = np.logical_and(freqs >= 4, freqs <= 8)
- bandpowers[1] = simps(psd[idx_band], dx=freq_res)
- idx_band = np.logical_and(freqs >= 8, freqs <= 12)
- bandpowers[2] = simps(psd[idx_band], dx=freq_res)
- idx_band = np.logical_and(freqs >= 12, freqs <= 30)
- bandpowers[3] = simps(psd[idx_band], dx=freq_res)
- # 计算总能量 dx为积分的步长,freq_res是频率分辨率,及频率轴上相邻频率值的间隔
- totalpower = simps(psd, dx=freq_res)
- if totalpower < 0.00000001:
- bandpowers = np.zeros(4)
- else:
- bandpowers /= totalpower
- barx = np.arange(1, 5) # 【1,2,3,4】
- # 绘制一个条形图,x轴由barx决定,高度y由bandpowers数组中的功率谱值决定,这代表频带功率在不同频带上的分布
- axis1.bar(barx, bandpowers)
- # 设置xy轴的范围
- axis1.set_xlim([0, 5])
- axis1.set_ylim([0, 0.8])
- # 标签
- axis1.set_ylabel("Relative power")
- # 设置刻度
- axis1.set_xticks([1, 2, 3, 4])
- axis1.set_xticklabels(['Delta', 'Theta', 'Alpha', 'Beta'])
- # draw the heatmap
- # 绘制样本长度
- xx = np.arange(1, (samplelength + 1))
- axis0.set_xticks([])
- axis0.set_ylim([-maxvalue - 10, maxvalue + 10])
- axis0.set_xlim([0, (samplelength + 1)])
- axis0.set_ylabel("mV")
- # 将信号索引与信号拼接 并且让索引与信号对应
- points = np.array([xx, rawsignal]).T.reshape(-1, 1, 2)
- # 将相邻的数据点结合成线段(用于表示线段?),存储在segments数组中
- segments = np.concatenate([points[:-1], points[1:]], axis=1)
- # 将数据归一化到
- norm = plt.Normalize(vmin=-1, vmax=1)
- # 创建了一组线段的集合 segments表示需要连接的线段,每个数据点由两个值,表示x和y坐标
- # camp 表示颜色映射方案
- lc = LineCollection(segments, cmap='viridis', norm=norm)
- # 将标准化好后的heatmap放入集合中
- lc.set_array(heatmap)
- lc.set_linewidth(2)
- # 将多条线段放入坐标轴中
- axis0.add_collection(lc)
- # 为图像加入颜色条 lc表示多条线段的集合,ax表示坐标轴位置,指定颜色条在水平方向显示
- fig.colorbar(lc, ax=axis0, orientation="horizontal", ticks=[-1, -0.5, 0, 0.5, 1])
- # draw all the signals
- # 计算多通道信号的第98%分位数
- thespan = np.percentile(multichannelsignal, 98)
- # 为多通道信号创建刻度位置 间隔为thespan
- yttics = np.zeros(channelnum)
- for i in range(channelnum):
- yttics[i] = i * thespan
- # 在位置三设置xy轴
- axis2.set_ylim([-thespan, thespan * channelnum])
- axis2.set_xlim([0, samplelength + 1])
- # 脑电位置 需要自定义(BCICIV2a)
- labels = ['Fp1', 'Fp2', 'F7', 'F3', 'Fz', 'F4', 'F8', 'FT7', 'FC3', 'FCZ', 'FC4', 'FT8', 'T3', 'C3', 'Cz', 'C4',
- 'T4', 'TP7', 'CP3', 'CPz', 'CP4', 'TP8', 'T5', 'P3', 'PZ', 'P4', 'T6', 'O1', 'Oz', 'O2']
- # 设置会话操作的焦点
- plt.sca(axis2)
- plt.yticks(yttics, labels)
- # 创建热力图1
- heatmap1 = np.zeros((channelnum, samplelength)) - 1
- # 复制热力图到热力图1倒数第二行
- heatmap1[-2, :] = heatmap
- # 由创建了一个xx,也就是样本序列
- xx = np.arange(1, samplelength + 1)
- # 对每个通道数据操作
- for i in range(0, channelnum):
- # 增加偏移量避免不同通道的数据重叠
- y = multichannelsignal[i, :] + thespan * i
- # 绘制导数图?
- dydx = heatmap1[i, :]
- # 将序列与单个通道匹配
- points = np.array([xx, y]).T.reshape(-1, 1, 2)
- # segments 是存储线段的数据,以便在绘图中显示连接的线段,一个是除了最后的数据点,还有一个是除了第一个数据点,组合创建了相连的数据点
- segments = np.concatenate([points[:-1], points[1:]], axis=1)
- norm = plt.Normalize(-1, 1)
- lc = LineCollection(segments, cmap='viridis', norm=norm)
- # dydx 表示要更新线段集合 lc 的颜色映射数据,通常这个数组将用于决定线段的颜色
- lc.set_array(dydx)
- lc.set_linewidth(2)
- axis2.add_collection(lc)
- def run():
- # 文件地址
- # filename = r'dataset.mat'
- # tmp = sio.loadmat(filename)
- # xdata = np.array(tmp['EEGsample']) # 得到原数据
- # label = np.array(tmp['substate']) # 得到标签
- # subIdx = np.array(tmp['subindex']) # 得到哪个人id
- # label.astype(int)
- # subIdx.astype(int)
- # 这里看出sample就是每次运行的结果,反映到BCICIV数据集即每4s为一个sample
- # samplenum = label.shape[0]
- # xdata 原始数据 包含所有人的
- # label 每个人的标签
- channelnum = 22
- classes = 4
- subjnum = 9
- samplelength = 1000
- lr = 5e-5 # for smalle net
- sf = 250
- batch_size = 64
- n_epoch = 100
- # ydata = np.zeros(samplenum, dtype=np.longlong)
- # for i in range(samplenum):
- # ydata[i] = label[i]
- # ydata 标签数据
- selectedchan = [22] # 选择的通道
- # rawx = xdata
- # rawx 是 xdata 的副本,也就是没有处理过的x
- # xdata = xdata[:, selectedchan, :] # 全选即可
- # 得到了xdata现在都是自己需要的通道了 其实和 rawx 和 xdata 一模一样
- # channelnum = len(selectedchan)
- # you can set the subject id here
- for i in range(2, 3):
- # 选择哪个被试作为测试集
- # trainindx = np.where(subIdx != i)[0]
- # xtrain = xdata[trainindx]
- # x_train = xtrain.reshape(xtrain.shape[0], 1, channelnum, samplelength * sf)
- # y_train = ydata[trainindx]
- # 从xdata中取出了当作被试的训练数据x_train
- # x_train为训练数据
- #
- # testindx = np.where(subIdx == i)[0]
- #
- # xtest = xdata[testindx]
- # rawxdata = rawx[testindx]
- # x_test = xtest.reshape(xtest.shape[0], 1, channelnum, samplelength * sf)
- # y_test = ydata[testindx]
- # 这个可以从自己的数据提取
- # train = TensorDataset(torch.from_numpy(x_train), torch.from_numpy(y_train))
- # train_loader = DataLoader(train, batch_size=batch_size, shuffle=True)
- # 自己的数据集提取方法
- source_path = "..\\..\\OwnDataset\\BCICIV2a\\mat\\TE\\oriprocessed\\blackman\\"
- x_train, y_train, xtest, ytest = UtilsmatTE.loadLOSO(subjects=[2],
- base_path=source_path,
- aug=0)
- y_test = ytest
- rawxdata = xtest
- train_loader, valid_loader, test_loader = BCICIV2Amatdataloader2D(path=source_path,
- batch_size=32,
- random_state=21,
- asubject=2,
- aug=0,
- addBase=False,
- newaxis=True,
- squeeze=False,
- mix=1)
- # 自己的Net
- my_net = Conformer().double().cuda()
- #
- optimizer = optim.Adam(my_net.parameters(), lr=lr)
- loss_class = torch.nn.CrossEntropyLoss().cuda()
- for p in my_net.parameters():
- p.requires_grad = True
- for epoch in range(n_epoch):
- for j, data in enumerate(train_loader, 0):
- inputs, labels = data
- input_data = inputs.cuda()
- class_label = labels.cuda().long()
- my_net.zero_grad()
- my_net.train()
- class_output = my_net(input_data)
- err_s_label = loss_class(class_output, class_label)
- err = err_s_label
- err.backward()
- optimizer.step()
- print("step: " + str(epoch))
- my_net.train(False)
- with torch.no_grad():
- x_test = torch.DoubleTensor(xtest).cuda()
- answer = my_net(x_test)
- probs = np.exp(answer.cpu().numpy())
- sampleVis = FeatureVis(my_net)
- # you can set the sample index here
- sampleidx = 1
- sampleVis.generate_heatmap(allsignals=x_test,
- sampleidx=sampleidx,
- subid=i,
- samplelabel=y_test[sampleidx],
- multichannelsignal=rawxdata[sampleidx],
- likelihood=probs[sampleidx])
- if __name__ == '__main__':
- run()
VisualizationTech.py at commit 1a83f9a, no license · at the source
Overview
- School of Smart Health, Chongqing Polytechnic University of Electronic Technology, Chongqing, China
- School of Artificial Intelligence, Chongqing University of Technology, Chongqing, China
- College of Computer Science and Engineering, Chongqing University of Technology, Chongqing, China
Abstract
Motor imagery electroencephalogram (MI-EEG) analysis is essential for natural interaction and autonomous control in brain-computer interfaces (BCIs). However, deep learning models often struggle with inter-subject variability, which limits their ability to generalize across subjects. This study proposes RMETNet, a novel framework that integrates TSLANet, a spatio-temporal convolution module, and a multi-scale Riemannian geometry feature module. TSLANet suppresses noise and captures complex temporal patterns for preliminary signal decoding, while the spatio-temporal convolution module extracts higher-order representations. The Riemannian branch learns geometry-based distribution features across subjects, and the fused features are used for classification. To address inter-subject distribution shifts, RMETNet incorporates Maximum Mean Discrepancy (MMD) loss for domain adaptation, aligning feature distributions between source and target domains. Experiments show that on the four-class BCI Competition IV 2a (BCICIV2a) dataset, RMETNet achieved accuracies of 71.39% in the cross-subject setting and 80.71% in the subject-dependent setting; on the two-class BCI Competition IV 2b (BCICIV2b) dataset, it achieved 80.93% and 86.76%, respectively. The model consistently outperformed baseline algorithms. Ablation and visualization analyses further validated its effectiveness in reducing inter-subject feature distribution disparities and enhancing MI-EEG decoding. The code is available at: https://
Reproduced under the paper's license (CC BY), from the paper cited above.
Repository
Its files are read in the Code ↔ Paper reader above, with 5 matches between paragraphs and lines of code.
rokanfeermecer486/RMETNet
1a83f9a75de39faffeb1890c6b6677db9b7873c2, 29 May 2025Availability: 1 check, the latest on 29 September 2026: the link answers
- 29 September 2026: the link answers
51 files
- bciciv2a/
LoaderBCICIV2a.py , Python, 361 lines, 1 match - bciciv2a/
LoaderMI.py , Python, 184 lines - bciciv2a/
MIBCICIV2a_gdf_generate. , Python, 38 linespy - bciciv2a/
MIBCICIV2a_mat_generate. , Python, 95 linespy - bciciv2a/
MIBCICIV2a_mat_generate_ , Python, 49 linesLOSO.py - bciciv2a/
MIBCICIV2a_mat_generate_ , Python, 87 lines, 1 matchTE.py - bciciv2a/
MIBCICIV2a_mat_generate_ , Python, 87 linescrosssub.py - bciciv2a/
MIBCIgenerator.py , Python, 85 lines - bciciv2a/
MIgenerator.py , Python, 79 lines - bciciv2a/
__init__.py , Python, 1 line - bciciv2a/
data_preprocess.py , Python, 93 lines - bciciv2a/
dataloader-o.py , Python, 80 lines - bciciv2a/
general_processor.py , Python, 348 lines, 1 match - bciciv2a/
general_processor_BCICIV , Python, 248 lines, 1 match.py - bciciv2a/
general_processor_BCICIV , Python, 554 lines_mat.py - bciciv2a/
general_processor_BCICIV , Python, 389 lines_mat_TE.py - bciciv2a/
general_processor_mibci. , Python, 415 linespy - gcn/
baseshallow/ , Python, 160 linesSLANetMultiLayerB.py - gcn/
baseshallow/ , Python, 161 linesSLANetMultiLayerRie.py - gcn/
baseshallow/ , Python, 152 linesSLANetMultiLayerRieB.py - gcn/
baseshallow/ , Python, 152 linesSLANetMultiLayerRieBWith outRie.py - gcn/
baseshallow/ , Python, 161 linesSLANetMultiLayerRieSavef eature.py - gcn/
baseshallow/ , Python, 160 linesSLANetMultiLayerRieWitho utRie.py - gcn/
baseshallow/ , Python, 133 linesShallowATFNet.py - gcn/
baseshallow/ , Python, 111 linesShallowNetSquare.py - gcn/
baseshallow/ , Python, 120 linesShallowSLANet.py - gcn/
baseshallow/ , Python, 120 linesShallowSLANetMultiLayer. py - gcn/
baseshallow/ , Python, 120 linesShallowSLANetMultiLayerW ithoutRie.py - gcn/
baseshallow/ , Python, 201 linesShallowTransformerNet.py - maingcn-mmdloss-2a-matri
cs.py , Python, 422 lines - tools/
EMA.py , Python, 35 lines - tools/
Interaug.py , Python, 33 lines - tools/
Lamb.py , Python, 101 lines - tools/
MMDLoss.py , Python, 46 lines - tools/
Regularization.py , Python, 102 lines - tools/
Rieman.py , Python, 68 lines - tools/
SpatialDropout.py , Python, 39 lines - tools/
VisualizationTech.py , Python, 345 lines, 1 match - tools/
early_stop.py , Python, 55 lines - tools/
graphtools.py , Python, 169 lines - tools/
log.py , Python, 21 lines - tools/
tensorboard_logger.py , Python, 37 lines - tools/
utilskcross.py , Python, 282 lines - tools/
utilskcrossV2.py , Python, 476 lines - tools/
utilsoriginal.py , Python, 168 lines - tools/
utilstrte.py , Python, 142 lines - tools/
utilstrva.py , Python, 443 lines - tools/
utilstrvate.py , Python, 428 lines - tools/
utilstrvate_jointloader. , Python, 345 linespy - tools/
utilstrvate_raytune.py , Python, 195 lines - tools/
utilstrvatefinetune.py , Python, 359 lines
The paper's code and data availability statement is in the Data section.
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 51 scripts, each with its path and the digest of its content;
- 5 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Data Availability
The code of this is available at: https://
Reproduced under the paper's license (CC BY), from the paper cited above.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 29 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 10 authors, 7 MeSH terms, 2 funders, 35 references.
Cite
This paper
Zhao, Y., He, D., Ren, F., Xia, Q., Xu, L., Xie, G., Zhang, X., Yang, R., Zou, S., & Jiang, B. (2026). RMETNet: A cross-subject motor imagery EEG signal classification model based on TSLANet and riemannian geometry features. PloS one, 21(4), e0347671. https://
BibTeX
@article{zhao2026rmetnet
author = {Zhao, Yun and He, Dongyi and Ren, Fudai and Xia, Qingling and Xu, Linhao and Xie, Guanghui and Zhang, Xiaoling and Yang, Renqiang and Zou, Shuaidong and Jiang, Bin},
title = {{RMETNet: A cross-subject motor imagery EEG signal classification model based on TSLANet and riemannian geometry features}},
journal = {PloS one},
year = {2026},
month = apr,
volume = {21},
number = {4},
pages = {e0347671},
publisher = {PLOS},
issn = {1932-6203},
doi = {10.1371/
url = {https://
pmid = {42018586},
pmcid = {PMC13102224}
}
RIS
TY - JOUR
AU - Zhao, Yun
AU - He, Dongyi
AU - Ren, Fudai
AU - Xia, Qingling
AU - Xu, Linhao
AU - Xie, Guanghui
AU - Zhang, Xiaoling
AU - Yang, Renqiang
AU - Zou, Shuaidong
AU - Jiang, Bin
TI - RMETNet: A cross-subject motor imagery EEG signal classification model based on TSLANet and riemannian geometry features
T2 - PloS one
J2 - PLoS One
PY - 2026
DA - 2026/
VL - 21
IS - 4
SP - e0347671
SN - 1932-6203
PB - PLOS
DO - 10.1371/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1371/
"type": "article-journal",
"title": "RMETNet: A cross-subject motor imagery EEG signal classification model based on TSLANet and riemannian geometry features",
"container-title": "PloS one",
"author": [
{
"family": "Zhao",
"given": "Yun"
},
{
"family": "He",
"given": "Dongyi"
},
{
"family": "Ren",
"given": "Fudai"
},
{
"family": "Xia",
"given": "Qingling"
},
{
"family": "Xu",
"given": "Linhao"
},
{
"family": "Xie",
"given": "Guanghui"
},
{
"family": "Zhang",
"given": "Xiaoling"
},
{
"family": "Yang",
"given": "Renqiang"
},
{
"family": "Zou",
"given": "Shuaidong"
},
{
"family": "Jiang",
"given": "Bin"
}
],
"container-title-short":
"volume": "21",
"issue": "4",
"page": "e0347671",
"DOI": "10.1371/
"PMID": "42018586",
"PMCID": "PMC13102224",
"ISSN": "1932-6203",
"publisher": "PLOS",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
22
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.3389/fpsyg.2026.1774068 [code]
- Analysis of cognitive mechanisms in phoneme perception and pronunciation errors among Korean language learners.Journal: Frontiers in psychologyIn common: Braindecode, pyRiemann, TensorFlow, 8 other tools, EEG, 1 reference
- [2] doi:10.3390/bios16080437 [code]
- Deep Learning for Ear-EEG-Based Brain-Computer Interface: A Systematic Comparison and Design Insights.Journal: BiosensorsIn common: Braindecode, MNE-Python, PyTorch, 4 other tools, EEG, 5 references
- [3] doi:10.1038/s41598-026-68186-2 [code]
- NeuroStream: spectral-spatio-temporal
deep learning for visual stimulus classification from EEG. Journal: Scientific reportsIn common: Braindecode, PyTorch, seaborn, 5 other tools, methods / tools, EEG, 4 references - [4] doi:10.3390/s26175327 [code]
- Subject Identity Confounds qEEG Emotion Recognition on DEAP and DREAMER.Journal: Sensors (Basel, Switzerland)In common: pyRiemann, imbalanced-learn, TensorFlow, 7 other tools, EEG
- [5] doi:10.1038/s42003-026-10957-8 [code]
- Brain defence by the extracellular matrix protein Cochlin.Journal: Communications biologyIn common: imbalanced-learn, CuPy, TensorFlow, 7 other tools
- [6] doi:10.1038/s41598-026-52330-z [code]
- SHAP analysis of an improved EEG-based mental workload classification framework: utilizing data augmentation and explainable AI.Journal: Scientific reportsIn common: imbalanced-learn, TensorFlow, MNE-Python, 5 other tools, methods / tools, EEG, 1 reference
- [7] doi:10.1371/journal.pone.0354976 [code]
- Improved motor imagery BCI performance via task-unaware compression in the BELT Bayesian Edge-Cloud architecture.Journal: PloS oneIn common: TensorFlow, MNE-Python, seaborn, 4 other tools, methods / tools, EEG, 2 references
- [8] doi:10.3389/fnins.2026.1874302 [code]
- Architecture-data matching for EEG-EMG decoding: compact deep models match classical spectral decoders on the WAY-EEG-GAL grasp-and-lift dataset.Journal: Frontiers in neuroscienceIn common: PyTorch, scikit-learn, pandas, 3 other tools, methods / tools, EEG, 4 references
- [9] doi:10.7554/elife.110588 [code]
- Opening the black box toward a modular approach to spike sorting.Journal: eLifeIn common: imbalanced-learn, TensorFlow, PyTorch, 6 other tools, methods / tools
- [10] doi:10.1038/s41592-026-03057-2 [code]
- CREsted: modeling genomic and synthetic cell-type-specific enhancers across tissues and species.Journal: Nature methodsIn common: CuPy, TensorFlow, PyTorch, 6 other tools, methods / tools
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 1 repository of the authors' code, each at its verified commit and with its license, 51 scripts, and 5 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:f23abd933959d82c…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
