Нейросеть для предсказания температуры поверхности звезд

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

Нейросеть для предсказания температуры поверхности звезд

Введение

Всем привет! Закончил проект по созданию нейросети для предсказания температуры поверхности звезд на основе физических характеристик в рамках самостоятельной работы по теме “Модели и алгоритмы в машинном обучении”.

Проект получился интересный, реализовал много графики для визуализации данных и результатов работы модели. Задействованные технологии: Python, PyTorch, Pandas, Scikit-learn, Matplotlib.

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

Архитектура решения

Подготовка данных

Работа с астрофизическими данными требует тщательной предобработки:

data_preprocessing.py python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

def load_and_preprocess_data(filepath):
    """Загрузка и предобработка астрофизических данных."""
    df = pd.read_csv(filepath)
    
    # Обработка пропущенных значений
    df = df.dropna(subset=['temperature', 'luminosity', 'radius', 'mass'])
    
    # Логарифмирование для нормализации распределений
    df['log_luminosity'] = np.log10(df['luminosity'])
    df['log_radius'] = np.log10(df['radius'])
    df['log_mass'] = np.log10(df['mass'])
    
    # Кодирование категориальных признаков (спектральные классы)
    spectral_classes = pd.get_dummies(df['spectral_class'], prefix='spec')
    df = pd.concat([df, spectral_classes], axis=1)
    
    # Определение признаков и целевой переменной
    features = ['log_luminosity', 'log_radius', 'log_mass'] + list(spectral_classes.columns)
    X = df[features].values
    y = df['temperature'].values
    
    # Масштабирование признаков
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)
    
    # Разделение на обучающую и тестовую выборки
    X_train, X_test, y_train, y_test = train_test_split(
        X_scaled, y, test_size=0.2, random_state=42
    )
    
    return X_train, X_test, y_train, y_test, scaler, features

Архитектура нейросети

Для задачи регрессии была реализована многослойная нейронная сеть:

model_architecture.py python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import torch
import torch.nn as nn
import torch.nn.functional as F

class StarTemperaturePredictor(nn.Module):
    """Нейронная сеть для предсказания температуры звезд."""
    
    def __init__(self, input_size, hidden_sizes=[128, 64, 32], dropout_rate=0.3):
        super(StarTemperaturePredictor, self).__init__()
        
        layers = []
        prev_size = input_size
        
        # Динамическое создание скрытых слоев
        for hidden_size in hidden_sizes:
            layers.append(nn.Linear(prev_size, hidden_size))
            layers.append(nn.BatchNorm1d(hidden_size))
            layers.append(nn.ReLU())
            layers.append(nn.Dropout(dropout_rate))
            prev_size = hidden_size
        
        # Выходной слой (регрессия)
        layers.append(nn.Linear(prev_size, 1))
        
        self.network = nn.Sequential(*layers)
    
    def forward(self, x):
        return self.network(x).squeeze()

Обучение модели

Процесс обучения с использованием PyTorch:

training.py python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import matplotlib.pyplot as plt

def train_model(model, X_train, y_train, X_val, y_val, epochs=100, lr=0.001):
    """Обучение модели с валидацией."""
    
    # Преобразование данных в тензоры PyTorch
    train_dataset = TensorDataset(
        torch.FloatTensor(X_train), 
        torch.FloatTensor(y_train)
    )
    val_dataset = TensorDataset(
        torch.FloatTensor(X_val), 
        torch.FloatTensor(y_val)
    )
    
    train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
    val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)
    
    # Оптимизатор и функция потерь
    optimizer = optim.Adam(model.parameters(), lr=lr)
    criterion = nn.MSELoss()
    
    # История обучения
    train_losses = []
    val_losses = []
    
    for epoch in range(epochs):
        # Обучение
        model.train()
        train_loss = 0
        for batch_X, batch_y in train_loader:
            optimizer.zero_grad()
            predictions = model(batch_X)
            loss = criterion(predictions, batch_y)
            loss.backward()
            optimizer.step()
            train_loss += loss.item()
        
        # Валидация
        model.eval()
        val_loss = 0
        with torch.no_grad():
            for batch_X, batch_y in val_loader:
                predictions = model(batch_X)
                val_loss += criterion(predictions, batch_y).item()
        
        # Сохранение метрик
        avg_train_loss = train_loss / len(train_loader)
        avg_val_loss = val_loss / len(val_loader)
        train_losses.append(avg_train_loss)
        val_losses.append(avg_val_loss)
        
        if (epoch + 1) % 10 == 0:
            print(f"Epoch {epoch+1}/{epochs}: "
                  f"Train Loss: {avg_train_loss:.4f}, "
                  f"Val Loss: {avg_val_loss:.4f}")
    
    return train_losses, val_losses

Визуализация результатов

График обучения

visualization.py python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def plot_training_history(train_losses, val_losses):
    """Визуализация процесса обучения."""
    plt.figure(figsize=(10, 6))
    plt.plot(train_losses, label='Training Loss', linewidth=2)
    plt.plot(val_losses, label='Validation Loss', linewidth=2)
    plt.xlabel('Epoch', fontsize=12)
    plt.ylabel('Mean Squared Error', fontsize=12)
    plt.title('Learning Curves: Star Temperature Prediction', fontsize=14)
    plt.legend(fontsize=11)
    plt.grid(True, alpha=0.3)
    plt.tight_layout()
    plt.show()

Сравнение предсказаний с реальными значениями

evaluation.py python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def plot_predictions_vs_actual(model, X_test, y_test):
    """Визуализация предсказаний против реальных значений."""
    model.eval()
    with torch.no_grad():
        predictions = model(torch.FloatTensor(X_test)).numpy()
    
    plt.figure(figsize=(10, 8))
    plt.scatter(y_test, predictions, alpha=0.6, s=50)
    
    # Идеальная линия предсказаний
    min_val = min(y_test.min(), predictions.min())
    max_val = max(y_test.max(), predictions.max())
    plt.plot([min_val, max_val], [min_val, max_val], 
             'r--', linewidth=2, label='Perfect Prediction')
    
    plt.xlabel('Actual Temperature (K)', fontsize=12)
    plt.ylabel('Predicted Temperature (K)', fontsize=12)
    plt.title('Model Predictions vs Actual Values', fontsize=14)
    plt.legend(fontsize=11)
    plt.grid(True, alpha=0.3)
    plt.tight_layout()
    plt.show()
    
    # Вычисление метрик
    from sklearn.metrics import mean_absolute_error, r2_score
    mae = mean_absolute_error(y_test, predictions)
    r2 = r2_score(y_test, predictions)
    
    print(f"Mean Absolute Error: {mae:.2f} K")
    print(f"R² Score: {r2:.4f}")

Ключевые особенности проекта

Основные достижения:

  1. Реализована end-to-end pipeline для обработки астрофизических данных
  2. Создана гибкая архитектура нейросети с настраиваемыми параметрами
  3. Достигнута высокая точность предсказаний (R² > 0.85 на тестовой выборке)
  4. Разработаны комплексные визуализации для анализа результатов

Вызовы и решения:

  • Проблема: Сильный разброс значений физических параметров звезд
  • Решение: Применение логарифмического преобразования для нормализации распределений
  • Проблема: Категориальные данные (спектральные классы)
  • Решение: One-hot encoding для интеграции в нейросеть

Технологический стек

Технология Назначение Версия
Python Основной язык программирования 3.9+
PyTorch Фреймворк для глубокого обучения 2.0+
Pandas Обработка и анализ данных 1.5+
Scikit-learn Предобработка и метрики 1.3+
Matplotlib Визуализация результатов 3.7+
Jupyter Notebook Интерактивная разработка 6.5+
NumPy Научные вычисления 1.24+

Заключение

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

Дальнейшее развитие:

  1. Добавление большего количества признаков (металличность, возраст звезды)
  2. Эксперименты с различными архитектурами нейросетей (LSTM для временных рядов)
  3. Применение методов интерпретации моделей (SHAP, LIME)
  4. Развертывание модели как веб-сервиса для исследователей

Ссылки и ресурсы

Зайти и посмотреть готовый Jupyter Notebook можно на GitHub:

GitHub Repository: Star Temperature Prediction Neural Network

Визуализация работы нейросети для предсказания температуры звезд
Архитектура нейросети и примеры предсказаний температуры для различных типов звезд

Проект выполнен в рамках самостоятельной работы по курсу “Модели и алгоритмы в машинном обучении”. Все код и визуализации доступны в открытом репозитории.