返回列表

10th place solution: CNN with pseudo labels

524. G2Net Detecting Continuous Gravitational Waves | g2net-detecting-continuous-gravitational-waves

开始: 2022-10-04 结束: 2023-01-03 物理与天文 数据算法赛
第10名方案:使用伪标签的 CNN

第10名方案:使用伪标签的 CNN

作者:anonamename | 排名:第10名

感谢主办方和组织者举办了如此具有挑战性的比赛!

我的解决方案基于 CNN。我融合了多种元素,但以下三项尤为重要:

  • 使用 RobustScaler 进行归一化
  • 目标值和频率的多任务学习
  • 伪标签

数据

我使用 PyFstat 生成了与测试数据具有相同时间戳范围、频率和振幅的数据。信号数据的信号深度 在 [1, 50] 范围内生成。各类数据的数量如下。

数据类型 数据数量
间隙噪声 3000
非平稳噪声 2983
信号 5400

预处理

通过对 H1 和 L1 分别执行以下处理,我创建了形状为 (C,H,W) = (2, 360, 127) 的图像。

  • 使用 sklearn.preprocessing.RobustScaler 对 H1 和 L1 的振幅平方进行归一化。
    • 由于测试数据中的真实噪声存在较大的异常值,我使用了 sklearn.preprocessing.RobustScaler,它对异常值具有鲁棒性。
  • 按照 G2NET large kernel inference 的方法对齐 H1 和 L1 的时间戳,生成形状为 (C,H,W) = (2, 360, 5760) 的图像。
  • 取移动平均值,将图像大小从 (2, 360, 5760) 变为 (2, 360, 127)。
  • 裁剪具有较大最大值的通道的数值。
    • 因为测试集中包含 H1 和 L1 最大值差异过大的数据。
  • 最后,使用整个数据的均值和标准差对图像进行标准化。

模型

这是一个预测目标值和频率的多输出模型。

  • 目标损失函数为 nn.BCEWithLogitsLoss
  • 频率//50 的损失函数为 11 个类别的 nn.CrossEntropyLoss
  • 架构为 tf_efficientnet_b5_ap
  • 将模型第一层卷积层的步幅 更改为 (1,2) 以提高图像分辨率
class CustomModel(nn.Module):
    def __init__(self, pretrained=True):
        super().__init__()
        self.net = timm.create_model("tf_efficientnet_b5_ap", 
                                     pretrained=pretrained, 
                                     num_classes=0, 
                                     in_chans=2)
        
        # 减小第一层卷积的步幅
        modules_iter = iter(self.net.modules())
        for module in modules_iter:
            if isinstance(module, torch.nn.Conv2d) and tuple(module.stride) == (2, 2):
                break
        module.stride = (1, 2)
        
        # 目标 
        self.head1 = nn.Sequential(
            nn.Linear(self.net.num_features, 1)
        )
        
        # 频率//50: 40-500Hz // 50
        freq_div_n = 50
        self.head2 = nn.Sequential(
            nn.Linear(self.net.num_features, (500 // freq_div_n) - (40 // freq_div_n) + 1)
        )

    def forward(self, x, labels=None):
        feat = self.net(x)
        y1 = self.head1(feat)
        y2 = self.head2(feat)
        return y1[:,0], y2

训练

  • 交叉验证:目标值 StratifiedKFold(n_splits=5)
  • 优化器:AdamW
  • 调度器:预热 0-3 epoch (lr=4e-6->4e-4) + 余弦退火 3-100 epoch (lr=4e-4->4e-6)
同比赛其他方案