(transfer-learning-taxonomy)=
# 迁移学习分类体系

{ref}`transfer-learning-intro` 中我们理解了迁移学习的核心动机：借用源领域的知识解决目标领域的问题。但"迁移"这个词很宽泛——

- 是用 ImageNet 预训练模型做医学影像分类？
- 是把英文情感分析模型迁移到中文？
- 还是让模型同时学习多个相关任务？

这些都是迁移学习，但技术路线完全不同。**本章将建立一套分类体系，帮助你在面对具体问题时快速找到合适的方法**。

## 按迁移情境分类

根据源域与目标域的关系，迁移学习可分为三类 {cite}`pan2010survey`：

1. **归纳式迁移学习**

    **定义**：源域和目标域的任务**不同**。

    **典型场景**：
    - 用ImageNet预训练模型，迁移到医学影像分类
    - 用通用语言模型，迁移到情感分析任务

    这是最常见的迁移学习场景。

2. **直推式迁移学习**

    **定义**：源域和目标域的**任务相同**但**领域不同**。

    **典型场景**：
    - 室外街景图像模型，处理室内场景图像
    - 英文情感分析模型，迁移到法文

    核心挑战是**领域偏移**：$P_s(X) \neq P_t(X)$

3. **无监督迁移学习**

    **典型场景**：
    - 用自监督预训练的特征提取器，处理下游聚类任务
    - 用对比学习预训练的视觉模型，进行零样本检索

    完全不依赖标注数据，近年来随着自监督学习的发展日益重要。

    ### 情境对比

    | 类型 | 任务关系 | 领域关系 | 标注需求 |
    |------|----------|----------|----------|
    | 归纳式 | 不同 | 可同可不同 | 目标域需标注 |
    | 直推式 | 相同 | 不同 | 目标域无/少标注 |
    | 无监督 | 可不同 | 可不同 | 均无需标注 |

## 按迁移方法分类

根据知识迁移的具体机制，可分为四类 {cite}`zhuang2020comprehensive`：

(transfer-instance-based)=
1. **基于实例的迁移**

    **核心思想**：对源域中与目标域相似的样本赋予更高权重，不相似的样本降低权重或丢弃。

    **数学形式**：

    给定源域数据集 $D_s = \{(x_i^s, y_i^s)\}_{i=1}^{n_s}$，为每个样本赋予权重 $w_i$，重新加权后的经验风险最小化：

    $$\min_f \frac{1}{n_s} \sum_{i=1}^{n_s} w_i \cdot L(f(x_i^s), y_i^s)$$

    **权重计算的核心问题**：

    如何计算 $w_i$？直观上，我们希望 $w_i \propto \frac{P_t(x_i^s)}{P_s(x_i^s)}$，即源域样本在目标域分布中的密度相对于源域密度的比值。

    #### 典型方法：TrAdaBoost

    TrAdaBoost 是 AdaBoost 的迁移学习版本，通过迭代调整源域样本权重：

    1. **初始化**：所有源域和目标域样本权重相等
    2. **迭代训练**：
    - 在当前权重下训练基分类器
    - **目标域样本**：分类错误则增加权重（关注难例）
    - **源域样本**：分类错误则降低权重（可能是噪声或与目标域不相关）
    3. **组合**：加权组合所有基分类器

    ```python
    # TrAdaBoost 的核心权重更新逻辑（教学简化版）
    # 假设目标域样本在前 n_t 个，源域样本在后 n_s 个
    def tradaboost_update_weights(weights, errors, is_target):
        """
        更新样本权重
        weights: 当前权重 [n_t + n_s]
        errors: 分类错误指示 [n_t + n_s]，1表示错误，0表示正确
        is_target: 是否目标域样本 [n_t + n_s]，True/False
        
        教学简化说明：
        标准 TrAdaBoost 的 epsilon 只基于目标域错误率计算：
        epsilon = errors_on_target / n_target
        beta = epsilon / (1 - epsilon)
        此处用 total errors 替代以简化代码，不影响核心思想的理解。
        """
        beta = errors.sum() / (1 - errors.sum())
        
        new_weights = weights.copy()
        for i in range(len(weights)):
            if is_target[i]:  # 目标域：错误增加权重
                new_weights[i] = weights[i] * (beta ** (1 - errors[i]))
            else:  # 源域：错误降低权重
                new_weights[i] = weights[i] * (beta ** errors[i])
        
        # 归一化
        return new_weights / new_weights.sum()
    ```

    **直观理解**：
    - 目标域：像普通 boosting 一样，关注分错的样本
    - 源域：如果某源域样本与目标域差异大，会被反复分错，权重逐渐降低至接近0

    **适用场景**：
    - 源域和目标域有一定重叠，分布略有差异
    - 源域中有大量样本，但只有部分与目标域相关
    - 可以获取源域的原始数据（不只是预训练模型）

    **局限性**：
    - 需要存储和访问源域原始数据
    - 当源域和目标域差异很大时，大部分源域样本权重都会趋近于0
    - 对高维数据，密度比估计困难

(transfer-feature-based)=
2. **基于特征的迁移**

    **核心思想**：寻找公共特征空间，使源域和目标域的分布对齐。

    当源域和目标域差异较大时（如**游戏画面→真实街景**），直接迁移模型效果不佳。基于特征的方法通过学习**域不变特征**来解决这个问题。

    #### 生活中的直觉

    > **类比：不同相机的照片**
    > 
    > 假设你有两台相机：
    > - 相机A：iPhone，照片鲜艳、清晰
    > - 相机B：老式手机，照片暗淡、模糊
    > 
    > 虽然拍的是同一个场景，但"风格"完全不同。
    > 
    > **基于特征的方法**就是：找到一种"滤镜"，让两种相机的照片看起来尽可能相似，这样用相机A照片训练的模型也能识别相机B的照片。

    #### 最大均值差异（MMD）——让两群数据"重心"靠近

    **直觉理解**：

    想象源域和目标域是两群学生：
    - 源域：重点中学学生
    - 目标域：普通中学学生

    虽然都是学生（特征空间相同），但成绩分布不同。MMD 想做的就是：**测量这两群学生成绩的"差异"，然后通过训练让他们变得更像**。

    **怎么做？**
    1. 计算源域的"平均特征"（所有学生成绩的平均）
    2. 计算目标域的"平均特征"
    3. 让这两个平均值尽可能接近

    ```python
    def mmd_loss(source_features, target_features):
        """
        MMD 损失：让两个域的特征分布更接近
        见 {ref}`transfer-learning-intro` 中领域偏移的讨论
        
        教学简化说明：
        此处使用的是线性核 MMD（特征空间中的均值差异）。
        标准实践中更常用 RBF 核 MMD，能捕捉更高阶的分布差异。
        """
        # 计算源域特征的平均值
        source_mean = source_features.mean(dim=0)
        # 计算目标域特征的平均值  
        target_mean = target_features.mean(dim=0)
        
        # MMD = 两个平均值的距离（线性核简化版）
        mmd = torch.norm(source_mean - target_mean, p=2)
        return mmd

    # 在训练中使用：分类损失 + MMD对齐损失
    # lambda=0.1 控制对齐强度，需根据任务调参
    total_loss = classification_loss + 0.1 * mmd_loss(source_feat, target_feat)
    ```

    **一句话总结**：MMD 就是让两个域的数据"看起来更像"——就像给两台相机的照片加上滤镜，让它们风格统一。

    #### 什么时候用基于特征的方法？

    | 场景 | 建议方法 |
    |-----|---------|
    | 有预训练模型，任务相似 | **基于模型的迁移**（更简单） |
    | 源域和目标域差异大（如游戏画面→真实街景） | 基于特征的迁移 |
    | 只有特征提取器，没有完整模型 | 基于特征的迁移 |

    ```{admonition} 实践建议
    :class: tip
    高中生读者建议：先掌握**基于模型的迁移**（下一节），这是工业界最主流、最简单的方法。基于特征的方法更适合研究场景或领域差异极大的情况。
    ```

(transfer-model-based)=
3. **基于模型的迁移**

    **核心思想**：直接复用预训练模型的参数和网络结构。

    这是**最常用、最有效**的迁移学习方法——你不需要设计复杂算法，只需加载一个预训练模型，然后做少量调整即可。

    **生活中的直觉**：
    > 想象你刚考到驾照（预训练模型），现在要开不同类型的车：
    > - **特征提取**：你只学"这辆车的按钮在哪"（新分类器），驾驶技能直接用
    > - **微调**：你稍微适应一下这辆车的刹车灵敏度（调整部分参数）
    > - **全量微调**：你重新学开车（所有参数调整）——通常没必要

    **为什么最流行？**
    - 操作简单：`model = torchvision.models.resnet50(pretrained=True)`
    - 生态丰富：PyTorch、HuggingFace 有大量预训练权重
    - 效果强大：在多数任务上远胜从头训练

    | 对比项 | 基于实例 | 基于特征 | 基于模型 |
    |-------|---------|---------|---------|
    | 需要源域数据 | ✅ 需要 | ✅ 需要 | ❌ 不需要 |
    | 实现复杂度 | 高 | 高 | 低 |
    | 适用场景 | 分布偏移小 | 分布偏移大 | 绝大多数场景 |
    | 主流程度 | ⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |

    **主要策略**：
    1. **特征提取（Feature Extraction）**：冻结预训练模型，仅训练新分类器
    2. **微调（Fine-tuning）**：在预训练权重基础上继续训练
    3. **参数高效微调（PEFT）**：只更新少量参数（如LoRA、Adapter）

    详细实践见 {doc}`part3-model-transfer`。

(transfer-relation-based)=
4. **基于关系的迁移**

    **核心思想**：挖掘和迁移数据之间的逻辑关系或知识结构。

    **生活中的直觉**：
    > 学生学完"苹果和香蕉都是水果"后，能推断"草莓也是水果"——这就是关系迁移。

    **典型场景**：
    - 推荐系统：用户A和B的购买模式相似，把A的推荐策略迁移给B
    - 知识图谱：实体关系（"出生在"→"居住在"）在不同领域间共享
    - 类比推理：源域的"总统领导国家"关系迁移到目标域的"CEO领导公司"

    **主要方法**：
    - **关系网络（Relation Networks）**：学习实体间的逻辑关系
    - **知识图谱嵌入**：迁移图结构中的关系模式
    - **类比学习**：从源域中提取可复用的推理规则

    **适用场景**：数据具有明确的结构化关系时效果最好，常见于推荐系统和知识图谱领域。

    **适用场景**：推荐系统、知识图谱、图结构数据。

## 方法选择指南

```{mermaid}
---
caption: 迁移学习方法选择流程
---
graph TD
    A[选择迁移方法] --> B{数据量充足？}
    B -->|是| C[基于模型的迁移：微调]
    B -->|否| D{源域与目标域分布差异大？}
    D -->|是| E[基于特征的迁移<br/>MMD/CORAL]
    D -->|否| F[基于模型的迁移：特征提取]
```

## 本章小结

**按迁移情境**：
- 归纳式：任务不同（最常见）
- 直推式：任务相同，领域不同
- 无监督：均无标注数据

**按迁移方法**：
- 基于实例：样本权重调整
- 基于特征：特征空间对齐
- 基于模型：参数共享与微调（最常用）
- 基于关系：逻辑关系迁移

### 下一步

掌握了分类体系后，{doc}`part3-model-transfer` 我们将深入讲解**基于模型的迁移**——这是工业界最主流的方法。你将学会如何加载预训练模型、冻结层、替换分类头，以及最重要的：**特征提取与微调两种策略**。

---

## 参考文献

```{bibliography}
:filter: docname in docnames
```
