Как переучить модель речи за час: от нулей к реальному шуму

Работал над проектом Speech to Text — нужна модель для детектирования команды “zapis” (запись). Звучит просто, но дьявол в деталях.
Сначала я обучил модель на синтетических данных: берёшь голос, оборачиваешь его нулями слева и справа, и вот — модель валидирует на 97.7% accuracy. Тесты в контролируемых условиях показывают 99.9% true positive rate. Казалось бы, в деле!
Но вот беда: в реальном потоке микрофона нет нулей. Вместо них — фоновый шум, шуршание, дыхание. Я запустил тест с настоящим шумом + голосом — результат потрясающий: 0.000000. Модель не видит команду вообще. Вот это поворот.
Проблема была в расхождении между тренировочными данными (идеальные нули) и реальностью (живой шум). Стандартный case в машинном обучении — если модель не генерализируется, нужны более репрезентативные данные.
Я решил переобучить модель на реальных записях с фоновым шумом. Новая архитектура zapis.onnx получилась более сложной: если раньше было ~6000 параметров (22 КБ), то теперь 107,137 параметров (433 КБ). Всё ещё крошечный размер для нейросети, но структура стала содержательнее.
Результат переобучения превзошёл ожидания: - Тест с шумом + голосом + шумом: 0.999716 (было 0.0) - Имитация реального потока: 0.999716 (было 0.0)
Драматическая трансформация! Но цена — модель теперь плохо работает с идеальными нулями (accuracy упал с 99.98% до 11.8%). Это справедливый компромисс: в реальности нулей нет, зато микрофон всегда шумит.
Параллельно я уже натравил обучение модели для команды “stop” — пока она вычисляет признаки из позитивных сэмплов, я занялся тестированием.
Главный урок: синтетические данные для тренировки и реальные условия — это разные миры. Иногда час переучивания даёт больше пользы, чем совершенствование неправильной архитектуры. И всё это помещается в 433 КБ! 😄
Метаданные
- Session ID:
- grouped_speech-to-text_20260219_1840
- Branch:
- master
- Dev Joke
- Если Elasticsearch работает — не трогай. Если не работает — тоже не трогай, станет хуже.