AI绘画:第一张AI图片是如何生成的

今天我们只需要输入一句:
一只戴着宇航员头盔的橘猫,站在火星表面,电影级光影
几秒钟后,AI 就能生成一张几乎可以以假乱真的图片。
现在大家已经习惯了 Midjourney、Stable Diffusion、DALL·E 这样的 AI 绘画工具。
但如果把时间往前推几十年,一个很有意思的问题就出现了:
人类历史上的第一张 AI 图片,到底是怎么生成出来的?
答案可能和很多人想象的不一样。
它没有 Stable Diffusion。
没有 Transformer。
没有 GPU。
甚至没有今天意义上的“训练数据集”。
早期 AI 绘画,实际上是从程序员手写规则,让计算机自己决定下一笔画在哪里开始的。
一、到底哪张图片才算“第一张 AI 图片”?
首先必须澄清一个概念:
目前并不存在一张被整个计算机科学界公认的“世界第一张 AI 图片”。
因为这里至少涉及三个不同概念:
计算机生成艺术
↓
AI 程序生成艺术
↓
机器学习生成图片
↓
深度学习生成图片
↓
文本生成图片
它们完全不是一回事。
早在 1960 年代,艺术家和计算机科学家就已经开始使用计算机绘图。
但是:
Computer Generated Art
并不一定等于:
AI Generated Art
真正经常被认为是 AI 艺术重要起点的,是一个叫:
AARON
的系统。
它由英国艺术家兼程序设计者 Harold Cohen 开发。
Whitney Museum 将 AARON 描述为最早的 AI 艺术创作软件之一,而英国 V&A 博物馆则直接称它为广泛认为的第一个 AI 艺术创作程序。
V&A 的馆藏中甚至保存着 Harold Cohen 在 1973 年制作的计算机生成绘画。
所以如果一定要寻找“AI 绘画的祖先”,AARON 是一个非常合适的起点。
二、1970 年代的 AI 是怎么画画的?
今天的 AI 绘画是:
学习数十亿张图片
↓
学习图片中的统计规律
↓
理解文字条件
↓
从噪声生成图片
而 AARON 完全不是这么工作的。
它更像:
人类艺术家的绘画经验
↓
转换成规则
↓
写成程序
↓
程序随机组合规则
↓
控制机器画图
Harold Cohen 尝试做的一件事情非常有意思。
他并不是简单告诉计算机:
在坐标 (10, 20) 画一条线
而是在思考:
一个艺术家究竟是如何决定下一笔画在哪里的?
例如画一个人物的时候,我们可能潜意识知道:
头通常在身体上方
眼睛通常位于脸部
两只眼睛不能完全重合
手臂从身体两侧伸出
植物通常从地面向上生长
树枝会产生分叉
Cohen 尝试把这种知识写进程序。
Computer History Museum 对 AARON 的描述中提到,它能够掌握类似树木形态、人物姿态等通用规则,再在规则范围内进行组合和“即兴发挥”。
这就已经非常接近早期 AI 的思想了:
Knowledge
+
Rules
+
Search
+
Randomness
=
Behavior
而不是今天的:
Data
+
Neural Network
+
Training
=
Model
三、假设我们自己写一个 1970 年代的 AI 画家
为了理解这个东西,可以写一个极简版本。
比如我们规定:
import random
def draw_person():
head_x = random.randint(100, 500)
head_y = random.randint(50, 150)
body_height = random.randint(100, 200)
left_arm_angle = random.randint(-60, 60)
right_arm_angle = random.randint(-60, 60)
return {
"head": (head_x, head_y),
"body_height": body_height,
"left_arm_angle": left_arm_angle,
"right_arm_angle": right_arm_angle
}
每运行一次:
person = draw_person()
print(person)
可能得到:
{
head: (323, 87),
body_height: 142,
left_arm_angle: -32,
right_arm_angle: 48
}
再次运行:
{
head: (271, 105),
body_height: 181,
left_arm_angle: 12,
right_arm_angle: -17
}
于是每一次生成出来的人物都不同。
如果再加入规则:
def valid_person(person):
if person["body_height"] < 100:
return False
if abs(person["left_arm_angle"]) > 70:
return False
if abs(person["right_arm_angle"]) > 70:
return False
return True
那么程序实际上已经开始拥有:
生成
+
判断
+
筛选
的能力。
四、真正关键的是:程序开始拥有“绘画知识”
例如画植物。
我们可以告诉程序:
def grow_branch(x, y, length, angle, depth):
if depth == 0:
return
new_x = x + length * cos(angle)
new_y = y + length * sin(angle)
draw_line(x, y, new_x, new_y)
grow_branch(
new_x,
new_y,
length * 0.7,
angle + random.uniform(0.2, 0.6),
depth - 1
)
grow_branch(
new_x,
new_y,
length * 0.7,
angle - random.uniform(0.2, 0.6),
depth - 1
)
这实际上就是:
一根树干
↓
随机分叉
↓
继续分叉
↓
继续分叉
最后就可以产生类似植物的图形。
每运行一次:
grow_branch(...)
生成出来的树都不同。
这是一种非常经典的:
Procedural Generation
也就是:
程序化生成。
Minecraft 地图生成、游戏地形生成、随机地下城生成,本质上都大量使用类似思想。
五、AARON 最开始甚至不是直接输出 JPG
这里还有一个非常有意思的地方。
今天 AI 生成图片:
模型
↓
像素
↓
PNG / JPG
AARON 早期却是:
AARON
↓
计算绘画路径
↓
生成运动指令
↓
控制绘图机器人
↓
笔在纸上移动
↓
真正画出作品
早期 AARON 会控制一种带有画笔的小型绘图装置,在真实纸张上绘制线条;部分早期作品之后还由 Harold Cohen 手工上色。
也就是说,它并不是:
生成图片文件
而更像:
生成绘画动作
这其实很像今天 AI Agent 控制机器人。
六、如果把 AARON 看成一个 Agent,会更容易理解
可以把它抽象成:
┌──────────────┐
│ 绘画知识库 │
└──────┬───────┘
↓
┌──────────────┐
│ 规则系统 │
└──────┬───────┘
↓
┌──────────────┐
│ 构图决策 │
└──────┬───────┘
↓
┌──────────────┐
│ 路径规划 │
└──────┬───────┘
↓
┌──────────────┐
│ 绘图设备 │
└──────────────┘
如果翻译成今天 AI Agent 的语言:
Knowledge Base
+
Planner
+
Rules
+
Tool
+
Environment
是不是突然熟悉了?
所以几十年前的 AI 绘画,其实已经出现了非常明显的 Agent 思想。
七、但 AARON 有一个巨大的问题
它不会真正意义上的:
学习
假设 Cohen 没有告诉它:
猫有两只耳朵
AARON 并不能自己看几百万张猫的图片以后学会这一点。
程序员需要自己写规则。
例如:
if object == "human":
draw_head()
draw_body()
draw_arm()
draw_leg()
那么问题来了。
如果要支持:
人
猫
狗
汽车
飞机
建筑
森林
城市
海洋
宇宙
程序会越来越复杂。
最后可能变成:
几万条规则
几十万条规则
甚至更多
这正是传统符号 AI 最大的问题之一:
人类很难把整个世界的知识全部写成规则。
于是 AI 绘画开始寻找另一条路线。
八、真正的革命:不要告诉 AI 怎么画,让它自己学
这就是机器学习。
思路从:
人类写规则
变成:
给 AI 看数据
比如我们给模型看:
100 万张人脸
不再告诉它:
眼睛应该在哪里
鼻子应该在哪里
耳朵应该在哪里
而是让神经网络自己学习这些统计规律。
模型最终可能学到:
眼睛附近经常出现某些像素组合
鼻子通常位于眼睛下面
嘴通常位于鼻子下面
左右结构具有一定对称性
但是模型并不会把知识保存成:
eye_y = face_y + 100
而是存储在:
神经网络参数
里面。
例如:
1 亿参数
10 亿参数
50 亿参数
每个参数可能只是一个浮点数:
0.18371
-0.78231
1.02318
但数十亿个参数组合起来,却形成了复杂的视觉知识。
九、2014 年:GAN 让 AI 真正开始“凭空画图”
现代 AI 图片生成史上,一个非常重要的节点是:
2014 年
GAN
Generative Adversarial Network
生成对抗网络
Ian Goodfellow 等人在 2014 年发表 GAN 论文,提出让两个神经网络通过对抗方式共同训练:一个负责生成,一个负责判断真假。
GAN 的架构非常漂亮。
只有两个核心角色:
Generator
生成器
Discriminator
判别器
十、GAN 是怎么画图片的?
假设我们的训练集里有:
100 万张真实人脸
首先创建:
Generator
输入一串随机数字:
z = [
0.13,
-0.52,
0.91,
...
]
生成器尝试输出:
一张人脸
刚开始训练的时候,它生成的图片可能完全是:
乱码
然后还有一个:
Discriminator
它负责判断:
这是真照片?
还是 AI 生成的?
整个过程类似:
生成器:我画了一张人脸。
判别器:假的。
生成器:那我修改一下。
判别器:还是假的。
生成器:再修改。
判别器:有点像了。
生成器:继续优化。
判别器:……
训练几百万次以后:
Generator
越来越会骗人。
十一、GAN 本质上是一场猫鼠游戏
数学上可以简化成:
Generator:
尽可能骗过 Discriminator
而:
Discriminator:
尽可能识别 Generator
可以理解成:
造假币的人
VS
验钞机
造假币的人越来越厉害。
验钞机也越来越厉害。
双方互相促进。
最终:
假币越来越像真的
换成 AI:
AI 图片越来越像真实图片
这也是为什么叫:
Generative Adversarial Network
↑
Adversarial
对抗
十二、一个极简 GAN 代码是什么样?
Generator:
class Generator(nn.Module):
def __init__(self):
super().__init__()
self.network = nn.Sequential(
nn.Linear(100, 256),
nn.ReLU(),
nn.Linear(256, 512),
nn.ReLU(),
nn.Linear(512, 784),
nn.Tanh()
)
def forward(self, z):
return self.network(z)
输入:
z = torch.randn(64, 100)
这里完全不是文字。
只是一堆随机数。
例如:
-0.721
0.218
1.271
-0.381
...
Generator 输出:
784 个数
因为:
28 × 28 = 784
把它重新排列:
image = output.reshape(28, 28)
就变成一张:
28 × 28
的图片。
十三、为什么随机数字最终可以变成图片?
这涉及 AI 绘画里非常重要的一个概念:
Latent Space
中文一般叫:
潜在空间
你可以想象一个巨大的空间。
空间里面的不同区域代表不同视觉特征。
比如:
区域 A
年轻人
区域 B
老年人
区域 C
戴眼镜的人
区域 D
微笑的人
模型训练以后:
随机向量 z
其实就是潜在空间中的一个坐标。
Generator 做的事情就是:
潜在空间坐标
↓
神经网络解码
↓
图片
于是:
z1
可能生成男人。
z2
可能生成女人。
z3
可能生成戴眼镜的人。
十四、2015 年:DeepDream 让全世界第一次感受到“AI 的梦”
2015 年,Google 发布了一个非常著名的项目:
DeepDream
它最初其实不是为了制作 AI 艺术。
而是为了研究:
神经网络到底在图片里面看到了什么?
Google 的研究人员发现,可以反过来不断增强神经网络已经检测到的视觉特征,于是产生大量极具迷幻风格的图片。Google 在 2015 年 7 月公开了相关代码。
例如给神经网络一张:
天空
神经网络可能隐约识别到:
狗
然后算法不断强化:
“这里像狗。”
最后:
越来越像狗
最终整个天空可能全部长满狗脸。
十五、DeepDream 技术上是怎么做的?
普通神经网络:
图片
↓
CNN
↓
识别结果
例如:
dog = 0.91
cat = 0.03
car = 0.01
DeepDream 做了一个很有意思的事情:
正常训练神经网络时,我们修改的是:
模型参数
DeepDream 却固定模型参数。
修改:
输入图片
也就是说:
Model
固定
然后计算:
Gradient
不断改变:
Image Pixels
让某一层神经元越来越兴奋。
伪代码:
image.requires_grad = True
for i in range(100):
features = model(image)
loss = features.mean()
loss.backward()
image.data += image.grad * 0.01
image.grad.zero_()
正常机器学习:
修改模型
DeepDream:
修改图片
这就是它最巧妙的地方。
十六、但是 GAN 依然有很多问题
GAN 曾经统治 AI 图片生成很多年。
出现了:
DCGAN
CycleGAN
StyleGAN
StyleGAN2
BigGAN
尤其是 StyleGAN。
一度让:
AI 生成人脸
达到非常惊人的水平。
但是 GAN 有几个典型问题。
第一个:
训练不稳定
因为 Generator 和 Discriminator 必须维持微妙平衡。
如果:
Discriminator 太强
Generator 学不到东西。
如果:
Generator 太强
Discriminator 又失去作用。
十七、GAN 还有一个著名问题:Mode Collapse
例如训练数据包含:
男人
女人
老人
小孩
亚洲人
欧洲人
非洲人
理论上 Generator 应该全部学会。
但是有时候 Generator 发现:
生成某一种脸
最容易骗过判别器
于是开始疯狂生成类似图片。
这叫:
Mode Collapse
也就是:
模式崩溃
生成结果多样性下降。
十八、真正改变今天 AI 绘画的,是 Diffusion
时间来到:
2020 年
Jonathan Ho、Ajay Jain 和 Pieter Abbeel 提出了著名的:
Denoising Diffusion Probabilistic Models
DDPM
论文展示了扩散概率模型能够获得高质量图片生成结果。
Diffusion 后来成为今天大量 AI 绘画系统的重要技术基础。
它的原理听起来甚至有点离谱:
先把一张图片彻底毁掉,然后训练 AI 学会怎么恢复。
十九、Diffusion 是怎么训练的?
假设有一张猫:
🐱
原始图片:
x0
然后加入一点噪声:
x1
继续加入:
x2
继续:
x3
一直:
x1000
最终:
纯随机噪声
整个过程:
猫
↓
有一点噪声
↓
更多噪声
↓
越来越模糊
↓
完全看不见
↓
纯噪声
这叫:
Forward Diffusion
二十、AI 学的不是怎么加噪声
加噪声非常容易。
真正需要学习的是:
反方向
也就是:
Noise
↓
去一点噪声
↓
再去一点噪声
↓
出现轮廓
↓
出现细节
↓
图片
这叫:
Reverse Diffusion
模型实际上学习:
给我一张带噪图片,我应该删除哪些噪声?
二十一、一个极简 Diffusion 加噪代码
例如:
import torch
image = load_image("cat.jpg")
noise = torch.randn_like(image)
alpha = 0.8
noisy_image = (
alpha ** 0.5 * image
+
(1 - alpha) ** 0.5 * noise
)
当:
alpha ≈ 1
图片还非常清晰。
当:
alpha ≈ 0
图片几乎全部变成:
随机噪声
二十二、训练 AI 预测噪声
假设:
noise = torch.randn_like(image)
我们知道真正加进去的噪声。
于是可以把:
带噪图片
交给神经网络:
predicted_noise = model(noisy_image, timestep)
然后计算:
loss = mse(predicted_noise, noise)
也就是:
AI 猜的噪声
VS
真正加入的噪声
不断训练:
optimizer.zero_grad()
loss.backward()
optimizer.step()
训练几亿次以后:
AI 越来越会猜噪声
换个角度看:
越来越会去噪
于是 AI 学会了:
从噪声恢复图片
二十三、那为什么可以“凭空生成”一只猫?
关键就在这里。
训练时:
真实图片
↓
加噪声
↓
AI 学习恢复
生成时根本不需要真实图片。
直接创建:
image = torch.randn(
1,
3,
512,
512
)
得到:
512 × 512
的纯随机噪声。
然后:
for t in timesteps:
noise = model(
image,
t
)
image = remove_noise(
image,
noise
)
慢慢去噪:
纯噪声
↓
模糊颜色
↓
轮廓
↓
物体
↓
纹理
↓
细节
↓
完整图片
于是:
一张原本不存在的图片出现了。
二十四、但是这时候还不能输入 Prompt
普通 Diffusion 只是:
随机生成图片
问题来了。
我们希望告诉 AI:
我要一只猫
而不是:
随便给我一张图片
于是需要:
Text Encoder
二十五、Prompt 是怎么控制图片的?
输入:
a cute orange cat
首先经过文本编码器:
Text
↓
Tokenizer
↓
Text Encoder
↓
Embedding
最后得到很多数字。
例如:
[
0.172,
-0.331,
0.872,
...
]
AI 并不是直接理解:
cat
这个英文单词。
它真正处理的是:
向量
二十六、于是现代 AI 绘画变成了两个条件
Diffusion Model 每一步生成时都会同时看到:
当前图片
+
Prompt Embedding
可以抽象为:
noise = unet(
image,
timestep,
text_embedding
)
比如:
Prompt:
A cute orange cat
模型在去噪过程中不断问:
按照这段文字,
现在应该去掉哪些噪声?
最终噪声逐渐向:
橘猫
靠拢。
二十七、Stable Diffusion 又做了什么?
早期 Diffusion 直接在图片像素空间工作。
例如:
512 × 512 × 3
数据量非常大。
Stable Diffusion 的重要思想之一是:
不直接在像素空间扩散,而是在 Latent Space 中扩散。
图片首先经过:
VAE Encoder
例如:
512 × 512 × 3
压缩成:
64 × 64 × 4
然后 Diffusion 在这个小得多的空间工作。
整体架构:
Prompt
↓
Text Encoder
↓
Text Embedding
↓
Noise → U-Net → Latent
↓
VAE Decoder
↓
Image
这就是:
Latent Diffusion
二十八、为什么这样速度会快很多?
假设原图:
512 × 512 × 3
大约有:
786432
个数。
Latent:
64 × 64 × 4
只有:
16384
个数。
计算规模一下减少很多。
因此模型可以:
更快训练
更快推理
降低显存
生成更大图片
Stable Diffusion 才真正具备了大规模普及的基础。
二十九、今天 AI 绘画的一次完整生成过程
假设你输入:
一只橘猫坐在程序员桌前写代码,
赛博朋克风格,
电影级灯光
现代图片生成模型大致经历:
Step 1
Prompt
↓
Step 2
Tokenizer
↓
Step 3
Text Encoder
↓
Step 4
Prompt Embedding
↓
Step 5
创建随机 Noise
↓
Step 6
Diffusion Model 多次去噪
↓
Step 7
Latent Image
↓
Step 8
VAE Decoder
↓
Step 9
RGB Image
↓
Step 10
PNG / JPG
你看到:
生成图片
可能只需要几秒钟。
但是背后实际上执行了:
文本编码
神经网络计算
注意力计算
潜空间运算
几十次迭代去噪
图像解码
三十、AI 到底是在“拼接图片”吗?
这是 AI 绘画最大的误解之一。
很多人认为:
AI 看过很多图片
所以:
AI = 从数据库找几张图片拼起来
但典型生成模型并不是这样工作的。
训练完成以后,模型核心保存的是:
Parameters
例如:
weight_1 = 0.1273
weight_2 = -0.8721
weight_3 = 0.3318
...
这些参数共同描述的是:
视觉规律
统计关系
语义关系
纹理模式
形状关系
空间关系
生成阶段通常执行:
Noise
↓
Neural Network
↓
Noise Prediction
↓
Denoising
↓
Image
并不是:
搜索数据库
↓
找到猫
↓
找到宇航服
↓
PS 拼接
当然,生成模型可能发生训练数据记忆、近似复现等问题,这也是模型研究、版权和数据治理中持续讨论的重要方向。
但从模型架构本身来说:
生成
和简单的:
图片拼接
完全是两种技术。
三十一、从 AARON 到 Stable Diffusion,真正发生了什么?
如果把几十年的 AI 绘画历史压缩成几行:
1970s
AARON
人类:
告诉机器怎么画
↓
1990s - 2000s
Neural Networks
人类:
让机器开始学习视觉特征
↓
2014
GAN
机器:
学习真实图片的分布
↓
2015
DeepDream
机器:
把自己看到的视觉特征放大
↓
2020
Diffusion
机器:
学习如何把噪声还原成图片
↓
2021+
Text-to-Image
机器:
根据文字控制图片生成
↓
今天
文字
图片
姿态
草图
深度
风格
人物
场景
全部成为生成条件
三十二、一个非常有意思的变化
AARON 时代:
Human Knowledge
↓
Code
↓
Image
今天:
Human Data
↓
Training
↓
Model
↓
Prompt
↓
Image
最大的区别就在这里。
以前:
人类需要告诉计算机规则是什么。
现在:
人类给计算机大量数据,让计算机自己发现规则。
这可能才是 AI 绘画几十年发展过程中真正意义上的技术革命。
三十三、所以,第一张 AI 图片究竟是怎么生成的?
如果我们把 Harold Cohen 的 AARON 作为 AI 绘画的重要起点,那么答案其实非常简单。
它并不是:
输入 Prompt
↓
GPU 推理
↓
Diffusion
↓
图片
而是:
艺术家研究绘画规律
↓
把绘画知识转换成规则
↓
把规则写成程序
↓
计算机根据规则进行决策
↓
加入随机性形成不同构图
↓
计算绘画路径
↓
控制绘图设备移动
↓
画笔落到纸面
↓
作品诞生
甚至早期作品中的颜色,还可能由 Harold Cohen 本人完成。
后来 AARON 才逐渐发展出了更加复杂的构图和自主颜色选择能力。
三十四、从第一笔,到今天的一句话生成图片
几十年前:
计算机能够自己决定
下一条线画在哪里
就已经是一件极其惊人的事情。
后来:
GAN
让计算机学会:
什么东西看起来像真实图片
再后来:
Diffusion
让计算机学会:
如何从随机噪声中恢复视觉世界
而今天:
Text Encoder
+
Diffusion
+
Transformer
+
Multimodal Model
又让机器进一步理解:
“一个人在雨夜的东京街头,
穿黑色风衣,
霓虹灯倒映在地面,
电影摄影风格。”
最终,人类几十年的研究,把 AI 绘画从:
让机器画一根线
发展到了:
让机器根据一句自然语言,
创造一个原本不存在的视觉世界。
这大概也是 AI 技术历史中最直观的一次进化。
第一代 AI 绘画试图回答的是:
能不能把“如何画画”写成程序?
而今天的生成式 AI 正在回答另一个问题:
如果机器看过足够多的世界,它能不能学会如何创造一个新的世界?

浙公网安备 33010602011771号