1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| import torch import torch.nn as nn import numpy as np
class SpectralBranch(nn.Module): """频谱分支:自适应频段权重学习""" def __init__(self, n_channels=17, n_bands=5): super().__init__() self.band_attention = nn.Sequential( nn.Linear(n_bands, n_bands * 2), nn.ReLU(), nn.Linear(n_bands * 2, n_bands), nn.Sigmoid() ) self.conv = nn.Sequential( nn.Conv2d(n_channels, 32, (n_bands, 3), stride=1), nn.BatchNorm2d(32), nn.ReLU(), nn.Conv2d(32, 64, (1, 3), stride=2), nn.BatchNorm2d(64), nn.ReLU(), nn.AdaptiveAvgPool2d(1), nn.Flatten() ) def forward(self, x): """x: [B, C, F, T]""" B, C, F, T = x.shape band_weights = self.band_attention( x.mean(dim=(2, 3)) ) x = x * band_weights.unsqueeze(1).unsqueeze(3) return self.conv(x)
class TemporalBranch(nn.Module): """时序分支:窗口方差+分组注意力""" def __init__(self, n_channels=17): super().__init__() self.conv = nn.Conv1d(n_channels, 64, 5, stride=2) self.lstm = nn.LSTM(64, 128, batch_first=True, bidirectional=True) self.attention = nn.Sequential( nn.Linear(256, 64), nn.ReLU(), nn.Linear(64, 1) ) def forward(self, x): """x: [B, C, T]""" feat = self.conv(x) feat = feat.permute(0, 2, 1) out, _ = self.lstm(feat) att = torch.softmax(self.attention(out), dim=1) context = (out * att).sum(dim=1) return context
class SFTNet(nn.Module): """SFT-Net: 双分支频谱-时序注意力融合""" def __init__(self, n_classes=3): super().__init__() self.spectral = SpectralBranch(n_channels=17, n_bands=5) self.temporal = TemporalBranch(n_channels=17) self.fusion = nn.Sequential( nn.Linear(64 + 256, 128), nn.ReLU(), nn.Dropout(0.3), nn.Linear(128, n_classes) ) def forward(self, eeg_4d, eeg_2d): """eeg_4d: [B,C,F,T], eeg_2d: [B,C,T]""" spec_feat = self.spectral(eeg_4d) temp_feat = self.temporal(eeg_2d) fused = torch.cat([spec_feat, temp_feat], dim=-1) return self.fusion(fused)
if __name__ == "__main__": model = SFTNet(n_classes=3) eeg_4d = torch.randn(4, 17, 5, 100) eeg_2d = torch.randn(4, 17, 100) out = model(eeg_4d, eeg_2d) print(f"SFT-Net输出: {out.shape}") print(f"参数: {sum(p.numel() for p in model.parameters()):,}")
|