ML в реальном мире: Складская система распознавания деталей

    Одним из проектов над которыми мне пришлось недавно поработать в качестве тим лида команды быстрого прототипирования ИИ решений компании ICL Services [1], стало создание складской системы для распознавания складируемых деталей. Проблема достаточно простая для понимания: на промышленном складе кладовщики, особенно новые, при поступлении новой партии, зачастую не могут с ходу понять что за детали поступили, и куда их нужно отнести. Когда имеются десятки тысяч позиций, задача перестает быть тривиальной, а незнание деталей “в лицо” зачастую превращается в получасовое листание каталогов и блуждание по просторам склада в поисках заветного контейнера, что является пустой тратой времени.

    Решение, которое сразу напрашивается - создание системы, которая при помощи компьютерного зрения распознает попавшую в поле зрения видеокамеры деталь и показывает место на складе, где эта деталь хранится.

    Решение в лоб - сделать с десяток фотографий каждой детали (из около 10-ти тысяч) и обучить на этом классификатор, а потом по мере появления добавлять фото новых деталей и дообучать систему в процессе эксплуатации. Решение вполне рабочее, но… создание обучающей выборки такого размера вживую займет несколько месяцев работы и впоследствии потребует постоянного контроля добавляемых примеров. Заказчик же обычно хочет получить результаты быстрее, дешевле и без ввязывания в дорогостоящее постоянное дообучение системы в ручном режиме.

    Можно ли что-то сделать?

    Нам повезло и ответ в нашем случае был утвердительным. Нюанс, который позволил нам в разы снизить стоимость и продолжительность проекта - это то, что в нашем случае мы имеем дело со складом завода по производству деталей, а сами детали плоские, хотя и производятся из стальных листов разной толщины. А главное - для всех деталей имеются CAD-модели.

    Рис. 1. Пример CAD-модели в Blender [2]
    Рис. 1. Пример CAD-модели в Blender [2]

    Соответственно, оптимальное решение к которому мы пришли - обучить систему на изображениях на основе CAD-моделей, а использовать уже на реальных. Тогда не надо создавать огромный датасет из фотографий реальных объектов. В нашем случае это становится возможным, учитывая, что все детали плоские.

    Делаем 2 модели:

    • Модель сегментации, которая по фото объекта дает его маску (маска плоского объекта однозначно определяет деталь; примеры масок можно посмотреть ниже на Рис. 5);

    • Модель классификации, которая по полученной маске объекта на входе говорит что это за деталь.

    Модель классификации - классическая ResNet-50 [3], предобученная на ImageNet [4]. Датасет создается достаточно прямолинейно. По имеющимся CAD-моделям при помощи скриптов для Blender [2] рендерим маски наших деталей с разбросом смещений детали от центра и под разными углами камеры относительно вертикали (это необходимо, т.к. несмотря на плоскость деталей снимает их камера, которая может это делать под различными ракурсами; мы допускали отклонение до 30 градусов). Количество классов равно количеству наименований деталей в каталоге. При добавлении новых деталей в каталог (на сетевом диске появляются новые CAD-модели) модель автоматически обновляется путем повторного обучения, что занимает несколько часов на том же самом GPU, который параллельно используется для распознавания деталей.

    С моделью сегментации немного сложнее. Необходимо научить модель сегментировать детали на синтетических данных так, чтобы потом сегментация происходила с высокой точностью уже на реальных фотографиях при различной освещенности, была устойчива к изменениям материала деталей, к изменениям фона, к теням.

    Сама модель сегментации - это классическая U-Net [5] (бинарный сегментатор, где для каждого пиксела изображения определяем принадлежит он детали или нет, обученный при помощи Dice Loss [6]) на основе той же ResNet-50 [3], предобученной на ImageNet [4]. Несмотря на нетривиальность, такой синтетический датасет для обучения сегментации удалось построить, симулируя разнообразие возможного внешнего вида деталей, которые мы строим из случайной комбинации следующих элементов:

    • масок деталей (строго говоря, не обязательно деталей; подойдет все, что выглядит как маска);

    Рис. 2. Примеры масок для генерации синтетических изображений деталей
    Рис. 2. Примеры масок для генерации синтетических изображений деталей
    • текстур фона (из любых свободно распространяемых подборок);

    Рис. 3. Примеры текстур фона для генерации синтетических изображений деталей
    Рис. 3. Примеры текстур фона для генерации синтетических изображений деталей
    • текстур материала деталей (из любых свободно распространяемых подборок);

    Рис. 4. Примеры текстур материала деталей для генерации изображений
    Рис. 4. Примеры текстур материала деталей для генерации изображений
    • того, как могут выглядеть блики на краях (см. примеры генерации ниже на Рис. 6);

    • того, как деталь на краях может отбрасывать тени (см. примеры генерации ниже на Рис. 6);

    • того, как тени могут налагаться на сцену (см. примеры генерации ниже на Рис. 6).

    Тема достаточно сложная, но толковый специалист по машинной графике за разумное время решит проблему генерации синтетических примеров для сегментации. Здесь я не буду приводить формул. Приведу лишь примеры масок (Рис. 5), которые относительно легко получаются из CAD-моделей, и процедурно сгенерированные по ним псевдо-фотографии (Рис. 6).

    Рис. 5. Примеры масок деталей для генерации синтетических изображений деталей
    Рис. 5. Примеры масок деталей для генерации синтетических изображений деталей
    Рис. 6. Примеры сгенерированных по маскам синтетических изображений деталей
    Рис. 6. Примеры сгенерированных по маскам синтетических изображений деталей

    Добавим аугментацию (augmentation [7]). Теперь примеры для обучения сегментатора выглядят так.

    Рис. 7. Аугментированные (augmented) примеры для обучения модели сегментации
    Рис. 7. Аугментированные (augmented) примеры для обучения модели сегментации

    Дальше все просто. Учим модель-сегментатор сегментировать изображения, а модель классификатор классифицировать маски деталей. И проверяем точность классификации на тестовой выборке (в нашем случае у нас было 177 реальных фотографий деталей).

    Рис. 8. Результаты классификации на нескольких примерах тестовой выборки
    Рис. 8. Результаты классификации на нескольких примерах тестовой выборки

    Итого имеем: Correct predictions: 100.00% (177 out of 177)

    Ну здесь нам просто повезло, и вся тестовая выборка определилась правильно на 100%, хотя от запуска к запуску результаты могут немного отличаться. Такое происходит, т.к. мы используем технику Test Time Augmentation (TTA) [8] как для сегментации, так и для классификации, т.к. TTA позволяет снизить ошибку примерно на 10%. Поэтому процесс классификации недетерминированный и зависит от random seed (на который завязана TTA). Если же смотреть усредненную точность по 10 запускам, то она получается около 99% (более объективные цифры мы получим позже, когда у нас появится доступ к большому количеству реальных изображений и мы сформируем полноценный test set).

    Остается завернуть все это в простой пользовательский интерфейс, который в первой версии выглядел так.

    Рис. 9. Пользовательский интерфейс первой версии системы
    Рис. 9. Пользовательский интерфейс первой версии системы

    Здесь мы видим изображение с камеры (в данном случае камеры тестового стенда, под которую мы подкладываем черно-белую распечатку фото детали), результат обработки детали моделью сегментации и топ 16 предсказаний модели (если вдруг модель ошибется с топ 1 предсказанием, то все-равно с вероятностью более 99.9% ее можно отыскать в топ 16). Для найденной детали мы видим ее наименование и позицию на карте склада с указанием номера полки.

    Таким образом, кладовщик теперь всегда может быстро понять что за деталь ему попалась, и где такие детали хранятся. Для этого ему нужно просто поместить деталь в поле зрения видеокамеры на входе в склад.

    PS:

    Эта статья является первой в цикле статей “ML в реальном мире” где я планирую поделиться историями создания продуктов, которые мы уже создали и еще только будем создавать нашими командами дата-саентистов компании ICL Services [1].

    Также я веду микроблог, в котором разбираю ключевые моменты и идеи в периодически появляющихся передовых работах в сфере машинного обучения.

    Не стесняйтесь оставлять обратную связь в комментариях. Всем удачи!

    Ссылки

    [1] ICL Services

    [2] Blender

    [3] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun, et al. Deep Residual Learning for Image Recognition. Ссылка.

    [4] Olga Russakovsky, Jia Deng, Hao Su, Jonathan Krause, Sanjeev Satheesh, Sean Ma, Zhiheng Huang, Andrej Karpathy, Aditya Khosla, Michael Bernstein, Alexander C. Berg, Li Fei-Fei, et al. ImageNet Large Scale Visual Recognition Challenge. Ссылка.

    [5] Olaf Ronneberger, Philipp Fischer, Thomas Brox, et al. U-Net: Convolutional Networks for Biomedical Image Segmentation. Ссылка.

    [6] Fausto Milletari, Nassir Navab, Seyed-Ahmad Ahmadi, et al. V-Net: Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation. Ссылка.

    [7] Data Augmentation

    [8] Test Time Augmentation

    ICL Services
    Цифровые технологии для бизнеса

    Комментарии 14

      +2
      Здесь мы видим изображение с камеры (в данном случае камеры тестового стенда, под которую мы подкладываем черно-белую распечатку фото детали), результат обработки детали моделью сегментации и топ 16 предсказаний модели (если вдруг модель ошибется с топ 1 предсказанием, то все-равно с вероятностью более 99.9% ее можно отыскать в топ 16). Для найденной детали мы видим ее наименование и позицию на карте склада с указанием номера полки.

      Обучение с подкреплением не делали?
      Если да, то каким способом?

      Например можно пользователя заставлять «ткнуть» на верную деталь. Если она не на первом месте — записывать данное изображение в обучающую выборку для дообучения модели.

      Дообучать можно сразу (если данных мало) или раз в сутки.

      Таким образом через год эксплуатации можно выйти на 99.9999%.

      Или не прав?
        +2
        Обучение с подкреплением не делали?
        Нет. Здесь все «классически» сделано.

        Например можно пользователя заставлять «ткнуть» на верную деталь. Если она не на первом месте — записывать данное изображение в обучающую выборку для дообучения модели.

        Дообучать можно сразу (если данных мало) или раз в сутки.
        Дополнительный трейн сет на основе фидбэка пользователя собирать можно, но это сильно удорожает поддержку решения. Будем рассматривать такой вариант только если в процессе эксплуатации возникнет непредвиденные кейсы с низким качеством распознавания, и это будет оптимальным решением.

        Таким образом через год эксплуатации можно выйти на 99.9999%.
        99.9999% это вряд ли. Всегда будут кейсы, когда распознавание будет сильно хуже среднего. У нас цель — ускорить работу кладовщика. Целевая метрика — 98% правильно распознанных деталей. Все что выше, это хорошо, но экономия, к примеру, 0.1% времени свыше 98% уже незаметна с точки зрения бизнеса. Поэтому экономически нецелесообразно тратить усилия на такие улучшения (хотя с точки зрения дата-саенса улучшить результат можно).
        +1
        А разве детали, поступающие на склад партиями не имеют артикула на упаковке или сопровождающих документах?
        Часто бывает, что детали одной формы имеют разные характеристики.
          0

          Вероятнее всего, это склад при производстве, т.е. завод сам их и производит.

            –1
            Так и есть. Кладовщик как раз и клеит наклейки.
              +1
              Если кладовщик клеит наклейки — это штучное производство, а ни как не (десятки тысяч наименований).
                –1
                Честно говоря, я лично ни разу не был на самом складе и не видел что они приклеивают. Возможно, номер партии прикладывают. А так в день поступает ~600 деталей.
          +1
          судя по деталям, должно быть большое количество похожих деталей, только разного физического размера(разного диаметра фланцы либо разной длины пластины). Есть ли такая проблема и как её решить, если маски по сути получаются идентичными?
            +1
            На самом деле так и есть. И мы ее решаем. Только ввиду формата блог-поста я не описал всех деталей.
            В нашем случае, мы во время трейна снизу изображения добавляем масштабную шкалу (черные и белые чередующиеся полоски) в 50% случаев (чтобы модель работала как со шкалой, так и без).
            Во время инференса, если расстояние от камеры до детали статично (как в случае камеры на входе склада), то мы также добавляем шкалу.
            Если же инференс будет с камеры телефона (пока не реализовано), то шкала не добавляется.
            Со шкалой модель не путает разные размеры.
            +1
            Можете рассказать в двух словах каким образом у вас организована поставка деталей на склад? Раз это производство, то по идее детали должны изготавливаться по заказ-нарядам (или как там называется документ?) в которых, среди прочего, должен быть указан код основного документа (чертежа или CAD файла), номер, ID, «имя» или что-то еще уникальное для детали. И на склад изготовленная партия, в теории, должна приходить с какой-никакой сопроводительной документацией (опять же код детали, кто ее изготовил и т.п.). Или на склад их приносят со словами «нате вам железо», а дальше это ваши проблемы?

            P.S. Ваше решение классное, все дела. Просто хочется понять почему реальная проблема на производстве нуждается именно в таком, весьма сложном, решении.
              0
              Да, конечно.
              Склад промежуточный и используется между операциями (после того как деталь вырезана, но до покраски/сборки узлов). Заказ-наряд есть, но он не отражает полного списка произведенного. Чтобы отходов производства было меньше, в остающиеся свободные места на металлическом листе добавляют детали, которых нет в заказ-наряде, но они повышают коэффициент использования материала.
              А для деталей, которые есть в списке, новый кладовщик, даже видя наименования, не всегда может соотнести их с тем что видит. Поэтому, даже имея наименования деталей, ему приходится рыться в каталогах, чтобы понять как деталь выглядит. С опытом они, наверняка, и в полной темноте могут детали отличать и место хранения находить, но из-за текучки опыт постоянно обнуляется. Изо дня в день заказы меняются по наименованиям (мелкая серия). А т.к. перечень деталей больше 10000 наименований, то постоянно попадаются детали, которых кладовщик раньше не видел.
              Через пару месяцев кладовщик меняется и все начинается по новой.
              +1
              Весьма интересный материал!
              Какой софт (скорее фреймворк) был использован для написания моделей классификации/сегментации?

              У меня есть небольшое дополнение – в данный момент камера для съёмок скорее всего находится в каком-то фиксированном месте. По этой причине, почему бы на этом месте не создать пост видеосъёмки? Если правильно понимаю, фон вносит коррективы в распознавание деталей. Так можно использовать определённую или наиболее подходящую подложку (с контрастным фоном, точками привязки, линейкой и т.д.).

              Фон, как пример — коврик для резки.
                0
                Весьма интересный материал!
                Спасибо.

                Какой софт (скорее фреймворк) был использован для написания моделей классификации/сегментации?
                На pytorch делалось.
                Классификация на «голом» ResNet-50.
                Сегментация на github.com/qubvel/segmentation_models.pytorch
                Аугментация на github.com/albumentations-team/albumentations

                У меня есть небольшое дополнение – в данный момент камера для съёмок скорее всего находится в каком-то фиксированном месте. По этой причине, почему бы на этом месте не создать пост видеосъёмки?
                Так и есть. Видеокамера находится на входе в склад.

                Если правильно понимаю, фон вносит коррективы в распознавание деталей. Так можно использовать определённую или наиболее подходящую подложку (с контрастным фоном, точками привязки, линейкой и т.д.).
                Фон, как пример — коврик для резки.
                Это тоже используется. Несмотря на то, что модель неплохо работает с широким спектром фоновых материалов при разных уровнях освещения, на однотонном контрастном фоне результат становится еще лучше. В продакшне под камерой располагается стол, который «на всякий случай» окрашен в зеленый цвет и сверху есть доп. подсветка.
                  +2
                  Благодарю за развёрнутый ответ.
                  Не воспринимайте слишком серьёзно, но если деталь протирать перед съёмкой чистящей салфеткой или каким-либо составом для обработки металла — контрастность должна быть еще выше.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое