pytorch 16 迁移学习核心技巧·从模型加载到按需初始化模块权重,再到各layer分组设置学习率

这篇博客介绍了在PyTorch中进行迁移学习时如何实现任意加载模型权重,按需进行权重初始化以及按需设置学习率。包括处理name和shape不匹配的权重加载,对模型的特定部分进行初始化,以及对模型的不同部分设置不同的学习率,包括冻结某些层和分组设置学习率的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现加载模型任意权重,自动跳过不匹配的layer(name不匹配,权重shape不匹配),该操作通常用在迁移学习模型加载中。

实现对模型中不同moudle甚至不同name的layer进行不同方式的初始化,该操作通常用在迁移学习模型初始化中。

实现对模型中不同的部分设置不同的学习率(支持冻结某些layer),该操作通常用在迁移学习模型训练阶段中。

1、实现任意加载模型权重

正常来说,pytorch中模型的保存就是torch.save(path), 模型的加载就是model=torch.load(path),但是为了能保持对模型的灵活操作能力,建议使用torch.save(model.module.state_dict())只保存其参数。在迁移学习过程中的模型加载,通常会因为修改了网络结构,导致使用torch.load(path)出现name不匹配。此外,在进行模型结构调整中新模型想使用旧模型的权重,也会导致权重shape不匹配。
对于仅有name不匹配的模型权重加载可以使用下列代码 

model_dict = model.state_dict()
pretrained_dict = torch.load(path)
new_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
model_dict.update(new_dict)
model.load_state_dict(model_dict)

对于仅有shape不匹配的模型权重加载可以使用 下列代码&nb

<think>好的,用户现在问的是适合迁移学习模型参数冻结训练的损失函数。我要先理解迁移学习的背景,以及参数冻结的情况。通常,迁移学习中,我们会冻结预训练模型的大部分层,只训练顶部的分类层。这时候,损失函数的选择要适应这种情况。 首先,用户可能是在进行迁移学习的实践,比如使用预训练的ResNet或BERT模型,冻结底层参数,只调整分类层。这种情况下,损失函数的选择可能会影响模型微调的效果。用户可能想知道哪些损失函数在这种情况下表现更好,或者有什么注意事项。 接下来,我要考虑常见的损失函数有哪些适合这种情况。交叉熵损失是分类任务中最常用的,应该首先提到。但可能用户要更深入的优化,比如处理类别不平衡的情况,这时候Focal Loss可能更合适。此外,如果任务涉及多标签分类,二元交叉熵损失也是必须的。Triplet Loss可能用于要特征对比的情况,比如人脸识别。还有,对比学习中的InfoNCE Loss也可能适用,但要具体情况具体分析。 另外,用户可能不太了解在冻结参数时损失函数的作用是否有变化。比如,当大部分参数固定时,损失函数的设计是否要特别调整。例如,在特征提取层不变的情况下,分类层的损失可能要更强的监督来适应新任务,这时候可能要调整损失函数的参数,如Focal Loss中的γ和α。 还要考虑是否有其他因素,比如数据量大小。如果用户的数据集很小,可能要选择更鲁棒的损失函数来防止过拟合。另外,任务类型也很重要,比如分类、回归、多标签等,不同的任务要不同的损失函数。 可能用户遇到的问题包括冻结后模型收敛慢,或者准确率不高,这时候损失函数的选择可能是一个调整方向。要给出具体的损失函数公式、适用场景以及优化策略,帮助用户根据实际情况选择。 最后,要确保回答结构清晰,分点说明,每个损失函数给出用途、公式、适用场景和注意事项,并给出选择建议,帮助用户做出决策。</think>在迁移学习的参数冻结训练中(通常冻结特征提取层,仅训练分类器),损失函数的选择重点关注**新任务的数据特性**和**分类器的优化效率**。以下是针对不同场景的推荐方案: --- ### 1. **基础分类任务:交叉熵损失(Cross-Entropy Loss)** - **公式**: $$ \mathcal{L} = -\sum_{i=1}^K y_i \log(p_i) $$ 其中 \( p_i = \text{softmax}(z_i) \),\( z_i \) 为分类器输出。 - **适用场景**:单标签分类(如 ImageNet 迁移到花卉分类)。 - **优势**:收敛稳定,梯度计算高效。 - **注意事项**: - 若新任务类别分布不均衡,配合**类别权重**(PyTorch 中 `weight` 参数)。 - 冻结特征层后,分类器的初始学习率建议设为特征层解冻时的 **5-10倍**(因特征已固定,快速调整分类器)。 --- ### 2. **类别严重不均衡:Focal Loss** - **公式**: $$ \mathcal{L} = -\sum_{i=1}^K \alpha_i (1-p_i)^\gamma y_i \log(p_i) $$ 其中 \( \gamma \) 抑制易分类样本的权重,\( \alpha_i \) 调节类别权重。 - **适用场景**:医学图像分类(如肿瘤检测中正负样本比例 1:100)。 - **冻结训练策略**: - 优先调大 \( \gamma \)(如 2~5)以强化难样本学习。 - 结合特征层冻结,可避免模型过度拟合头部类别。 --- ### 3. **细粒度分类:Triplet Loss + 交叉熵联合训练** - **设计逻辑**: - **Triplet Loss** 约束同类特征紧凑、异类特征远离: $$ \mathcal{L}_{\text{tri}} = \max(d(a,p) - d(a,n) + \text{margin}, 0) $$ - **交叉熵** 保证分类准确性。 - **适用场景**:鸟类子类识别、人脸验证等。 - **冻结训练技巧**: - 仅冻结特征提取层的前半部分(如 ResNet 的 conv1~layer3),保留部分高层特征层可微调。 - 联合损失权重建议设为 \( \mathcal{L} = 0.7\mathcal{L}_{\text{ce}} + 0.3\mathcal{L}_{\text{tri}} \)。 --- ### 4. **多标签分类:二元交叉熵(BCEWithLogitsLoss)** - **公式**: $$ \mathcal{L} = -\sum_{i=1}^K y_i \log(\sigma(z_i)) + (1-y_i)\log(1-\sigma(z_i)) $$ 其中 \( \sigma \) 为 sigmoid 函数。 - **适用场景**:图像多标签标注(如同时包含“天空”“山脉”“湖泊”)。 - **关键调整**: - 使用 `pos_weight` 参数缓解正负标签不平衡。 - 冻结特征层后,建议在分类器中添加 **1x1 卷积适配层**(减少通道维度冲突)。 --- ### 5. **小样本学习:对比损失(Contrastive Loss)** - **公式**: $$ \mathcal{L} = \frac{1}{N} \sum_{i=1}^N \left[ y_i d(x_i, x_j)^2 + (1-y_i)\max(\text{margin} - d(x_i, x_j), 0)^2 \right] $$ - **适用场景**:每类仅 5-20 个样本的迁移任务(如工业缺陷检测)。 - **冻结策略**: - 完全冻结特征提取层,仅训练对比投影头(Projection Head)。 - 数据增强强度加大(如 MixUp、CutMix)。 --- ### 参数冻结训练的通用优化建议 1. **学习率策略**: - 分类器初始学习率设为特征层解冻时的 **5-10倍**(例如特征层用 `1e-4`,分类器用 `1e-3`)。 - 使用 `ReduceLROnPlateau` 动态调整而非固定学习率。 2. **正则化**: - 在分类器中添加 **Dropout 层**(概率 0.3~0.5),即使特征层冻结也能防止过拟合。 - 对分类器的权重使用 **L2 正则化**(系数 1e-4)。 3. **特征维度匹配**: - 若预训练模型输出特征维度与任务不匹配(如从 2048 维到 128 维),插入 **线性适配层** 后再接损失计算。 --- ### 代码示例(PyTorch) ```python # 冻结特征提取层 model = torchvision.models.resnet50(pretrained=True) for param in model.parameters(): param.requires_grad = False # 冻结所有层 # 替换分类器并解冻 model.fc = nn.Sequential( nn.Linear(2048, 512), nn.ReLU(), nn.Dropout(0.5), nn.Linear(512, num_classes) ) for param in model.fc.parameters(): param.requires_grad = True # 仅训练分类器 # 定义损失函数(以 Focal Loss 为例) criterion = FocalLoss(gamma=2.0, alpha=[0.2, 0.8]) # 假设两类样本不均衡 optimizer = torch.optim.Adam(model.fc.parameters(), lr=1e-3, weight_decay=1e-4) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万里鹏程转瞬至

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值