返回报告目录

天气预测 CNN 基线训练

Train 1 Report: CNN Baseline v1

1. Experiment Overview

Item Detail
Run name cnn_baseline_1
Model class BaselineCNN (models/cnn_baseline.py)
SLURM job 315256
GPU NVIDIA L40S
Date 2026-03-15
Status Completed (50/50 epochs)
Total time ~14.4 hours (~1040s/epoch)
Trainable parameters 11,325,062

2. Architecture (Reproducible Specification)

2.1 Overview

单帧 2D CNN,输入一张气象空间快照,经 6 层 ResBlock 逐步降采样后全局平均池化,最后由全连接层回归 6 个目标变量。架构为自定义设计。

Input (B, 42, 450, 449)
    |
    +-- Stem -----------------------------------------------------------------
    |    Conv2d(42, 64, kernel=7x7, stride=2, padding=3, bias=False)
    |    BatchNorm2d(64)
    |    ReLU(inplace=True)
    |    Output: (B, 64, 225, 225)
    |
    +-- Layer1: ResBlock(64 -> 64, stride=1)   -> (B, 64, 225, 225)
    +-- Layer2: ResBlock(64 -> 128, stride=2)  -> (B, 128, 113, 113)
    +-- Layer3: ResBlock(128 -> 256, stride=2) -> (B, 256, 57, 57)
    +-- Layer4: ResBlock(256 -> 256, stride=2) -> (B, 256, 29, 29)
    +-- Layer5: ResBlock(256 -> 512, stride=2) -> (B, 512, 15, 15)
    +-- Layer6: ResBlock(512 -> 512, stride=2) -> (B, 512, 8, 8)
    |
    +-- AdaptiveAvgPool2d(1) ------------------> (B, 512, 1, 1)
    |
    +-- Head -----------------------------------------------------------------
         Flatten                              -> (B, 512)
         Linear(512, 128)
         ReLU(inplace=True)
         Dropout(p=0.3)
         Linear(128, 6)                       -> (B, 6)

2.2 ResBlock Detail

每个 ResBlock 包含 2 个 3x3 卷积 + BatchNorm,以及一条 skip connection:

Input x (in_ch, H, W)
    |
    +-- Main path:
    |    Conv2d(in_ch, out_ch, 3x3, stride=stride, padding=1, bias=False)
    |    BatchNorm2d(out_ch)
    |    ReLU(inplace=True)
    |    Conv2d(out_ch, out_ch, 3x3, stride=1, padding=1, bias=False)
    |    BatchNorm2d(out_ch)
    |
    +-- Shortcut:
    |    if stride != 1 or in_ch != out_ch:
    |        Conv2d(in_ch, out_ch, 1x1, stride=stride, bias=False)
    |        BatchNorm2d(out_ch)
    |    else:
    |        Identity()
    |
    +-- Output = ReLU(main + shortcut)

2.3 Channel Progression

Stage Input Ch Output Ch Spatial Size Stride Parameters (approx)
Stem 42 64 225x225 2 42x64x7x7 = 131,712
Layer1 64 64 225x225 1 2x(64x64x3x3) = 73,728
Layer2 64 128 113x113 2 ~221K
Layer3 128 256 57x57 2 ~885K
Layer4 256 256 29x29 1 ~1.18M
Layer5 256 512 15x15 2 ~3.54M
Layer6 512 512 8x8 1 ~4.72M
Head 512 6 - - 512x128 + 128x6 = 66,438
Total 11,325,062

2.4 Design Choices

Choice Value Rationale
base_channels 64 ResNet-style 起始宽度
Stem kernel 7x7, stride 2 快速降低空间分辨率,减少后续计算量
ResBlock kernel 3x3 标准 ResNet 设计
所有 Conv bias False 配合 BatchNorm 使用,bias 冗余
激活函数 ReLU(inplace) 节省显存
Pooling AdaptiveAvgPool2d(1) 全局平均池化,不依赖输入尺寸
Head 2 层 FC (512->128->6) 轻量回归头
分类头 无 AUC 直接用 APCP 预测值排序

3. Optimization Configuration

3.1 Optimizer

Param Value
Optimizer AdamW (torch.optim.AdamW)
Learning rate 1e-3
Weight decay 1e-4
Betas (0.9, 0.999) (PyTorch default)
Epsilon 1e-8 (PyTorch default)

3.2 Learning Rate Schedule

Param Value
Scheduler CosineAnnealingLR
T_max 50 (= total epochs)
eta_min 0 (default)
Warmup None

LR trajectory: lr(t) = 0.5 * lr_init * (1 + cos(pi * t / T_max))

3.3 Loss Function

criterion = nn.MSELoss()
  • 对 6 个标准化后的目标变量统一计算 MSE,无 per-variable 加权
  • 无独立分类 loss(AUC 通过 APCP 预测值的大小做 ranking score 计算,不参与训练)

3.4 Gradient Clipping

torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)

4. Regularization

4.1 Current Methods

Method Location Config
Weight decay 全部参数 (AdamW) 1e-4
Dropout FC head (Linear(512,128) 之后) p=0.3
BatchNorm 每个 Conv 之后 共 13 个 BN 层
Gradient clipping 全局 max_norm=1.0 (数值稳定性,非严格正则化)

4.2 Coverage Analysis

Component Parameters % of Total Dropout Coverage
卷积层 (Stem + 6 ResBlocks) ~11.26M 99.4% None
FC Head ~66K 0.6% Dropout(0.3)

问题: 99.4% 的参数(卷积层)仅靠 weight decay (1e-4) 和 BN 的轻微正则效果。对 11.3M 参数 / ~20K 样本 (~565:1 参数/样本比) 而言不足以防止过拟合。

4.3 Not Used

Data augmentation, Spatial dropout / DropBlock, Label smoothing, Stochastic depth, Early stopping, Mixup / CutMix


5. Data Pipeline

5.1 Dataset

Item Value
数据来源 HRRR (High-Resolution Rapid Refresh) 气象再分析
空间范围 新英格兰地区, Lambert Conformal 投影, 3km 网格
空间尺寸 450 x 449 格点
通道数 42 个大气变量
时间覆盖 3 年逐小时数据 (~26,280 小时)
每样本大小 (450, 449, 42) bfloat16 -> float32
预测目标 Jumbo Statue 网格点, t+24h, 6 个变量 + 1 个二元标签

5.2 Data Split

Split Years Samples (approx) Batches
Train 2018, 2019 ~12,888 (1611 x 8) 1611
Validation 2020 ~8,784 (1098 x 8) 1098
Test 2021 TBD 未运行

5.3 Normalization

  • Method: Per-channel z-score
  • Computation: 从训练集随机采样 1000 个样本,计算每通道的空间均值/标准差
  • Input: x_norm = (x - mean) / (std + 1e-7), mean/std shape (42, 1, 1)
  • Target: y_norm = (y - mean) / (std + 1e-7), mean/std shape (6,)
  • Persistence: 保存为 norm_stats.pt; 推理时从 checkpoint 加载

5.4 NaN Handling

Stage Method
Dataset __getitem__ 含 NaN 的帧返回 None
DataLoader collate collate_skip_none 过滤 None 样本
Training loop torch.isnan(loss) 时跳过 batch
Validation RMSE 逐变量过滤 NaN (~2% 样本)

5.5 DataLoader Config

Param Train Val
batch_size 8 8
shuffle True False
drop_last True False
num_workers 2 2
pin_memory True True
prefetch_factor 2 2

6. Training Process

6.1 Per-Epoch Loop

for epoch in range(50):
    1. train_one_epoch():
       - model.train()
       - for batch in train_loader (1611 batches):
           - forward -> MSELoss -> NaN check -> backward -> clip_grad -> step
           - print every 200 batches
    2. validate():
       - model.eval() + no_grad()
       - collect all preds/targets/binary
       - compute val_loss (MSE)
    3. compute_metrics():
       - denormalize preds & targets
       - per-variable RMSE (filter NaN per variable)
       - conditional APCP RMSE (true > 2mm only)
       - AUC via roc_auc_score
    4. scheduler.step() (cosine)
    5. save latest.pt; if val_loss improved: save best.pt
    6. log CSV + update training_curves.png

6.2 Earlier Failed Runs

Job GPU Issue
312194 H200 手动取消 (首次调试)
312214 A100 OOM killed
312227 H200 NaN crash in roc_auc_score (后修复: 加 NaN 过滤)
312336 A100 SLURM 超时 24h, 跑了 27/30 epochs; RMSE 全 nan (后修复: denorm bug)

7. Results

7.1 Best Validation (Epoch 11) -- best.pt

Variable RMSE Unit
TMP@2m 3.577 K
RH@2m 14.978 %
UGRD@10m 2.148 m/s
VGRD@10m 1.935 m/s
GUST@surface 3.368 m/s
APCP_1hr (cond.) 4.007 mm
AUC (rain) 0.679 -
Val Loss 0.6177 -

7.2 Final Epoch (Epoch 49) -- latest.pt

Variable RMSE Unit
TMP@2m 3.455 K
RH@2m 15.214 %
UGRD@10m 2.162 m/s
VGRD@10m 1.951 m/s
GUST@surface 3.394 m/s
APCP_1hr (cond.) 4.000 mm
AUC (rain) 0.647 -
Val Loss 0.6249 -

7.3 Best Per-Variable Across All Epochs

Variable Best RMSE Epoch
TMP@2m 3.358 26
RH@2m 14.839 10
UGRD@10m 2.146 30
VGRD@10m 1.917 15
GUST@surface 3.335 17
APCP_1hr (cond.) 3.926 22
AUC (rain) 0.745 7

7.4 Training Curves

Training Curves

Left (Loss): train 0.89->0.37, val 0.96->0.62 (epoch 11 后停滞), 过拟合明显。 Right (RMSE): RH ~15 主导; TMP ~3.5; 风速 ~2-3.4; APCP ~4.0; epoch 8-10 后全部收敛。


8. Evaluation Scope and Limitations

独立测试集评估与 persistence 基线对比尚未完成。第 11 轮保存点由验证损失选出,验证结果不代表独立测试结果。

训练记录显示过拟合、降雨 AUC 退化,以及数据中的 NaN batch 被跳过。统一 MSE 对不同变量的影响需要进一步分析。


10. Reproduction

10.1 Command

# On HPC (Tufts Pax cluster)
module load class/default
module load cs137/2026spring

cd <PROJECT_ROOT>
sbatch scripts/train.slurm  # or:
python train.py --model cnn_baseline --epochs 50 --batch_size 8 --lr 0.001 \
    --weight_decay 0.0001 --scheduler cosine --base_channels 64 --num_workers 2

10.2 Key Files

File Description
models/cnn_baseline.py Model definition (BaselineCNN, ResBlock)
train.py Training script
data_preparation/dataset.py WeatherDataset, DataLoader, normalization
runs/cnn_baseline_1/config.json Exact hyperparameters used
runs/cnn_baseline_1/checkpoints/best.pt Best model (epoch 11, val_loss=0.6177)

用单帧气象空间数据训练六变量回归 CNN,记录模型结构、训练曲线、验证误差和过拟合现象。

实验日期
原报告作者
原训练报告未单列作者,来源为 Jeff Liu 的实验仓库。
报告语言
中英混排

主要观察

完成 50 轮训练,原记录以第 11 轮的最低验证损失选择保存点;同时记录不同变量的 RMSE 与降雨 AUC。

范围与限制

独立测试集评估与 persistence 基线对比尚未完成;验证集表现不能替代测试结论。

相关材料

来源

查看原始来源及其版本

作为历史实验记录保留,软件、条件和观察结果以原报告所记载的实验为准。