我第一次接触图像生成技术是在2016年,当时还在用GAN(生成对抗网络)做实验。记得有天深夜调试代码时,突然看到屏幕上出现了一张勉强能辨认的人脸,那种兴奋感至今难忘。如今,扩散模型已经彻底改变了这个领域,而这一切的起点,竟然是我们最熟悉的监督学习。
监督学习就像是教小孩认东西。你给他看一张苹果的图片,告诉他"这是苹果";再给他看香蕉的图片,说"这是香蕉"。经过足够多的例子后,孩子就能自己识别水果了。扩散模型用的也是这个原理,只不过它学习的是如何"去噪"——把一团模糊的像素逐渐还原成清晰的图像。
这里有个有趣的对比:传统监督学习是"看图说话",而扩散模型是"听画作图"。比如你给模型看100万张带标签的苹果图片,它不仅能学会识别苹果,还能根据文字描述"画"出苹果。这种能力跃迁的关键,在于扩散模型创造性地把图像生成问题,转化成了渐进式的去噪任务。
想象你正在看老式电视机,突然信号变差,画面开始出现雪花点。扩散模型训练的第一步就是人为制造这种"信号丢失"效果。以一张清晰的苹果图片为例,算法会逐步添加高斯噪声,经过几十步操作后,图片就变成了完全随机的像素点。
这个过程有个专业术语叫"前向扩散"。我做过一个实验:用Python的PIL库给图片加噪,设置噪声强度从0.01逐步增加到0.99。当强度达到0.5时,图片已经像蒙了一层薄雾;到0.8时只能勉强看出轮廓;超过0.9后就完全是一堆彩色噪点了。
python复制from PIL import Image, ImageFilter
import numpy as np
def add_noise(image, noise_level):
arr = np.array(image)
noise = np.random.randn(*arr.shape) * noise_level * 255
noisy_arr = arr + noise
return Image.fromarray(np.clip(noisy_arr, 0, 255).astype('uint8'))
接下来就是监督学习的核心环节了。模型要学习的是如何逆向操作——给定第10步的噪点图,预测第9步的样子;给定第50步的模糊图,还原第49步的状态。这就好比教AI玩"大家来找茬",只不过游戏变成了"大家来修图"。
这里有个技术细节很关键:模型不是直接预测原始图片,而是预测当前步骤的噪声。这样做的好处是训练更稳定。用PyTorch代码表示的话,损失函数大概长这样:
python复制import torch
import torch.nn as nn
def diffusion_loss(model, x_start, t):
# 添加噪声
noise = torch.randn_like(x_start)
x_noisy = add_noise(x_start, t)
# 预测噪声
predicted_noise = model(x_noisy, t)
# 计算损失
return nn.functional.mse_loss(noise, predicted_noise)
单纯的去噪只能随机生成图片,加入文本提示才是真正的魔法时刻。这就像给画家一个创作主题——当你说"星空下的向日葵",模型会把噪声中的黄色像素往向日葵方向调整,把深色区域变成夜空。
我测试过Stable Diffusion的不同提示词组合。发现用"梵高风格"+"4K高清"+"光影效果"这样的组合提示时,生成质量明显提升。这是因为在训练时,模型见过大量带文字描述的图片,学会了将语义概念与视觉特征关联。
现代图像生成模型都内置了一个强大的文本理解模块,这通常来自大语言模型(LLM)。比如CLIP模型就能把文字和图片映射到同一个语义空间。当你说"戴着墨镜的柯基犬",模型会先把这个描述转换成一组数字向量(比如[0.2, -0.5, 1.3,...]),然后指导图像生成过程。
实测发现,使用不同的文本编码器效果差异很大。我在Colab上对比过BERT和CLIP的效果,同样的提示词"未来城市夜景",CLIP生成的画面明显更有科技感,建筑物细节也更丰富。
LLM的注意力机制也被移植到了扩散模型中。这种技术让模型能够聚焦于提示词的关键部分。比如处理"红色跑车在沙漠中行驶"时,模型会特别关注"红色"和"沙漠"的对应像素区域。
有个技巧很有意思:在提示词中重复关键词能增强效果。比如"极其精致的,极其精致的,极其精致的机械手表"生成的细节会比单次提示丰富得多。这是因为注意力机制会给重复出现的词分配更高权重。
扩散模型有多个关键参数需要调整:
我曾经为了生成完美的动漫角色头像,连续调整了3小时参数。最后发现关键在于把CFG(提示词引导)参数设为9,同时使用Euler a采样器。这种微调就像老摄影师冲洗照片时控制显影时间。
新手常会遇到这些问题:
有次我生成"钢琴家在月球表面演奏"的图片,结果钢琴键数不对,月面也过于光滑。后来在提示词中加入"88键三角钢琴"和"粗糙的月球表面"才解决问题。