Skip to content

refactor(riemann): update embedding extractor pipeline#259

Merged
v1docq merged 6 commits into
mainfrom
riemann_topology
Jul 20, 2026
Merged

refactor(riemann): update embedding extractor pipeline#259
v1docq merged 6 commits into
mainfrom
riemann_topology

Conversation

@Nikikir30

@Nikikir30 Nikikir30 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Сделаны TRE-101 -- TRE-103 и подготовлена ветка к вливанию в актуальную main после KL/PDL merge.

Связанные issues:

Что изменено

  • Полностью переработан RiemannExtractor в fedot_ind/core/operation/transformation/representation/manifold/riemann_embeding.py:

    • поддержаны стратегии tangent, mdm, ensemble;
    • добавлена строгая проверка параметров estimator, SPD_metric, tangent_metric, centroid_strategy, centroid_type;
    • добавлены предупреждения для методологических конфликтов: tangent + class-wise, tangent + median, одномерный вход;
    • параметры операции попадают в logging_params и diagnostics генератора.
  • Riemann generator подключен к новой KL-архитектуре main:

    • riemann_spec() живет в fedot_ind/core/kernel_learning/generators/specs.py;
    • регистрация riemann_extractor живет в fedot_ind/core/kernel_learning/generators/registry.py;
    • fedot_ind/core/kernel_learning/generators/adapters.py остается коротким public index, без возврата старого monolithic-кода.
  • Отработано главное замечание из ревью:

    • spec использует допустимые значения: centroid_strategy="global", centroid_type="mean", extraction_strategy="tangent";
    • добавлена проверка основного registry-пути: для малого входа diagnostics source == "fedot_industrial_operation", fallback не включается.
  • Обновлен топологический контур:

    • PointCloudBuilder и PersistenceDiagramsExtractor поддерживают батчевый 3D-вход и стратегии independent/joint;
    • TopologicalExtractor переведен на новый pipeline point-cloud -> persistence diagrams -> topological features;
    • TopologicalRidgeForecaster обновлен под новый контур.
  • Дополнительная подготовка к main:

    • ripserplusplus сделан ленивой optional-зависимостью: модуль импортируется без него, ошибка возникает только при явном backend="ripser++";
    • gtda-путь использует n_jobs=1 для стабильных локальных и CI smoke-тестов на Windows/sandbox;
    • OperationParameters теперь создается через keyword-аргументы;
    • kernel feature adapters поддерживают task_type="ts_forecasting";
    • diagnostics включают source, budget, operation specs и фактически разрешенные operation logging params;
    • исправлен mutable default в TopologicalRidgeForecaster через default_factory.

Что сознательно не закрывается этим PR

Сравнительный benchmark новых римановых признаков против статистических, топологических и baseline-извлекателей не входит в этот merge как блокер. Это лучше вынести в отдельный сравнительный набор перед TRE_SCI-101 -- TRE_SCI-104: датасеты UCR/многомерные задачи, качество, время, память и доля fallback.

GPU-переход топологических признаков также не должен начинаться с прямой замены на одну библиотеку. Для этого нужен отдельный слой: вычислитель диаграмм -> преобразователь диаграмм в признаки -> extractor/forecaster.

Проверки

Локально в venv_3.9_new:

PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python -m pytest \
  tests/unit/core/kernel_learning/test_generators.py \
  tests/unit/core/operation/transformation/representation/test_riemann_embeding.py \
  tests/unit/core/operation/transformation/representation/test_topological_extractor.py \
  tests/unit/core/models/test_lagged_forecaster.py

Результат: 67 passed.

Также пройдены:

  • autopep8 --diff --exit-code по измененным Python-файлам;
  • py_compile по измененным Python-файлам с PYTHONPYCACHEPREFIX во временной папке;
  • git diff --check.

@v1docq

v1docq commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Надо доработать несколько моментов.

Главное исправление: сделать _riemann_spec() допустимой и добавить небольшую проверку пути через реестр по умолчанию: для обычного малого входа diagnostics["source"] должен быть равен "fedot_industrial_operation", а запасной путь не должен включаться. Извлекатель признаков нельзя считать проверенным только по конечным числам на выходе, если запасной путь удовлетворяет тем же утверждениям.

Главные замечания по самому коду:

  1. неверное значение centroid_strategy="riemann" в _riemann_spec() и проверки, которые могут пройти через запасной путь, все еще нужно исправить до слияния.

  2. Сейчас нет сравнения с уже имеющимися топологическими, статистическими и обычными извлекателями, а также нет условия, при котором новый извлекатель оправдывает усложнение. Я бы перенес эти доработки из разряда прямого замечания перед мерджем в разряд входного условия перед TRE_SCI-101 - TRE_SCI-104. То есть текущие изменения это подготовка "механики", но следующие концептуальные улучшения римановых вложений нельзя начинать без зафиксированного набора сравнительных проверок.

  3. Я бы завел отдельную задачу: «Сравнительный набор для римановых признаков». В ней закрепить:
    3.1. Наборы данных: несколько задач классификации временных рядов, отдельно короткие/длинные, одномерные/многомерные, малые/средние. По датасетам имеет смысл брать UCR набор можешь проконсультроваться с Ромой Кукло у него есть готовый модуль для бенчмаркинга.
    3.2 Признаки: текущие статистические, топологические, старые римановы, новые римановы варианты tangent, mdm, ensemble;
    3.3 Модели: простая линейная модель, лес, опорные векторы или ближайшие соседи, плюс один обычный путь через Industrial;
    3.4. Показатели: качество, время вычисления признаков, память, число переходов на запасной путь;
    3.5. Правило успеха: не «где-то стало лучше», а, например, «не хуже простой опоры на большинстве наборов и лучше хотя бы на N задачах при приемлемой цене вычислений».

  4. По переходу топологических признаков на GPU. Из того, что сейчас выглядит практически применимым:
    4.1. Ripser++ - главный кандидат именно для вычисления диаграмм Vietoris-Rips на графическом ускорителе. У него есть ускорение через CUDA, привязки к Python и заявленные ускорения относительно Ripser. Минусы: сборка, CUDA, требования к окружению и памяти. (github.com)
    4.2. torchph - интересен, если хочется тесной связи с PyTorch и дифференцируемой топологией. Но последний выпуск старый, хотя есть CUDA/C++ и тематика GPU/PyTorch. (github.com)
    4.3. Для TRE-105 сделать короткую проверку Ripser++ против giotto-ph и текущей реализации. Не начинать переписывать TopologicalExtractor и TopologicalForecaster сразу вокруг одной библиотеки. Лучше сначала ввести тонкий слой - вычислитель диаграмм -> преобразователь диаграмм в признаки -> извлекатель/прогнозист
    Тогда TopologicalExtractor и TopologicalForecaster не будут зависеть напрямую от Ripser++, а GPU станет заменяемым исполнителем. Это резко снижает риск, если CUDA-сборка окажется ломкой на части машин.

Практическая правка к плану задач
TRE-105: выбрать библиотеку через малую проверку: установка, время, память, совпадение диаграмм с текущей реализацией.
TRE-106: выделить чистый договор вычислителя диаграмм и преобразования диаграмм в признаки.
TRE-107: переписать извлекатель и прогнозист поверх этого договора, с проверками на повторяемость, форму выхода, отсутствие обучения на проверочных данных и близость CPU/GPU-результатов.

@Nikikir30

Copy link
Copy Markdown
Collaborator Author

1. Исправления по замечаниям из прошлого:

  • Исправлен _riemann_spec() в адаптерах. В тесты (test_riemann_embeding.py) добавлена проверка основного пути выполнения.

2. Основные изменения:

  • Point Cloud и диаграммы: Созданы новые классы в point_cloud.py:

  • PointCloudBuilder — строит матрицы траекторий из рядов за $O(1)$ по памяти, используя torch.as_strided. В этом классе сосредоточена вся логика построения облака точек из временного ряда.

  • PersistenceDiagramsExtractor — вычисляет персистентные диаграммы с поддержкой двух бэкендов (gtda, ripser++) и двух типов комплексов (Alpha, Vietoris-Rips).

  • Извлечение признаков: Класс TopologicalExtractor полностью переписан под интеграцию нового пайплайна. В topofeatures.py вычисления признаков из диаграмм полностью тензоризованы и переведены на PyTorch вместо собственных, не векторизованных, методов GTDA.

  • Прогнозирование: TopologicalRidgeForecaster обновлен для нативной работы с новым тензорным графом.

Что было удалено

Полностью удален устаревший класс TopologicalTransformation (из point_cloud.py) и PersistenceDiagramsExtractor (из topofeatures.py).


3. Архитектура батчевых вычислений и многоканальность

Новый пайплайн спроектирован для сквозной работы с 3D-тензорами. Входной TopologicalExtractor всегда ожидает тензор (B, C, N), где:

  • $B$ — размер батча (количество временных рядов).
  • $C$ — количество каналов (переменных).
  • $N$ — длина временного ряда.
  • $W$ — размер окна (window_size).
  • $M$ — количество окон (зависит от параметров stride и delay).

Шаг 1. Топологическое вложение (Takens' Embedding)

Исходный тензор виртуально нарезается на окна через torch.as_strided, образуя форму (B, C, M, W). Дальнейшая обработка зависит от стратегии:

  • independent (Независимые пространства): Каждый канал обрабатывается отдельно. Размерности схлопываются в (B * C, M, W). Получаем $B \times C$ облаков точек в $\mathbb{R}^W$.
  • joint (Объединенное пространство): Каналы сливаются в единое фазовое пространство. Транспонирование и решейп дают (B, M, C * W). Получаем $B$ облаков точек в $\mathbb{R}^{C \times W}$.

Шаг 2. Вычисление персистентных диаграмм

На вход поступает облако (B', M, d) (где $B'$ и $d$ зависят от стратегии шага 1).

  1. Считается матрица попарных расстояний (B', M, M) через батчевый torch.cdist.
  2. Выбранный бэкенд строит симплициальные комплексы.
  3. На выходе формируется паддированный тензор диаграмм (B', K, 3), где $K$ — максимальное число топологических «дыр» в батче, а 3 — это параметры $(birth, death, dim)$.

Шаг 3. Извлечение топологических признаков

Вместо итераций по точкам диаграммы к тензору (B', K, 3) применяются булевы маски по размерностям гомологий. Признаки от всех экстракторов конкатенируются. На выходе получается плоский тензор признаков (B', F_{total}).

Шаг 4. Финальное форматирование

Признаки возвращаются к исходной размерности батча $B$:

  • Для independent: Тензор (B * C, F_{total}) решейпится в (B, C * F_{total}). К именам колонок добавляются суффиксы каналов (_ch0, _ch1).
  • Для joint: Тензор уже имеет готовую размерность (B, F_{total}).

4. Следующий шаг

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

@v1docq
v1docq force-pushed the riemann_topology branch from b0b597d to f1b31fe Compare July 20, 2026 12:42
@v1docq
v1docq changed the base branch from kernel_clf_reg to main July 20, 2026 12:42
@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

✅ PR Title Validation Passed

Thank you for following Conventional Commits! 🎉

Current Title: refactor(riemann): update embedding extractor pipeline
Title Length: ✅ 54 characters
Description: ✅ Provided
Status: ✅ Passed
Last Updated: Mon, 20 Jul 2026 12:47:05 GMT

@v1docq
v1docq self-requested a review July 20, 2026 12:46
@v1docq v1docq changed the title Refactor Riemannian Embedding refactor(riemann): update embedding extractor pipeline Jul 20, 2026
@v1docq
v1docq merged commit 6a8f5a5 into main Jul 20, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants