问题背景
进行有效波高单点预测的迁移学习实验:在源域(数据充足的站点)上预训练时序模型,再迁移到目标域(数据稀缺的站点),比较不同迁移策略的效果。
4 种方案
- Case1 :仅迁移隐藏层参数,输出层在目标域重新训练;
- Case2 :仅迁移输出层参数,隐藏层在目标域重新训练;
- Case3 :隐藏层 + 输出层全部迁移,再小样本微调(fine-tune);
- Case4:不做迁移学习,全部层随机初始化,目标域从头训练(基线)。
三类参数具体指什么
以「输入层 → 隐藏层(LSTM/GRU/全连接)→ 输出层」的时序预测网络为例,参数可以这样划分:
| 参数类别 | 具体包含 | 作用 |
|---|---|---|
| 隐藏层参数 | 各隐藏层的权重矩阵 W、偏置 b;循环层的 W_x、W_h、b;以及 BatchNorm/LayerNorm 的 γ、β |
提取海浪时序的通用特征(周期、趋势、波动模式) |
| 输出层参数 | 最后一层全连接层的权重 W_out、偏置 b_out(回归任务通常 1 个输出神经元) |
把隐藏特征映射为目标域的有效波高数值 |
| 小样本微调参数 | 被解冻并继续更新的那部分参数(通常是全部层,或仅输出层 + 最后一层隐藏层),配合较小的学习率 | 用少量目标域样本把通用特征适配到具体站点 |
| Case4 全部参数(随机初始化) | 网络中的全部可训练参数 :输入层权重 W_in、偏置 b_in;各隐藏层权重 W、偏置 b;循环层 W_x、W_h、b;归一化层 γ、β;输出层 W_out、b_out |
不加载任何预训练权重,全部用随机初始化(如 Xavier/He 初始化)在目标域从头训练,作为无迁移基线,用于衡量迁移学习带来的增益 |
示例:用 PyTorch 划分参数组
python
import torch
import torch.nn as nn
class WaveLSTM(nn.Module):
def __init__(self, input_dim=6, hidden_dim=64, out_dim=1):
super().__init__()
self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers=2, batch_first=True)
self.head = nn.Linear(hidden_dim, out_dim) # 输出层
def forward(self, x):
h, _ = self.lstm(x)
return self.head(h[:, -1, :])
model = WaveLSTM()
# 1) 隐藏层参数:LSTM 内部所有权重与偏置
hidden_params = list(model.lstm.parameters())
# 2) 输出层参数:最后一层全连接
output_params = list(model.head.parameters())
print("隐藏层参数张量个数:", len(hidden_params))
print("输出层参数张量个数:", len(output_params))
for name, p in model.named_parameters():
print(f"{name:20s} shape={tuple(p.shape)}")
示例:四种 Case 的参数冻结方式
python
def build_optimizer(model, case, lr_head=1e-3, lr_finetune=1e-4):
if case == "Case1": # 只迁移隐藏层,输出层重训
for p in model.lstm.parameters():
p.requires_grad = False
return torch.optim.Adam(model.head.parameters(), lr=lr_head)
if case == "Case2": # 只迁移输出层,隐藏层重训
for p in model.head.parameters():
p.requires_grad = False
return torch.optim.Adam(model.lstm.parameters(), lr=lr_head)
if case == "Case3": # 全部迁移 + 小样本微调
return torch.optim.Adam([
{"params": model.lstm.parameters(), "lr": lr_finetune},
{"params": model.head.parameters(), "lr": lr_finetune},
])
if case == "Case4": # 不迁移,全部随机初始化
model.apply(lambda m: m.reset_parameters()
if hasattr(m, "reset_parameters") else None)
return torch.optim.Adam(model.parameters(), lr=lr_head)
说明:Case3 的「小样本微调」本质是把全部参数设为可训练,但用更小的学习率(如
1e-4)和更少的 epoch,避免少量目标域样本把预训练特征「冲掉」(灾难性遗忘)。若目标域样本极少,也可只解冻输出层 + 最后一层隐藏层,其余保持冻结。
测试结果
- Case3(全部层迁移 + 微调) > Case1(仅迁移隐藏层) > Case2(仅迁移输出层) > Case4(无迁移从头训练)
- 表明:把预训练得到的隐藏层 + 输出层整体迁移,再做微调,最适合海浪时序预报;只迁移输出层效果很差。