返回列表

2nd place solution

686. PhysioNet - Digitization of ECG Images | physionet-ecg-image-digitization

开始: 2025-10-21 结束: 2026-01-22 医学影像分析 数据算法赛
第二名解决方案 - Takashi Someya
作者: Takashi Someya (Grandmaster)
发布时间: 2026-01-24
竞赛排名: 第 2 名

第二名解决方案

致谢

我要感谢组织者和 Kaggle 工作人员举办并运行了这场出色的竞赛。我也向 @hengck23 致以诚挚的谢意,感谢他发布了出色的 baseline 笔记本和讨论。

概述

我的 pipeline 在阶段 0 和阶段 1 未经修改地使用了 @hengck23公开实现。因此,本解决方案主要侧重于阶段 2 的分割和后处理技术。

关键创新:

  • 将竞赛时间序列数据替换为原始的 PTB-XL 数据集信号 (500Hz)
  • 使用稀疏掩码直接预测信号采样位置
  • 构建一个融合导间相位和振幅信息的 2.5D 分割模型(序列模型)
  • 开发一个结合 timm 编码器和 @hengck23MyCoordUnetDecoder 的全图分割模型(整体模型)

注意:在本解决方案说明中,我将标准 12 导联 ECG 的每一行称为“序列 (0-3)"。

策略

竞赛 metric 计算每张图像的 SNR,在线性 SNR 域中对其进行平均,然后转换为 SNR(dB) (讨论)。

因此,提高中等至高 SNR 图像的分数往往比在最难的低 SNR 案例上花费精力更能提高最终得分。在分析折外 (OOF) 预测后,我专注于改进中等难度和简单的图像,这些图像数量更多且更容易改进。

为了通过靠近采样点来最小化预测误差,我在三个关键领域改进了我的方法:

  • 分割掩码创建
  • 建模架构
  • 后处理方法

数据

竞赛数据

竞赛数据是 PTB-XL 数据集 的子集。

虽然 PTB-XL 数据集以 500Hz 采样频率提供所有时间序列数据,但竞赛数据使用多种频率:250、256、500、512、1000 和 1025Hz。这表明竞赛组织者将原始的 500Hz 信号重采样到了这些不同的频率。

我通过计算相关系数将竞赛数据匹配回原始的 PTB-XL 时间序列,并将所有信号替换为其 500Hz 原始信号。

500hz 信号对比

这种替换提高了采样位置的一致性,从而在训练期间带来了明显的 CV 改进。单折模型的 LB 分数从 21.67dB 提高到 22.49dB。

合成数据

由于仅使用竞赛数据就取得了令人满意的分数,且合成数据的进一步改进微乎其微,我没有在额外的数据合成上投入太多时间(使用 PTB-XL 数据集和 ECG-Image-Kit)。

考虑到私人数据集可能包含困难的 0015 类型褶皱数据,我在每个 epoch 的训练集中添加了少量随机选择的 0015 数据。

分割掩码

创建分割掩码的方法至关重要。这是因为通过 pipeline(时间序列 → 分割掩码 → 时间序列)重建信号时实现的 SNR 直接与模型的上限性能相关。

密集掩码(覆盖整个信号线)没有产生高的重建 SNR。相反,我创建了稀疏掩码,每列最多标注 2 个像素。

为了在后处理阶段实现亚像素精度的重建,我根据 y 坐标的小数部分将标签分布到两个像素(整数部分和整数部分 + 1)。在重建期间,我通过使用标签值作为权重计算 y 坐标的加权平均将其转换为时间序列数据。

掩码重建示意图

为了在不重采样的情况下从 500Hz (sig_len=5000) 映射到掩码,我将掩码宽度设置为 5600 像素,并在 [301:5301] 范围内绘制掩码,覆盖 5000 像素。

以下是创建的掩码和在此掩码上训练的模型的 OOF 预测结果(黄色:GT,绿色:预测)。

掩码预测结果

模型

我使用了两种类型的模型:

  • 整体模型 (whole model):结合 timm 编码器和 @hengck23MyCoordUnetDecoder 的 U-Net 模型。
  • 序列模型 (series model):融合序列图像的 2.5D 分割模型。我使用它在导联之间共享相位和振幅信息。

整体模型架构

我基于 @hengck23 的模型构建了整体模型架构。我将编码器更改为来自 segmentation_models_pytorch 的 timm 编码器。我裁剪了图像的顶部并将其调整大小为 (1280, 5600)。

序列模型架构

特定的 ECG 导联具有很强的相关性(例如,爱因托芬定律)。为了将这些关系纳入模型,我构建了一个接受四个序列作为输入的 2.5D 模型。

我在以零 mV y 坐标位置为中心的 ±3mV (240 像素) 范围内裁剪每个序列。共享的 U-Net 编码器处理每个序列图像,然后我在每个 U-Net 解码器层的连接路径中融合跨序列的特征。解码器提取特征,分割头将其转换为掩码预测。

模型架构 v5

融合模块

我测试了三种融合模块变体:

  • conv2d
  • 共享 conv2d
  • conv3d

通常,2.5D 模型使用 conv3d、LSTM 或 transformers 来提取深度信息。LSTM 效果不佳(可能是由于参数设置不当)。由于经验有限,我没有尝试 transformers。

由于我想混合所有深度(序列堆叠顺序)信息,我还尝试了使用 conv2d 进行特征融合。虽然变体之间的差异很小,但 conv2d 显示了最好的 CV 结果。

conv2d

我应用 conv2d 块 (Conv2d→BatchNorm2d→ReLU) 进行特征缩减和特征融合。

conv2d 融合

共享 conv2d

为了节省参数,共享 conv2d 在所有序列之间共享缩减 conv2d 块。

conv3d

我将特征重塑为 (C, 4, H, W) 并多次应用 conv3d 块 (Conv3d→BatchNorm3d→LeakyReLU)。

模型比较

为了验证融合模块的有效性,我比较了预测结果。

顶行显示具有未掩码信号和 GT 掩码的图像。中间行和底行显示具有掩码区域(模拟图像伪影)的图像,以及分别来自整体模型和序列模型的预测。

虽然整体模型无法预测掩码区域,但序列模型跨导联共享信息,使其能够合理预测峰值相位和振幅。

掩码预测对比

训练策略

参数

  • 输入图像:阶段 1 校正图像
    • 整体模型:输入形状 = (3, 1280, 5600)
    • 序列模型:输入形状 = (4, 3, 480, 5600)
  • Loss: BCEWithLogitsLoss(pos_weight=20)
  • Epoch: 50
  • Batch size: 4
  • Optimizer: AdamW
    • Learning rate: 5e-4 ~ 1e-3
    • Weight decay: 0.01
  • Scheduler: CosineAnnealingLR

提示:梯度检查点 (Gradient checkpointing) 对于减少高分辨率图像的激活内存消耗非常有效

数据增强

image_only_aug = A.Compose([
    A.RandomBrightnessContrast(brightness_limit=(-0.1,0.1), contrast_limit=(-0.1, 0.1), p=0.2),
    A.RandomShadow(p=0.2),
    A.GaussianBlur(p=0.2),
    A.CoarseDropout(num_holes_range=(1,8), hole_height_range=(0.01, 0.1), hole_width_range=(0.01, 0.05), fill=0, p=0.1),
    A.ToGray(p=0.25),
])
image_and_mask_aug = A.HorizontalFlip(p=0.5)

后处理

掩码后处理

我使用预测结果计算掩码每一列的加权平均,以获得亚像素级别的预测。

重采样方法

我测试了:

  • scipy.signal.resample
  • scipy.signal.resample_poly(padtype='line')
  • torch.nn.functional.interpolate(mode="linear")

scipy.signal.resample 给出了最好的结果。

像素转序列

完整的掩码→时间序列转换 pipeline 代码,包括掩码后处理和重采样:

def pixel_to_series(pixel, length):
    _, H, W = pixel.shape
    eps=1e-8
    y_idx = np.arange(H, dtype=np.float32)[:, None]

    series = []
    for j in [0, 1, 2, 3]:
        p = pixel[j]
        denom = p.sum(axis=0)
        y_exp = (p * y_idx).sum(axis=0) / (denom + eps)
        series.append(y_exp)
    series = np.stack(series).astype(np.float32)

    if length!=W:
        resampled_series = []
        for s in series:
            rs = signal.resample(s, length).astype(np.float32)
            resampled_series.append(rs)
        series = np.stack(resampled_series)
    return series

推理

TTA

  • 水平翻转

结果

提交 A (6 个模型)

公共 LB: 23.37, 私人 LB: 23.27

提交 B (11 个模型)

公共 LB: 23.34, 私人 LB: 23.23

编码器 模型 (融合模块) 合成数据 公共 LB 私人 LB 提交 A 提交 B
EfficientNet B7 整体 22.93 22.65 ☑️ ☑️
EfficientNetV2 L 整体 22.60 22.55 ☑️ ☑️
EfficientNetV2 M 整体 22.52 22.38 ☑️
EfficientNetV2 M 整体 22.58 22.39 ☑️
EfficientNet B6 序列 (共享 conv2d) 23.10 22.92 ☑️ ☑️
EfficientNet B6 序列 (共享 conv2d) 23.00 22.81 ☑️ ☑️
EfficientNet B4 序列 (共享 conv2d) 22.93 22.73 ☑️
EfficientNetV2 L 序列 (conv3d) 22.92 22.77 ☑️ ☑️
EfficientNetV2 L 序列 (conv2d) 22.85 22.70 ☑️ ☑️
EfficientNetV2 M 序列 (conv3d) 22.73 22.49 ☑️
EfficientNetV2 M 序列 (conv2d) 22.76 22.55 ☑️

参考文献

  • https://www.kaggle.com/code/hengck23/demo-submission
  • Shivashankara KK, Deepanshi, Shervedani AM, Reyna MA, Clifford GD, Sameni R. ECG-Image-Kit: a synthetic image generation toolbox to facilitate deep learning-based electrocardiogram digitization. Physiological Measurement 2024; 45:055019. DOI: 10.1088/1361-6579/ad4954
  • Reyna MA, Deepanshi, Weigle J, Koscova Z, Campbell K, Shivashankara KK, Saghafi S, Nikookar S, Motie-Shirazi M, Kiarashi Y, Seyedi S, Hassannia M, Bjørnstad AM, Stenhede E, Ranjbar A, Clifford GD, and Sameni R. ECG-Image-Database: A dataset of ECG images with real-world imaging and scanning artifacts; a foundation for computerized ECG image digitization and analysis, 2024. DOI: 10.48550/arXiv.2409.16612.
  • Wagner, P., Strodthoff, N., Bousseljot, R., Samek, W., & Schaeffter, T. (2022). PTB-XL, a large publicly available electrocardiography dataset (version 1.0.3). PhysioNet. RRID:SCR_007345. https://doi.org/10.13026/kfzx-aw45
  • Wagner, P., Strodthoff, N., Bousseljot, R.-D., Kreiseler, D., Lunze, F.I., Samek, W., Schaeffter, T. (2020), PTB-XL: A Large Publicly Available ECG Dataset. Scientific Data. https://doi.org/10.1038/s41597-020-0495-6
  • Goldberger, A., Amaral, L., Glass, L., Hausdorff, J., Ivanov, P. C., Mark, R., … & Stanley, H. E. (2000). PhysioBank, PhysioToolkit, and PhysioNet: Components of a new research resource for complex physiologic signals. Circulation [Online]. 101 (23), pp. e215–e220. RRID:SCR_007345.

代码获取

同比赛其他方案