Генератор синтетических данных. Обучение нейронных сетей для промышленной дефектоскопии
В этой заметке мы расскажем о генераторе синтетических данных — инструменте, генерирующем датасеты для обучения нейронных сетей.
Введение
Мы разрабатывали генератор синтетических данных в рамках работы над проектом, целью которого было создать решение, позволяющее обнаружить дефекты труб на ТЭЦ при помощи беспилотников (БПЛА) и нейронных сетей, тем самым оптимизировать время и расходы на проведение сервисного обслуживания станции.
Использование корректно сгенерированных синтетических данных (качество сгенерированных данных должно соответствовать качеству реальных данных, также важны детализации и семантика объектов в данных — они должны соответствовать реальным) может улучшить качество работы нейронных сетей и различных алгоритмов машинного обучения. Синтетические данные также позволяют привнести в датасет те объекты, которые редко встречаются в реальных данных или те, которые еще не были зафиксированы в реальных данных, но ясно как их сконструировать.
Если говорить совсем коротко, то главными преимуществами генераторов синтетических данных являются:
- возможность получения данных, которые трудно или невозможно получить в реальном мире (см. наш проект Kaspersky Plant Sim);
- возможность экономить время и деньги в процессе формирования датасета для обучения моделей машинного обучения (например за счет генерации автоматической разметки).
В нашем случае, генератор позволяет получать 3D данные в виде пространственных сцен, и способен стать источником новых данных не только для задачи классического компьютерного зрения (CV), но и для целого ряда задач геометрического глубокого обучения (3D ML, GDL).
Применение алгоритмов из области GDL могут дать значительное преимущество, так как пространственные сканеры / камеры глубины (RGB-D) позволяют находить менее очевидные человеческому глазу дефекты и реконструировать изучаемые объекты.
Создание генератора
Стоит начать с того, что вся работа по созданию искусственного набора данных была осуществлена в Blender, иногда прибегая к скриптам на языке Python (потому что змеевики). Исключение составила лишь программа преобразования растровой разметки в формат Yolo, написанная на языке Rust (потому что ржавые).
На начальных этапах работы тестировалось построение сцены средствами полигонального моделирования, незамедлительно встал вопрос о внесении разнообразия в модели и неудобстве создания разметки, потому что отмечать поврежденные участки кроме как группами вершин на ум не приходило. Из этих соображений было принято решение объединить создание дефектов и выведение их разметки в шейдерах.
Задача была разделена на следующие этапы:
- Настройка цифрового двойника камеры БПЛА с накамерным светом;
- Создание инструмента для быстрого моделирования базовой геометрии труб;
- Настройка процедурных материалов для различных поверхностей труб;
- Настройка процедурных материалов для различных дефектов труб;
- Настройка процедурной анимации позиции камеры, освещения и материалов для создания разнообразных изображений из одной сцены;
- Настройка масок дефектов;
- Рендер;
- Приведение разметки дефектов к формату YOLO.
Ниже продемонстрируем как выглядят эти отдельные этапы при их разработке в Blender.
Настройка цифрового двойника камеры БПЛА с накамерным светом
Сначала на сцену добавляется объект с самосветящимся материалом, имитирующий кольцевой осветитель, и всенаправленная лампа назначены дочерними объектами камеры. Размер сенсора, угол обзора, относительное отверстие объектива и разрешение получаемого изображения настроены в соответствии с реальными характеристиками камеры DJI Mavic 2 Zoom.
Инструмент для быстрого моделирования базовой геометрии труб
В первую очередь нужно отметить, что вся геометрия труб строилась по NURBs без прямой конвертации в полигональные модели. Все дефекты, в том числе геометрические создавались посредством материалов на этапе рендера.
Не было никакой необходимости выстраивать совершенно новую сцену в отношении геометрии для каждого кадра, достаточно было сделать несколько заготовок и менять ракурсы, освещение и материалы. Выяснилось, что наиболее распространённая схема размещения труб — простой массив. Создать массив параллельных труб — не представляло никакой сложности, для этого есть модификатор Array. Другой распространенной схемой оказались змеевики, в том числе облегающие цилиндрические поверхности. Для быстрого создания таких труб был написан скрипт на языке Python, в котором можно настроить радиус цилиндрической поверхности, шаг змеевика, его направление и количество повторений.
Настройка материалов поверхностей труб
От использования готовых наборов текстур из изображений пришлось отказаться по нескольким причинам: необходима корректная проекция на геометрию, повторяемость рисунка, предел детализации из-за разрешения. Запекание сгенерированных текстур, например из Substance Painter, было исключено из соображений бритвы Оккама.
Все ноды базовых материалов были объединены в группу с выведенными в интерфейс основными параметрами. В зависимости от конкретной сцены к тем или иным параметрам материала подключались генераторы псевдо-случайных чисел, собранные из ноды белого шума, произвольного индекса объекта, анимированного значения и математических нод.
Сами же материалы внутри группы собирались преимущественно из шумов и градиентов.
Настройка материалов дефектов труб
Такие дефекты как коррозия и цвета побежалости создавались непосредственно из шума Перлина, градиентов и смещения по нормали к поверхности.
В основе каждой трещины лежит процедурная текстура — сферический градиент и по сути трещины имеют форму эллипса, подверженного предварительно многочисленным деформациям через изменение его UV координат. Границы трещин подвержены, как и в случае с коррозией — смещениями по нормали. Повреждённая часть визуализируется шейдером прозрачности, так что в зависимости от освещения через трещины иногда можно разглядеть тыльную поверхность трубы.
Для таких дефектов как выход трубы из ряда и разрыв использовалось векторное смещение по выбранной оси в системе координат объекта. Создание такого, казалось бы чисто геометрического результата, средствами шейдеров опять же обусловлено удобством вывода данных для разметки как значения материала.
Анимация камеры, освещения и материалов
Для получения набора разнообразных изображений из одной сцены позиция и поворот камеры, яркость источников света и параметры материалов анимировались одним ключём и анимационным модификатором Noise с заданными пороговыми значениями. Таким способом можно было не беспокоиться о количестве кадров последующего рендера, — сколько бы их не оказалось, каждый был бы уникальным безо всяких закономерностей.
Настройка масок дефектов
Для вывода черно-белых масок разметки дефектов использовался канал Arbitrary Output Value (AOV), в ноду которого подавался коэффициент смешивания базового материала и материала дефекта. Иногда использовалась бинарная математическая нода Greater Than, выдающая 0, если входное значение меньше порогового и 1 в противоположном случае. Подробнее о методах вывода масок и разметки мы расскажем в следующей статье цикла.
Рендер
В композиторе было настроено две выводящих ноды: одна сохраняла изображение, вторая маску. Сцены рендерились как анимированные, то есть на каждый кадр в заданном диапазоне сохранялось два файла. Изображения отправлялись в директорию с данными согласно соглашениям разметки Yolo, одноименные маски сохранялись во временной директории для последующего преобразования в разметку.
Приведение разметки к формату YOLO
Формат разметки YOLO предполагает обозначение участков изображения ограничивающими прямоугольниками. Текстовый файл должен содержать нормированные координаты центров ограничивающих прямоугольников и их габариты. Для получения такого вида разметки была написана программа, рекурсивно проходящая по соседним пикселам маски, значения которых отличны от нуля, и сохраняющая минимальные и максимальные координаты связанных пикселов, после чего абсолютные координаты вершин прямоугольников нормализовались.
Выбор языка Rust для написания этой программы был обусловлен скоростью выполнения и возможностью с лёгкостью реализовать одновременную обработку нескольких изображений на разных потоках процессора.
Заключение
Blender обладает богатым набором инструментов для создания изображений из трёхмерных сцен, которые также можно использовать для генерации и визуализации многомерных данных. Каналы и пассы позволяют создавать маски для участков изображения, представляющих интерес для разметки. Выгодной особенностью Blender также является возможность расширения его функционала за счет скриптов на языке Python.