Tech

Compreendendo modelos de difusão: um mergulho profundo na IA generativa

Modelos de difusão surgiram como uma abordagem poderosa em IA generativa, produzindo resultados de última geração em geração de imagem, áudio e vídeo. Neste artigo técnico aprofundado, exploraremos como os modelos de difusão funcionam, suas principais inovações e por que eles se tornaram tão bem-sucedidos. Abordaremos os fundamentos matemáticos, o processo de treinamento, os algoritmos de amostragem e as aplicações de ponta dessa nova e empolgante tecnologia.

Introdução aos Modelos de Difusão

Modelos de difusão são uma classe de modelos generativos que aprendem a gradualmente reduzir o ruído dos dados revertendo um processo de difusão. A ideia central é começar com ruído puro e refiná-lo iterativamente em uma amostra de alta qualidade da distribuição alvo.

Essa abordagem foi inspirada pela termodinâmica de não equilíbrio – especificamente, o processo de reversão da difusão para recuperar a estrutura. No contexto do aprendizado de máquina, podemos pensar nisso como aprender a reverter a adição gradual de ruído aos dados.

Algumas vantagens principais dos modelos de difusão incluem:

  • Qualidade de imagem de última geração, superando GANs em muitos casos
  • Treinamento estável sem dinâmicas adversas
  • Altamente paralelizável
  • Arquitetura flexível – qualquer modelo que mapeie entradas para saídas da mesma dimensionalidade pode ser usado
  • Forte embasamento teórico

Vamos nos aprofundar em como os modelos de difusão funcionam.

Fonte: Tune et al.

Equações Diferenciais Estocásticas governam os processos direto e reverso em modelos de difusão. A SDE direta adiciona ruído aos dados, transformando-os gradualmente em uma distribuição de ruído. A SDE reversa, guiada por uma função de pontuação aprendida, take away progressivamente o ruído, levando à geração de imagens realistas a partir de ruído aleatório. Essa abordagem é essencial para atingir desempenho generativo de alta qualidade em espaços de estado contínuos

O Processo de Difusão Direta

O processo de difusão direta começa com um ponto de dados x₀ amostrado da distribuição de dados actual e adiciona gradualmente ruído gaussiano ao longo de T intervalos de tempo para produzir versões cada vez mais ruidosas x₁, x₂, …, xT.

Em cada passo de tempo t, adicionamos uma pequena quantidade de ruído de acordo com:

x_t = √(1 - β_t) * x_{t-1} + √(β_t) * ε

Onde:

  • b_t é um cronograma de variação que controla quanto ruído é adicionado em cada etapa
  • e é ruído gaussiano aleatório

Esse processo continua até que xT seja quase ruído gaussiano puro.

Matematicamente, podemos descrever isso como uma cadeia de Markov:

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

Onde N denota uma distribuição gaussiana.

O cronograma β_t é tipicamente escolhido para ser pequeno para os primeiros passos de tempo e aumentar ao longo do tempo. Escolhas comuns incluem cronogramas lineares, cosseno ou sigmoides.

O Processo de Difusão Reversa

O objetivo de um modelo de difusão é aprender o inverso desse processo: começar com ruído puro xT e progressivamente reduzi-lo para recuperar uma amostra limpa x₀.

Modelamos esse processo reverso como:

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

Onde μ_θ e σ_θ^2 são funções aprendidas (normalmente redes neurais) parametrizadas por θ.

A principal inovação é que não precisamos modelar explicitamente a distribuição reversa completa. Em vez disso, podemos parametrizá-la em termos do processo ahead, que conhecemos.

Especificamente, podemos mostrar que a média ótima do processo reverso μ* é:

μ* = 1/√(1 - β_t) * (x_t - β_t/√(1 - α_t) * ε_θ(x_t, t))

Onde:

  • α_t = 1 – β_t
  • ε_θ é uma rede de previsão de ruído aprendida

Isso nos dá um objetivo simples: treinar uma rede neural ε_θ para prever o ruído que foi adicionado em cada etapa.

Objetivo do treinamento

O objetivo de treinamento para modelos de difusão pode ser derivado de inferência variacional. Após alguma simplificação, chegamos a uma perda L2 simples:

L = E_t,x₀,ε ( ||ε - ε_θ(x_t, t)||² )

Onde:

  • t é amostrado uniformemente de 1 a T
  • x₀ é amostrado a partir dos dados de treinamento
  • ε é ruído gaussiano amostrado
  • x_t é construído adicionando ruído a x₀ de acordo com o processo direto

Em outras palavras, estamos treinando o modelo para prever o ruído que foi adicionado em cada intervalo de tempo.

Arquitetura do modelo

Fonte: Ronneberger et al.

Fonte: Ronneberger et al.

A arquitetura U-Web é central para a etapa de denoising no modelo de difusão. Ela apresenta uma estrutura codificador-decodificador com conexões de salto que ajudam a preservar detalhes de granulação fina durante o processo de reconstrução. O codificador reduz progressivamente a amostragem da imagem de entrada enquanto captura recursos de alto nível, e o decodificador aumenta a amostragem dos recursos codificados para reconstruir a imagem. Essa arquitetura é particularmente eficaz em tarefas que exigem localização precisa, como segmentação de imagem.

A rede de previsão de ruído ε_θ pode usar qualquer arquitetura que mapeie entradas para saídas da mesma dimensionalidade. Arquiteturas de estilo U-Web são uma escolha in style, especialmente para tarefas de geração de imagens.

Uma arquitetura típica pode se parecer com:

class DiffusionUNet(nn.Module):
    def __init__(self):
        tremendous().__init__()
        
        # Downsampling
        self.down1 = UNetBlock(3, 64)
        self.down2 = UNetBlock(64, 128)
        self.down3 = UNetBlock(128, 256)
        
        # Bottleneck
        self.bottleneck = UNetBlock(256, 512)
        
        # Upsampling 
        self.up3 = UNetBlock(512, 256)
        self.up2 = UNetBlock(256, 128)
        self.up1 = UNetBlock(128, 64)
        
        # Output
        self.out = nn.Conv2d(64, 3, 1)
        
    def ahead(self, x, t):
        # Embed timestep
        t_emb = self.time_embedding
        
        # Downsample
        d1 = self.down1(x, t_emb)
        d2 = self.down2(d1, t_emb)
        d3 = self.down3(d2, t_emb)
        
        # Bottleneck
        bottleneck = self.bottleneck(d3, t_emb)
        
        # Upsample
        u3 = self.up3(torch.cat((bottleneck, d3), dim=1), t_emb)
        u2 = self.up2(torch.cat((u3, d2), dim=1), t_emb)
        u1 = self.up1(torch.cat((u2, d1), dim=1), t_emb)
        
        # Output
        return self.out(u1)

Os principais componentes são:

  • Arquitetura estilo U-Web com conexões de salto
  • Incorporação de tempo para condicionar o passo de tempo
  • Profundidade e largura flexíveis

Algoritmo de Amostragem

Uma vez que treinamos nossa rede de predição de ruído ε_θ, podemos usá-la para gerar novas amostras. O algoritmo básico de amostragem é:

  1. Comece com ruído gaussiano puro xT
  2. Para t = T para 1:
    • Prever ruído: ε_θ(x_t, t)
    • Calcular média: μ = 1/√(1-β_t) * (x_t - β_t/√(1-α_t) * ε_θ(x_t, t))
    • Amostra: x_{t-1} ~ N(μ, σ_t^2 * I)
  3. Retornar x₀

Esse processo elimina gradualmente o ruído da amostra, guiado pela nossa rede de previsão de ruído aprendida.

Na prática, existem várias técnicas de amostragem que podem melhorar a qualidade ou a velocidade:

  • SEM amostragem: Uma variante determinística que permite menos etapas de amostragem
  • Amostragem ancestral: Incorpora a variância aprendida σ_θ^2
  • Amostragem truncada: Para cedo para geração mais rápida

Aqui está uma implementação básica do algoritmo de amostragem:

def pattern(mannequin, n_samples, system):
    # Begin with pure noise
    x = torch.randn(n_samples, 3, 32, 32).to(system)
    
    for t in reversed(vary(1000)):
        # Add noise to create x_t
        t_batch = torch.full((n_samples,), t, system=system)
        noise = torch.randn_like(x)
        x_t = add_noise(x, noise, t)
        
        # Predict and take away noise
        pred_noise = mannequin(x_t, t_batch)
        x = remove_noise(x_t, pred_noise, t)
        
        # Add noise for subsequent step (besides at t=0)
        if t > 0:
            noise = torch.randn_like(x)
            x = add_noise(x, noise, t-1)
    
    return x

A matemática por trás dos modelos de difusão

Screenshot 2024 08 26 090603

Para entender verdadeiramente os modelos de difusão, é essential se aprofundar na matemática que os sustenta. Vamos explorar alguns conceitos-chave em mais detalhes:

Cadeia de Markov e equações diferenciais estocásticas

O processo de difusão para frente em modelos de difusão pode ser visto como uma cadeia de Markov ou, no limite contínuo, como uma equação diferencial estocástica (SDE). A formulação SDE fornece uma estrutura teórica poderosa para analisar e estender modelos de difusão.

O SDE avançado pode ser escrito como:

dx = f(x,t)dt + g

Artigos relacionados

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button