257 lines
13 KiB
Python
257 lines
13 KiB
Python
"""
|
||
ПРОСТОЕ ОБЪЯСНЕНИЕ РЕЗУЛЬТАТОВ ОБУЧЕНИЯ
|
||
========================================
|
||
|
||
Этот файл объясняет результаты обучения модели простыми словами,
|
||
как будто ты студент, который только начал изучать машинное обучение.
|
||
|
||
Представь, что train.py - это предыдущая ячейка в твоем блокноте,
|
||
где ты обучил модель. Теперь давай посмотрим, что у нас получилось!
|
||
"""
|
||
|
||
print("=" * 70)
|
||
print("ПРОСТОЕ ОБЪЯСНЕНИЕ РЕЗУЛЬТАТОВ МОДЕЛИ")
|
||
print("=" * 70)
|
||
print()
|
||
|
||
# -------------------------------------------------------------------
|
||
# ЧАСТЬ 1: ЧТО МЫ СДЕЛАЛИ?
|
||
# -------------------------------------------------------------------
|
||
print("1. ЧТО МЫ СДЕЛАЛИ?")
|
||
print("-" * 40)
|
||
print("Мы создали модель, которая смотрит на две картинки и говорит:")
|
||
print(" - 'ДА' - если это одно и то же место (с Google и Яндекс карт)")
|
||
print(" - 'НЕТ' - если это разные места")
|
||
print()
|
||
print("Модель училась на тысячах пар картинок!")
|
||
print("Сначала она делала много ошибок, но потом научилась.")
|
||
print()
|
||
|
||
# -------------------------------------------------------------------
|
||
# ЧАСТЬ 2: КАК МЫ ИЗМЕРЯЕМ УСПЕХ?
|
||
# -------------------------------------------------------------------
|
||
print("2. КАК МЫ ИЗМЕРЯЕМ УСПЕХ?")
|
||
print("-" * 40)
|
||
print("Мы проверяем модель на новых картинках, которых она не видела.")
|
||
print("Считаем, сколько раз она угадала правильно.")
|
||
print()
|
||
|
||
print("Есть 4 возможных исхода:")
|
||
print(" 1. ✅ Истинно-положительный (True Positive - TP):")
|
||
print(" Модель сказала 'ДА' и это правда 'ДА'")
|
||
print()
|
||
print(" 2. ❌ Ложно-положительный (False Positive - FP):")
|
||
print(" Модель сказала 'ДА', но на самом деле 'НЕТ'")
|
||
print(" (Ошибка типа I: приняла разные места за одинаковые)")
|
||
print()
|
||
print(" 3. ❌ Ложно-отрицательный (False Negative - FN):")
|
||
print(" Модель сказала 'НЕТ', но на самом деле 'ДА'")
|
||
print(" (Ошибка типа II: не узнала одинаковые места)")
|
||
print()
|
||
print(" 4. ✅ Истинно-отрицательный (True Negative - TN):")
|
||
print(" Модель сказала 'НЕТ' и это правда 'НЕТ'")
|
||
print()
|
||
|
||
# -------------------------------------------------------------------
|
||
# ЧАСТЬ 3: ПРОСТЫЕ МЕТРИКИ
|
||
# -------------------------------------------------------------------
|
||
print("3. ПРОСТЫЕ МЕТРИКИ (ЧТО ОНИ ЗНАЧАТ?)")
|
||
print("-" * 40)
|
||
|
||
# Примерные результаты (в реальности будут другие)
|
||
accuracy = 0.82 # 82%
|
||
precision = 0.78 # 78%
|
||
recall = 0.85 # 85%
|
||
f1_score = 0.81 # 81%
|
||
|
||
print(f"ТОЧНОСТЬ (Accuracy): {accuracy:.0%}")
|
||
print(" Это как общая оценка в школе.")
|
||
print(" Сколько всего ответов правильных из 100.")
|
||
print(f" Наша модель правильна в {accuracy:.0%} случаев.")
|
||
print()
|
||
|
||
print(f"ТОЧНОСТЬ КЛАССИФИКАЦИИ (Precision): {precision:.0%}")
|
||
print(" Когда модель говорит 'ДА', насколько ей можно верить?")
|
||
print(" Из 100 раз когда она сказала 'ДА', {precision:.0%} были правдой.")
|
||
print(" Высокая точность = мало ложных 'ДА'.")
|
||
print()
|
||
|
||
print(f"ПОЛНОТА (Recall): {recall:.0%}")
|
||
print(" Сколько настоящих 'ДА' модель нашла?")
|
||
print(f" Из 100 настоящих 'ДА', модель нашла {recall:.0%}.")
|
||
print(" Высокая полнота = мало пропущенных 'ДА'.")
|
||
print()
|
||
|
||
print(f"F1-МЕРА (F1 Score): {f1_score:.0%}")
|
||
print(" Баланс между точностью и полнотой.")
|
||
print(" Как золотая середина - не слишком строгая, не слишком добрая.")
|
||
print()
|
||
|
||
# -------------------------------------------------------------------
|
||
# ЧАСТЬ 4: ТАБЛИЦА РЕЗУЛЬТАТОВ (ПРОСТАЯ)
|
||
# -------------------------------------------------------------------
|
||
print("4. ТАБЛИЦА РЕЗУЛЬТАТОВ")
|
||
print("-" * 40)
|
||
print("Давай представим, что мы протестировали модель на 1000 пар картинок:")
|
||
print()
|
||
|
||
# Простая таблица
|
||
print(" | Модель сказала 'ДА' | Модель сказала 'НЕТ' | Всего")
|
||
print("-----------------|---------------------|----------------------|-------")
|
||
print(f"На самом деле 'ДА' | TP: 425 | FN: 75 | 500")
|
||
print(f"На самом деле 'НЕТ' | FP: 95 | TN: 405 | 500")
|
||
print("-----------------|---------------------|----------------------|-------")
|
||
print(f"Всего | 520 | 480 | 1000")
|
||
print()
|
||
|
||
print("Расчеты:")
|
||
print(f" Точность = (TP + TN) / Всего = (425 + 405) / 1000 = {accuracy:.0%}")
|
||
print(f" Точность классификации = TP / (TP + FP) = 425 / 520 = {precision:.0%}")
|
||
print(f" Полнота = TP / (TP + FN) = 425 / 500 = {recall:.0%}")
|
||
print()
|
||
|
||
# -------------------------------------------------------------------
|
||
# ЧАСТЬ 5: КАК ИНТЕРПРЕТИРОВАТЬ РЕЗУЛЬТАТЫ?
|
||
# -------------------------------------------------------------------
|
||
print("5. ЧТО ЭТО ЗНАЧИТ ДЛЯ НАШЕЙ ЗАДАЧИ?")
|
||
print("-" * 40)
|
||
|
||
if precision > 0.75:
|
||
print("✅ ХОРОШО: Когда модель говорит 'это одно место',")
|
||
print(" ей можно доверять ({precision:.0%} случаев она права).")
|
||
else:
|
||
print("⚠ МОЖНО ЛУЧШЕ: Модель иногда путает разные места с одинаковыми.")
|
||
|
||
if recall > 0.75:
|
||
print("✅ ХОРОШО: Модель находит большинство одинаковых мест")
|
||
print(f" ({recall:.0%} настоящих 'одинаковых' мест она находит).")
|
||
else:
|
||
print("⚠ МОЖНО ЛУЧШЕ: Модель пропускает много одинаковых мест.")
|
||
|
||
print()
|
||
print("ДЛЯ АВТОПИЛОТА:")
|
||
print(" - Ложные 'ДА' (FP): Может думать, что мы в нужном месте,")
|
||
print(" когда это не так → опасно!")
|
||
print(" - Ложные 'НЕТ' (FN): Не узнает нужное место → менее опасно,")
|
||
print(" но машина может проехать мимо.")
|
||
print()
|
||
|
||
# -------------------------------------------------------------------
|
||
# ЧАСТЬ 6: ГРАФИКИ (ЧТО МЫ ВИДИМ?)
|
||
# -------------------------------------------------------------------
|
||
print("6. КАКИЕ ГРАФИКИ МЫ ПОЛУЧАЕМ?")
|
||
print("-" * 40)
|
||
print("После обучения мы строим 4 основных графика:")
|
||
print()
|
||
|
||
print("1. 📉 ГРАФИК ОШИБОК (Loss):")
|
||
print(" - Синяя линия: ошибки на обучающих данных")
|
||
print(" - Красная линия: ошибки на проверочных данных")
|
||
print(" - ХОРОШО: обе линии идут вниз и близки друг к другу")
|
||
print(" - ПЛОХО: линии далеко друг от друга (переобучение)")
|
||
print()
|
||
|
||
print("2. 📈 ГРАФИК ТОЧНОСТИ (Accuracy):")
|
||
print(" - Показывает, как растет точность со временем")
|
||
print(" - Должен расти и стабилизироваться")
|
||
print()
|
||
|
||
print("3. 🎯 МАТРИЦА ОШИБОК (Confusion Matrix):")
|
||
print(" - Квадратная таблица 2x2")
|
||
print(" - Показывает все 4 типа ответов (TP, FP, FN, TN)")
|
||
print(" - Идеально: все числа на диагонали, нули вне диагонали")
|
||
print()
|
||
|
||
print("4. 📊 ROC-КРИВАЯ:")
|
||
print(" - Показывает, насколько хорошо модель отличает 'ДА' от 'НЕТ'")
|
||
print(" - Чем больше площадь под кривой, тем лучше")
|
||
print(" - Идеально: площадь = 1.0 (100%)")
|
||
print()
|
||
|
||
# -------------------------------------------------------------------
|
||
# ЧАСТЬ 7: ЧТО ДЕЛАТЬ ДАЛЬШЕ?
|
||
# -------------------------------------------------------------------
|
||
print("7. ЧТО ДЕЛАТЬ, ЕСЛИ РЕЗУЛЬТАТЫ ПЛОХИЕ?")
|
||
print("-" * 40)
|
||
print("Если точность меньше 70%:")
|
||
|
||
print("1. 🎯 ПРОБЛЕМА: Модель плохо учится")
|
||
print(" РЕШЕНИЕ:")
|
||
print(" - Учить дольше (увеличить количество эпох)")
|
||
print(" - Изменить скорость обучения (learning rate)")
|
||
print(" - Добавить больше данных для обучения")
|
||
print()
|
||
|
||
print("2. 🎯 ПРОБЛЕМА: Модель запоминает, а не учится (переобучение)")
|
||
print(" РЕШЕНИЕ:")
|
||
print(" - Добавить регуляризацию (dropout)")
|
||
print(" - Использовать augmentation (искажать картинки)")
|
||
print(" - Упростить модель (меньше слоев)")
|
||
print()
|
||
|
||
print("3. 🎯 ПРОБЛЕМА: Много ложных 'ДА' (FP)")
|
||
print(" РЕШЕНИЕ:")
|
||
print(" - Повысить порог принятия решения (например, 0.7 вместо 0.5)")
|
||
print(" - Добавить больше примеров 'разных' мест")
|
||
print()
|
||
|
||
print("4. 🎯 ПРОБЛЕМА: Много ложных 'НЕТ' (FN)")
|
||
print(" РЕШЕНИЕ:")
|
||
print(" - Понизить порог принятия решения (например, 0.3 вместо 0.5)")
|
||
print(" - Добавить больше примеров 'одинаковых' мест")
|
||
print()
|
||
|
||
# -------------------------------------------------------------------
|
||
# ЧАСТЬ 8: ПРАКТИЧЕСКИЙ ПРИМЕР
|
||
# -------------------------------------------------------------------
|
||
print("8. ПРАКТИЧЕСКИЙ ПРИМЕР: КАК ИСПОЛЬЗОВАТЬ МОДЕЛЬ")
|
||
print("-" * 40)
|
||
print("После обучения модель можно использовать так:")
|
||
print()
|
||
|
||
print("```python")
|
||
print("# 1. Загружаем обученную модель")
|
||
print("model = load_trained_model('best_model.pt')")
|
||
print()
|
||
print("# 2. Берем две картинки")
|
||
print("google_img = load_image('google_map.png')")
|
||
print("yandex_img = load_image('yandex_map.png')")
|
||
print()
|
||
print("# 3. Спрашиваем у модели")
|
||
print("similarity_score = model.predict(google_img, yandex_img)")
|
||
print()
|
||
print("# 4. Интерпретируем результат")
|
||
print("if similarity_score > 0.5:")
|
||
print(" print('✅ Это похоже на одно и то же место!')")
|
||
print("else:")
|
||
print(" print('❌ Это разные места')")
|
||
print("```")
|
||
print()
|
||
|
||
print(f"Порог 0.5 можно менять:")
|
||
print(f" - Порог 0.7: более строгая модель (меньше ложных 'ДА')")
|
||
print(f" - Порог 0.3: более добрая модель (меньше ложных 'НЕТ')")
|
||
print()
|
||
|
||
# -------------------------------------------------------------------
|
||
# ЧАСТЬ 9: ЗАКЛЮЧЕНИЕ
|
||
# -------------------------------------------------------------------
|
||
print("9. ЧТО МЫ УЗНАЛИ?")
|
||
print("-" * 40)
|
||
print("✅ Модель учится сравнивать картинки")
|
||
print("✅ Мы можем измерить, насколько она хороша")
|
||
print("✅ Есть разные метрики для разных целей")
|
||
print("✅ Графики помогают понять процесс обучения")
|
||
print("✅ Можно улучшить модель, если результаты плохие")
|
||
print()
|
||
|
||
print("=" * 70)
|
||
print("🎉 ВОТ И ВСЁ! ТЕПЕРЬ ТЫ ЗНАЕШЬ, КАК ОЦЕНИВАТЬ МОДЕЛЬ!")
|
||
print("=" * 70)
|
||
print()
|
||
print("Следующие шаги:")
|
||
print("1. Запусти evaluation.py чтобы увидеть реальные графики")
|
||
print("2. Посмотри на матрицу ошибок - какие ошибки чаще?")
|
||
print("3. Попробуй изменить порог принятия решений")
|
||
print("4. Если нужно - переобучи модель с другими параметрами")
|