← Назад к вопросам

Как переносить данные из одной модели в другую?

1.0 Junior🔥 131 комментариев
#Машинное обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Перенос данных из одной модели в другую

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

1. Transfer Learning: переиспользование весов

Самый эффективный способ переноса знаний из одной нейросети в другую.

import torch
import torch.nn as nn
from torchvision.models import resnet50, resnet101

# Загружаем предтренированную модель (source)
source_model = resnet50(pretrained=True)

# Создаём новую модель (target)
target_model = resnet101()

# Копируем слои, которые совместимы по форме
source_state = source_model.state_dict()
target_state = target_model.state_dict()

for name, param in source_state.items():
    if name in target_state and source_state[name].shape == target_state[name].shape:
        target_state[name] = source_state[name]
    elif "fc" not in name:  # Пропускаем полносвязные слои
        try:
            target_state[name] = source_state[name]
        except RuntimeError:
            print(f"Не могу скопировать слой {name}")

target_model.load_state_dict(target_state, strict=False)

2. Feature Extraction: использование промежуточных представлений

Передача признаков из одной модели в другую.

import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler

class FeatureExtractor:
    def __init__(self, source_model):
        """Инициализируем экстрактор на основе исходной модели"""
        self.source_model = source_model
    
    def extract_features(self, X):
        """Получаем промежуточные представления (embeddings)"""
        # Для нейросети — выход предпоследнего слоя
        # Для дерева — примеси признаков
        features = self.source_model.predict_proba(X)
        return features

# Используем извлечённые признаки в новой модели
X_train_features = feature_extractor.extract_features(X_train)
X_test_features = feature_extractor.extract_features(X_test)

# Обучаем новую модель на этих признаках
target_model = RandomForestClassifier(n_estimators=100)
target_model.fit(X_train_features, y_train)

3. Fine-tuning: адаптация моделей

Перенос с частичной переподготовкой на новых данных.

import torch
import torch.nn as nn
from torch.optim import Adam

class Finetuner:
    def __init__(self, pretrained_model, num_classes_new):
        self.model = pretrained_model
        
        # Заменяем только последний слой
        in_features = self.model.fc.in_features
        self.model.fc = nn.Linear(in_features, num_classes_new)
        
        # Замораживаем early layers (backbone)
        for name, param in self.model.named_parameters():
            if "fc" not in name:
                param.requires_grad = False
    
    def finetune(self, train_loader, val_loader, epochs=10, lr=0.001):
        """Fine-tuning на новых данных"""
        optimizer = Adam(self.model.parameters(), lr=lr)
        criterion = nn.CrossEntropyLoss()
        
        for epoch in range(epochs):
            for X_batch, y_batch in train_loader:
                logits = self.model(X_batch)
                loss = criterion(logits, y_batch)
                
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()
        
        return self.model

4. Knowledge Distillation: передача знаний

Одна модель (teacher) обучает другую (student) через softened predictions.

import torch.nn.functional as F

class DistillationLoss(nn.Module):
    def __init__(self, temperature=3.0, alpha=0.7):
        super().__init__()
        self.temperature = temperature
        self.alpha = alpha  # Вес между distillation и supervised loss
    
    def forward(self, student_logits, teacher_logits, true_labels):
        """Комбинированная loss: distillation + supervision"""
        
        # Softened predictions от teacher
        teacher_probs = F.softmax(teacher_logits / self.temperature, dim=1)
        student_log_probs = F.log_softmax(student_logits / self.temperature, dim=1)
        
        # KL divergence loss
        kl_loss = F.kl_div(student_log_probs, teacher_probs, reduction="mean")
        
        # Supervised loss
        ce_loss = F.cross_entropy(student_logits, true_labels)
        
        # Комбинированный лосс
        total_loss = self.alpha * kl_loss + (1 - self.alpha) * ce_loss
        return total_loss

5. Domain Adaptation: адаптация для другого домена

Данные из одного домена (source) переносятся в другой домен (target).

from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression

class DomainAdapter:
    def __init__(self, source_model):
        self.source_model = source_model
        self.adapter = None
    
    def adapt(self, X_source_train, X_target_train, y_source_train):
        """CORAL: Correlation Alignment"""
        # Вычисляем корреляционные матрицы
        cov_source = np.cov(X_source_train.T)
        cov_target = np.cov(X_target_train.T)
        
        # Трансформируем target данные к распределению source
        from scipy.linalg import sqrtm
        
        sqrt_cov_source = sqrtm(cov_source)
        sqrt_cov_target = sqrtm(cov_target)
        
        # Адаптационная трансформация
        transformation = sqrt_cov_source @ np.linalg.inv(sqrt_cov_target).real
        X_target_adapted = X_target_train @ transformation.T
        
        return X_target_adapted

6. Практический пример: Миграция sklearn на XGBoost

import xgboost as xgb
from sklearn.ensemble import RandomForestClassifier

# Старая модель (sklearn)
old_model = RandomForestClassifier(n_estimators=100)
old_model.fit(X_train, y_train)

# Новая модель (XGBoost)
new_model = xgb.XGBClassifier(
    n_estimators=100,
    max_depth=10,
    learning_rate=0.1,
    random_state=42
)

# Стратегия миграции:
# 1. Обучаем обе параллельно на 10% данных
from sklearn.model_selection import train_test_split
X_sample, _, y_sample, _ = train_test_split(X_train, y_train, test_size=0.9)

old_model.fit(X_sample, y_sample)
new_model.fit(X_sample, y_sample)

# 2. Сравниваем метрики
old_score = old_model.score(X_test, y_test)
new_score = new_model.score(X_test, y_test)

print(f"Old model accuracy: {old_score:.4f}")
print(f"New model accuracy: {new_score:.4f}")

# 3. Постепенный переход: A/B тест
# Запускаем обе модели параллельно на production, изменяя traffic распределение

7. Чеклист переноса данных

  • Проверка совместимости входных/выходных размеров
  • Версионирование обеих моделей и их артефактов
  • A/B тестирование перед полной миграцией
  • Мониторинг качества на обеих моделях параллельно
  • Откат на старую модель, если качество упало
  • Синхронизация гиперпараметров и preprocessing pipeline

Вывод: Выбор стратегии переноса зависит от архитектур моделей. Transfer Learning эффективен для нейросетей, feature extraction — универсален, знач знание distillation сжимает функционал, а domain adaptation решает проблемы с разными данными.