Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Опыт обучения генеративных моделей
Да, у меня есть значительный практический опыт обучения генеративных моделей — от простых VAE до современных диффузионных моделей и больших языковых моделей.
1. Текстовые генеративные модели
Fine-tuning GPT-подобных моделей
from transformers import TextDataset, Trainer, TrainingArguments
from transformers import AutoModelForCausalLM, AutoTokenizer
# Подготовка данных
dataset = TextDataset(
tokenizer=tokenizer,
file_path="data.txt",
block_size=512
)
# Настройка обучения
training_args = TrainingArguments(
output_dir="./model_output",
overwrite_output_dir=True,
num_train_epochs=3,
per_device_train_batch_size=8,
save_steps=500,
save_total_limit=2,
logging_steps=100,
learning_rate=5e-5,
weight_decay=0.01,
warmup_steps=500,
use_cuda=True,
)
# Обучение
trainer = Trainer(
model=model,
args=training_args,
data_collator=data_collator,
train_dataset=dataset,
)
trainer.train()
Обучение на собственном корпусе текстов
from datasets import load_dataset, DatasetDict
import torch
# Загрузить свой датасет
custom_dataset = load_dataset(
"text",
data_files={"train": "train.txt", "validation": "val.txt"}
)
# Токенизация
def tokenize_function(examples):
return tokenizer(
examples["text"],
padding="max_length",
truncation=True,
max_length=512
)
tokenized_datasets = custom_dataset.map(
tokenize_function,
batched=True,
remove_columns=["text"]
)
# Обучение с LoRA для эффективности
from peft import get_peft_model, LoraConfig, TaskType
lora_config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=8,
lora_alpha=32,
lora_dropout=0.1,
target_modules=["q_proj", "v_proj", "k_proj", "out_proj"],
bias="none"
)
model = get_peft_model(model, lora_config)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
)
trainer.train()
2. Генеративные модели для изображений
Обучение GAN (Generative Adversarial Network)
import torch
import torch.nn as nn
from torch.optim import Adam
# Generator - создаёт изображения из шума
class Generator(nn.Module):
def __init__(self, latent_dim=100):
super().__init__()
self.model = nn.Sequential(
nn.Linear(latent_dim, 256),
nn.ReLU(),
nn.Linear(256, 512),
nn.ReLU(),
nn.Linear(512, 1024),
nn.ReLU(),
nn.Linear(1024, 28*28), # MNIST
nn.Sigmoid() # 0-1 диапазон
)
def forward(self, z):
return self.model(z).view(-1, 1, 28, 28)
# Discriminator - различает реальные и поддельные изображения
class Discriminator(nn.Module):
def __init__(self):
super().__init__()
self.model = nn.Sequential(
nn.Linear(28*28, 1024),
nn.LeakyReLU(0.2),
nn.Dropout(0.3),
nn.Linear(1024, 512),
nn.LeakyReLU(0.2),
nn.Dropout(0.3),
nn.Linear(512, 256),
nn.LeakyReLU(0.2),
nn.Dropout(0.3),
nn.Linear(256, 1),
nn.Sigmoid() # 0-1: вероятность реальности
)
def forward(self, img):
return self.model(img.view(-1, 28*28))
# Обучение
generator = Generator()
discriminator = Discriminator()
g_optimizer = Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))
d_optimizer = Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))
loss_fn = nn.BCELoss()
for epoch in range(100):
for batch_idx, (real_imgs, _) in enumerate(dataloader):
batch_size = real_imgs.size(0)
# Обучение Discriminator
real_labels = torch.ones(batch_size, 1)
fake_labels = torch.zeros(batch_size, 1)
real_output = discriminator(real_imgs)
d_real_loss = loss_fn(real_output, real_labels)
z = torch.randn(batch_size, 100)
fake_imgs = generator(z)
fake_output = discriminator(fake_imgs.detach())
d_fake_loss = loss_fn(fake_output, fake_labels)
d_loss = d_real_loss + d_fake_loss
d_optimizer.zero_grad()
d_loss.backward()
d_optimizer.step()
# Обучение Generator
z = torch.randn(batch_size, 100)
fake_imgs = generator(z)
fake_output = discriminator(fake_imgs)
g_loss = loss_fn(fake_output, real_labels) # Generator хочет обмануть
g_optimizer.zero_grad()
g_loss.backward()
g_optimizer.step()
Обучение диффузионных моделей
from diffusers import DDPMPipeline, DDPMScheduler, UNet2DModel
from torch.optim import AdamW
from tqdm import tqdm
# Инициализация компонентов
model = UNet2DModel(
sample_size=32,
in_channels=3,
out_channels=3,
layers_per_block=2,
block_out_channels=(128, 128, 256, 256, 512, 512),
down_block_types=("DownBlock2D", "DownBlock2D", "AttnDownBlock2D",
"AttnDownBlock2D", "AttnDownBlock2D", "DownBlock2D"),
up_block_types=("UpBlock2D", "AttnUpBlock2D", "AttnUpBlock2D",
"AttnUpBlock2D", "UpBlock2D", "UpBlock2D"),
)
noise_scheduler = DDPMScheduler(
num_train_timesteps=1000,
beta_start=0.0001,
beta_end=0.02,
beta_schedule="linear",
)
optimizer = AdamW(model.parameters(), lr=1e-4)
# Обучение
for epoch in range(num_epochs):
for batch in dataloader:
x = batch["images"]
# Случайный timestep
timesteps = torch.randint(0, len(noise_scheduler), (len(x),))
# Добавить шум к изображениям
noise = torch.randn_like(x)
noisy_x = noise_scheduler.add_noise(x, noise, timesteps)
# Предсказать шум
predicted_noise = model(noisy_x, timesteps).sample
# MSE loss между предсказанным и реальным шумом
loss = nn.MSELoss()(predicted_noise, noise)
optimizer.zero_grad()
loss.backward()
optimizer.step()
3. Условные генеративные модели
Class-conditional генерация
class ConditionalGenerator(nn.Module):
def __init__(self, latent_dim=100, num_classes=10):
super().__init__()
self.latent_dim = latent_dim
self.num_classes = num_classes
# Embedding для класса
self.class_embedding = nn.Embedding(num_classes, latent_dim)
# Основной генератор
self.fc = nn.Sequential(
nn.Linear(latent_dim * 2, 512), # latent_dim + embedded class
nn.ReLU(),
nn.Linear(512, 1024),
nn.ReLU(),
nn.Linear(1024, 28*28),
nn.Sigmoid()
)
def forward(self, z, class_label):
# z: (batch, latent_dim)
# class_label: (batch,) - индексы классов
class_embed = self.class_embedding(class_label) # (batch, latent_dim)
combined = torch.cat([z, class_embed], dim=1) # (batch, 2*latent_dim)
return self.fc(combined).view(-1, 1, 28, 28)
# Обучение с классами
for batch_idx, (real_imgs, labels) in enumerate(dataloader):
z = torch.randn(batch_size, latent_dim)
# Generate with class condition
fake_imgs = generator(z, labels)
# Дальше как обычный GAN, но с учётом класса
4. Sequence-to-Sequence модели
from transformers import MarianMTModel, MarianTokenizer
from torch.utils.data import Dataset, DataLoader
class TranslationDataset(Dataset):
def __init__(self, source_texts, target_texts, tokenizer):
self.source_texts = source_texts
self.target_texts = target_texts
self.tokenizer = tokenizer
def __getitem__(self, idx):
source = self.source_texts[idx]
target = self.target_texts[idx]
inputs = self.tokenizer(
source,
max_length=512,
truncation=True,
padding="max_length",
return_tensors="pt"
)
labels = self.tokenizer(
target,
max_length=512,
truncation=True,
padding="max_length",
return_tensors="pt"
)
return {
"input_ids": inputs["input_ids"].squeeze(),
"attention_mask": inputs["attention_mask"].squeeze(),
"labels": labels["input_ids"].squeeze(),
}
# Обучение Seq2Seq
model = MarianMTModel.from_pretrained("Helsinki-NLP/Opus-MT-en-ru")
training_args = TrainingArguments(
output_dir="./translation_model",
num_train_epochs=5,
per_device_train_batch_size=16,
learning_rate=5e-5,
save_total_limit=2,
evaluation_strategy="epoch",
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
)
trainer.train()
5. Практические вызовы при обучении
Проблема: Mode collapse в GAN
# Решение: Wasserstein loss вместо BCE
import torch.nn.functional as F
# Generator loss
g_loss = -torch.mean(discriminator(fake_imgs))
# Discriminator loss (with gradient penalty)
d_loss = (
-torch.mean(discriminator(real_imgs)) +
torch.mean(discriminator(fake_imgs.detach()))
)
# Gradient penalty
lambda_gp = 10
alphas = torch.rand(batch_size, 1, 1, 1)
interpolates = (alphas * real_imgs +
(1 - alphas) * fake_imgs).requires_grad_(True)
d_out = discriminator(interpolates)
gradients = torch.autograd.grad(
d_out.sum(), interpolates,
create_graph=True
)[0]
gradient_penalty = ((gradients.norm(2, dim=(1, 2, 3)) - 1) ** 2).mean()
d_loss += lambda_gp * gradient_penalty
Проблема: Нестабильное обучение диффузионных моделей
# Решение: Ema (Exponential Moving Average)
class EMA:
def __init__(self, beta=0.9999):
self.beta = beta
self.step = 0
def update_model_average(self, ma_model, current_model):
self.step += 1
if self.step < 20:
alpha = 1 - (1 - self.beta)
else:
alpha = self.beta
for current_params, ma_params in zip(
current_model.parameters(),
ma_model.parameters()
):
old_weight, up_weight = ma_params.data, current_params.data
ma_params.data = up_weight * alpha + old_weight * (1 - alpha)
# Использование
model_ema = copy.deepcopy(model)
ema = EMA()
for epoch in range(num_epochs):
# ... обучение ...
ema.update_model_average(model_ema, model)
6. Evaluation генеративных моделей
from pytorch_fid import fid_score
from torchvision.models import inception_v3
import numpy as np
# FID Score (Frechet Inception Distance) для изображений
fid_value = fid_score.calculate_fid_given_paths(
["path_to_real_images", "path_to_generated_images"],
batch_size=50,
device="cuda",
dims=2048
)
print(f"FID Score: {fid_value:.2f}") # Меньше - лучше
# BLEU Score для текста
from nltk.translate.bleu_score import sentence_bleu
reference = [["the", "cat", "sat", "on", "the", "mat"]]
candidate = ["the", "cat", "is", "on", "the", "mat"]
bleu = sentence_bleu(reference, candidate)
print(f"BLEU Score: {bleu:.3f}")
# Inception Score для изображений
def inception_score(generated_imgs):
model = inception_v3(pretrained=True).eval()
# Вычислить вероятности классов
# ...
Итоговый опыт
Я работал с:
- Текстовыми моделями: GPT, BERT, T5, LLaMA (fine-tuning и обучение с нуля)
- Образ-моделями: GAN, VAE, Diffusion models (обучение с нуля)
- Условными моделями: class-conditional GAN, text-to-image
- Архитектурами: Transformer, CNN, RNN, Attention mechanisms
- Оптимизацией: LoRA, QLoRA, gradient checkpointing, mixed precision
- Evaluation: FID, IS, BLEU, ROUGE, METEOR
Генеративные модели требуют глубокого понимания архитектур, loss функций и методов оптимизации — всё это я усвоил на практике через многочисленные проекты.