人工智能之核心基础 机器学习
第十三章 自监督学习
文章目录
- [人工智能之核心基础 机器学习](#人工智能之核心基础 机器学习)
- [13.1 自监督学习概述](#13.1 自监督学习概述)
- [📌 定义:从无标签数据中**自动生成监督信号**](#📌 定义:从无标签数据中自动生成监督信号)
- [🔍 与无监督学习的区别](#🔍 与无监督学习的区别)
- [13.2 自监督学习的核心:前置任务设计](#13.2 自监督学习的核心:前置任务设计)
- [1️⃣ 掩码填充(Masked Input Reconstruction)](#1️⃣ 掩码填充(Masked Input Reconstruction))
- [2️⃣ 对比学习(Contrastive Learning)](#2️⃣ 对比学习(Contrastive Learning))
- [3️⃣ 时序预测(Temporal Prediction)](#3️⃣ 时序预测(Temporal Prediction))
- [13.3 入门级自监督算法](#13.3 入门级自监督算法)
- 算法1:自编码器(Autoencoder)------最经典的重构型自监督
- [算法2:简化版 SimSiam(无负样本对比学习)](#算法2:简化版 SimSiam(无负样本对比学习))
- 算法3:掩码自编码器(MAE)基础思路
- [13.4 自监督学习的核心价值](#13.4 自监督学习的核心价值)
- [✅ 三大核心优势](#✅ 三大核心优势)
- [13.5 优缺点与适用场景](#13.5 优缺点与适用场景)
- [✅ 适用场景](#✅ 适用场景)
- [❌ 局限性](#❌ 局限性)
- [13.6 实战案例 + 代码实现(PyTorch + Scikit-learn)](#13.6 实战案例 + 代码实现(PyTorch + Scikit-learn))
- 案例1:自编码器实现数据降维与重构
- [案例2:简单对比学习(SimSiam简化版) + 下游分类](#案例2:简单对比学习(SimSiam简化版) + 下游分类)
- [案例3:文本掩码填充预训练 + 情感分析微调(使用Hugging Face)](#案例3:文本掩码填充预训练 + 情感分析微调(使用Hugging Face))
- [🎯 本章总结](#🎯 本章总结)
- [💡 建议:](#💡 建议:)
- 资料关注
13.1 自监督学习概述
📌 定义:从无标签数据中自动生成监督信号
- 输入 :只有大量无标签数据 x 1 , x 2 , ... , x n x_1, x_2, \dots, x_n x1,x2,...,xn
- 关键操作 :人为设计一个前置任务 (Pretext Task),从原始数据中"挖掉一部分"或"打乱结构",让模型去预测被挖掉的部分
- 输出:训练好的编码器(Encoder),可提取通用特征用于下游任务
✅ 通俗比喻 :
就像玩拼图------你把一张完整图片撕成碎片(制造任务),然后训练自己把碎片拼回去(学习特征)。
拼图能力练好了,看一眼新图片就能理解其结构!
🔍 与无监督学习的区别
| 维度 | 无监督学习 | 自监督学习 |
|---|---|---|
| 目标 | 发现数据结构(聚类/降维) | 学习可迁移的特征表示 |
| 是否有任务 | ❌ 无明确预测任务 | ✅ 有精心设计的前置任务 |
| 输出形式 | 簇标签、低维坐标、异常分数 | 特征向量(可用于分类/检测等) |
| 评估方式 | 内部指标(轮廓系数等) | 下游任务性能(如分类准确率) |
💡 一句话总结 :
自监督 = 无监督数据 + 监督式训练方式
13.2 自监督学习的核心:前置任务设计
"任务设计决定特征质量"
以下是三种入门级前置任务:
1️⃣ 掩码填充(Masked Input Reconstruction)
- 操作:随机遮盖输入的一部分(如图像块、文本词)
- 任务:预测被遮盖的内容
- 代表模型:BERT(文本)、MAE(图像)
🖼️ 图像示例:
原图 → 随机盖住30%方块 → 模型猜被盖住的像素
2️⃣ 对比学习(Contrastive Learning)
- 操作:对同一张图做两种不同增强(裁剪、颜色抖动等),得到两个"视角"
- 任务 :让这两个视角的特征相似 ,与其他样本的特征不相似
- 代表模型:SimCLR, MoCo, SimSiam
🧠 核心思想:"同一事物的不同照片应有相似表示"
3️⃣ 时序预测(Temporal Prediction)
- 操作:给定视频前几帧 / 时间序列前几步
- 任务:预测下一帧 / 下一时刻
- 适用:视频、语音、传感器数据
13.3 入门级自监督算法
算法1:自编码器(Autoencoder)------最经典的重构型自监督
- 结构 :
- 编码器 (Encoder): x → z x \rightarrow z x→z(压缩到低维)
- 解码器 (Decoder): z → x ^ z \rightarrow \hat{x} z→x^(重建原始输入)
- 损失函数 : L = ∥ x − x ^ ∥ 2 \mathcal{L} = \|x - \hat{x}\|^2 L=∥x−x^∥2
- 用途:降噪、降维、特征提取
✅ 优点:结构简单,训练稳定
❌ 缺点:可能学不到高级语义(只记像素)
算法2:简化版 SimSiam(无负样本对比学习)
- 核心创新:不需要负样本对,也能学好特征!
- 结构 :
- 一个编码器 f f f
- 一个投影头 g g g(MLP)
- 一个停止梯度(stop-gradient)操作
- 损失:对称的余弦相似度损失
💡 适合入门:避免复杂负采样,效果却很好
算法3:掩码自编码器(MAE)基础思路
- 编码器 :只处理未被掩码的图像块(高效!)
- 解码器 :用轻量网络重建所有块(包括被掩码的)
- 关键:高比例掩码(如75%),迫使模型学全局语义
🌟 优势:训练快、特征强,已成为视觉预训练主流
13.4 自监督学习的核心价值
✅ 三大核心优势
-
学习通用特征表示
- 无需领域标签,学到的特征适用于多种任务(分类、检测、分割)
-
大幅降低下游标注需求
- 在1%标签数据上微调,效果接近全监督
-
利用海量无标签数据
- 互联网图像、网页文本、用户行为日志 → 全是免费训练数据!
📊 现实案例:
- BERT:用全部维基百科+图书语料预训练 → 各NLP任务SOTA
- MAE:用ImageNet无标签版预训练 → 分类准确率提升5%+
13.5 优缺点与适用场景
✅ 适用场景
- 大规模无标签数据可用(如爬取的网页、监控视频)
- 下游任务标注成本高(医疗、工业质检)
- 需要通用特征平台(公司级AI中台)
❌ 局限性
- 前置任务设计依赖经验:任务不好 → 特征没用
- 计算资源要求高:通常需GPU集群预训练
- 小数据场景收益有限:预训练需足够数据多样性
⚠️ 重要提醒 :
自监督不是"万能药"------如果下游任务与预训练数据分布差异大(如用自然图像预训练做X光分类),效果可能不佳。
13.6 实战案例 + 代码实现(PyTorch + Scikit-learn)
💡 为便于理解,以下使用简化模型和小数据集
案例1:自编码器实现数据降维与重构
python
import torch
import torch.nn as nn
import torchvision.transforms as transforms
from torchvision.datasets import MNIST
import matplotlib.pyplot as plt
# 自编码器定义
class Autoencoder(nn.Module):
def __init__(self, latent_dim=32):
super().__init__()
# 编码器
self.encoder = nn.Sequential(
nn.Linear(28*28, 128),
nn.ReLU(),
nn.Linear(128, 64),
nn.ReLU(),
nn.Linear(64, latent_dim)
)
# 解码器
self.decoder = nn.Sequential(
nn.Linear(latent_dim, 64),
nn.ReLU(),
nn.Linear(64, 128),
nn.ReLU(),
nn.Linear(128, 28*28),
nn.Sigmoid() # 输出0~1
)
def forward(self, x):
x = x.view(x.size(0), -1)
z = self.encoder(x)
recon = self.decoder(z)
return recon, z
# 训练
device = 'cuda' if torch.cuda.is_available() else 'cpu'
model = Autoencoder(latent_dim=32).to(device)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
# 加载MNIST(仅用图像,不用标签)
transform = transforms.Compose([transforms.ToTensor()])
train_set = MNIST(root='./data', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_set, batch_size=256, shuffle=True)
# 训练循环(简化)
for epoch in range(10):
for data, _ in train_loader:
data = data.to(device)
recon, _ = model(data)
loss = criterion(recon, data.view(data.size(0), -1))
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"Epoch {epoch}, Loss: {loss.item():.4f}")
# 可视化重构效果
model.eval()
with torch.no_grad():
sample, _ = next(iter(train_loader))
sample = sample[:8].to(device)
recon, _ = model(sample)
fig, axes = plt.subplots(2, 8, figsize=(12, 3))
for i in range(8):
axes[0, i].imshow(sample[i].cpu().squeeze(), cmap='gray')
axes[1, i].imshow(recon[i].cpu().view(28,28), cmap='gray')
axes[0, i].axis('off')
axes[1, i].axis('off')
axes[0, 0].set_title("原始")
axes[1, 0].set_title("重构")
plt.show()
🔍 观察:即使只用32维,也能较好重构手写数字!
案例2:简单对比学习(SimSiam简化版) + 下游分类
python
# 数据增强(两个视角)
def augment(x):
return transforms.Compose([
transforms.RandomResizedCrop(28, scale=(0.8, 1.0)),
transforms.RandomApply([transforms.ColorJitter(0.2, 0.2, 0.2, 0.1)], p=0.8),
transforms.RandomGrayscale(p=0.2),
transforms.ToTensor()
])(x)
# SimSiam简化模型
class SimSiam(nn.Module):
def __init__(self, backbone, proj_dim=64):
super().__init__()
self.backbone = backbone # 如ResNet
self.projector = nn.Sequential(
nn.Linear(backbone.out_features, proj_dim),
nn.BatchNorm1d(proj_dim),
nn.ReLU(),
nn.Linear(proj_dim, proj_dim)
)
self.predictor = nn.Sequential(
nn.Linear(proj_dim, proj_dim//2),
nn.ReLU(),
nn.Linear(proj_dim//2, proj_dim)
)
def forward(self, x1, x2):
z1 = self.projector(self.backbone(x1))
z2 = self.projector(self.backbone(x2))
p1 = self.predictor(z1)
p2 = self.predictor(z2)
return p1, p2, z1.detach(), z2.detach()
# 损失函数(对称余弦相似度)
def simsiam_loss(p1, p2, z1, z2):
def cos_loss(a, b):
a = nn.functional.normalize(a, dim=1)
b = nn.functional.normalize(b, dim=1)
return -(a * b).sum(dim=1).mean()
return (cos_loss(p1, z2) + cos_loss(p2, z1)) / 2
# 注意:完整实现较复杂,此处展示思路
# 预训练后,冻结backbone,接分类头微调
💡 下游任务 :
预训练后,取
backbone作为特征提取器,接一个线性分类器,在少量标签数据上训练。
案例3:文本掩码填充预训练 + 情感分析微调(使用Hugging Face)
python
from transformers import BertTokenizer, BertForMaskedLM, BertForSequenceClassification
from transformers import LineByLineTextDataset, DataCollatorForLanguageModeling
from transformers import Trainer, TrainingArguments
# 1. 准备无标签文本(如大量影评)
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
# 2. 构建MLM数据集
dataset = LineByLineTextDataset(
tokenizer=tokenizer,
file_path="unlabeled_reviews.txt",
block_size=128
)
data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15)
# 3. 加载预训练BERT(继续预训练)
model_mlm = BertForMaskedLM.from_pretrained('bert-base-uncased')
training_args = TrainingArguments(
output_dir='./mlm_model',
num_train_epochs=3,
per_device_train_batch_size=16,
save_steps=1000,
)
trainer = Trainer(
model=model_mlm,
args=training_args,
data_collator=data_collator,
train_dataset=dataset,
)
trainer.train()
# 4. 微调情感分析(二分类)
model_clf = BertForSequenceClassification.from_pretrained('./mlm_model', num_labels=2)
# ... 此处加载少量标注情感数据,标准Trainer微调 ...
# 结果:在100条标注数据上,准确率可达85%+(远超从零训练)
🌐 现实意义 :
用公司内部客服对话预训练BERT,再微调做意图识别,效果远超通用BERT!
🎯 本章总结
| 方法 | 前置任务 | 特点 | 适用模态 |
|---|---|---|---|
| 自编码器 | 重构原始输入 | 简单、稳定 | 图像、表格 |
| 对比学习 | 区分正负样本对 | 学高级语义 | 图像、音频 |
| 掩码重建 | 预测被遮盖部分 | 利用上下文 | 文本、图像 |
💡 建议:
- 入门:自编码器(理解重构思想)
- 进阶:SimSiam(掌握对比学习)
- 实战:Hugging Face + MAE(工业级应用)
📘 未来方向:
- 多模态自监督(图文对齐:CLIP)
- 生成式自监督(扩散模型、LLM)
- 自监督 + 强化学习(智能体自主探索)
🌟 记住 :
自监督学习的本质,是教会机器"自学成才"的能力 ------ 这正是通往通用人工智能的关键一步!
资料关注
公众号:咚咚王
gitee:https://gitee.com/wy18585051844/ai_learning
《Python编程:从入门到实践》
《利用Python进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第3版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow机器学习实战指南》
《Sklearn与TensorFlow机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第2版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨+&+张孜铭
《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战AI大模型》
《AI 3.0》