PyTorch 初始化参数
torch.optim.lr_scheduler提供了多种学习率调度方法,它可以动态地在训练过程中调整学习率。下面是一个使用torch.optim.lr_scheduler中的StepLR调度器的例子:
例子:使用StepLR
StepLR是一个简单的学习率调度器,它会在固定的步数(epochs)间隔内按给定的因子降低学习率。
- 设置优化器和调度器:
import torch.optim as optim
model = ... # 假设你的模型定义在这里
optimizer = optim.Adam(model.parameters(), lr=0.001) # 初始化优化器
# 定义StepLR调度器,每10个epoch,学习率乘以gamma=0.9
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.9)
- 在训练循环中使用调度器:
num_epochs = 50
for epoch in range(num_epochs):
# 训练代码...
for i, data in enumerate(trainloader, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# 每个epoch结束后,调用scheduler的step方法来更新学习率
scheduler.step()
# 打印当前学习率(可选)
print(f"Epoch {epoch+1}, LR: {scheduler.get_last_lr()[0]}")
注意:
scheduler.step()通常在每个epoch结束后调用。- 你可以通过
scheduler.get_last_lr()来获取当前的学习率。
PyTorch 常用的调度器
torch.optim.lr_scheduler 提供了多种学习率调度策略,用于调整优化器中的学习率。下面简要介绍一些常用的调度器:
-
StepLR: 每隔固定步数,学习率乘以一个给定的因子(gamma)。
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1) -
MultiStepLR: 在给定的多个步数进行学习率衰减。
scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[30, 80], gamma=0.1) -
ExponentialLR: 每个 epoch 学习率乘以一个给定的因子。
scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.95) -
CosineAnnealingLR: 余弦退火调度。学习率会根据余弦退火调度策略进行调整。
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=50) -
ReduceLROnPlateau: 当某个指标(如验证集上的 loss)停止下降时,减小学习率。这通常用于模型训练时,当进度停滞不前时动态地降低学习率。
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, 'min') -
CyclicLR: 循环学习率策略,学习率在最小值和最大值之间循环变化。
scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.001, max_lr=0.01) -
OneCycleLR: 一次循环学习率策略,起初学习率线性增加,然后线性减少。
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.01, total_steps=num_epochs)
使用调度器时,每个 epoch 后(或每个 batch 后,根据需要)都需要调用 scheduler.step() 来更新学习率。
Sampler 是什么?
在深度学习中,"Sampler"(采样器)通常是指一种用于从数据集中选择样本的方法或对象。采样器决定了如何从数据集中获取样本,以供模型的训练或评估使用。在 PyTorch 中,采样器通常用于数据加载器(DataLoader)中,用于确定每个批次中包含哪些样本。
PyTorch 提供了多种类型的采样器,每种采样器都有不同的应用场景和特点。以下是几种常见的采样器:
RandomSampler: 随机采样器,从数据集中随机选择样本,可以用于训练和验证。SequentialSampler: 顺序采样器,按照数据集的顺序选择样本,适用于验证和测试。SubsetRandomSampler: 子集随机采样器,从指定的子集中随机选择样本。SubsetSequentialSampler: 子集顺序采样器,从指定的子集中按顺序选择样本。WeightedRandomSampler: 带权重的随机采样器,可以根据样本的权重进行采样,用于处理不均衡数据集。BatchSampler: 批次采样器,用于将样本分成批次。
这些采样器可以通过将其传递给 DataLoader 的 sampler 参数来使用。例如:
from torch.utils.data import DataLoader, RandomSampler
dataset = YourDataset()
sampler = RandomSampler(dataset)
dataloader = DataLoader(dataset, batch_size=32, sampler=sampler)
通过合适的采样器,你可以有效地从数据集中获取样本,使得模型的训练和评估过程更加高效和有序。不同的采样器适用于不同的数据集和任务,因此根据具体情况选择合适的采样器非常重要。
学习率调度器(Scheduler)
在训练深度神经网络时,学习率的设置是一个关键的超参数,可以影响模型的收敛速度和性能。学习率调度器用于自动调整学习率,以适应训练过程中的不同阶段。PyTorch 提供了多种学习率调度器,如 torch.optim.lr_scheduler 模块中的 StepLR、ReduceLROnPlateau、CosineAnnealingLR 等。这些调度器可以在训练过程中根据指定的策略自动更新学习率。
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR
optimizer = optim.SGD(model.parameters(), lr=0.1)
scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
在 Stable Diffusion 中,调度器有时也被称为采样器,它是作用于 UNet 阶段
在 Stable Diffusion 的应用
一个标准的 Stable Diffusion 分为两个步骤;前向扩散过程,和后向的去噪、复原以及生成目标的过程。前向过程不断向输入数据中添加噪声,而采样器主要在后向过程中负责去噪的过程。
在图像生成前,模型会首先在 Latent Space 中生成一个完全随机的图像,然后噪声预测器会开始工作,从图像中减去预测的噪声。随着这个步骤的不断重复,最终我们得到了一个清晰的图像。Stable Diffusion 在每个步骤中都会生成一张新的采样后的图像,整个去噪的过程,即为采样,使用的采样手段,即为采样器或称为采样方法
在 ComfyUI 中的 KSampler 是一个复合的采样器 Question about Samplers? (Normal, simple, karras, DDIM Uniform) #227

Stable Diffusion 使用工作流程
第一步,Prompt Encoder 过程(Text Encoder) 模型将潜在空间的随机种子和文本提示词 (Prompt)同时作为输入,然后使用潜在空间的种子生成大小为 64×64 的随机潜在图像表示,通过 CLIP 的文本编码器将输入的文本提示转换为大小为77×768的文本嵌入。
第二步,使用 U-Net 进行 Diffusion 过程 使用经过修改,含注意力机制的 U-Net,在接受文本嵌入作为注意力机制计算对象的同时迭代地对随机潜在图像表示进行去噪。 U-Net 的输出是噪声的残差,用于通过 scheduler 程序算法计算去噪的潜在图像表示。 scheduler 算法根据先前的噪声表示和预测的噪声残差计算预测的去噪图像表示。去噪过程重复约 50-100 次,这样可以逐步检索更好的潜在图像表示。
许多不同的 scheduler 算法可以用于这个计算,每一个都有它的优点和缺点。对于 Stable Diffusion,可以使用包括 PNDM scheduler、DDIM scheduler+PLMS、K-LMS scheduler等。