Как переносить данные из одной модели в другую?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Перенос данных из одной модели в другую
Перенос данных между моделями машинного обучения — это сложная задача, требующая понимания архитектур, типов данных и стратегий совместимости. Существует несколько подходов в зависимости от контекста.
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 решает проблемы с разными данными.