Pomegranate — библиотека Python для создания вероятностных моделей, таких как байесовские сети или марковские модели

МЕНЮ


Главная страница
Поиск
Регистрация на сайте
Помощь проекту
Архив новостей

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


Pomegranate — это библиотека для вероятностного моделирования, определяемая ее модульной реализацией и трактовкой всех моделей как распределений вероятностей, которыми они являются. Модульная реализация позволяет легко добавлять нормальное распределение в модель смеси для создания модели гауссовой смеси так же легко, как добавлять гамма-распределение и распределение Пуассона в модель смеси для создания гетерогенной смеси. Но это не все! Поскольку каждая модель рассматривается как распределение вероятностей, байесовские сети можно объединить в смесь так же легко, как и нормальное распределение, а скрытые модели Маркова можно добавить в классификаторы Байеса, чтобы создать классификатор последовательностей. Вместе эти два варианта проектирования обеспечивают гибкость, не встречающуюся ни в одном другом пакете вероятностного моделирования.

Недавно Pomegranate (v1.0.0) был переписан с нуля с использованием PyTorch, чтобы заменить устаревший бэкэнд Cython. Эта переработка дала мне возможность исправить многие неудачные дизайнерские решения, которые я сделал, будучи инженером-программистом. К сожалению, многие из этих изменений не имеют обратной совместимости и нарушат рабочие процессы. С другой стороны, эти изменения значительно ускорили работу большинства методов, улучшили и упростили код, исправили многие проблемы, поднимавшиеся сообществом на протяжении многих лет, и значительно облегчили внесение вклада. Я написал больше ниже, но вы, вероятно, сейчас здесь, потому что ваш код не работает, и это ошибка.

Особая благодарность NumFOCUS за поддержку этой работы специальным грантом на развитие.

Монтаж

pip install pomegranate

Если вам нужна последняя версия Cython перед перезаписью, используйте pip install pomegranate==0.14.8. Возможно, вам придется вручную установить версию Cython до версии v3.

Зачем переписывать?

Это переписывание было мотивировано четырьмя основными причинами:

  • Скорость : собственный PyTorch обычно значительно быстрее, чем код Cython, настроенный вручную, который я написал.
  • Особенности : PyTorch имеет множество функций, таких как сериализация, смешанная точность и поддержка графического процессора, которые теперь можно напрямую использовать в Pomegranate без дополнительной работы с моей стороны.
  • Вклад сообщества : Проблема, с которой столкнулись многие люди при использовании граната, заключалась в том, что они не могли изменить или расширить его, потому что не знали Cython. Даже если бы они знали Cython, кодирование на нем — это боль, которую я чувствовал каждый раз, когда пытался добавить новую функцию, исправить ошибку или выпустить новую версию. Использование PyTorch в качестве бэкэнда значительно сокращает количество усилий, необходимых для добавления новых функций.
  • Совместимость : такие библиотеки, как PyTorch, предлагают бесценную возможность не просто использовать свои вычислительные серверные части, но и лучше интегрироваться в существующие ресурсы и сообщества. Эта переработка облегчит людям интеграцию вероятностных моделей с нейронными сетями, такими как потери, ограничения и структурные регуляризации, а также с другими проектами, построенными на PyTorch.

Изменения высокого уровня

  1. Общий
  • Вся кодовая база была переписана в PyTorch, и все модели являются экземплярамиtorch.nn.Module
  • Эта база кода проверяется комплексным набором из более чем 800 модульных тестов, вызывающих утверждения утверждения несколько тысяч раз, что намного больше, чем в предыдущих версиях.
  • Проблемы с установкой теперь, скорее всего, возникают из-за PyTorch, для решения которого существует бесчисленное множество ресурсов.
  1. Функции
  • Все модели теперь имеют поддержку графического процессора.
  • Все модели теперь поддерживают половинную/смешанную точность.
  • Сериализация теперь обрабатывается PyTorch, что обеспечивает более компактный и эффективный ввод-вывод.
  • Отсутствующие значения теперь поддерживаются через torch.masked.MaskedTensorобъекты.
  • Априорные вероятности теперь можно передавать во все соответствующие модели и методы, что обеспечивает более комплексное/гибкое полуконтролируемое обучение, чем раньше.
  1. Модели
  • Все дистрибутивы теперь по умолчанию являются многовариантными и обрабатывают каждую функцию независимо (кроме обычного).
  • Из названий убрано слово «Распространение», так что, например, NormalDistributionтеперьNormal
  • FactorGraphтеперь поддерживается как первоклассный гражданин со всеми методами прогнозирования и обучения.
  • Скрытые марковские модели были разделены на DenseHMMмодели SparseHMM, которые отличаются способом кодирования матрицы перехода, при этом DenseHMMобъекты работают значительно быстрее на действительно плотных графах.
  1. Различия
  • NaiveBayesбыл окончательно удален, так как он является избыточным дляBayesClassifier
  • MarkovNetworkеще не реализовано
  • Графы ограничений и обучение структур с ограничениями для байесовских сетей еще не реализованы.
  • Тихие состояния для скрытых марковских моделей еще не реализованы.
  • Витерби для скрытых марковских моделей еще не реализован.

Скорость

Большинство моделей и методов в Pomegranate v1.0.0 работают быстрее, чем их аналоги в более ранних версиях. Обычно это масштабируется по сложности: наблюдается лишь небольшое ускорение для простых распределений на небольших наборах данных, но гораздо большее ускорение для более сложных моделей на больших наборах данных, например, обучение скрытой марковской модели или вывод байесовской сети. Заметным исключением на данный момент является то, что обучение структуре байесовской сети, за исключением построения дерева Чоу-Лю, все еще не завершено и не намного быстрее. В примерах ниже torchegranateотносится к временному репозиторию, использованному для разработки Pomegranate v1.0.0, и pomegranateотносится к Pomegranate v0.14.8.

K-средние

Кто знает, что здесь происходит? Дикий.

изображение

Скрытые марковские модели

Плотная матрица перехода (ЦП)

изображение

Разреженная матрица перехода (ЦП)

изображение

Обучение модели из 125 узлов с плотной матрицей перехода

изображение

Байесовские сети

изображение
изображение

Функции

Примечание. Примеры кода см. в папке с учебными пособиями .

Переход с бэкэнда Cython на бэкэнд PyTorch включил или расширил большое количество функций. Поскольку перезапись представляет собой тонкую оболочку над PyTorch, по мере выпуска новых функций для PyTorch их можно применять к моделям граната без необходимости получения от меня новой версии.

Поддержка графического процессора

Все дистрибутивы и методы в Pomegranate теперь поддерживают графический процессор. Поскольку каждый дистрибутив является torch.nn.Moduleобъектом, его использование идентично другому коду, написанному на PyTorch. Это означает, что пользователь должен перенести и модель, и данные на графический процессор. Например:

>>> X = torch.exp(torch.randn(50, 4))  # Will execute on the CPU >>> d = Exponential().fit(X) >>> d.scales Parameter containing: tensor([1.8627, 1.3132, 1.7187, 1.4957])  # Will execute on a GPU >>> d = Exponential().cuda().fit(X.cuda()) >>> d.scales Parameter containing: tensor([1.8627, 1.3132, 1.7187, 1.4957], device='cuda:0')

Аналогично, все модели являются дистрибутивами и поэтому могут аналогичным образом использоваться на графическом процессоре. Когда модель перемещается в графический процессор, все связанные с ней модели (например, распределения) также перемещаются в графический процессор.

>>> X = torch.exp(torch.randn(50, 4)).cuda() >>> model = GeneralMixtureModel([Exponential(), Exponential()]).cuda() >>> model.fit(X) [1] Improvement: 1.26068115234375, Time: 0.001134s [2] Improvement: 0.168121337890625, Time: 0.001097s [3] Improvement: 0.037841796875, Time: 0.001095s >>> model.distributions[0].scales Parameter containing: >>> model.distributions[1].scales tensor([0.9141, 1.0835, 2.7503, 2.2475], device='cuda:0') Parameter containing: tensor([1.9902, 2.3871, 0.8984, 1.2215], device='cuda:0')

Смешанная точность

Модели граната теоретически могут работать в тех же смешанных или низкоточных режимах, что и другие модули PyTorch. Однако, поскольку гранат использует более сложные операции, чем большинство нейронных сетей, это иногда не работает или не помогает на практике, поскольку эти операции не были оптимизированы или реализованы в режиме низкой точности. Итак, надеемся, что со временем эта функция станет более полезной.

>>> X = torch.randn(100, 4) >>> d = Normal(covariance_type='diag') >>> >>> with torch.autocast('cuda', dtype=torch.bfloat16): >>>     d.fit(X)

Сериализация

Все дистрибутивы граната являются экземплярами torch.nn.Module, поэтому сериализация такая же, как и любая другая модель PyTorch.

Сохранение:

>>> X = torch.exp(torch.randn(50, 4)).cuda() >>> model = GeneralMixtureModel([Exponential(), Exponential()], verbose=True) >>> model.cuda() >>> model.fit(X) >>> torch.save(model, "test.torch")

Загрузка:

>>> model = torch.load("test.torch")

факел.компилировать

Примечание torch.compile находится в стадии активной разработки командой PyTorch и может быстро улучшиться. На данный момент вам может потребоваться передать его check_data=Falseпри инициализации моделей, чтобы избежать проблем с совместимостью.

В PyTorch v2.0.0 torch.compileон был представлен как гибкая оболочка инструментов, которые объединяли операции, использовали графики CUDA и в целом пытались устранить узкие места ввода-вывода при выполнении графического процессора. Поскольку эти узкие места могут быть чрезвычайно существенными при настройке данных малого и среднего размера, с которыми сталкиваются многие пользователи граната, torch.compileпохоже, что это будет чрезвычайно ценно. Вместо того, чтобы ориентироваться на целые модели, которые в основном просто компилируют метод forward, вам следует компилировать отдельные методы из ваших объектов.

# Create your object as normal >>> mu = torch.exp(torch.randn(100)) >>> d = Exponential(mu).cuda()  # Create some data >>> X = torch.exp(torch.randn(1000, 100)) >>> d.log_probability(X)  # Compile the `log_probability` method! >>> d.log_probability = torch.compile(d.log_probability, mode='reduce-overhead', fullgraph=True) >>> d.log_probability(X)

К сожалению, мне было трудно приступить torch.compileк работе, когда методы вызываются вложенным образом, например, при компиляции метода predictдля модели смеси, которая внутри себя вызывает log_probabilityметод каждого распределения. Я пытался организовать код таким образом, чтобы избежать некоторых из этих ошибок, но поскольку сообщения об ошибках сейчас непрозрачны, у меня возникли некоторые трудности.

Отсутствующие значения

гранат поддерживает обработку данных с пропущенными значениями через torch.masked.MaskedTensorобъекты. Проще говоря, нужно просто наложить маску на отсутствующие значения.

>>> X = <your tensor with NaN for the missing values> >>> mask = ~torch.isnan(X) >>> X_masked = torch.masked.MaskedTensor(X, mask=mask) >>> d = Normal(covariance_type='diag').fit(X_masked) >>> d.means Parameter containing: tensor([0.2271, 0.0290, 0.0763, 0.0135])

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

Поскольку для MaskedTensors пока доступны не все операции, для отсутствующих значений пока не поддерживаются следующие распределения: Бернулли, категориальное, нормальное с полной ковариацией, равномерное.

Априорные вероятности и полуконтролируемое обучение

Новой функцией граната v1.0.0 является возможность передавать априорные вероятности для каждого наблюдения для моделей смеси, классификаторов Байеса и скрытых моделей Маркова. Это априорная вероятность того, что наблюдение принадлежит компоненту модели до оценки вероятности, и она должна находиться в диапазоне от 0 до 1. Когда эти значения включают 1,0 для наблюдения, оно рассматривается как метка, поскольку вероятность больше не имеет значения. с точки зрения присвоения этого наблюдения состоянию. Следовательно, можно использовать эти априорные вероятности для помеченного обучения, когда каждое наблюдение имеет значение 1,0 для некоторого состояния, полуконтролируемого обучения, когда подмножество наблюдений (в том числе когда последовательности помечены лишь частично для скрытых марковских моделей) или для более сложных форм взвешивание, когда значения находятся между 0 и 1.

изображение

О


Источник: github.com

Комментарии: