Содержание статьи
Это всегда черный ящик»: как тестировать нейросети
Постановка задачи
Еще одним, наверное, самым популярным способом определения тренда и его силы являются индикаторы-осцилляторы. Применение таких индикаторов удобно еще и тем, что выходные данные индикаторов являются нормализованными. Недолго думая, для эксперимента я взял 4 стандартных индикатора RCI, CCI, ATR и MACD со стандартными параметрами. Я не проводил никакого дополнительного анализа по выбору индикаторов и подбора их параметров.
Следить за нейросетью нужно с момента ее запуска. Иногда даже идеально подготовленная модель со временем устаревает и теряет актуальность. К примеру, через полгода рядом с пекарней может открыться детский сад, и это тоже скажется на продажах. Появятся новые условия и данные, и нужно будет провести апдейт нейросети. Если не учесть этот фактор, модель станет невалидной.
Нельзя проверять модель исключительно как отдельную сущность. Следует провести классическое интеграционное тестирование. Ведь нейросети обязательно взаимодействуют с некоторыми посторонними сервисами. В случае пекарни это может быть сервис прогноза погоды, откуда система будет брать данные на ближайшую неделю. Это позволит опробовать модель в условиях, максимально приближенных к реальности. Следите за взаимодействием всех элементов системы.
Удаление данных работает эффективно, но нивелирует время и усилия, затраченные на обучение модели. Проблему лучше предупредить, чем решать радикальными методами. Поэтому советую отслеживать количество тренировочных и тестовых ошибок нейросети на протяжении всех обучающих циклов.
Представим двух студентов. Один ходит на пары, все учит и хорошо понимает, как применять теорию на практике. Он, скорее всего, успешно сдаст экзамен. Второй студент зазубривает готовые ответы к билетам, не задумываясь о сути того, что написано. Он тоже может сдать экзамен на отлично. Но если ему дать задачи, отличные от зазубренных, наверное, он не справится. Аналогичная проблема может постичь и нейросеть.
Затем даем ей вторую картинку с котом, третью, десятую — и так далее до нужного предела. Этим условным пределом станет момент, когда нейросеть начнет сама нам «говорить», что на картинке изображен кот. Она будет «узнавать» его по общим для всех изображений критериям. Здесь все работает примерно так же, как у людей. Мы отличаем кошек от других животных по форме тела, головы, ушей, хвоста, усов.
Вы можете собрать свой датасет. Он состоит из ряда параметров: дата, температура воздуха на улице, праздничные события, день недели, месяц и т.д. Эти поля называются features . Отдельная колонка в датасете — количество ожидаемой выпечки в определенный день ( target) :
Если не удалось загрузить данные предварительно обученной сети, то выводим в журнал сообщение с указанием кода ошибки и приступаем к созданию новой необученной сети. Вначале объявляем экземпляр класса CArrayInt, в котором укажем структуру нейронной сети, количество элементов указывает на количество слоев нейронной сети, а значение элементов указывает на количество нейронов в соответствующем слое.
Программы, используемые в статье
Результаты тестирования показывают, что оба варианта организации нейронной сети дают схожие результаты как по времени обучения, так и по точности предсказания. В тоже время полученные показатели говорят о необходимости дополнительных затрат времени и ресурсов на обучение. Желающие проанализировать динамику обучения нейронных сетей могут ознакомиться со скриншотами каждой эпохи обучения во вложении.
В первой статье упоминался метод «5-почему» и я предлагаю продолжить данный эксперимент и создать сеть с 4-мя скрытыми слоями. Количество нейронов в первом скрытом слое я поставил равным 1000, но вполне допускаю и настраивание некой зависимости от глубины анализируемого периода. Воспользовавшись правилом Парето, будем уменьшать количество нейронов в каждом последующем слое на 70%. К вышесказанному добавим ограничение по количеству нейронов в скрытом слое не менее 20.
Следующим шагом приступим к работе непосредственно с классом нейронной сети. Вначале нам нужно создать экземпляр класса. При инициализации класса CNet в параметрах конструктора передается ссылка на массив с указанием структуры сети. Здесь хочется сказать, что обучение нейронной сети процесс довольно трудозатратный как по вычислительным ресурсам, так и по времени. Поэтому, было бы, наверно, неправильно каждый раз при перезапуске программы обучать нашу нейронную сеть заново. И я применил небольшую хитрость, вначале объявляем экземпляр сети без указания структуры и пытаемся загрузить предварительно обученную сеть с локального хранилища (имя файла я вынес в #define).
Когда вы все проверили, разработчики исправили баги и модель отправилась в деплой на продакшен, ваша работа как тестировщика еще не заканчивается. На этом этапе вы должны продумать алерты. К примеру, если нейросеть прогнозирует увеличение количества нужной выпечки на 5% в течение 3 дней подряд, следует узнать об этом. Пригодится email-сообщение. Этот алерт позволит быстрее зафиксировать нестандартную ситуацию и разобраться, почему модель ведет себя именно так.
В свое время мне казалось, что поскольку нейросеть учится схожим с нами образом, то количество итераций должно быть максимальным. Ведь чем чаще мы повторяем какую-нибудь информацию, тем надежнее запомним ее. Как результат — качественнее будем работать со связанными данными. Но здесь есть подводный камень, который может полностью испортить нейросеть.
А можно не ограничиваться готовыми данными. Если вам их не хватает, чтобы улучшить качество обучения и тестирования нейросети, то можете сделать свои. Для этого необязательно создавать новые. С помощью простого графического редактора можно отобразить оригинальную картинку, перевернуть ее, изменить цвета, контрастность, вырезать фрагменты и т.д. Таким образом, вы быстро получите подмножество данных, на которых сможете тренировать и тестировать нейросеть. Ведь на изображениях фактически разные кексы.
По сути это код со специфическим алгоритмом, созданный подобно биологическим нейронным сетям человеческого мозга. Представьте себе систему, состоящую из слоев. Каждый слой из искусственных нейронов, соединенных между собой десятками или сотнями связей. Таких нейронов, как и слоев, может быть множество: от нескольких до миллионов. Детальнее можете узнать из этого видео:
Затем проверим, было ли просчитано прогнозное состояние системы на предыдущем шаге цикла. Если да, то проведем корректировку весов в направлении правильного значения. Для этого очистим содержимое массива TempData, проверим сформировался ли фрактал на предыдущей свече и внесем правильное значение в массив TempData (ниже приведен код для нейронной сети регрессии с одним нейроном в выходном слое). После чего вызовем метод backProp нашей нейронной сети с передачей ссылки на массив TempData в качестве параметра. И актуализируем статистические данные в переменных dForecast (процент правильно предсказанных фракталов) и dUndefine (процент пропущенных фракталов).