Серия «ml»

Пишем модель генерации изображений с нуля

Привет пикабушники!
Сегодня мы создадим и обучим модель инверсионной диффузии для генерации изображений.

Требования - python, conda/rocm, pytoch, torchvision matplotlib(для визуализации)

1 Скачайте и установите python, на GNU/Linux установите uv , а затем uv python install python3.12

2 Создайте и активируйте виртуальное окружение.
Что такое виртуальное окружение(venv)? venv это изолированная среда python для установки зависимостей

1 Вариант (для uv, очень простой)
uv venv .venv --python python3.12, выполните команду, которую выдаст uv,
установка зависимостей в окружении uv pip install datasets torch torchvision matplotlib (для cpu, для gpu ниже).
Внимание!! Вам нужна особая команда для установки torch с поддержкой gpu.
Полный список здесь -
uv pip install torch torchvision --index-url https://download.pytorch.org/whl/cu128, это для nvidia
uv pip install torch torchvision --index-url https://download.pytorch.org/whl/rocm6.4 amd rocm(только на GNU/Linux).

2 Вариант для python venv.

На винде - py -3.12 -m venv .venv, дальнейшие этапы аналогичные, только команды для установки зависимостей без uv, просто pip.
3 Этап создайте файл, назовите его как хотите, но с расширением py , например model.py.
Скопируйте туда данный код, запустите через python вашфайл.py и начнется скачивание mnist датасет с рукописными цифрами и затем обучение в 20 эпох.

Если у вас слабый gpu или его нет, то, к сожалению, ждать нужно будет очень долго.
С gpu +- час - 2 часа. В результате у вас отобразится результат генерации, а также поле для ввода цифры, чтобы сгенерировать. Чем больше эпох при обучении, тем лучше результат. Но не стоит ставить огромные значения, модель может переобучиться.

Для тех у кого нет gpu можете загрузить пред обученную модель с моего гитхаба.

Пишем модель генерации изображений с нуля Программирование, Python, Машинное обучение, Длиннопост


Как это работает и что это такое

Это условная диффузионная модель (Conditional Diffusion Model), которая генерирует изображения цифр MNIST (0–9) с контролем над классом (например, можно запросить генерацию именно цифры "5"). Модель сочетает:

  1. Диффузионный процесс — постепенное добавление/удаление шума.

  2. Условную генерацию — зависимость от целевого класса (цифры).

  3. Архитектуру U-Net — для обработки изображений на разных уровнях детализации.


Как это работает?

1. Прямой диффузионный процесс (заражение шумом)

  • Цель: Постепенно превратить изображение в случайный шум за T=1000 шагов.

  • Математика:

    xt=αˉt

⋅x0+1−αˉt

  • ⋅ϵ

    где:

    • x0 — исходное изображение,

    • ϵ — случайный шум (Gaussian noise),

    • αˉt=∏s=1t(1−βs) — кумулятивное произведение коэффициентов "чистоты" сигнала.

  • В коде:

    python

  • 1

    2

    3

    4

    def forward_diffusion(self, x0, t):

    noise = torch.randn_like(x0)

    xt = sqrt_alphas_cumprod[t] * x0 + sqrt_one_minus_alphas_cumprod[t] * noise

    return xt, noise

2. Обратный процесс (генерация из шума)

  • Цель: Восстановить изображение из шума, шаг за шагом уменьшая шум.

  • Как учится модель?
    На каждом шаге t модель предсказывает шум ϵθ(xt,t,y) , где y — целевой класс (цифра).

    Функция потерь: MSE между предсказанным и реальным шумом:

    L=Ex0,ϵ,t[∥ϵ−ϵθ(xt,t,y)∥2]

  • В коде:

    def forward_diffusion(self, x0, t):

    noise = torch.randn_like(x0)

    xt = sqrt_alphas_cumprod[t] * x0 + sqrt_one_minus_alphas_cumprod[t] * noise

    return xt, noise

  • 1

    2

    noise_pred = self.model(xt, t, y) # Предсказание шума

    loss = F.mse_loss(noise_pred, noise) # Расчет потерь

3. Условная генерация (ключевая особенность)

Модель генерирует изображение конкретного класса (например, цифру "7") благодаря:

  • Встраиванию класса:

    • Класс y преобразуется в эмбеддинг через nn.Embedding(num_classes, class_emb_dim).

    • Эмбеддинг проходит через MLP для нелинейного преобразования.

  • Интеграция в U-Net:

    • В каждом блоке U-Net информация о классе добавляется к промежуточным активациям:

      noise_pred = self.model(xt, t, y) # Предсказание шума

      loss = F.mse_loss(noise_pred, noise) # Расчет потерь

  • 1

    h = h + t_emb[..., None, None] + c_emb[..., None, None]

    • Это позволяет модели адаптировать обработку изображения под целевую цифру.

4. Архитектура модели: Условный U-Net

  • Структура:

    • Downsampling: 2 уровня уменьшения размерности (с сохранением skip-соединений).

    • Bottleneck: Обработка на низком разрешении.

    • Upsampling: 2 уровня увеличения размерности (с использованием skip-соединений).

  • Особенности:

    • Позиционное кодирование времени: timestep_embedding преобразует шаг t в вектор, чтобы модель "понимала", на каком этапе диффузии она работает.

    • Групповая нормализация (GroupNorm): Улучшает стабильность обучения.

    • SiLU активации: Нелинейность, улучшающая градиентный поток.


Этапы работы модели

1. Обучение

  1. Загружаем данные MNIST (нормализованные в диапазон [-1, 1]).

  2. Для каждого батча:

    • Случайно выбираем шаг диффузии t∈[0,T−1] .

    • Добавляем шум к изображению: xt=f(x0,t) .

    • Модель предсказывает шум ϵθ(xt,t,y) .

    • Обновляем веса через MSE-потерю.

  3. Каждую эпоху генерируем образцы для всех классов (0–9) и сохраняем их.

2. Генерация (сэмплирование)

  1. Начинаем с случайного шума xT∼N(0,I) .

  2. Итеративно уменьшаем шум от t=T−1 до t=0 :

    • Предсказываем шум ϵθ(xt,t,y) .

    • Обновляем изображение:

      xt−1=αt

1(xt−1−αˉt

Показать полностью 1

Делаем свою простую nlp модель с нуля на pytorch для оценки отзывов

Привет, пикабушники!
Сегодня мы с вами напишем и обучим простую модель обработки языка на архитектуре трансформеров.

Что потребуется:
python, рекомендую 3.12, cuda/rocm (желательно), torch, datasets.

Для установки зависимостей можете использовать uv или pip.
Установка:

1 Скачайте и установите python

2 Создайте и активируйте виртуальное окружение.
Что такое виртуальное окружение(venv)? venv это изолированная среда python для установки зависимостей

1 Вариант (для uv, очень простой)
uv venv .venv --python python3.12, выполните команду которую выдаст uv,
установка зависимостей в окружении uv pip install datasets torch(для cpu, для gpu ниже).
Внимание!! Вам нужна особая команда для установки torch с поддержкой gpu.
Полный список здесь -
uv pip install torch torchvision --index-url https://download.pytorch.org/whl/cu128, это для nvidia
uv pip install torch torchvision --index-url https://download.pytorch.org/whl/rocm6.4 amd rocm(только на GNU/Linux).
2 Вариант для python venv.

На винде - py -3.12 -m venv .venv, дальнейшие этапы аналогичные, только команды для установки зависимостей без uv ,просто pip.
3 Этап создайте файл, назовите его как хотите, но с расширением py , например nlp.py.
Скопируйте туда данный код, замените в нём отзывы на свои. Модель простая и понимает только англ язык. При первом запуске скачается датасет и начнётся обучение в 5 эпох, с gpu будет раз в 10 быстрее, запуск через python вашфайл.py, это нужно делать в окружении.

Как это работает?

Этот код реализует бинарную классификацию отзывов из датасета IMDB (положительный/отрицательный) с использованием упрощенной архитектуры трансформера. Вот ключевые аспекты работы модели:


1. Подготовка данных (пред обработка)

  • Датасет: Используется IMDB (50k отзывов, разделенных на 25k обучающих и 25k тестовых примеров).

  • Словарь:

    • Строится на основе 10,000 самых частых слов из обучающих данных.

    • Добавлены специальные токены: <pad> (0), <unk> (1), <sos> (начало последовательности, 2), <eos> (конец, 3).

    • Редкие слова заменяются на <unk>.

  • Векторизация:

    • Каждый отзыв преобразуется в последовательность индексов.

    • Добавляются токены <sos> в начало и <eos> в конец.

    • Пример: "good film" → [2, "good", "film", 3].


2. Архитектура модели

Модель SimpleTransformerClassifier состоит из:

a) Эмбеддинг и позиционное кодирование

  • Токеновые эмбеддинги: nn.Embedding(vocab_size, embedding_dim)

  • Позиционное кодирование:

    • Добавляет информацию о позиции токена через синусоидальные функции.

    • Реализовано как PositionalEncoding с фиксированными весами (не обучаемое).

b) Трансформерные слои (2 уровня)

Каждый слой включает:

  1. Многоголовое внимание:

    • nn.MultiheadAttention с 4 головами.

    • Использует маску паддинга (key_padding_mask), чтобы игнорировать заполнение.

    • Выход объединяется с исходными данными через residual connection.

  2. Нормализация и dropout:

    • Слой нормализации LayerNorm и dropout (10%) для регуляризации.

  3. Позиционно-зависимая Feed-Forward сеть:

    • Два линейных слоя с ReLU и dropout между ними.

    • Также использует residual connection.

c) Классификация

  • Для принятия решения используется только первый токен (<sos>, позиция x[:, 0, :]).

  • Выход проходит через:

    • Линейный слой → Sigmoid → вероятность положительного отзыва.

  • Почему <sos>? Аналогично токену [CLS] в BERT: модель обучается агрегировать информацию всей последовательности в одном векторе.


3. Обработка переменной длины

  • Паддинг:

    • Последовательности в батче выравниваются до максимальной длины с помощью pad_sequence.

    • Заполнение обозначается индексом 0 (<pad>).

  • Маска паддинга:

    • Генерируется в collate_fn как (padded == 0).

    • Передается в MultiheadAttention через key_padding_mask, чтобы модель игнорировала заполнение при вычислении внимания.


4. Обучение

  • Гиперпараметры:

    • Batch size: 16 (маленький из-за длинных последовательностей).

    • Оптимизатор: Adam (lr=0.0001).

    • Функция потерь: BCELoss (бинарная кросс-энтропия).

    • Обрезка градиентов: clip_grad_norm_(max_norm=0.5) для стабильности.

  • Особенности:

    • Эмбеддинги масштабируются на √embedding_dim (как в оригинальном трансформере).

    • Используется dropout (10%) на всех этапах для борьбы с переобучением.


5. Оценка и анализ

  • Метрика: Accuracy (доля правильных предсказаний).

  • Диагностика:

    • Вывод примеров с высокой/низкой уверенностью.

    • Анализ ошибок: показывает тексты, где модель ошиблась (например, ирония или сложные формулировки).

  • Пользовательские тесты:

    • Функция predict_sentiment позволяет проверить модель на новых отзывах.

    • Уверенность рассчитывается как max(output, 1-output).

      А на этом всё

Показать полностью
Отличная работа, все прочитано!