KiSinWi — AutoML-платформа с микросервисной архитектурой и мультиагентными воркфлоу. automl.. automl. LLM-агенты.. automl. LLM-агенты. классификация изображений.. automl. LLM-агенты. классификация изображений. компьютерное зрение.. automl. LLM-агенты. классификация изображений. компьютерное зрение. машинное обучениe.. automl. LLM-агенты. классификация изображений. компьютерное зрение. машинное обучениe. мультиагентные системы.. automl. LLM-агенты. классификация изображений. компьютерное зрение. машинное обучениe. мультиагентные системы. нейронные сети.

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

В какой-то момент (прошлой осенью) я подумал: а почему этим до сих пор занимаюсь я, а не модель, которая в этом разбирается не хуже (ну наверное)? Так началась KiSinWi – платформа, где команда из LLM-агентов сама проходит весь путь от сырого датасета до обученной модели. Анализирует данные, спорит об архитектуре, изучает лучшие практики, собирает конфиг обучения, запускает его и потом сама же разбирает, что получилось.

С тех пор прошло уже больше полугода работы. Да, это не проект выходного дня, собранный на коленке между двумя чашками кофе. Настал момент рассказать о нём и заодно честно взглянуть на цифры. Не на красивые обещания на листе со шрифтом Times New Roman, а на реальные итоги. Работает ли оно по-настоящему?

Для этого я взял пять публичных датасетов с известными эталонными результатами и прогнал через платформу. Ниже представлено что вышло со всеми конфигами лучших моделей, цитатами агентов и с двумя датасетами, где платформа недотянула по метрикам. Их я тоже покажу. Надеюсь, к концу вы согласитесь, что это лечится не переписыванием платформы, а парой функций или ещё одним агентом в команде. А сел писать я не потому, что всё готово, а потому что “вот допилить нужно ещё чуть-чуть” говорил я и откладывал уже четыре раза – пора вылезать из этой ловушки перфекциониста.

Да, это именно так

Да, это именно так

Сначала – зачем всё это

Обучить классификатор картинок – это не “вызвать model.fit() и пойти спать”. Это цепочка решений, каждое из которых требует осмысленных действий:

  • какую архитектуру взять и обучать ли её с нуля или дообучать её;

  • какие аугментации помогут, а какие, наоборот, сотрут полезные признаки;

  • какой оптимизатор, какой scheduler, сколько эпох;

  • где вовремя остановиться и не переобучиться.

Каждое из этих решений человек принимает головой и опытом, а перебор стоит времени и GPU-часов. Идея KiSinWi проста, отдать весь этот цикл агентам. Пользователь приносит датасет и формулирует требование по-человечески – “хочу точность не ниже 0.93, и чтобы инференс был дешёвым”. А дальше платформа сама идёт от анализа данных до готовых весов и отчёта о качестве. Причём управлять агентами можно не только целевой метрикой. Им можно задать ограничения по гипотезам – например, направить в сторону конкретных архитектур или, наоборот, запретить лишние эксперименты, если вы уже знаете, что хотите. А можно описать железо, на котором модель будет жить в проде: сколько памяти, есть ли GPU, какой бюджет на latency. Агенты учитывают это при выборе архитектуры – нет смысла подбирать тяжёлую сеть под сервер, который её не потянет. По сути вы очерчиваете рамки, а внутри них платформа ищет лучшее решение сама. И в итоге мы имеем не просто AutoML с перебором гиперпараметров, а агентную систему, где каждый агент рассуждает вслух.

Как это устроено под капотом

Под капотом платформа – это конвейер из микросервисов. Данные проходят через них последовательно, как по конвейерной ленте:

datasets -> agents -> tasker -> trainer -> metrics + ml_models -> agent_history

Я разбил систему на сервисы не ради моды, а для возможности беспрерывного масштабирования. Сейчас платформа заточена под классификацию изображений, но это не тупик. Чтобы добавить новый тип задачи, к примеру детекцию объектов или NLP, достаточно добавить в сервис datasets возможность работать с данными и поднять отдельный trainer с соответствующей логикой. Все остальные сервисы остаются неизменными. Платформа расширяется не переписыванием старого, а подключением нового.

Важный момент о котором вы уже могли подумать – конфиг обучения динамический. Агенты не заполняют жёсткую форму с фиксированными полями – они собирают конфигурацию из доступных кирпичиков (архитектуры из timm, оптимизаторы, scheduler’ы, аугментации) и прогоняют её через формальную валидацию перед запуском. Никакого хардкода – это позволило в процессе разработки добавлять новые фичи в сервис тренировок без изменения агентов и позволит в будущем с лёгкостью внедрять новые сервисы обучения с другими задачами.

Знакомьтесь, команда

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

Роль

Чем занимается

Computer Vision Dataset Analyst

Анализирует датасет: классы, баланс, размеры, возможные утечки между выборками. Запускается первым и имеет право вето – если данные не готовы, воркфлоу останавливается.

ML Researcher

Выдвигает гипотезы по архитектуре, аугментациям и регуляризации. Дирижёр обсуждения гипотез. В его подчинении есть агент Internet Best-Practices Scout.

Internet Best-Practices Scout

По запросу Researcher’а ищет свежие практики – arXiv, парсинг страниц.

ML Engineer

Оценивает гипотезы Researcher’а: принимает, отклоняет или отправляет на доработку. Собирает финальный конфиг и валидирует его перед запуском.

ML Debugging Engineer

Включается только если обучение упало с ошибкой. Локализует проблемный параметр в конфиге и чинит его точечно не переписывая всё с нуля.

ML Model Metrics Analyst

Оценивает полученные результаты модели и запускает новую итерацию обучения в случае, если модель не достигла бизнес требований.

ML Model Production Readiness Expert

В конце подводит итог всех попыток и выдаёт вердикт: ДА / НЕТ / УСЛОВНО готова модель к проду.

Схема взаимодействия показана на рисунке ниже. (Агенты подписаны полными именами)

схема взаимодействия агентов.

схема взаимодействия агентов.

Как вы видите на рисунке выше это не конвейер, где каждый говорит по разу. Dataset Analyst отрабатывает один раз в начале, а дальше крутится главный цикл – Researcher <-> ML Engineer. Researcher предлагает гипотезы, ML Engineer их судит: согласен – собирает конфиг и запускает обучение; не согласен – отправляет Researcher’а думать заново, и так до трёх подходов. Если обучение падает с ошибкой, запускается отдельный цикл с ML Debugging Engineer. Он имеет три попытки починить поломку, а так же может отказаться чинить остановив обучение, если решение ошибки не зависит от его действий. А поверх всего – внешний цикл итераций: платформа обучает модель, агент ML Model Metrics Analyst определяет, достигла модель требований, и если не достигла, запускает новую итерацию обучения(максимум прогонов 5, т.к. вероятность, что вам придётся брать кредит на токены из-за галлюцинаций никуда не пропадает).

ML Engineer не сочиняет конфиг по памяти – у него есть инструменты: список реально доступных архитектур (timm), опрос железа (есть ли GPU и сколько памяти), перечни поддерживаемых оптимизаторов, scheduler’ов и аугментаций, а финальный конфиг прогоняется через валидатор до запуска. Поэтому в обучение уходит не “галлюцинация”, а проверенная конфигурация – что во многом и объясняет, почему дефолты у платформы получаются вменяемыми.

Быстрый режим – это урезанный вариант обучения с одной итерацией обучения. Добавлен он чтобы гонять платформу на тестах, не упираясь в отказы от рассуждающего блока и агента аналитика данных. В нём ML Engineer обязан проанализировать данные и запустить обучение на имеющихся данных (права сказать “нет, эта задача безнадёжна” у него нет). После обучения подключается агент ML Model Metrics Analyst, который разбирает метрики готовой модели.

В бенчмарке я гонял именно полный пайплайн и самое приятное, что спор и действия агентов не спрятаны в логах сервера. Он живёт прямо в интерфейсе. Открываешь дискуссию – и видишь вертикальную ленту-таймлайн: сообщение за сообщением, каждое подписано ролью агента и помечено статусом. Кликаешь по карточке – она разворачивается, и под ней полное рассуждение агента, отрендеренное как Markdown: с заголовками, списками, кусками конфига. А рядом – кнопка “Инструменты”: жмёшь и видишь, чем именно агент пользовался – какие модели искал, что прогонял через валидацию, с какими аргументами на входе и что получил на выходе. То есть видно не только что агент решил, но и на основании чего.

Скриншоты интерфейса
меню агентов в интерфейсе

меню агентов в интерфейсе
Дискуссия агентов в интерфейсе - часть 1/4

Дискуссия агентов в интерфейсе – часть 1/4
Дискуссия агентов в интерфейсе - часть 2/4

Дискуссия агентов в интерфейсе – часть 2/4
Дискуссия агентов в интерфейсе - часть 3/4

Дискуссия агентов в интерфейсе – часть 3/4
Дискуссия агентов в интерфейсе - часть 4/4

Дискуссия агентов в интерфейсе – часть 4/4

И всё это в реальном времени: пока идёт прогон, лента сама подтягивает новые сообщения раз в пару секунд, статусы переключаются с “в процессе” на “готово”.

Для AutoML такая прозрачность редкость. Возьмите тот же AutoGluon или Auto-sklearn: после fit() вы зовёте .leaderboard() и получаете аккуратную таблицу – модель, score, время обучения. У H2O AutoML – то же самое через .leaderboard. Полезно, спору нет, но это ответ на вопрос “что победило”, а не “почему”. Цепочку рассуждений – какие гипотезы рассматривались, что отмели и на каком основании, какими инструментами это проверялось – оттуда не вытащишь, её просто нет. А здесь она есть, прямо в виде живого, читаемого диалога.

Подготовка: какой моделью “думают” агенты

Прежде чем гонять бенчмарк, надо было решить вопрос, от которого зависит вообще всё: какую LLM поставить мозгом агентов. И это оказалось совсем не формальностью – пара кандидатов отвалилась прямо на старте.

Платформу я с самого начала затачивал под модели OpenAI, и не из вкусовщины. Вся мультиагентная механика держится на двух вещах: агенты должны возвращать строгие структуры (я описываю их как Pydantic-схемы – это лучшая практика при использовании crewAi) и уметь дёргать инструменты. У OpenAI зрелые Structured Outputs со strict JSON – модель не просто “старается” попасть в формат, а гарантированно отдаёт JSON, который ложится в мою схему. Провайдер валидирует это на своей стороне. Плюс надёжный вызов инструментов во всей актуальной линейке. У меня же агенты вызывают инструменты буквально на каждом шаге.

И это не пустые слова – я пробовал поставить за штурвал других, и упёрся ровно в эти две вещи:

  • DeepSeek V4 – спотыкался на инструментах. Он раз за разом не мог корректно вызвать tools, а без инструментов агенты слепы: им нечем ни датасет посмотреть, ни конфиг провалидировать. Так что дальше первых шагов на нём не уедешь. Зато цена и скорость явно превосходят OpenAI модели.

  • Anthropic: Claude Opus 4.6 – наоборот, с инструментами дружил, но не держал строгую структуру ответа: возвращаемый JSON регулярно не сходился с моей Pydantic-схемой, и шаг падал на валидации.

Чтобы не вводить в заблуждение: это не приговор самим моделям. И DeepSeek, и Claude в принципе умеют и tool’ы использовать, и структурированный вывод – просто у каждого провайдера свой способ это отдавать, и litellm на тот момент дружил с ними по-разному. У меня всё было заточено под strict-режим OpenAI, поэтому именно с ним связка вела себя предсказуемо, а остальных пришлось бы отдельно настраивать. Возможно, под них платформу ещё допилю – но для бенчмарка я взял то, что работает как часы: openai/gpt-5.1. [1]

Как я вообще это мерил

Важная оговорка: я проверял не техническую работу платформы, а её качество как ML-инструмента. Бенчмарк под это написан сознательно максимально просто. Он не оценивает, не считает метрики и не ставит вердиктов: его задача – прогнать датасеты через платформу, запустить обучения и принести ссылки на готовые модели. А дальше начинается ручная работа: смотреть метрики, сравнивать с эталоном, разбираться, почему вышло так, а не иначе, – это мы делаем уже сами, глазами и головой.

Почему так? Потому что источник правды по метрикам – это сами сервисы платформы, а не локальная копия в JSON. Дублировать их в скрипте – значит плодить второй “оракл”, который рано или поздно разойдётся с реальностью. Поэтому скрипт намеренно держит у себя только ссылки. Также подчеркну, что в интерфейсе реализован просмотр моделей для сравнения.

Скриншоты интерфейса при сравнении
Сравнение обученных моделей - часть 1/5

Сравнение обученных моделей – часть 1/5
Сравнение обученных моделей - часть 2/5

Сравнение обученных моделей – часть 2/5
Сравнение обученных моделей - часть 3/5

Сравнение обученных моделей – часть 3/5
Сравнение обученных моделей - часть 4/5

Сравнение обученных моделей – часть 4/5
Сравнение обученных моделей - часть 5/5

Сравнение обученных моделей – часть 5/5

Сравнивать дальше я буду с эталоном типичной точностью на тесте для ResNet50 с предобучением на ImageNet [2]. Это честный ориентир именно для инструмента: не “побей лучшую модель в мире”, а “выйди на уровень, который грамотный инженер получает стандартным дообучением”.

Baseline у каждого датасета – не рекорд SOTA и не цифра с потолка, а уровень “ResNet50, дообученный с ImageNet”: крепкий, общеизвестный transfer-результат, который на этих датасетах берут годами. Сами проценты (98/96/93/96/80) я взял как типичные значения такого transfer-дообучения по литературе и публичным репортам – это не строгие официальные числа из одной таблицы, а ориентир “куда дотягивается грамотный инженер стандартным подходом”. И я не требую попасть в него тютелька-в-тютельку – мы с вами держим в уме разумную погрешность для метрик. Плюс отдельно посмотрим на разрыв train−val как индикатор переобучения.

Источники каждого датасета: CIFAR-10, Oxford Flowers-102, Oxford-IIIT Pets, Food-101, Beans. Шестым кейсом идёт deepfake-классификация: там я мерил платформу уже не против baseline, а против решения живого Kaggle-мастера на мета-датасете, собранном из 6 датасетов Kaggle (подробный разбор – в отдельной главе ниже).

Все прогоны – от 2026-06-15, GPU NVIDIA RTX 5080 Laptop, с несколькими итерациями рассуждений, в роли мозга агентов – openai/gpt-5.1 (почему именно она – в главе “Подготовка” выше).

А сколько это стоит по токенам. Резонный вопрос для AutoML: семь агентов с инструментами и несколькими итерациями – это не бесплатно. Цифры из сервиса метрик (он считает токены по каждому агенту): один датасет обходился в среднем примерно в 740k токенов – от ~640k на самых быстрых прогонах (Flowers, Pets) до ~945k на CIFAR-10, который крутил больше всего итераций. Подавляющая часть – это prompt-токены (~90%): агенты на каждом шаге таскают за собой контекст и результаты инструментов. По биллингу OpenRouter это выходило порядка 0,9$ за датасет. Для ясности так же обозначу, что цена могла быть ниже, если бы я использовал API OpenAI напрямую, а не через OpenRouter.

Результат сравнений

Вот сводная таблица, а дальше разберём каждый случай по-отдельности – что увидели агенты, что выбрали и чем всё кончилось.

Датасет

Классы

Архитектура

Baseline

Test acc

Разрыв

F1

Test AUROC

Train−val

Итераций

Время

Вердикт

Beans

3

mobilenetv3_large_100

98.0%

98.4%

+0.4 п.п.

0.985

0.99

0 п.п.

4

15.5 мин

✅ ОК

Oxford Flowers-102

102

efficientnet_b0

96.0%

98.3%

+2.3 п.п.

0.984

0.99

+0.9 п.п.

3

24 мин

✅ ОК

Food-101 (урезан до 100 картинок на класс)

101

mobilenetv3_large_100

80.0%

71.6%

−8.4 п.п.

0.711

0.98

+33.8 п.п.

3

57.8 мин

◐ ориентир (subset)

CIFAR-10

10

resnet18 (с нуля)

96.0%

88.7%

−7.3 п.п.

0.887

0.99

+3.6 п.п.

4

82.7 мин

⚠️ accuracy недотянул

Oxford-IIIT Pets

37

efficientnet_b0

93.0%

88.5%

−4.5 п.п.

0.882

0.99

+6.5 п.п.

3

22 мин

⚠️ accuracy недотянул

Deepfake

2

resnet50

98.0%

98.3%

+0.3 п.п.

0.983

0.99

+0.2 п.п.

3

8 ч 34 мин

✅ ОК

Пара слов про колонки, чтобы не запутаться. Архитектура – это то, что агенты выбрали сами. Разрыв – это отставание/опережение test accuracy от baseline, а Train−val – это разрыв между точностью на обучении и на валидации, то есть индикатор переобучения (чем больше, тем сильнее модель “зазубрила” трейн). F1 добавил как устойчивую к перекосам альтернативу accuracy.

Пара слов про методологию. Платформа крутит внешний цикл итераций и в конце сама выносит вердикт, какая из обученных версий лучшая – это делает агент-эксперт по метрикам. Именно эту, отмеченную платформой лучшую модель я и ставлю в таблицу: то самое итоговое решение, которое забрал бы и живой инженер. Любопытная деталь: на CIFAR-10 и Pets лучшей оказалась не последняя итерация, а более ранняя – то есть платформа не улучшает любой ценой и не выдаёт случайный регресс за прогресс.

Поехали по порядку. Но сразу обратите внимание на колонку AUROC – к ней мы вернёмся, когда дойдём до двух датасетов, где accuracy “недотянул”. Спойлер: всё не так грустно, как кажется по одной только accuracy.

Если AUROC вам ни о чём не говорит – это метрика того, насколько хорошо модель ранжирует объекты по уверенности, независимо от выбранного порога. Accuracy отвечает на вопрос “сколько угадал”, AUROC – “понимает ли модель, где какой класс, в принципе”. 1.0 – идеал, 0.5 – монетка. Важная оговорка наперёд: в многоклассовой задаче AUROC считается по схеме one-vs-rest (каждый класс против всех остальных), а такой бинарный вопрос решается легко, поэтому 0.99 здесь – частое и не особо геройское значение. Высокий AUROC не равно “почти взял baseline по accuracy” – это разные вопросы, и дальше я на этом подробно остановлюсь.

Beans – 98.4% на больных листьях фасоли

Это датасет состоящий из 3 классов, около 1300 фотографий листьев фасоли (здоровые и две болезни). Такой датасет взят, чтобы проверить – а базовый-то сценарий вообще работает? Если платформа спотыкается тут, дальше можно не смотреть. Агенты считали ситуацию мгновенно: мало данных, мало классов – значит, лёгкая предобученная архитектура плюс сильные аугментации против переобучения. ML Engineer выбрал mobilenetv3_large_100 (предобученный) и прямо обосновал выбор компромиссом “качество против дешёвого инференса в проде”. Не “давайте самую жирную сеть”, а именно по делу.

Полный конфиг обучения (Beans) – для тех, кому интересны внутренности
{
  "model_params": { "type": "mobilenetv3_large_100", "pretrained": true },
  "data_loader_params": {
    "batch_size": 32,
    "num_workers": 2,
    "train_transforms_config": [
      { "name": "RandomResizedCrop", "params": { "scale": [0.8, 1.0], "size": [224, 224] } },
      { "name": "RandomHorizontalFlip", "params": { "p": 0.5 } },
      { "name": "RandomVerticalFlip", "params": { "p": 0.25 } },
      { "name": "RandomRotation", "params": { "degrees": 22 } },
      { "name": "ColorJitter", "params": { "brightness": 0.25, "contrast": 0.25, "saturation": 0.25, "hue": 0.05 } },
      { "name": "ToTensor", "params": {} },
      { "name": "Normalize", "params": { "mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225] } }
    ]
  },
  "trainer_params": {
    "epochs": 40,
    "loss_fn": { "name": "CrossEntropyLoss", "params": { "label_smoothing": 0.1 } },
    "optimizer": { "name": "AdamW", "params": { "lr": 0.001, "weight_decay": 0.0003 } },
    "scheduler": { "name": "CosineAnnealingLR", "params": { "T_max": 40, "eta_min": 1e-06 } },
    "early_stop": { "metric_name": "loss", "patience": 8, "min_delta": 0.001, "mode": "min" },
    "grad_clip_norm": 1.0,
    "use_amp": true
  },
  "device": "cuda"
}

Итог – 98.4%, на 0.4 п.п. выше baseline, переобучения ноль, всё уложилось в 15 с половиной минут. Эталонный прогон, придраться не к чему. Приятно, когда базовый кейс просто берёт и работает.

Oxford Flowers-102 – 98.3% на сотне с лишним классов

А вот тут я слегка напрягся перед прогоном. 102 класса цветов, примеров на класс мало. Казалось бы, идеальный повод для платформы споткнуться. Но нет. ML Researcher и ML Engineer быстро сошлись на efficientnet_b0 (предобученном) – лёгкий, дешёвый. Из данных, собранных ML Researcher, ML Engineer вывел вот такое заключение:

«EfficientNet-B0 исторически показывает высокое качество на датасете Oxford Flowers-102, и при использовании предобученных весов, адекватных аугментаций и настройки обучения достижение accuracy выше 0.96 на сбалансированном тестовом сплите – реалистичная цель.» — ML Engineer

То есть они не нашли какую-то секретную архитектуру, а подтвердили общеизвестный best practice и решили не изобретать велосипед. И это, кстати, правильное поведение ML-инженера.

Полный конфиг обучения (Flowers-102)
{
  "model_params": { "type": "efficientnet_b0", "pretrained": true },
  "data_loader_params": {
    "batch_size": 32,
    "num_workers": 4,
    "train_transforms_config": [
      { "name": "RandomResizedCrop", "params": { "scale": [0.7, 1.0], "size": [224, 224] } },
      { "name": "RandomHorizontalFlip", "params": { "p": 0.5 } },
      { "name": "RandomRotation", "params": { "degrees": 15 } },
      { "name": "ColorJitter", "params": { "brightness": 0.2, "contrast": 0.2, "saturation": 0.2, "hue": 0.1 } },
      { "name": "ToTensor", "params": {} },
      { "name": "Normalize", "params": { "mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225] } }
    ]
  },
  "trainer_params": {
    "epochs": 40,
    "loss_fn": { "name": "CrossEntropyLoss", "params": { "label_smoothing": 0.1 } },
    "optimizer": { "name": "AdamW", "params": { "lr": 0.001, "weight_decay": 0.01 } },
    "scheduler": { "name": "CosineAnnealingLR", "params": { "T_max": 30, "eta_min": 1e-06 } },
    "early_stop": { "metric_name": "accuracy", "patience": 6, "min_delta": 0.0005, "mode": "max" },
    "grad_clip_norm": 1.0,
    "use_amp": true
  },
  "device": "cuda"
}

98.3%, на 2.3 п.п. выше baseline, переобучения почти нет – и это на 102 классах за 24 минуты. Платформа держит планку не только на “игрушечных” трёх классах, но и на нормальной многоклассовой fine-grained задаче.

Food-101 (subset) – сознательный стресс-тест

Здесь я специально подложил платформе свинью: 101 класс еды, но датасет урезан до 100 картинок на класс. Это классический рецепт переобучения – много классов, мало данных. Baseline в 80% дан для полного датасета, поэтому результат на subset я считаю грубым ориентиром, а не строгой планкой. И вот тут агенты показали то, ради чего всё затевалось. На второй итерации обучения ML Researcher увидел, что предыдущая попытка на EfficientNet-B1 даёт ~70% и сильно переобучается, и сам сменил стратегию – выбрал mobilenetv3_large_100 с усиленной регуляризацией:

«Текущий лучший бенчмарк на EfficientNet-B1 даёт ≈0.70 accuracy и сильно переобучается. С учётом продакшн-ограничения “минимизировать затраты инференса” целесообразно перейти на лёгкую архитектуру MobileNetV3 Large… усиленную регуляризацию для борьбы с переобучением.» — ML Researcher

Заметьте: это не я вмешался и подсказал. Агент сам прочитал результат предыдущей итерации, поставил диагноз “переобучение” и сменил подход. Именно то поведение, которого ждёшь от живого ML-инженера.

Полный конфиг обучения (Food-101 subset)
{
  "model_params": { "type": "mobilenetv3_large_100", "pretrained": true },
  "data_loader_params": {
    "batch_size": 64,
    "num_workers": 4,
    "train_transforms_config": [
      { "name": "RandomResizedCrop", "params": { "scale": [0.6, 1.0], "size": [224, 224] } },
      { "name": "RandAugment", "params": { "num_ops": 2, "magnitude": 9 } },
      { "name": "RandomHorizontalFlip", "params": { "p": 0.5 } },
      { "name": "ColorJitter", "params": { "brightness": 0.2, "contrast": 0.2, "saturation": 0.2, "hue": 0.1 } },
      { "name": "RandomRotation", "params": { "degrees": 15 } },
      { "name": "ToTensor", "params": {} },
      { "name": "Normalize", "params": { "mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225] } }
    ]
  },
  "trainer_params": {
    "epochs": 40,
    "loss_fn": { "name": "CrossEntropyLoss", "params": { "label_smoothing": 0.1 } },
    "optimizer": { "name": "AdamW", "params": { "lr": 0.0008, "weight_decay": 0.02 } },
    "scheduler": { "name": "CosineAnnealingLR", "params": { "T_max": 40, "eta_min": 1e-06 } },
    "early_stop": { "metric_name": "accuracy", "patience": 6, "min_delta": 0.001, "mode": "max" },
    "grad_clip_norm": 1.0,
    "use_amp": true
  },
  "device": "cuda"
}

Получилось 71.6% при ориентире 80% – на урезанном датасете я считаю это приемлемым. Но разрыв train−val настораживает: +34 п.п. Модель буквально упёрлась в нехватку данных, и тут уже никакая регуляризация полностью не спасёт – 100 картинок на класс для задачи с 101 классом это просто мало. Платформа взяла планку-ориентир, но кейс показал её реальный предел. И это нормально: важно, что предел виден в метриках, а не замаскирован.

Всё под контролем

Всё под контролем

Задачи, где accuracy недотянул

Два датасета из пяти baseline по accuracy не взяли. И это, пожалуй, самая интересная часть статьи и интересна она не тем, что у недобора есть понятная, измеримая причина, и я её не угадываю, а проверяю руками.

Сразу остужу один соблазн, в который легко свалиться. Помните колонку AUROC? На обоих “провальных” датасетах он получился 0.99 – практически как у датасетов-отличников. Заманчиво сказать: “ну вот, видите, модель всё понимает”. Так вот, это было бы передёргиванием, и я не хочу вам его продавать: как я уже оговорил во врезке выше, one-vs-rest AUROC в многоклассе структурно высок почти всегда и сам по себе не доказывает, что до baseline рукой подать. Высокий AUROC и проваленная accuracy спокойно живут вместе – и это нормально, а не парадокс.

Что AUROC говорит – так это что признаки разделимы: фундамент под капотом рабочий. Это полезный индикатор, но именно индикатор, а не пруф потенциала. Настоящее доказательство, что недобор – это вопрос полировки, а не потолка, лежит ниже: в обоих кейсах я взял ровно те же конфиги, поменял по сути одну вещь (предобучение на CIFAR, learning rate на Pets) и числом вернул большую часть отставания. Вот это – аргумент. AUROC лишь подсказал, где искать. Так же есть догадка, что агенты могли дойти до этого, если бы мы дали количество итераций побольше, но по моей изначальной задумке они должны за 3 прогона уже приходить к результату который мы хотим получить…

Разберём оба кейса по этой логике: что выбрали агенты, где именно недотянули, что показывает AUROC, и как это можно было сделать лучше. (Я не поленился и проверил экспериментально)

CIFAR-10 – accuracy 88.7% при baseline 96%, но AUROC 0.99

CIFAR-10 – это 60 тысяч крошечных картинок 32×32, 10 классов, классика, на которой baseline 96% знает каждый. Платформа сделала четыре попытки, потратила 82 минуты – и её лучший прогон дал accuracy 88.7%. Test AUROC при этом – 0.99, а F1 и precision/recall сошлись на 0.88. Но на эти 0.990 не ведёмся (см. врезку выше): недостающие 7.3 п.п. accuracy сидят не в AUROC, а в конкуренции похожих классов на argmax.

А вот что забавно: агенты всё поняли правильно. ML Researcher разложил канонический рецепт для CIFAR-10 – RandomCrop с padding, RandAugment, RandomErasing, label smoothing, длинное обучение с cosine annealing. ML Engineer собрал технически грамотный конфиг: resnet18, SGD с momentum, 200 эпох, сильные аугментации. На бумаге – всё как по учебнику. Первую попытку, к слову, агенты сделали на чуть более тяжёлой resnet32ts – та дала всего 75.6%, после чего они сознательно упростились до resnet18 как более дешёвой в инференсе и при этом более удачной.

Полный конфиг обучения (CIFAR-10)
{
  "model_params": { "type": "resnet18", "pretrained": false },
  "data_loader_params": {
    "batch_size": 128, "num_workers": 2,
    "train_transforms_config": [
      { "name": "RandomCrop", "params": { "size": [32, 32], "padding": 4 } },
      { "name": "RandomHorizontalFlip", "params": { "p": 0.5 } },
      { "name": "RandAugment", "params": {} },
      { "name": "ToTensor", "params": {} },
      { "name": "Normalize", "params": { "mean": [0.4914, 0.4822, 0.4465], "std": [0.247, 0.243, 0.261] } }
    ],
    "val_and_test_transforms_config": [
      { "name": "Resize", "params": { "size": [32, 32] } },
      { "name": "ToTensor", "params": {} },
      { "name": "Normalize", "params": { "mean": [0.4914, 0.4822, 0.4465], "std": [0.247, 0.243, 0.261] } }
    ]
  },
  "trainer_params": {
    "epochs": 200,
    "loss_fn": { "name": "CrossEntropyLoss", "params": { "label_smoothing": 0.1 } },
    "optimizer": { "name": "SGD", "params": { "lr": 0.1, "momentum": 0.9, "weight_decay": 0.0005 } },
    "scheduler": { "name": "CosineAnnealingLR", "params": { "T_max": 200, "eta_min": 1e-06 } },
    "early_stop": { "metric_name": "accuracy", "patience": 60, "min_delta": 0.0005, "mode": "max" },
    "grad_clip_norm": 1.0,
    "use_amp": true
  },
  "device": "cuda"
}

Кстати, на CIFAR заодно пригодился тот самый отдельный цикл с ML Debugging Engineer, о котором я писал выше – на одной из итераций ML Engineer сунул в аугментации RandomApply с вложенным RandomErasing, и прогон на этом упал. Debug-агент не стал гадать, а аккуратно вскрыл трейсбэк и починил ровно одну строку, не трогая остальное:

«Тип ошибки: ошибка на этапе … трансформации данных … TypeError: 'dict' object is not callable … единственный проблемный параметр … использование вложенной трансформации в RandomApply … достаточно … использовать RandomErasing напрямую.» — ML Debugging Engineer

Ровно то, ради чего этот агент и задуман: не переписать весь конфиг с перепугу, а локализовать поломку до конкретного параметра и заменить точечно. После правки обучение поехало дальше.

Видите ключевую строчку? "pretrained": false. Агенты решили обучать resnet18 с нуля. А baseline бенчмарка – это ResNet50 с предобучением на ImageNet. То есть платформа соревновалась с предобученной моделью, а пошла путём обучения с нуля на мелких 32×32 – и закономерно отстала на 7.3 п.п. по accuracy. Конфиг технически прекрасен, но стратегически на этом датасете агенты предпочли “лёгкость и дешевизну инференса” гонке за метрикой.

И вот тут высокий AUROC(0.99) расставляет всё по местам. Признаки модель развела (кошка/собака, олень/лошадь на 32×32), просто без предобучения ей не хватило тех самых последних процентов. Лечится это, по сути, одной эвристикой: “для маленьких разрешений всё равно тяни предобученную архитектуру с upscale”. Маленькая правка в логике агентов – и этот датасет с большой вероятностью переходит в зелёную зону. Потенциал не гипотетический, он измерен. И характерная деталь: сам агент списал недобор на нехватку ёмкости архитектуры (“нужна сетка потяжелее ResNet-18”), а recovery на той же resnet18 показал, что дело было не в размере модели, а в отсутствии предобучения. То есть диагноз агента был мимо, и это ещё один аргумент именно за доработку его эвристик.

И что важно – платформа не стала врать и выдавать недотянувшую модель за успех. Финальный агент честно вынес вердикт “не готова”, заодно сам проговорив ту самую ловушку с AUROC, о которой я предупреждал выше:

«Ключевое бизнес-требование accuracy ≥ 0.96 на тесте не выполнено ни одной моделью … Несмотря на … высокий AUROC (~0.99) и отсутствие серьёзного оверфита, уровень ошибки … всё ещё далёк от ожидаемого топового качества.» — ML Model Production Readiness Expert

Проверка догадки. Чтобы не быть голословным, я взял ту же resnet18 и изменил в конфиге следующее: "pretrained": false -> "pretrained": true плюс upscale 32->224 на входе. Вместе с предобучением логично сменился и режим обучения: вместо SGD с нуля на 200 эпох – мягкий AdamW (lr=5e-4) на 30 эпох и аугментации под 224 (RandomResizedCrop вместо RandomCrop по 32). То есть это не “правка одной строки”, а честная смена стратегии с “учим с нуля” на “дообучаем предобученное” – но рычаг тут именно в предобучении, остальное лишь обслуживает его. Прогнал напрямую через платформу – и test accuracy прыгнула с 88.7% до 94.5% (+5.8 п.п.), а разрыв с baseline схлопнулся с −7.3 до −1.5 п.п. – то есть датасет переезжает в зелёную зону, в пределах допуска. Перевод в transfer-режим добрал недостающее – ровно как я и предполагал по высокому AUROC. Догадка подтверждена не на словах, а числом.

Я знаю, что делаю

Я знаю, что делаю

Oxford-IIIT Pets – accuracy 88.5% при baseline 93%

37 пород кошек и собак – fine-grained классификация, где классы визуально похожи (попробуйте сами на глаз отличить две породы короткошёрстных кошек). И вот что показательно: лучшей моделью здесь у платформы оказалась её самая первая и самая простая попытка – предобученный efficientnet_b0, 88.5%. Test AUROC при этом – 0.993 (даже выше, чем у CIFAR), при F1 0.882 и kappa 0.882 – и снова это лишь индикатор разделимости, а не пруф близости к baseline. Недостающие проценты тут теряются на недокрученном режиме fine-tuning: предобученные признаки есть, но их подстройку модель провела слишком грубо.

ML Engineer выбрал лёгкую предобученную архитектуру сразу и по делу:

«Выбранная архитектура efficientnet_b0 является сильным и при этом лёгким baseline для fine‑grained классификации.» — ML Engineer

Полный конфиг обучения (Oxford-IIIT Pets)
{
  "model_params": { "type": "efficientnet_b0", "pretrained": true },
  "data_loader_params": {
    "batch_size": 64, "num_workers": 4,
    "train_transforms_config": [
      { "name": "RandomResizedCrop", "params": { "scale": [0.8, 1.0], "size": [224, 224] } },
      { "name": "RandomHorizontalFlip", "params": { "p": 0.5 } },
      { "name": "RandomRotation", "params": { "degrees": 10 } },
      { "name": "ColorJitter", "params": { "brightness": 0.1, "contrast": 0.1, "saturation": 0.1, "hue": 0.02 } },
      { "name": "ToTensor", "params": {} },
      { "name": "Normalize", "params": { "mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225] } }
    ],
    "val_and_test_transforms_config": [
      { "name": "Resize", "params": { "size": [224, 224] } },
      { "name": "ToTensor", "params": {} },
      { "name": "Normalize", "params": { "mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225] } }
    ]
  },
  "trainer_params": {
    "epochs": 80,
    "loss_fn": { "name": "CrossEntropyLoss", "params": { "label_smoothing": 0.05 } },
    "optimizer": { "name": "AdamW", "params": { "lr": 0.001, "weight_decay": 0.01 } },
    "scheduler": { "name": "CosineAnnealingLR", "params": { "T_max": 80, "eta_min": 1e-06 } },
    "early_stop": { "metric_name": "accuracy", "patience": 12, "min_delta": 0.001, "mode": "max" },
    "grad_clip_norm": 1.0,
    "use_amp": true
  },
  "device": "cuda"
}

Accuracy вышла 88.5% – на 4.5 п.п. ниже baseline, с переобучением +6.5 п.п. train−val. Здесь подвёл learning rate: на AdamW великоват – он слишком грубо “расталкивает” предобученные признаки, вместо того чтобы аккуратно их подстроить. И AUROC 0.993 с этим согласуется (не доказывает, а согласуется): архитектура выбрана правильно, признаки модель ухватила – недокручен режим fine-tuning, а не сама модель. Более консервативная подстройка (меньший lr, дольше обучение) почти наверняка добрала бы недостающие проценты. Это та зона, где итерациям ещё есть куда копать глубже, и где видно, что упирается всё в настройку платформы, а не в её потолок.

А дальше – самое интересное про итерации, потому что путь у агентов был не по прямой. Получив первую efficientnet_b0, они попробовали два разных хода, и оба поучительны. Сначала – лобовой “добавить регуляризации и аугментаций посильнее”, и сами же зафиксировали, что это сделало только хуже:

«усиленная регуляризация и агрессивные аугментации привели к сильному снижению качества … такая комбинация RandAugment+сильный ColorJitter для fine-grained пород избыточна и разрушает полезные признаки.» — ML Model Production Readiness Expert

Потом сменили курс на более тяжёлую и современную tf_efficientnetv2_s, рассчитывая дотянуться до 93%:

«Выбран backbone tf_efficientnetv2_s как разумный компромисс между качеством и вычислительной стоимостью: он существенно компактнее тяжёлых ConvNeXt/ViT, но заметно сильнее классического EfficientNet-B0.» — ML Engineer

Но и она дала лишь 88.1% – то есть более тяжёлая сеть так и не превзошла простую b0. Трезвый сигнал: дело тут не в размере модели, а в том самом режиме дообучения. И снова – никакого приукрашивания со стороны платформы. Финальный агент прямо назвал и недобор по целевой метрике, и переобучение, не пряча их за высоким AUROC:

«Ни одна из трёх обученных версий … не достигает целевого порога accuracy≥0.93 на тестовом сплите … Наблюдается выраженное переобучение: train≈1.0 против test≈0.88.» — ML Model Production Readiness Expert

Проверка догадки. Гипотезу про lr я тоже проверил руками, а не оставил на честном слове. Взял ту самую более тяжёлую tf_efficientnetv2_s, что пробовали агенты, те же аугментации – но learning rate спустил с 1e-3 до 2e-4, а обучение чуть длиннее (80 эпох вместо 60). Прогнал через платформу – accuracy выросла с 88.1% до 91.0% (+2.9 п.п.). Разрыв с baseline сократился до −2.0 п.п. (в пределах допуска), а переобучение просело почти вдвое (с +9.5 до ~+4 п.п. train−val). Один лишь бережный lr добрал почти три процента и заодно усмирил переобучение.

Deepfake – accuracy 98.3% при baseline 98.0%

Для дополнительной проверки я сравнил платформу с решением задачи классификации deepfake действующим Notebooks Master`ом из Kaggle(далее буду упоминать автора под его ником “MuqaddasEjaz”). Предобработка датасетов (только деление на train/val/test) выполнялась точно так же, как у MuqaddasEjaz.

Датасеты используемые для решения этой задачи:

Для начала я написал скрипт для скачивания требуемых датасетов из Kaggle и создания из датасетов единого мета-датасета в точности как в ноутбуке. И при запуске Computer Vision Dataset Analyst выявил в мета-датасете несколько проблем: больше полумиллиона картинок, но с дубликатами, утечкой между train/val/test (одни и те же изображения в разных сплитах) и шумными метками от шести разных источников. Вердикт:

«🟥 Не готов к обучению…» — Computer Vision Dataset Analyst

Скриншоты ответа аналитика данных
Агент аналитик не пустил обучаться датасет - часть 1/3

Агент аналитик не пустил обучаться датасет – часть 1/3
Агент аналитик не пустил обучаться датасет - часть 2/3

Агент аналитик не пустил обучаться датасет – часть 2/3
Агент аналитик не пустил обучаться датасет - часть 3/3

Агент аналитик не пустил обучаться датасет – часть 3/3

Но мне же интересно сравнить платформу с работой человека и посмотреть, что будет дальше. Поэтому я сознательно отключил вето аналитика и продавил обучение на свой риск – платформа это позволяет, отметив в системном логе: «Аналитик данных забраковал датасет, но проверка отключена при запуске. Продолжаем обучение на свой риск». И вот тут начинается интересная часть, которую я и хочу разобрать, что предлагали агенты и как аргументировали.

Итерация 1. ML Engineer не стал делать вид, что данные чистые – он прямо заложил риски в конфиг: взял предобученный resnet50, добавил label_smoothing=0.1 против шумных меток и набор аугментаций (включая GaussianBlur) против дубликатов и разнобоя источников. Обучение на 500k+ картинок шло примерно пять с половиной часов и дало вполне приличную модель:

«Test accuracy: 0.9833 (≈98.33%) … Test AUROC ~0.9984 … kappa ~0.967 … Модель хорошо обобщает: разрыв между train (98.59%) и val/test (≈98.3%) небольшой.» — ML Model Metrics Analyst

Полный конфиг обучения
{
  "model_params": { "type": "resnet50", "pretrained": true },
  "data_loader_params": {
    "batch_size": 64,
    "num_workers": 4,
    "dataset_id": "97e60848-c175-4409-9dd1-5882fb2ffaf4",
    "img_h_size": null,
    "img_w_size": null,
    "version_id": "ccc63255-8257-4eea-b524-81cdffa97461",
    "train_transforms_config": [
      { "name": "RandomResizedCrop", "params": { "scale": [0.6, 1], "size": [224, 224] } },
      { "name": "RandomHorizontalFlip", "params": { "p": 0.5 } },
      { "name": "ColorJitter", "params": { "brightness": 0.2, "contrast": 0.2, "saturation": 0.2, "hue": 0.05 } },
      { "name": "GaussianBlur", "params": { "kernel_size": 3, "sigma": [0.1, 1] } },
      { "name": "ToTensor", "params": {} },
      { "name": "Normalize", "params": { "mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225] } }
    ],
    "val_and_test_transforms_config": [
      { "name": "Resize", "params": { "size": [224, 224] } },
      { "name": "ToTensor", "params": {} },
      { "name": "Normalize", "params": { "mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225] } }
    ]
  },
  "trainer_params": {
    "epochs": 60,
    "loss_fn": { "name": "CrossEntropyLoss", "params": { "reduction": "mean", "label_smoothing": 0.1 } },
    "optimizer": { "name": "AdamW", "params": { "lr": 0.001, "weight_decay": 0.01 } },
    "scheduler": { "name": "CosineAnnealingLR", "params": { "T_max": 60, "eta_min": 1e-06 } },
    "early_stop": { "metric_name": "accuracy", "patience": 6, "min_delta": 0.0005, "mode": "max" },
    "grad_clip_norm": 1.0,
    "use_amp": true
  },
  "device": "cuda"
}

Казалось бы – почти как у MuqaddasEjaz (~99%), бери и радуйся. Но бизнес-цель я сформулировал жёстко – «максимальный accuracy, как у конкурентов, 99%» и агент-аналитик метрик не стал округлять 98.33% в 99%:

«… по бизнес-критерию “как у конкурентов: 99% accuracy” требование не выполнено … Также нет информации, что данные/сплит/метод подсчёта метрики точно совпадают с конкурентами; без этой уверенности честная позиция – считать, что требование не достигнуто.» — ML Model Metrics Analyst

Тонкий момент, который мне понравился: аналитик не просто увидел недобор в 0.7 п.п., он сам заметил, что сравнивать вслепую некорректно (он не знает, что у “конкурентов” данные точь-в-точь).

А дальше началась погоня за метрикой. Раз 99% не взято, внешний цикл пошёл на новую итерацию, и агенты начали наращивать мощность, чтобы добрать недостающие доли процента:

  • итерация 2 – tf_efficientnet_b4 с входом 380×380;

  • итерация 3 – tf_efficientnet_b5 с входом 456×456.

Логика агентов вполне понятна: ограничений по железу я не задал, значит можно брать тяжёлые модели и разрешение повыше. Вот только на датасете в полмиллиона картинок это означает совсем другое время обучения – одна эпоха стала занимать больше восьми часов. И обе последние попытки я остановил руками: ждать 8+ часов на эпоху ради гипотетических +0.5 п.п. на датасете, который аналитик с самого начала пометил как грязный, занятие на любителя. Платформа это зафиксировала так: «Обучение остановлено пользователем … Разбираем частичные метрики, чтобы понять причину», а затем – «Работа агентов остановлена пользователем». Вы скажете, что тут нужно добавить взаимосвязь, чтоб агенты понимали причину остановки и вы совершенно правы. Если бы такая возможность была то скорее всего наши агенты начали бы искать конфигурацию для обучения с более простой моделью и подбирать под неё конфигурации, но увы этого ещё нет в платформе.

И главный вывод тут вовсе не “надо было слушаться вето”. Наоборот – я считаю 98.33% отличным результатом: платформа автономно, на сыром объединённом датасете, фактически вышла на уровень конкурента. Откуда тогда те самые 0.7 п.п. недобора? Достаточно посмотреть, чем эти 99% брали у MuqaddasEjaz – там не CNN, а ViT с кастомной головой (LayerNorm -> Dropout -> Linear(512) -> GELU -> ещё один LayerNorm/Dropout -> классификатор), то есть принципиально другой класс архитектуры и более тонко настроенная регуляризация:

# код из ноутбука MuqaddasEjaz
class ViTDeepFakeDetector(nn.Module):
    def __init__(self, num_classes=2, dropout=0.4):
        ...
        self.backbone = timm.create_model(
            CFG['model_name'], pretrained=True, num_classes=0, global_pool='token')
        self.head = nn.Sequential(
            nn.LayerNorm(feat_dim), nn.Dropout(p=dropout),
            nn.Linear(feat_dim, 512), nn.GELU(),
            nn.LayerNorm(512), nn.Dropout(p=dropout * 0.67),
            nn.Linear(512, num_classes),
        )

А наши агенты пошли проверенным путём CNN c предобучением – resnet50 и далее семейство EfficientNet. Это не хуже и не лучше, это другой инструмент под ту же задачу, и разница между ними в районе одного процента и это то, что отделяет крепкое стандартное решение от вылизанного под конкретный датасет.

Что кейс действительно подсветил – так это дырку в обратной связи, о которой я писал абзацем выше: агенты наращивали мощность (а с ней и время эпохи до 8+ часов), не понимая, что я остановил обучение не из-за плохих метрик, а из-за стоимости. Дай я им этот сигнал – они бы наверняка свернули в сторону модели полегче, а не тяжелее.

Итог:

  • На двух из пяти бенчмарк-датасетов человек не нужен вообще (с натяжкой можно сказать на трёх, если считать Food-101 с урезанным количеством данных): принёс данные – забрал модель, которая бьёт или превосходит публичный baseline. Ещё на трёх платформа отработала так же автономно – просто там есть что разобрать по метрикам. И в шестом тесте, deepfake-кейсе, где на мета-датасете из 6 датасетов платформа автономно вышла на уровень живого Kaggle-мастера, где ориентиром был уже не baseline, а человек.

  • Дефолты не стыдные. Предобученные модели, аугментации под задачу, AdamW/SGD + CosineAnnealingLR, label smoothing, early stopping, AMP – агенты собирают конфиги, которые не стыдно показать живому ML-инженеру.

  • Recovery действительно спасает. До четырёх итераций подряд: первая модель слабая – платформа не отдаёт мусор, а думает заново.

  • Адаптация стратегии на лету. На Food-101 агенты сами диагностировали переобучение прошлой попытки и сменили архитектуру.

  • Полная прозрачность. Каждое решение задокументировано и читается в UI – видно не только что выбрано, но и почему.

  • Недобор по accuracy оказался полировкой, а не потолком – и это проверено числом. На обоих “слабых” датасетах система не стала прятаться за метрику.

2 из 5 датасетов – выше публичный baseline для ResNet50 transfer learning по accuracy, причём оба уверенно. Третий “успешный” кейс – Food-101 – я сознательно гонял на урезанном датасете (100 картинок на класс). И всё это полностью автономно: от датасета до обученной модели и отчёта о качестве, с подробным логом рассуждений, который не нужно принимать на веру – его можно открыть и проверить.

А два оставшихся датасета – это не “провалы платформы”, а её зоны роста с измеренным потенциалом. И ключевое слово здесь – измеренным. Я взял каждый из двух недотянувших кейсов, поправил по одному осмысленному рычагу и точечный повторный прогон вернул большую часть отставания, загнав разрыв с baseline в разумный допуск. Это принципиально другая ситуация, чем “не работает”.

Таким образом инструмент уже сейчас закрывает типовые задачи классификации изображений “под ключ”. А прозрачность рассуждений значит, что каждый его шаг можно не только использовать, но и перепроверить – что для AutoML, на мой взгляд, важнее любой одной красивой цифры, будь то accuracy или эффектный AUROC.

Если дочитали досюда – спасибо. Платформа ещё в пути, и я буду рад вопросам и критике в комментариях.


Источники:

  1. Artificial Analysis GPT-5.1

  2. Kornblith et al., Do Better ImageNet Models Transfer Better?, arXiv:1805.08974, 2018.

Автор: sSindiKk

Источник