Творческий потенциал нормализующих потоков в генеративном искусственном интеллекте

Творческий потенциал нормализующих потоков в ГИИ

Введение

Генеративное искусственное интеллекта (AI), с его замечательной способностью создавать данные, которые тесно напоминают реальные примеры, привлекло значительное внимание в последние годы. В то время как модели, такие как GAN и VAE, захватили внимание, малоизвестный «Нормализующий поток» в генеративном AI тихо переформатировал ландшафт генеративного моделирования.

В этой статье мы отправляемся в путешествие в мир Нормализующих потоков, исследуя их уникальные особенности и применения, а также предоставляя практические примеры на Python для разъяснения их внутреннего устройства. В этой статье мы узнаем о следующем:

  • Основное понимание Нормализующих потоков.
  • Применение Нормализующих потоков, таких как оценка плотности, генерация данных, вариационное внесение поправок и аугментация данных.
  • Пример кода на Python для понимания Нормализующих потоков.
  • Понимание класса аффинных преобразований.

Эта статья была опубликована как часть блогона по науке о данных.

Раскрытие Нормализующих потоков

Нормализующие потоки, часто сокращенно обозначаемые как NF, являются генеративными моделями, которые справляются с задачей выборки из сложных вероятностных распределений. Они основаны на концепции изменения переменных из теории вероятности. Основная идея заключается в том, чтобы начать с простого вероятностного распределения, такого как гауссовское, и применять серию инъективных (обратимых) преобразований для его постепенного преобразования в желаемое сложное распределение.

Основной отличительной чертой Нормализующих потоков является их обратимость. Каждое преобразование, применяемое к данным, может быть обращено, что обеспечивает возможность как выборки, так и оценки плотности. Это свойство отличает их от многих других генеративных моделей.

Анатомия Нормализующего потока

  • Базовое распределение: Простое вероятностное распределение (например, гауссовское), из которого начинается выборка.
  • Преобразования: Серия биективных (обратимых) преобразований, постепенно модифицирующих базовое распределение.
  • Обратные преобразования: Каждое преобразование имеет обратное преобразование, позволяющее генерировать данные и оценивать правдоподобие.
  • Итоговое сложное распределение: Композиция преобразований приводит к сложному распределению, которое тесно соответствует целевому распределению данных.

Применения Нормализующих потоков

  1. Оценка плотности: Нормализующие потоки прекрасно справляются с оценкой плотности. Они могут точно моделировать сложные распределения данных, что делает их ценными для обнаружения аномалий и оценки неопределенности.
  2. Генерация данных: NF могут генерировать выборки данных, которые тесно напоминают реальные данные. Эта способность является важной в приложениях, таких как генерация изображений, генерация текста и композиция музыки.
  3. Вариационное внесение поправок: Нормализующие потоки играют важную роль в байесовском машинном обучении, особенно в вариационных автоэнкодерах (VAE). Они позволяют более гибкие и выразительные аппроксимации апостериорных распределений.
  4. Аугментация данных: NF могут дополнять наборы данных, генерируя синтетические выборки, что полезно, когда данных мало.

Давайте погрузимся в Python: Реализация Нормализующего потока

Мы реализуем простой одномерный Нормализующий поток с использованием Python и библиотеки PyTorch. В этом примере мы сосредоточимся на преобразовании гауссовского распределения в более сложное распределение.

import torch
import torch.nn as nn
import torch.optim as optim

# Определение инъективного преобразования
class AffineTransformation(nn.Module):
    def __init__(self):
        super(AffineTransformation, self).__init__()
        self.scale = nn.Parameter(torch.Tensor(1))
        self.shift = nn.Parameter(torch.Tensor(1))
    
    def forward(self, x):
        return self.scale * x + self.shift, torch.log(self.scale)

# Создание последовательности преобразований
transformations = [AffineTransformation() for _ in range(5)]
flow = nn.Sequential(*transformations)

# Определение базового распределения (гауссовского)
base_distribution = torch.distributions.Normal(0, 1)

# Выборка из сложного распределения
samples = flow(base_distribution.sample((1000,))).squeeze()

Используемые библиотеки

  1. torch: Эта библиотека – PyTorch, популярный фреймворк глубокого обучения. Он предоставляет инструменты и модули для создания и обучения нейронных сетей. В коде мы используем ее для определения модулей нейронной сети, создания тензоров и эффективного выполнения различных математических операций над тензорами.
  2. torch.nn: Этот подмодуль PyTorch содержит классы и функции для создания нейронных сетей. В коде мы используем его для определения класса nn.Module, который служит базовым классом для создания пользовательских модулей нейронной сети.
  3. torch.optim: Этот подмодуль PyTorch содержит оптимизационные алгоритмы, обычно используемые для обучения нейронных сетей. В коде он используется для определения оптимизатора для обучения параметров модуля AffineTransformation. Однако, предоставленный мной код не содержит явной настройки оптимизатора.

Класс AffineTransformation

Класс AffineTransformation – это пользовательский модуль PyTorch, представляющий один шаг в последовательности преобразований, используемых в нормализующем потоке. Разберем его составляющие:

  • nn.Module: Этот класс является базовым классом для всех пользовательских модулей нейронных сетей в PyTorch. Путем наследования от nn.Module AffineTransformation сам становится модулем PyTorch и может содержать обучаемые параметры (например, self.scale и self.shift) и определять операцию прямого прохода.
  • __init__(self): Метод-конструктор класса. При создании экземпляра AffineTransformation он инициализирует два обучаемых параметра: self.scale и self.shift. Эти параметры будут оптимизироваться во время обучения.
  • self.scale и self.shift: Это объекты PyTorch nn.Parameter. Параметры – это тензоры, автоматически отслеживаемые автоградом PyTorch, что делает их подходящими для оптимизации. Здесь self.scale и self.shift представляют масштабирование и сдвиг, применяемые к входу x.
  • forward(self, x): Этот метод определяет прямой проход модуля. Когда вы передаете входной тензор x экземпляру AffineTransformation, он вычисляет преобразование с помощью аффинной операции self.scale * x + self.shift. Кроме того, он возвращает логарифм self.scale. Логарифм используется, потому что он обеспечивает положительность self.scale, что важно для обратимости в нормализующих потоках.

В контексте генеративного искусственного интеллекта в нормализующем потоке этот класс AffineTransformation представляет простое обратимое преобразование, применяемое к данным. Каждый шаг в потоке состоит из таких преобразований, которые совместно изменяют вероятностное распределение от простого (например, гауссовского) к более сложному, более точно соответствующему целевому распределению данных. Эти преобразования, когда они объединяются, позволяют гибкую оценку плотности и генерацию данных.

# Создание последовательности преобразований
transformations = [AffineTransformation() for _ in range(5)]
flow = nn.Sequential(*transformations)

В приведенном выше коде мы создаем последовательность преобразований, используя класс AffineTransformation. Эта последовательность представляет серию обратимых преобразований, которые будут применяться к нашему базовому распределению для его усложнения.

Что происходит?

Вот что происходит:

  • Мы инициализируем пустой список с именем transformations.
  • Мы используем генератор списка (list comprehension) для создания последовательности экземпляров класса AffineTransformation. Конструкция [AffineTransformation() for _ in range(5)] создает список, содержащий пять экземпляров класса AffineTransformation. Эти преобразования применяются последовательно к нашим данным.
# Определение базового распределения (гауссовского)
base_distribution = torch.distributions.Normal(0, 1)

Здесь мы определяем базовое распределение как отправную точку. В данном случае мы используем гауссовское распределение с математическим ожиданием 0 и стандартным отклонением 1 (т.е. стандартное нормальное распределение). Это распределение представляет простое вероятностное распределение, от которого мы начинаем нашу последовательность преобразований.

# Генерация данных из сложного распределения
samples = flow(base_distribution.sample((1000,))).squeeze()

Этот раздел включает выборку данных из сложного распределения, которое получается в результате применения нашей последовательности преобразований к базовому распределению. Разберем это подробнее:

  • base_distribution.sample((1000,)): Мы используем метод sample объекта base_distribution для генерации 1000 выборок из базового распределения. Последовательность преобразований преобразует эти выборки, чтобы создать сложные данные.
  • flow(…): Объект flow представляет последовательность преобразований, которую мы создали ранее. Мы применяем эти преобразования последовательно, передавая выборки из базового распределения через поток.
  • squeeze(): Это удаляет ненужные измерения из сгенерированных выборок. Люди часто используют его при работе с тензорами PyTorch, чтобы убедиться, что форма соответствует требуемому формату.

Заключение

NFs – это генеративные модели, которые формируют сложные распределения данных, постепенно преобразуя простое базовое распределение через серию инвертируемых операций. В статье рассматриваются основные компоненты NFs, включая базовые распределения, биективные преобразования и инвертируемость, лежащую в их основе. Она подчеркивает их важную роль в оценке плотности, генерации данных, вариационном выводе и увеличении данных.

Основные выводы

Основные выводы из статьи:

  1. Нормализующие потоки – это генеративные модели, которые преобразуют простое базовое распределение в сложное целевое распределение через серию инвертируемых преобразований.
  2. Они находят применение в оценке плотности, генерации данных, вариационном выводе и увеличении данных.
  3. Нормализующие потоки обладают гибкостью и интерпретируемостью, что делает их мощным инструментом для описания сложных распределений данных.
  4. Реализация нормализующего потока включает определение биективных преобразований и последовательное их компонование.
  5. Исследование нормализующих потоков раскрывает универсальный подход к генеративному моделированию, предлагающий новые возможности для творчества и понимания сложных распределений данных.

Часто задаваемые вопросы

Медиа, показанное в этой статье, не принадлежит Analytics Vidhya и используется по усмотрению автора.