【老计带你懂AI算法】17:GAN生成对抗网络,两个网络互相较劲,造出以假乱真
开头:让AI从判断走向创造
前面讲的模型,大多在做判断和预测,这是猫还是狗、房价多少、会不会流失。它们是在认识世界。从这一篇开始,我们进入一个更神奇的领域,生成式AI,让AI去创造,生成本来不存在的图片、艺术、内容。
如今满天飞的AI绘画、AI换脸、AI生成的虚拟人脸,这些"无中生有"的能力,背后的开山鼻祖之一,就是这一篇的主角,GAN(生成对抗网络,Generative Adversarial Network)。它2014年提出,用一个极其巧妙、充满博弈智慧的设计,让机器学会了创造,一度是生成式AI最耀眼的明星,也让"AI也能搞创作"这件事第一次真正走进大众视野。
核心思想:一个造假高手和一个鉴宝专家的较量
GAN最精彩的地方,是它的设计思想,像一场猫鼠游戏。它让两个神经网络互相对抗、彼此较劲,在斗争中共同进步。这两个网络是:
- 生成器:一个"造假高手"。它的任务是凭空造出假的东西(比如假的人脸图片),目标是骗过鉴别者。
- 判别器:一个"鉴宝专家"。它的任务是判断给它的东西,是真的(来自真实数据)还是生成器造的假货,目标是别被骗。
这两个网络的目标完全对立,于是形成了一场持续的博弈。我用一个比方讲清这个过程,特别生动:
想象一个专造假钞的团伙(生成器)和一个验钞的警察(判别器)。一开始,造假团伙手艺很烂,造的假钞一眼假,警察轻松识破。造假团伙一看被识破了,就改进手艺,造得更逼真。警察发现认不出了,也提升自己的鉴别本领,学会看更细的破绽。造假团伙再升级,警察再升级……就这样,双方在一轮轮的对抗中互相逼着对方进步,造假的越来越以假乱真,验钞的越来越火眼金睛。最终,造假团伙的手艺高超到连最厉害的警察都难辨真假,这时候,生成器就能造出以假乱真的作品了。
这就是GAN的精髓,用对抗来驱动学习。不是直接教生成器怎么画好,而是给它找了个越来越强的对手(判别器),逼着它在对抗中自己学会造出逼真的东西。这个设计在当时惊艳了整个AI界,它的提出者古德费洛也因此声名大噪,据说灵感就来自一次酒吧里和朋友的争论。
值得一提的是,这种"对抗"的智慧,其实在生活里随处可见,理解了能帮你记住GAN。竞技体育里,对手越强你越能被逼出真实力;商业竞争中,旗鼓相当的对手会逼着双方都不断创新;甚至学习本身,一个会不断出难题挑你毛病的严师,比一味夸你的老师更能让你进步。GAN不过是把这个"在对抗中共同进化"的朴素道理,用两个神经网络精巧地实现了出来。想通这一层,你就抓住了GAN的灵魂,它的技术细节可以忘,但这个对抗博弈的思想值得记一辈子。
为什么对抗能学会创造
再把这个"对抗为什么有效"讲深一层,你会更佩服这个设计。
判别器的存在,本质是给生成器提供了一个不断进化的、越来越苛刻的评判标准。如果只是让生成器随便生成、没人评判,它根本不知道自己造得好不好、往哪个方向改。判别器就是那个挑剔的老师,它总能指出"你这里还是假、那里露馅了",生成器就朝着"骗过判别器"的方向努力。
关键在于,判别器自己也在变强。这就避免了一个问题,如果评判标准是固定的、僵化的,生成器很容易钻空子、糊弄过去。可判别器越来越聪明,生成器就没法糊弄,只能真刀真枪地把质量提上去。这种"魔高一尺、道高一丈"的动态对抗,逼出了双方真正的实力。到最后,生成器为了骗过一个几乎完美的判别器,就不得不学会生成几乎和真实数据分不出差别的作品,这就是创造。
输入和输出长什么样
- 生成器的输入:一串随机数字(术语叫随机噪声,可以理解成随机的种子)。从一堆随机数出发,是GAN能"无中生有"的关键,不同的随机种子,生成不同的作品。
- 生成器的输出:一个生成的样本(比如一张图片)。
- 判别器的输入:一个样本(可能真可能假)。输出:一个概率,判断它是真的可能性。
- 训练完成后,我们要的是生成器,判别器完成了陪练的使命就可以功成身退。用的时候,给生成器喂随机噪声,它就源源不断产出新作品。
上代码:训练一个生成手写数字的GAN
用PyTorch搭一个极简GAN生成手写数字。输入:随机噪声。输出:生成的数字图像。重点看两个网络对抗训练的结构。
# 依赖:pip install torch torchvisionimporttorchimporttorch.nnasnnfromtorchvisionimportdatasets,transformsfromtorch.utils.dataimportDataLoader# 加载MNIST,像素归一化到[-1,1]tf=transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5],[0.5])])loader=DataLoader(datasets.MNIST("./data",train=True,download=True,transform=tf),batch_size=128,shuffle=True)# 生成器:从100维随机噪声 生成 784维(28x28)图像G=nn.Sequential(nn.Linear(100,256),nn.ReLU(),nn.Linear(256,784),nn.Tanh(),# Tanh输出到[-1,1])# 判别器:输入784维图像,输出"是真图"的概率D=nn.Sequential(nn.Linear(784,256),nn.LeakyReLU(0.2),nn.Linear(256,1),nn.Sigmoid(),)loss_fn=nn.BCELoss()optG=torch.optim.Adam(G.parameters(),lr=0.0002)optD=torch.optim.Adam(D.parameters(),lr=0.0002)forepochinrange(1):# 演示只跑1轮fori,(imgs,_)inenumerate(loader):real=imgs.view(imgs.size(0),-1)bs=real.size(0)real_label=torch.ones(bs,1);fake_label=torch.zeros(bs,1)# 1.训练判别器:真图判真,假图判假z=torch.randn(bs,100)fake=G(z)d_loss=loss_fn(D(real),real_label)+loss_fn(D(fake.detach()),fake_label)optD.zero_grad();d_loss.backward();optD.step()# 2.训练生成器:努力让判别器把假图判成真z=torch.randn(bs,100)g_loss=loss_fn(D(G(z)),real_label)# 目标:骗过判别器optG.zero_grad();g_loss.backward();optG.step()ifi%200==0:print(f"批{i}判别器损失{d_loss.item():.3f}生成器损失{g_loss.item():.3f}")print("训练中,G在学着造更真的数字,D在学着更好地鉴别")运行输出(示例,训练有随机性,两个损失会来回拉锯,数值每次不同):
批0 判别器损失1.386 生成器损失0.693 批200 判别器损失0.921 生成器损失1.487 批400 判别器损失1.043 生成器损失1.126 训练中,G在学着造更真的数字,D在学着更好地鉴别运行你会看到两个损失此消彼长地拉锯。核心就是那两段训练,先训练判别器提高鉴别力,再训练生成器努力骗过它,两者交替、互相对抗。多训练些轮次后,生成器就能画出像模像样的手写数字了。这段代码把GAN的对抗博弈完整地展现了出来。
关键概念与难训练的坑
GAN效果惊艳,但出了名的难训练,这是它一个绕不开的短板:
- 训练不稳定:两个网络的对抗要棋逢对手、势均力敌才能一起进步。一旦一方太强(比如判别器碾压生成器),另一方就学不动了,训练崩掉。调平衡很微妙。
- 模式崩溃:生成器可能偷懒,发现只造某一种能骗过判别器的样本就够了,于是翻来覆去只生成那几种,失去了多样性。比如让它生成人脸,它只会生成几张雷同的脸。
- 不好评价:生成的东西好不好,没有一个简单的数字指标能衡量,往往要靠人看。
这些坑让GAN的调试很吃功夫,后来有很多改进版本(如DCGAN、WGAN、StyleGAN)来缓解这些问题,其中StyleGAN能生成极其逼真的高清人脸,那些"这个人不存在"的网站就是它的杰作。
让生成听指挥:条件GAN
原始的GAN从随机噪声出发,你没法控制它生成什么,喂进去随机种子,出来的是随机的数字或人脸,全凭它高兴。可实际中我们常常想指定生成的内容,比如"我就要生成数字7"“生成一只戴帽子的猫”。
这就催生了条件GAN。思路很简单,在给生成器喂随机噪声的同时,再多喂一个条件(比如你想要的类别标签),并且让判别器也知道这个条件,判断的不再是"这张图真不真",而是"这张图是不是符合条件的真图"。这么一来,生成器就学会了按你的指令来造。打个比方,原始GAN像个只会随手涂鸦的画家,你不知道他下一笔画啥;条件GAN则像个能听要求的画师,你说画只猫他就画猫。
这个"给生成过程加上可控条件"的思想极其重要,它是通往今天文生图(输入一句话生成对应图片)的关键一步。你现在用的那些AI绘画工具,输入"赛博朋克风格的城市夜景"就能出图,本质上就是把你那句话当成了控制生成的条件。虽然它们背后的主力已经换成了扩散模型,但"用文字或标签作为条件来引导生成"这个思路,正是从条件生成这里一脉相承下来的。理解了这一步,你就明白AI绘画为什么能听懂你的话。
优缺点与适用场景
优点:能生成非常逼真的样本、对抗思想新颖强大、生成速度快(一次前向就出结果)。缺点:训练不稳定难调、可能模式崩溃、不好评价质量。
适合场景:图像生成、人脸生成、图像风格转换(把照片变成油画)、图像超分辨率(把模糊图变清晰)、数据增强(造更多训练数据)、老照片修复等。
这里必须严肃地提一句GAN带来的一个现实问题,深度伪造(Deepfake)。GAN能生成以假乱真的人脸和视频,这项技术被滥用,就出现了换脸假视频、伪造名人言论、制造虚假色情内容等严重危害,甚至被用于诈骗(伪造老板的声音和视频骗员工转账)。这提醒我们,生成式AI是一把锋利的双刃剑,同样的造假能力,用在影视特效、艺术创作上是造福,用在欺诈和诽谤上就是作恶。作为技术人,理解这些技术的同时,也要有清醒的伦理底线,不参与、不助长技术的恶意滥用。好在,道高一尺魔高一丈的对抗也延伸到了这里,如今也有大量研究在做AI生成内容的检测和溯源,用技术手段来对抗技术的滥用。这场攻防,某种意义上又是一场新的"生成对抗"。
要说明它今天的定位:GAN开创了生成式AI的一个时代,但近几年在图像生成的王座上,已经很大程度上被下一篇要讲的扩散模型取代了。如今最火的AI绘画工具,背后多是扩散模型。不过GAN的对抗思想影响深远,仍在很多地方发挥作用,它是理解生成式AI绕不开的经典。
小结与承上启下
- GAN:两个网络对抗,生成器造假、判别器鉴假,在猫鼠游戏里双双变强。
- 为什么行:判别器提供不断进化的苛刻评判标准,逼生成器真刀真枪把质量提上去。
- 输入输出:生成器从随机噪声无中生有造样本,训练完只留生成器用。
- 短板与定位:难训练、易模式崩溃,图像生成已很大程度上被扩散模型取代,但对抗思想影响深远,仍是理解生成式AI绕不开的经典一课。
GAN用对抗来学习创造,思路巧妙但难驯服。有没有一种更稳定、生成质量更高的创造方式?有,它的灵感来自一个意想不到的地方,物理学里的扩散现象。下一篇我们讲如今AI绘画背后的真正主力,扩散模型,看它怎么从一片噪声里"雕刻"出精美的图像。
我们下一篇见。
延伸阅读
- GAN 原始论文《Generative Adversarial Networks》(Goodfellow等,2014):https://arxiv.org/abs/1406.2661
- StyleGAN 相关工作与人脸生成示例可按关键词StyleGAN检索
- PyTorch DCGAN 官方教程:https://pytorch.org/tutorials/beginner/dcgan_faces_tutorial.html
(说明:以上为官方与经典公开资料地址,可能随版本调整,如打不开可用标题搜索。)