从隐变量建模到对抗训练,掌握现代生成模型的核心算法与实现技巧


环境声明

  • Python版本:Python 3.12+
  • 深度学习框架:PyTorch 2.3+
  • 关键依赖库:torchvision >= 0.18, numpy >= 1.26, matplotlib >= 3.8
  • 开发工具:PyCharm / VS Code / Jupyter Notebook
  • 硬件要求:支持CUDA的GPU(推荐)或CPU
  • 操作系统:Windows / macOS / Linux(通用)

学习目标

完成本章学习后,你将能够:

  1. 理解生成模型与判别模型的本质区别及各自适用场景
  2. 深入掌握VAE的编码器-解码器架构与重参数化技巧
  3. 完整推导ELBO目标函数及其数学原理
  4. 理解GAN的对抗训练机制与纳什均衡概念
  5. 掌握GAN训练中的关键技巧(DCGAN、WGAN、WGAN-GP)
  6. 了解扩散模型的基本原理及2024-2025年最新进展
  7. 使用PyTorch实现VAE和GAN进行图像生成

1. 生成模型概述

1.1 生成模型 vs 判别模型

机器学习模型可分为两大类:判别模型(Discriminative Models)和生成模型(Generative Models)。

特性 判别模型 生成模型
建模目标 P(Y|X):给定输入预测标签 P(X)或P(X,Y):学习数据分布
典型算法 逻辑回归、SVM、CNN分类器 VAE、GAN、扩散模型
核心能力 分类、回归、预测 数据生成、插值、半监督学习
信息利用 决策边界 完整数据分布
计算复杂度 通常较低 通常较高

一句话总结:判别模型回答"是什么",生成模型回答"像什么"。

1.2 生成模型的分类

根据建模方式的不同,生成模型可分为两大类:

显式密度模型(Explicit Density Models)

显式密度模型直接对数据分布P(X)进行建模,可以计算似然值。

  • 自回归模型:PixelCNN、WaveNet
  • 流模型:Normalizing Flows、RealNVP、Glow
  • 变分自编码器(VAE):通过变分推断近似后验分布
隐式密度模型(Implicit Density Models)

隐式密度模型不直接定义P(X),而是通过采样过程生成数据。

  • 生成对抗网络(GAN):通过对抗训练学习数据分布
  • 能量模型:Boltzmann Machine

1.3 生成模型的核心挑战

生成模型面临三个核心挑战:

  1. 模式崩溃(Mode Collapse):模型只生成少数几类样本,忽略数据分布的其他部分
  2. 训练不稳定性:尤其是GAN,生成器和判别器的平衡难以把握
  3. 评估困难:生成质量的量化评估缺乏统一标准

2. VAE原理详解

变分自编码器(Variational Autoencoder, VAE)由Kingma和Welling于2013年提出,是一种基于变分推断的生成模型。

2.1 VAE的基本架构

VAE包含三个核心组件:

编码器(Encoder)

编码器将输入数据X映射到隐变量空间Z,输出隐变量的分布参数:

q(z|x) = N(z; μ(x), σ²(x)I)

其中μ(x)和σ(x)由神经网络参数化。

解码器(Decoder)

解码器从隐变量z重构原始数据:

p(x|z) = Bernoulli(x; f(z))  或  N(x; μ(z), σ²I)
隐变量先验

通常假设隐变量服从标准高斯分布:

p(z) = N(z; 0, I)

2.2 重参数化技巧(Reparameterization Trick)

VAE训练的关键问题:如何从q(z|x)采样同时保持梯度可传播?

解决方案:重参数化技巧

z = μ + σ ⊙ ε,  其中 ε ~ N(0, I)

这样,随机性来自与网络参数无关的噪声ε,梯度可以通过μ和σ反向传播。

2.3 ELBO推导

VAE的目标是最大化数据的对数似然log p(x)。根据概率论:

log p(x) = log ∫ p(x|z)p(z) dz

这个积分通常难以直接计算。我们引入变分分布q(z|x)来近似真实的后验p(z|x):

log p(x) = log ∫ p(x|z)p(z) [q(z|x)/q(z|x)] dz
         = log E_{z~q(z|x)} [p(x|z)p(z)/q(z|x)]

利用Jensen不等式(对数函数的凹性):

log p(x) ≥ E_{z~q(z|x)} [log p(x|z) + log p(z) - log q(z|x)]

这就是证据下界(Evidence Lower Bound, ELBO)

ELBO = E_{z~q(z|x)} [log p(x|z)] - KL(q(z|x) || p(z))
ELBO的两项解释
名称 含义
E[log p(x|z)] 重构损失 解码器重构输入的能力
KL(q(z|x) || p(z)) KL散度 近似后验与先验的匹配程度

KL散度的解析计算

当q(z|x) = N(μ, σ²I),p(z) = N(0, I)时:

KL(q||p) = -0.5 * Σ(1 + log(σ²) - μ² - σ²)

2.4 VAE的损失函数

综合上述推导,VAE的总损失为:

L_VAE = -E_{z~q(z|x)} [log p(x|z)] + KL(q(z|x) || p(z))

对于图像数据,重构损失通常采用二元交叉熵或均方误差。


3. GAN原理详解

生成对抗网络(Generative Adversarial Network, GAN)由Goodfellow等人于2014年提出,开创了隐式密度模型的新范式。

3.1 GAN的基本架构

GAN由两个网络组成,形成对抗博弈:

生成器(Generator, G)
  • 输入:随机噪声 z ~ p(z)(通常为标准高斯分布)
  • 输出:生成的假样本 G(z)
  • 目标:生成足以欺骗判别器的样本
判别器(Discriminator, D)
  • 输入:真实样本 x 或生成样本 G(z)
  • 输出:样本为真的概率 D(x) ∈ [0, 1]
  • 目标:正确区分真实样本和生成样本

3.2 对抗训练目标

GAN的训练是一个极小极大博弈(Minimax Game):

min_G max_D V(D, G) = E_{x~p_data(x)} [log D(x)] + E_{z~p(z)} [log(1 - D(G(z)))]
判别器的优化目标

固定生成器G,判别器D最大化:

max_D E_{x~p_data} [log D(x)] + E_{z~p(z)} [log(1 - D(G(z)))]

这等价于二分类的交叉熵损失。

生成器的优化目标

固定判别器D,生成器G最小化:

min_G E_{z~p(z)} [log(1 - D(G(z)))]

训练技巧:实践中常使用最大化log D(G(z))替代最小化log(1-D(G(z))),以缓解早期梯度消失问题。

3.3 纳什均衡分析

当GAN达到纳什均衡时:

最优判别器:给定生成器G,最优判别器为:

D*(x) = p_data(x) / [p_data(x) + p_G(x)]

最优生成器:当p_G = p_data时,判别器无法区分真假样本:

D*(x) = 0.5

此时生成器达到了理论最优,完美拟合了真实数据分布。

3.4 理论保证

当判别器最优时,生成器的目标等价于最小化Jensen-Shannon散度:

C(G) = max_D V(D, G) = 2 * JSD(p_data || p_G) - log(4)

当且仅当p_G = p_data时,C(G)达到全局最小值-log(4)。


4. GAN训练技巧与改进

原始GAN存在训练不稳定、模式崩溃等问题,研究者提出了多种改进方案。

4.1 DCGAN(Deep Convolutional GAN)

DCGAN于2015年提出,首次成功将CNN应用于GAN,奠定了后续研究的基础。

核心设计原则

组件 设计原则
卷积层 使用步长卷积替代池化层
激活函数 生成器使用ReLU,判别器使用LeakyReLU
归一化 使用Batch Normalization稳定训练
输出层 生成器使用Tanh,判别器使用Sigmoid
架构 移除全连接隐藏层

4.2 WGAN(Wasserstein GAN)

WGAN于2017年提出,使用Wasserstein距离替代JS散度,从根本上改善了训练稳定性。

核心改进

  1. Wasserstein距离

    W(p_data, p_G) = inf_{γ∈Γ} E_{(x,y)~γ} [||x - y||]
    

    相比JS散度,Wasserstein距离在分布不重叠时仍能提供有意义的梯度。

  2. Lipschitz约束:通过权重裁剪(weight clipping)保证判别器满足Lipschitz条件

  3. 移除Sigmoid:判别器输出实数值而非概率

WGAN目标函数

min_G max_{D∈Lipschitz} E_{x~p_data} [D(x)] - E_{z~p(z)} [D(G(z))]

4.3 WGAN-GP(Gradient Penalty)

WGAN-GP于2017年提出,使用梯度惩罚替代权重裁剪,解决了WGAN的容量不足问题。

梯度惩罚项

GP = λ * E_{x~P_x} [(||∇_x D(x)||_2 - 1)²]

其中P_x是真实样本和生成样本之间的插值分布。

WGAN-GP完整目标

L_D = -E_{x~p_data} [D(x)] + E_{z~p(z)} [D(G(z))] + GP
L_G = -E_{z~p(z)} [D(G(z))]

4.4 StyleGAN简介

StyleGAN(2018-2020)代表了GAN架构的重大突破,实现了高质量、可控的图像生成。

核心创新

技术 说明
映射网络 将输入噪声映射到中间隐空间W
自适应实例归一化(AdaIN) 在不同尺度注入风格信息
渐进式增长 从低分辨率逐步生成高分辨率图像
风格混合 支持不同层次的风格插值

5. 扩散模型简介

扩散模型(Diffusion Models)是2020年后兴起的新一代生成模型,在图像生成领域取得了突破性进展。

5.1 DDPM原理

去噪扩散概率模型(Denoising Diffusion Probabilistic Models, DDPM)由Ho等人于2020年提出。

前向过程(扩散过程)

前向过程逐步向数据添加高斯噪声,共T步:

q(x_t | x_{t-1}) = N(x_t; √(1-β_t) x_{t-1}, β_t I)

通过重参数化,可以直接从x_0采样任意时刻的x_t:

x_t = √(ᾱ_t) x_0 + √(1-ᾱ_t) ε,  ε ~ N(0, I)

其中ᾱ_t = ∏_{s=1}^t (1-β_s)。

反向过程(去噪过程)

反向过程学习从噪声中恢复数据:

p_θ(x_{t-1} | x_t) = N(x_{t-1}; μ_θ(x_t, t), Σ_θ(x_t, t))

神经网络学习预测噪声ε,从而计算均值:

μ_θ(x_t, t) = [x_t - β_t/√(1-ᾱ_t) ε_θ(x_t, t)] / √(1-β_t)
训练目标

DDPM的训练目标是预测添加的噪声:

L_simple = E_{t, x_0, ε} [||ε - ε_θ(x_t, t)||²]

5.2 2024-2025年最新进展

Flow Matching(流匹配)

2022-2024年,Flow Matching范式兴起,统一了扩散模型和流模型的训练框架。

核心思想:学习一个常微分方程(ODE),将简单分布(如高斯)变换为数据分布。

优势

  • 训练更稳定
  • 采样速度更快
  • 与扩散模型性能相当

代表模型:Stable Diffusion 3、FLUX

Consistency Models(一致性模型)

2023年由OpenAI提出,旨在加速扩散模型的采样过程。

核心思想:训练模型使得同一数据在不同噪声水平下的去噪结果保持一致。

优势

  • 单步或少步生成
  • 达到GAN的生成速度
  • 保持扩散模型的生成质量
FLUX模型(2024)

由Stable Diffusion原班人马创立的Black Forest Labs发布,代表了当前开源文生图模型的最高水平。

技术特点

  • 基于Flow Matching架构
  • 120亿参数
  • 卓越的文字渲染能力
  • 开源可商用

5.3 生成模型对比

模型 训练稳定性 采样速度 生成质量 模式覆盖
VAE 中等 完整
GAN 易崩溃
DDPM 极高 完整
一致性模型 完整

6. 实战案例:使用PyTorch实现VAE和GAN进行MNIST图像生成

6.1 环境准备

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
import numpy as np

# 设置随机种子保证可复现
torch.manual_seed(42)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"使用设备: {device}")

# 数据预处理
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))  # 归一化到[-1, 1]
])

# 加载MNIST数据集
train_dataset = datasets.MNIST(
    root='./data', 
    train=True, 
    download=True, 
    transform=transform
)

train_loader = DataLoader(
    train_dataset, 
    batch_size=128, 
    shuffle=True, 
    num_workers=2
)

6.2 VAE实现

class VAEEncoder(nn.Module):
    """VAE编码器:将图像映射到隐变量分布"""
    def __init__(self, input_dim=784, hidden_dim=400, latent_dim=20):
        super(VAEEncoder, self).__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.fc_mu = nn.Linear(hidden_dim, latent_dim)
        self.fc_logvar = nn.Linear(hidden_dim, latent_dim)
        self.relu = nn.ReLU()
    
    def forward(self, x):
        h = self.relu(self.fc1(x))
        mu = self.fc_mu(h)
        logvar = self.fc_logvar(h)
        return mu, logvar


class VAEDecoder(nn.Module):
    """VAE解码器:从隐变量重构图像"""
    def __init__(self, latent_dim=20, hidden_dim=400, output_dim=784):
        super(VAEDecoder, self).__init__()
        self.fc1 = nn.Linear(latent_dim, hidden_dim)
        self.fc2 = nn.Linear(hidden_dim, output_dim)
        self.relu = nn.ReLU()
        self.sigmoid = nn.Sigmoid()
    
    def forward(self, z):
        h = self.relu(self.fc1(z))
        x_recon = self.sigmoid(self.fc2(h))
        return x_recon


class VAE(nn.Module):
    """完整的VAE模型"""
    def __init__(self, input_dim=784, hidden_dim=400, latent_dim=20):
        super(VAE, self).__init__()
        self.encoder = VAEEncoder(input_dim, hidden_dim, latent_dim)
        self.decoder = VAEDecoder(latent_dim, hidden_dim, input_dim)
        self.latent_dim = latent_dim
    
    def reparameterize(self, mu, logvar):
        """重参数化技巧"""
        std = torch.exp(0.5 * logvar)
        eps = torch.randn_like(std)
        return mu + eps * std
    
    def forward(self, x):
        mu, logvar = self.encoder(x)
        z = self.reparameterize(mu, logvar)
        x_recon = self.decoder(z)
        return x_recon, mu, logvar


def vae_loss_function(x_recon, x, mu, logvar):
    """VAE损失函数:重构损失 + KL散度"""
    # 二元交叉熵重构损失
    BCE = nn.functional.binary_cross_entropy(
        x_recon, x.view(-1, 784), reduction='sum'
    )
    
    # KL散度: -0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
    KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())
    
    return BCE + KLD


def train_vae(epochs=20):
    """训练VAE模型"""
    model = VAE(latent_dim=20).to(device)
    optimizer = optim.Adam(model.parameters(), lr=1e-3)
    
    model.train()
    for epoch in range(epochs):
        train_loss = 0
        for batch_idx, (data, _) in enumerate(train_loader):
            data = data.to(device)
            data = data.view(-1, 784)  # 展平图像
            
            optimizer.zero_grad()
            recon_batch, mu, logvar = model(data)
            loss = vae_loss_function(recon_batch, data, mu, logvar)
            loss.backward()
            train_loss += loss.item()
            optimizer.step()
        
        avg_loss = train_loss / len(train_loader.dataset)
        print(f'VAE Epoch {epoch+1}/{epochs}, 平均损失: {avg_loss:.4f}')
    
    return model


def generate_vae_samples(model, num_samples=64):
    """使用VAE生成样本"""
    model.eval()
    with torch.no_grad():
        # 从先验分布采样隐变量
        z = torch.randn(num_samples, model.latent_dim).to(device)
        samples = model.decoder(z).cpu()
        samples = samples.view(num_samples, 1, 28, 28)
    return samples

6.3 GAN实现

class Generator(nn.Module):
    """GAN生成器:将噪声向量映射到图像"""
    def __init__(self, latent_dim=100, hidden_dim=256, output_dim=784):
        super(Generator, self).__init__()
        self.model = nn.Sequential(
            nn.Linear(latent_dim, hidden_dim),
            nn.LeakyReLU(0.2),
            nn.Linear(hidden_dim, hidden_dim * 2),
            nn.BatchNorm1d(hidden_dim * 2),
            nn.LeakyReLU(0.2),
            nn.Linear(hidden_dim * 2, hidden_dim * 4),
            nn.BatchNorm1d(hidden_dim * 4),
            nn.LeakyReLU(0.2),
            nn.Linear(hidden_dim * 4, output_dim),
            nn.Tanh()  # 输出范围[-1, 1]
        )
        self.latent_dim = latent_dim
    
    def forward(self, z):
        return self.model(z)


class Discriminator(nn.Module):
    """GAN判别器:区分真实图像和生成图像"""
    def __init__(self, input_dim=784, hidden_dim=256):
        super(Discriminator, self).__init__()
        self.model = nn.Sequential(
            nn.Linear(input_dim, hidden_dim * 4),
            nn.LeakyReLU(0.2),
            nn.Dropout(0.3),
            nn.Linear(hidden_dim * 4, hidden_dim * 2),
            nn.LeakyReLU(0.2),
            nn.Dropout(0.3),
            nn.Linear(hidden_dim * 2, hidden_dim),
            nn.LeakyReLU(0.2),
            nn.Dropout(0.3),
            nn.Linear(hidden_dim, 1),
            nn.Sigmoid()  # 输出概率
        )
    
    def forward(self, x):
        return self.model(x)


def train_gan(epochs=50):
    """训练GAN模型"""
    latent_dim = 100
    generator = Generator(latent_dim=latent_dim).to(device)
    discriminator = Discriminator().to(device)
    
    # 优化器
    g_optimizer = optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))
    d_optimizer = optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))
    
    # 损失函数
    criterion = nn.BCELoss()
    
    for epoch in range(epochs):
        for batch_idx, (real_data, _) in enumerate(train_loader):
            batch_size = real_data.size(0)
            real_data = real_data.view(batch_size, -1).to(device)
            
            # 真实标签和假标签
            real_labels = torch.ones(batch_size, 1).to(device)
            fake_labels = torch.zeros(batch_size, 1).to(device)
            
            # ========== 训练判别器 ==========
            d_optimizer.zero_grad()
            
            # 真实样本的损失
            real_output = discriminator(real_data)
            d_loss_real = criterion(real_output, real_labels)
            
            # 生成假样本
            z = torch.randn(batch_size, latent_dim).to(device)
            fake_data = generator(z)
            
            # 假样本的损失
            fake_output = discriminator(fake_data.detach())
            d_loss_fake = criterion(fake_output, fake_labels)
            
            # 判别器总损失
            d_loss = d_loss_real + d_loss_fake
            d_loss.backward()
            d_optimizer.step()
            
            # ========== 训练生成器 ==========
            g_optimizer.zero_grad()
            
            # 生成器希望判别器将假样本判断为真
            fake_output = discriminator(fake_data)
            g_loss = criterion(fake_output, real_labels)
            
            g_loss.backward()
            g_optimizer.step()
        
        if (epoch + 1) % 10 == 0:
            print(f'GAN Epoch {epoch+1}/{epochs}, '
                  f'D_loss: {d_loss.item():.4f}, G_loss: {g_loss.item():.4f}')
    
    return generator


def generate_gan_samples(generator, num_samples=64):
    """使用GAN生成样本"""
    generator.eval()
    with torch.no_grad():
        z = torch.randn(num_samples, generator.latent_dim).to(device)
        samples = generator(z).cpu()
        samples = samples.view(num_samples, 1, 28, 28)
    return samples

6.4 可视化函数

def visualize_samples(samples, title, nrow=8):
    """可视化生成的样本"""
    fig, axes = plt.subplots(nrow, nrow, figsize=(10, 10))
    fig.suptitle(title, fontsize=16)
    
    for i in range(nrow):
        for j in range(nrow):
            idx = i * nrow + j
            if idx < len(samples):
                img = samples[idx].squeeze().numpy()
                axes[i, j].imshow(img, cmap='gray')
                axes[i, j].axis('off')
    
    plt.tight_layout()
    plt.show()


def compare_models():
    """对比VAE和GAN的生成效果"""
    # 训练VAE
    print("开始训练VAE...")
    vae_model = train_vae(epochs=20)
    vae_samples = generate_vae_samples(vae_model, num_samples=64)
    visualize_samples(vae_samples, "VAE生成的MNIST样本")
    
    # 训练GAN
    print("\n开始训练GAN...")
    gan_generator = train_gan(epochs=50)
    gan_samples = generate_gan_samples(gan_generator, num_samples=64)
    visualize_samples(gan_samples, "GAN生成的MNIST样本")


# 运行对比实验
if __name__ == "__main__":
    compare_models()

6.5 训练结果分析

指标 VAE GAN
训练稳定性 高,收敛平稳 中等,需要仔细调参
生成质量 略模糊但多样 清晰但可能模式崩溃
隐空间 结构良好,可插值 通常无明确结构
训练速度 较快 较慢(需交替训练)

7. 避坑小贴士

7.1 VAE常见问题

问题1:生成图像模糊

  • 原因:使用MSE损失导致平均化效应
  • 解决:尝试使用二元交叉熵损失,或结合感知损失

问题2:KL散度趋于0

  • 原因:模型退化为普通自编码器
  • 解决:使用KL退火(KL Annealing)逐渐增加KL权重

问题3:后验崩溃(Posterior Collapse)

  • 原因:解码器忽略隐变量
  • 解决:使用更强大的解码器,或采用循环退火策略

7.2 GAN常见问题

问题1:模式崩溃

  • 现象:生成器只产生少数几类样本
  • 解决
    • 使用WGAN-GP替代原始GAN
    • 尝试不同的小批量判别(Minibatch Discrimination)
    • 使用多个生成器或判别器

问题2:训练不稳定

  • 现象:损失震荡剧烈,无法收敛
  • 解决
    • 使用谱归一化(Spectral Normalization)
    • 调整学习率,通常生成器学习率略高于判别器
    • 使用TTUR(Two Time-Scale Update Rule)

问题3:梯度消失/爆炸

  • 解决
    • 使用LeakyReLU替代ReLU
    • 添加Batch Normalization
    • 使用梯度裁剪

7.3 超参数调优建议

参数 VAE建议值 GAN建议值
学习率 1e-3 ~ 1e-4 1e-4 ~ 2e-4
Batch Size 64 ~ 256 32 ~ 128
隐变量维度 20 ~ 128 100 ~ 256
优化器 Adam Adam (β1=0.5)

8. 本章小结

本章系统介绍了生成模型的核心算法:

核心知识点回顾

  1. VAE:通过变分推断学习隐变量表示,ELBO目标平衡重构质量与隐空间正则化
  2. GAN:通过生成器与判别器的对抗博弈学习数据分布,训练过程需要精心设计
  3. 扩散模型:通过逐步去噪生成样本,代表了当前生成模型的最高水平

技术演进脉络

2013: VAE —— 变分推断在深度生成模型中的首次成功应用
2014: GAN —— 开创对抗训练新范式
2015: DCGAN —— 将CNN成功应用于GAN
2017: WGAN/WGAN-GP —— 从根本上改善训练稳定性
2018: StyleGAN —— 实现高质量可控生成
2020: DDPM —— 扩散模型崛起
2023: Consistency Models —— 单步快速生成
2024: FLUX/SD3 —— Flow Matching架构成为主流

下一步学习建议

  • 深入研究扩散模型的数学原理与实现
  • 探索条件生成模型(Conditional GAN、Classifier-Free Guidance)
  • 学习大规模预训练生成模型(Stable Diffusion、GPT系列)
  • 了解生成模型在下游任务中的应用(图像编辑、数据增强)

系列导航

方向 章节 链接
上一篇 第9章 [第9章-深度生成模型基础](file:///d:/python/Python全栈开发/机器学习精通系列/第09章-深度生成模型基础.md)
下一篇 第11章 [第11章-强化学习基础](file:///d:/python/Python全栈开发/机器学习精通系列/第11章-强化学习基础.md)

如果本章内容对你有帮助,欢迎点赞、收藏、评论交流。你的支持是我持续创作的动力!


标签python 深度学习 生成模型 VAE GAN PyTorch

摘要:本章深入讲解生成模型的两大核心算法VAE与GAN,包含完整的数学推导、PyTorch代码实现及MNIST图像生成实战案例,同时介绍扩散模型及2024-2025年最新进展。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐