返回列表

7th Place solution

600. HMS - Harmful Brain Activity Classification | hms-harmful-brain-activity-classification

开始: 2024-01-09 结束: 2024-04-08 临床决策支持 数据算法赛

第七名解决方案

感谢Kaggle和主办方举办这场有趣的比赛。这也是一次非常棒的团队合作经历,感谢@gunesevitan。

我们的解决方案包括2D原始EEG模型和2D EEG频谱图模型。我们没有使用Kaggle的10分钟频谱图,因为在实验中发现它们的交叉验证分数一直很低。我们对所有模型使用了18个双极信号差分。EKG信号没有带来提升。我们对所有类型的数据使用了convnext_basemaxvit_tiny_rw_224

2D 原始 EEG

我们将每个(10000,)的信号重塑为(20,500),使用步长20,然后将18个信号垂直堆叠形成360×500的2D图像。我们训练了两种类型的模型:50秒模型和50/10秒模型。


inputs = inputs.T

if center_10_stack:
    center_10 = inputs[:, 4000:6000]

image = []
n_channels = 18

for i in range(n_channels):
    for j in range(20):
        image.append(inputs[i, j::20])

    if center_10_stack:
        for j in range(4):
            image.append(center_10[i, j::4])

image = np.stack(image, axis=0)

2D STFT 频谱图

我们使用cusignal为每个信号生成频谱图,然后垂直堆叠形成2D图像。参数的选择使最终图像形状为(512,512)。我们尝试了其他分辨率,但发现这个是最优的。使用该数据训练的模型获得了最佳的交叉验证分数,因此我们训练了四种模型:50秒、50/10秒、50/30/10秒和30/10秒。


spectrogram_50_second = []
for signal_idx in range(18):
    frequencies, _, spectrogram = cusignal.spectrogram(
        eeg_differences[:, signal_idx],
        fs=200,
        nperseg=280,
        noverlap=261,
        nfft=None
    )
    frequency_mask = (frequencies >= 0.5) & (frequencies <= 20)
    spectrogram = spectrogram[frequency_mask, :]
    spectrogram = spectrogram.get().astype(np.float32)
        
    spectrogram_50_second.append(spectrogram)
    
spectrogram_50_second = np.concatenate(spectrogram_50_second, axis=0)
spectrogram_50_second = np.log1p(spectrogram_50_second)

2D 多窗口频谱图

我们发现Kaggle的10分钟频谱图是多窗口频谱图,来源见此处。我们使用此处的Python代码生成EEG频谱图,然后通过水平堆叠、垂直堆叠和填充操作创建(500,372)的图像。我们训练了两种模型:50秒和50/10秒模型。


eeg_spec = []
for idx in range(18):
    spect, stimes, sfreqs = multitaper_spectrogram(
        eeg_differences[:, idx],
        fs=200,
        frequency_range=[0.5, 20],
        window_params=[4, 0.5],
        multiprocess=True,
        plot_on=False,
        verbose=False
    )
    eeg_spec.append(spect)
    
eeg_spec = np.stack(eeg_spec, axis=0).astype(np.float32)
eeg_spec = np.log1p(eeg_spec)

img = []
for eeg_spec_idx in [(0, 4), (4, 8), (8, 12), (12, 16), (16, 18)]:
    eeg_spec_temp = eeg_spec[eeg_spec_idx[0]:eeg_spec_idx[1]]

    if eeg_spec_temp.shape[0] == 2:
        eeg_spec_temp = np.concatenate([eeg_spec_temp, np.zeros_like(eeg_spec_temp)], axis=0)

    img.append(np.concatenate([eeg_spec_temp[0], eeg_spec_temp[1],
                               eeg_spec_temp[2], eeg_spec_temp[3]], axis=1))

img = np.concatenate(img, axis=0)

我们的最终提交是对三种数据的加权融合,权重分别为0.2、0.65和0.15。

同比赛其他方案