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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
| """ 论文:EEG-Driven Decoding Framework for Passenger Hazard Perception arXiv: 2609.07128 代码:https://github.com/SOTIF-AVLab/EEG2023
核心方法:3D-CRNN 用于EEG信号的风险预测和危险识别 """
import torch import torch.nn as nn import torch.nn.functional as F
class CRNN3D(nn.Module): """ 3D Convolutional Recurrent Neural Network 论文Section 3描述的3D-CRNN模型: - 3D卷积层: 提取EEG空间-时序特征 - 循环层: 建模时序依赖 - 分类头: 风险预测(RP) + 危险识别(DI) 输入: EEG信号, shape=(batch, channels, time, freq) 或 (batch, 1, channels, time) 输出: RP logits + DI logits """ def __init__(self, num_channels: int = 32, time_steps: int = 1200, num_classes_rp: int = 2, num_classes_di: int = 2): super().__init__() self.conv3d_1 = nn.Conv3d( in_channels=1, out_channels=16, kernel_size=(3, 3, 3), stride=(1, 1, 1), padding=(1, 1, 1) ) self.bn1 = nn.BatchNorm3d(16) self.pool1 = nn.MaxPool3d(kernel_size=(2, 1, 1)) self.conv3d_2 = nn.Conv3d( in_channels=16, out_channels=32, kernel_size=(3, 3, 3), stride=(1, 1, 1), padding=(1, 1, 1) ) self.bn2 = nn.BatchNorm3d(32) self.pool2 = nn.MaxPool3d(kernel_size=(2, 1, 1)) self.conv3d_3 = nn.Conv3d( in_channels=32, out_channels=64, kernel_size=(3, 3, 3), stride=(1, 1, 1), padding=(1, 1, 1) ) self.bn3 = nn.BatchNorm3d(64) self.pool3 = nn.MaxPool3d(kernel_size=(2, 1, 1)) time_after_conv = time_steps // 8 flat_size = 64 * time_after_conv * num_channels self.lstm = nn.LSTM( input_size=64 * num_channels, hidden_size=128, num_layers=2, batch_first=True, bidirectional=True, dropout=0.3 ) self.rp_head = nn.Sequential( nn.Linear(256, 64), nn.ReLU(), nn.Dropout(0.5), nn.Linear(64, num_classes_rp) ) self.di_head = nn.Sequential( nn.Linear(256, 64), nn.ReLU(), nn.Dropout(0.5), nn.Linear(64, num_classes_di) ) def forward(self, x): """ 前向传播 Args: x: EEG信号, shape=(B, 1, T, C, F) B=batch, T=time, C=channels, F=freq Returns: rp_logits: 风险预测 logits di_logits: 危险识别 logits """ x = F.relu(self.bn1(self.conv3d_1(x))) x = self.pool1(x) x = F.relu(self.bn2(self.conv3d_2(x))) x = self.pool2(x) x = F.relu(self.bn3(self.conv3d_3(x))) x = self.pool3(x) B, C, T, Ch, F = x.shape x = x.permute(0, 2, 1, 3, 4) x = x.reshape(B, T, C * Ch * F) lstm_out, _ = self.lstm(x) last_output = lstm_out[:, -1, :] rp_logits = self.rp_head(last_output) di_logits = self.di_head(last_output) return rp_logits, di_logits
class CSPFeatureExtractor(nn.Module): """ Common Spatial Pattern (CSP) 特征提取 论文中的基线方法: 1. CSP: 空间滤波,最大化两类方差比 2. XGBDIM: XGBoost用于危险识别 3. EEGNet/DeepConvNet: 深度学习基线 """ def __init__(self, num_channels: int = 32, num_filters: int = 6): super().__init__() self.num_filters = num_filters def forward(self, x): """CSP特征提取""" return x
if __name__ == "__main__": batch_size = 8 time_steps = 1200 num_channels = 32 x = torch.randn(batch_size, 1, time_steps, num_channels, 1) model = CRNN3D(num_channels=num_channels, time_steps=time_steps) rp_logits, di_logits = model(x) print(f"输入形状: {x.shape}") print(f"RP logits形状: {rp_logits.shape}") print(f"DI logits形状: {di_logits.shape}") print(f"\n模型参数量: {sum(p.numel() for p in model.parameters()):,}") print("\n=== 论文实验结果 ===") print("3D-CRNN:") print(f" RP Balanced Accuracy: 95.3% ± 2.7%") print(f" DI (单被试): 80.9% → 85.0% (RSL提升)") print(f" DI (跨会话): 77.0% ± 5.3%") print(f" DI (跨被试, 已见): 77.4% ± 1.1%") print(f" DI (跨被试, 未见): 64.9% ± 8.5%") print("\n基线对比:") print(" CSP+XGBDIM: 基线性能") print(" EEGNet: 深度学习基线") print(" DeepConvNet: 深度学习基线")
|