PlanetFinder — быстрая кроссплатформенная система машинного обучения, написанная на Rust, которая обнаруживает экзопланеты методом транзита: анализируя колебания яркости звезды во времени (кривые блеска), нейронная сеть предсказывает количество планет в звёздной системе.
Проект использует реальные астрономические данные миссий NASA Kepler и TESS, предоставляемые через Python-библиотеку lightkurve.
С астрономической точки зрения — позволяет автоматически анализировать миллионы кривых блеска, которые невозможно обработать вручную, ускоряет поиск кандидатов в экзопланеты и помогает проверять гипотезы о транзитных маршрутах и орбитальных периодах.
С точки зрения разработки — практический пример применения LSTM для анализа временных рядов на Rust, демонстрация работы с реальными научными данными NASA и кроссплатформенный проект с опциональным GPU-ускорением через CUDA.
Метод, который использует PlanetFinder, называется транзитной фотометрией. Когда планета проходит перед своей звездой, она блокирует часть её света — яркость звезды незначительно падает. По глубине, форме и периодичности этих провалов можно определить количество планет.
Яркость звезды
│
│████████████████████████████████████████████████
│ ↓ транзит планеты
│████████████████████████ ████████████████████
│ ░░░░░
└──────────────────────────────────────────────▶ Время
└─ падение яркости ~1%
Пайплайн обработки данных:
Данные NASA (Kepler/TESS)
│
▼
download_data.py
├── Загрузка кривых блеска через lightkurve
├── Нормализация яркости
├── Удаление выбросов и NaN
└── Сохранение в learn*.txt
│
▼
PlanetFinder (Rust)
├── Парсинг .txt файлов
├── Нормализация времени [0..1]
├── Формирование тензоров
└── LSTM → Linear → Предсказание
│
▼
Результат: N планет в системе
PlanetFinder использует LSTM (Long Short-Term Memory) — рекуррентную нейронную сеть, специально разработанную для работы с последовательностями и временными рядами.
Входная последовательность (кривая блеска)
[яркость₁, время₁] → [яркость₂, время₂] → ... → [яркостьₙ, временₙ]
│
▼
┌─────────────────────────────────────────────────┐
│ LSTM Layer (скрытые состояния) │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ LSTM │ ──▶ │ LSTM │ ── ... ──▶│ LSTM │ │
│ │ячейка│ │ячейка│ │ячейка│ │
│ └──────┘ └──────┘ └──┬───┘ │
│ ↑ ↑ │ │
│ [br₁,t₁] [br₂,t₂] последнее │
│ состояние │
└─────────────────────────────────────────────────┘
│
▼ (последнее скрытое состояние hₙ)
┌─────────────────────────────────────────────────┐
│ Fully Connected Layer (Linear) │
│ hidden_size → 1 │
└─────────────────────────────────────────────────┘
│
▼
Число планет (f64 → округляется до целого)
Почему LSTM, а не простая RNN или CNN?
LSTM решает проблему затухающего градиента и способна "запоминать" паттерны, разнесённые во времени — в данном случае периодические транзиты, которые могут происходить раз в несколько недель или месяцев. CNN хорошо ловит локальные паттерны, но хуже справляется с долгосрочными зависимостями.
Ключевые параметры модели:
| Параметр | Значение | Описание |
|---|---|---|
input_size |
2 | Яркость + Время на каждый шаг |
output_size |
1 | Предсказанное число планет |
| Функция потерь | MSE | Среднеквадратичная ошибка |
| Оптимизатор | Adam | Адаптивная оптимизация |
| Прогресс-репорт | каждые 2.5% эпох | Вывод текущей ошибки |
PlanetFinder/
│
├── src/ # Исходный код на Rust
│ └── main.rs # Точка входа: CLI, обучение, предсказание
│
├── download_data.py # Python-скрипт загрузки данных NASA
│
├── Cargo.toml # Зависимости и метаданные Rust-пакета
├── Cargo.lock # Зафиксированные версии зависимостей
├── .gitignore # Исключения для Git
│
├── model.ot # Сохранённая модель (создаётся после обучения)
├── learn1.txt # Обучающий файл 1 (создаётся download_data.py)
├── learn2.txt # Обучающий файл 2
├── ... # learnN.txt — столько, сколько загрузите
│
├── README.md # Этот файл
└── LICENSE # Apache 2.0
Реализует интерактивный текстовый интерфейс. Пользователь выбирает режим работы (1 — обучение, 2 — предсказание).
В режиме обучения программа:
- Сканирует директорию на наличие файлов
learn*.txt - Парсит каждый файл: читает пары
(яркость, время)и меткуresult N - Нормализует яркость (делением на среднее) и время (в диапазон
[0, 1]) - Формирует тензоры и запускает цикл обучения
- Каждые 2.5% эпох выводит прогресс и текущую ошибку MSE
- Автоматически сохраняет
model.otпри достижении минимальной ошибки
В режиме предсказания программа:
- Загружает
model.otс диска - Принимает пары
(яркость, время)из стандартного ввода до командыend - Прогоняет последовательность через LSTM и выводит предсказание
Python-скрипт, использующий библиотеку lightkurve для доступа к архивам Kepler и TESS. Загружает кривые блеска звёзд с известным числом планет и конвертирует их в формат, понятный PlanetFinder.
Ключевая зависимость проекта — tch (rust-биндинги к LibTorch, C++ API PyTorch). Именно через неё реализуются тензорные операции, LSTM-слой и сохранение/загрузка модели в формате .ot.
Каждый обучающий файл имеет имя learn1.txt, learn2.txt, ... и следующую структуру:
0.998 131.2
1.002 132.1
0.995 133.0
0.999 133.9
0.872 134.8 ← транзит: яркость упала
0.870 135.7 ← транзит: продолжается
0.998 136.6
...
result 2 ← метка: 2 планеты в системе
| Поле | Тип | Описание |
|---|---|---|
яркость |
f64 |
Нормализованная яркость звезды (≈ 1.0 в норме) |
время |
f64 |
Момент наблюдения (BJD или произвольные единицы) |
result N |
строка | Последняя строка — число известных планет |
Важно: файлы должны называться строго
learnN.txt(например,learn1.txt,learn42.txt). Программа находит их автоматически по шаблонуlearn*.txt.
| Компонент | Версия | Где взять |
|---|---|---|
| Rust | 1.70+ | rustup.rs |
| LibTorch | 2.x | pytorch.org |
| Компонент | Назначение | Где взять |
|---|---|---|
| CUDA 11.x+ | GPU-ускорение обучения | developer.nvidia.com |
| Python 3.8+ | Только для download_data.py |
python.org |
| lightkurve, astropy, numpy | Загрузка данных NASA | pip3 install lightkurve astropy numpy |
# Linux / macOS
export LIBTORCH=/path/to/libtorch
export LD_LIBRARY_PATH=$LIBTORCH/lib:$LD_LIBRARY_PATH
# Windows (PowerShell)
$env:LIBTORCH = "C:\path\to\libtorch"
$env:Path = "$env:LIBTORCH\lib;$env:Path"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
rustc --version # должно вывести: rustc 1.70.0 или вышеПерейдите на pytorch.org/get-started/locally, выберите:
- Package: LibTorch
- Language: C++
- OS: ваша ОС
- CUDA: нужная версия (или CPU-only)
Распакуйте архив и задайте переменную LIBTORCH (см. выше).
git clone https://github.com/Ztry8/PlanetFinder.git
cd PlanetFindercargo build --releaseПервая сборка занимает несколько минут из-за компиляции зависимостей. Последующие — значительно быстрее. Готовый бинарник появится в
target/release/.
pip3 install lightkurve astropy numpy
python3 download_data.pyСкрипт загрузит кривые блеска из архива Kepler/TESS и сохранит их как learn_1.txt, learn_2.txt, ... в рабочую папку.
Если нет доступа к Python или вы хотите начать немедленно — скачайте готовые .txt файлы и предобученную модель model.ot:
Скачать готовые файлы → Releases v1.0.1
Поместите скачанные файлы в корневую директорию проекта.
cargo run --release> 1
Найдено обучающих файлов: 42
Начинаем обучение...
Completed 50 epochs ( 2.5% done) — current error: 1.2885
Completed 100 epochs ( 5.0% done) — current error: 0.9341
Completed 150 epochs ( 7.5% done) — current error: 0.7102
...
Completed 2000 epochs (100.0% done) — current error: 0.0487
✓ Лучшая модель сохранена: model.ot
Программа автоматически находит все файлы learn*.txt, обучает LSTM и сохраняет лучшие веса в model.ot.
> 2
Загружена модель: model.ot
Вводите пары "яркость время", по одной на строку.
Введите "end" для получения результата.
> 0.998 131.2
> 1.002 132.1
> 0.872 134.8
> 0.870 135.7
> 0.999 136.6
> end
Predicted number of planets: 1
Для предсказания файл
model.otдолжен быть в рабочей директории. Либо обучите модель (режим 1), либо скачайте готовую из релиза.
# Большая планета, орбита ~3 дня
1.001 0.0
1.000 0.5
0.830 1.0 ← транзит: -17% яркости
0.829 1.5
0.831 2.0
1.000 2.5
0.829 4.0 ← повторный транзит, тот же период
result 1
# Малый транзит (период ~5 дней) + крупный (период ~18 дней)
1.000 0.0
0.991 5.3 ← маленькая планета (-0.9%)
1.001 10.6
0.992 15.9
0.870 18.2 ← большая планета (-13%)
1.000 21.2
0.991 26.5
result 2
| Режим | Конфигурация | Скорость |
|---|---|---|
| Обучение | CPU (Intel i7) | ~200 эпох/сек |
| Обучение | GPU (RTX 3060, CUDA) | ~2000 эпох/сек |
| Предсказание | CPU или GPU | < 10 мс |
Точность зависит от числа обучающих файлов (рекомендуется 50+), их разнообразия и числа эпох.
Q: Могу ли я использовать свои данные, не из NASA?
A: Да. Любые данные в формате яркость время построчно, с завершающей строкой result N, будут приняты программой.
Q: Зачем нужна нормализация?
A: Разные звёзды имеют разную базовую яркость. Нормализация приводит все кривые к единому масштабу, позволяя модели учиться на паттернах транзитов, а не абсолютных значениях.
Q: Как долго нужно обучать модель?
A: Для 50 файлов на CPU — около 15–30 минут при 2000 эпохах. С GPU — в ~10 раз быстрее.
Q: Работает ли проект на Apple Silicon (M1/M2/M3)?
A: Да, в CPU-режиме. Поддержка Metal/MPS зависит от версии LibTorch.
Q: Почему Rust, а не Python?
A: Rust обеспечивает высокую скорость выполнения, безопасность памяти без GC и возможность компилировать в единый бинарник без зависимостей от интерпретатора.
| Источник | Описание | Ссылка |
|---|---|---|
| NASA Kepler | Главный источник кривых блеска | nasa.gov/kepler |
| NASA TESS | Расширенный обзор транзитных экзопланет | tess.mit.edu |
| NASA Exoplanet Archive | Каталог подтверждённых экзопланет | exoplanetarchive.ipac.caltech.edu |
| Библиотека | Язык | Назначение | Ссылка |
|---|---|---|---|
tch-rs |
Rust | LibTorch (PyTorch C++) биндинги для LSTM и тензоров | github.com/LaurentMazare/tch-rs |
lightkurve |
Python | Загрузка и обработка кривых блеска Kepler/TESS | docs.lightkurve.org |
astropy |
Python | Астрономические вычисления и форматы | astropy.org |
numpy |
Python | Численные операции | numpy.org |
Распространяется под лицензией Apache License 2.0 — свободное использование, в том числе коммерческое, при сохранении указания авторства. Подробности — в файле LICENSE.