Буквально пару дней назад компания Aurorai передала в опытную эксплуатация систему распознавания дефектов и контроля состояния тележек для локомотивов Ермак. Задача нетривиальная и очень интересная, первым этапом которой было предложено оценить состояние тормозных колодок и ширины бандажа. Нам удалось решить задачу с точность до 1мм при скорости локоматива до 30 км/ч! Хочу отметить, что благодаря специфики можно было использовать “TTA (test-time augmentation)” – яркий пример kaggle-style хака из соревнований, который плохо ложится на прод и семантическую сегментацию на базе se_resnext50 encoder, которая даёт поразительный по точности результат в предсказании маски.

Описание задачи

Необходимо создать аппаратно-программный комплекс детектирования дефектов тормозных колодок и вывода данных бригадиру смены.

Предпосылки к задаче

Как оказалось, огромное количество колодок, около 80%, меняется в ПТОЛ (пунктах технического осмотра локомотивов), и это происходит каждые 72 часа для каждого локомотива. Основная масса проверок в ПТОЛ – это визуальный осмотр мастером внешней части тележки локомотива.



План решения задачи:

  1. Подбор оборудования
  2. Сбор данных
  3. Обучение модели
  4. Разработка сервера с REST API
  5. Разработка клиента для планшета на Android
  6. Проектирование и сборка стойки для размещения камер и света
  7. Опытная эксплуатация

Подбор оборудования

Пожалуй, одной из самых сложных, если не сказать самой сложной, задачей было выбрать камеры, объективы и свет в условиях ограниченного бюджета и времени: MVP нужно было сделать за полтора месяца. За пару дней гугл сделал из меня эксперта по железу для машинного зрения. Выбор остановился на камерах Basler и импульсной подсветке 6к люмен, синхронизирующейся с камерой. В пользу Basler(70 кад/сек, разрешение до 1920х1024) говорило его API на python, что значительно облегчало интеграцию всех компонентов системы, единственный минус — это цена камер ~ 100 т.р.

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

Подсветка: опытным путем было установлено необходимое время свечения светодиодов, их тип, параметры линз. Пробовал 3 разные модификации линз для светодиодов, с углом 30, 45, 60 в конечном итоге выбрал матовые линзы с углом 45.





Сборка и проверка сигнала управления импульсной подсветкой для камеры



Для серверного железа я взял, Intel Core i7-7740X Kaby Lake, 46gb RAM, 1 TB SSD и 3х1080Ti — этого вполне хватает, чтобы предсказывать два 3-секционных локомотива не дольше чем за 2 мин.

Колхозное охлаждение бутерброда из видеокарт сдувает 10 град.



Сбор данных

Создание датасета – это отдельная песня, никому нельзя доверить сие мероприятие, и поэтому меня отправили в далекий малоизвестный городок в глубине нашей необъятной родины. Я сфотографировал на телефон(!!!) около 400 колодок. Забегая вперёд, скажу, что доблестные сотрудники депо, видимо испугавшись ревизора из Москвы, поменяли все колодки на локомотивах на абсолютно новые и покрасили их свеженьким слоем краски, смотреть на это было смешно и страшно. Я предвкушал худшее, правда еще было около 400 фоток совсем других колодок, которые я сделал в московском депо.

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

Ожидание:



Реальность:





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

Обучение модели

Лучше всего себя показала модель c энкодером se_resnext50 и декодером с scse блоком из этого репозитория, но scse(реализация для pytorch) пришлось убрать из соображений ускорения процесса предсказания, т.к. нужно было предсказать за минуту. Для обучения модели использовался фреймворк Pytorch 1.0.1, с большим количеством аугментаций от albumentations и самописной аугментаций Horizontal Flip для смены класса при отображение.

def train_transform(p=1):
        return Compose([
            OneOf([
                CLAHE(clip_limit=2),
                IAASharpen(),
                IAAEmboss(),
                RandomBrightnessContrast(brightness_limit=0.8, contrast_limit=0.8),
                HueSaturationValue(hue_shift_limit=50, sat_shift_limit=50, val_shift_limit=50),
                RGBShift(r_shift_limit=50, g_shift_limit=50, b_shift_limit=50),
                JpegCompression(quality_lower=30),
                RandomGamma(),
                GaussNoise()
            ], p=0.3),
            OneOf([
                Blur(),
                MotionBlur(),
                MedianBlur(),
            ], p=0.3),
            ShiftScaleRotate(shift_limit=0.2, scale_limit=0.4, rotate_limit=5, p=0.5),
            Normalize(p=1)
        ], p=p)

В качестве функции потерь я выбрал The Lovasz-Softmax loss, вел он себя практически также как и bce + jaccard, но лучше BCE, который слишком сильно фитится на разметку. Так же вызовом стал выбор алгоритма определения порядкового номера колесной пары и колодки, были варианты с metric learning, но мне нужно было быстро показывать результат, и в голову пришла идея разметить колодки на классы 1 и 2, где 1 — ориентация вправо, а 2 — влево. Сеть начала предсказывать не только маску, но ориентацию. С помощью нехитрых эвристик удалось достаточно надежно определять порядковые номера колодок и колёсных пар, далее усредняя предсказания, фактически использую ТТА с небольшим сдвигом объекта при движении и разным углом освещения дает хороший результат в точности маски даже на разрешении 320х320.

Отдельно стояла задача определения клиновидного дефекта у колодок, было много идей от Преобразования хаффа, до разметки углов/границ колодки точками/линиями разных классов. В конечном итоге победил вариант, как это делают рабочие: нужно отступить 5 см от узкого края и замерить ширину, если она в пределах нормы, то колодку пропускаем.

Пайплайн для обучения взял отсюда MICCAI 2017 Robotic Instrument Segmentation. Процесс обучения состоит из трех этапов: обучения с замороженным энкодером, обучение всей сети и обучение c CosineAnnealingLR. В первых двух стадиях используется ReduceLROnPlateau.

Программирование REST сервера и клиента на Android

Для REST сервера я выбрал flask — проще не придумать, запуск за 2 минуты. Базу данных для хранения решил сделать своими руками в виде простой структуры папок и файла текущего состояния. Приложение для планшета на Android Studio, благо последние версии просто рай для разработчика.

Проектирование и сборка стойки для размещения камер и света

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





Приступаем к испытаниям!


Результат превзошел все ожидания. Специалистам компьютерного зрения задача может показаться достаточно прямолинейной и простой. Однако у меня был некоторый скепсис из-за двух вещей: во-первых, обучающая выборка была небольшой и не содержала граничные кейсы типа очень тонких колодок; во-вторых, испытания проходили в сильно других условиях съемки и освещения.





Jaccard на валидации доходит до 0.96, визуально колодки от сегментированы очень чётко, добавим усреднение по нескольким фото и получаем очень хорошую точность оценки ширины колодки. По ходу испытаний оказалось, что можно работать и с тележками других локомотивов, но брать более скоростные камеры:





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

Благодарности

Благодарю сообщество ods.ai, без вашей помощи мне бы не удалось всё это сделать в столь короткие сроки! Огромное спасибо n01z3, надоумевшему меня заняться DL, за его бесценные советы и чрезвычайный профессионализм! Большое спасибо идейному вдохновителю Василию Манько (CEO, компания Aurorai), лучшему дизайнеру Татьяне Брусовой.

До встречи в следующей серии рассказа!

Aurorai, llc

Комментарии (44)


  1. slaFFik
    11.03.2019 14:45

    Из статьи я не понял, в чем помогает ваше решение или какую проблему оно решает.


    Раньше — 1:{каждые 3 дня} в 2:{ПТОЛ} 3:{визуальный осмотр мастером}.
    Теперь — 1:{?} в 2:{?} 3:{визуальный осмотр камерой + анализ сеткой}.


    Проверка стала дешевле? Более качественной? Чаще стала проводиться? Была ли выведена зависимость каких-то проблем старой проверкой и влияние новой проверки на результаты?


    ЗЫ Потом увидел вот это заключение:


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

    То есть оценок никаких не было, расчетов и прочего (из-за "на мой взгляд"). То, что технология хорошо себя показала, — не релевантно, если нет полезного "выхлопа". Тот же блокчейн, технология хорошая, но...


    ЗЫ2 Не хватает легенды для цветового кодирования на обработанных фотках и какой-то базовой информации о том, как именно стираются эти самый колодки (например, я не знаю — у них уменьшается диаметр или они становятся "тоньше", или еще какие особенности).


    1. Alex_Donchuk Автор
      11.03.2019 15:48

      Спасибо, учту!


  1. ChePeter
    11.03.2019 14:45
    +1

    Класс, вопросы возникли
    1. На видео 4 тележки на тепловоз и по 8 колодок, и точность алгоритма 0.96.
    4*8*(1-0.96) = 1.28
    Это значит, что на каждом тепловозе при каждой проверке ваша супер система будет пропускать одну изношенную колодку. А как у людей качество осмотра?
    2. Алгоритм ищет только износ, а как с другими дефектами? Трещину пропустит?
    3. Как определяете узкий край? «нужно отступить 5 см от узкого края»
    4. А разве бывают не круглые колёса, зачем такой мощный и универсальный инструмент, как Албументация? Для чего нужна такая сложная аугментация?
    5. Если человек пропустит брак, то у него есть личная ответственность ( при И.В. могли и расстрелять), а в этом данном случае какую ответственность несут программисты? Или система не будет внедряться?


    1. Alex_Donchuk Автор
      11.03.2019 15:47
      -1

      1. Jaccard для сравнения масок одного объекта, а не всех сразу.
      2. В следующим этапе.
      3. Изходя из маски у неё есть узкий и широкий край если присутсвует клиновидный дефект.
      4. Плохо читали статью =)
      5. Возложим отвественность на люей задающих странные вопросы.


      1. ChePeter
        11.03.2019 16:33
        -1

        1. Покажите пожалуйста код валидации. Очень интересно
        2. Т.е. человек остался и ваша эта супер система как дополнительный придаток (типа пятое колесо )
        3. Ясно, что у маски может быть и узкий и еще какой край. Вопрос то в том, как ваша программа его находит?
        4. Может плохо писали статью?
        5. Кто будет подписывать акт осмотра и нести ответственность?


        1. Alex_Donchuk Автор
          11.03.2019 16:52
          +1

          1. Ссылка на репу с валидацией в тексте, ну и описание что такое Jaccard тоже.
          2. Москва не сразу строилась.
          3. Легко =)
          4. Как вариант!
          5. Обязательно выясню


          1. ChePeter
            11.03.2019 17:06

            Если Вы про вот этот код github.com/ternaus/robot-surgery-segmentation/blob/master/validation.py
            то обратите внимание на 24 строку " valid_jaccard = np.mean(jaccard).astype(np.float64)"
            тут берется среднее по всем картинкам валидационной последовательности.
            Вы же утверждаете, что на КАЖДОЙ! картинке у Вас точность 0.96.
            И это две большие разницы, если не поняли сами, то спросите у старших товарищей.
            И Вы написали ерунду, очередное неправильное решение ненужной никому задачи и пытаетесь прикрыться уважаемыми именами.


            1. Alex_Donchuk Автор
              11.03.2019 17:21

              Ждём ваших разработок! Чтобы было на кого равняться, спасибо за комментарии.


  1. lelik363
    11.03.2019 15:03

    Буквально пару дней назад компания Aurorai передала в опытную эксплуатация систему

    На какой считалке (вероятно, промышленный комьютер) думаете делать рабочую систему?


    1. Alex_Donchuk Автор
      11.03.2019 15:43

      Планировал на jetson TX2, но пока не понятно. В финальном варианте будет существенно более широкий функционал.


      1. lelik363
        11.03.2019 20:38

        Jetson TX2 это всего лишь комплект разработчика…
        Боевая система должна сильно отличается от комплекта разработчика…
        Исполнение уличное?


        1. Alex_Donchuk Автор
          11.03.2019 20:56

          Не хочу вдаваться в полемику, но dev kit он отдельно так и маркируется. TX2 просто плиткой продаётся, на которую вешается в зависимости от требований панелька с I/O дырочками, ну и есть еще на другой компонетной базе TX2i, для отправки в космос) А исполнение будет и уличное и нет, в зависимости от требований. Вообще я думаю, что системы уйдёт на высокие скорости и будет поддерживать до 250 км/ч, соответсвенно с уличной установкой и требованием по вибрации.


  1. Zolg
    11.03.2019 15:21

    На видео за первым составом с интервалом в несколько метров идет локомотив. Это как вообще?


    1. Alex_Donchuk Автор
      11.03.2019 15:41

      Это не состав, а локомотив. Их вместе загоняют в ПТОЛ.


      1. Zolg
        11.03.2019 15:48

        удержание дистанции как-то автоматизированно? насколько это безопасно? и в чем смысл так впритык ехать?


        1. Alex_Donchuk Автор
          11.03.2019 15:56

          Это нарушение правил, ошибка диспетчера.


  1. Tyiler
    11.03.2019 15:50
    +3

    Спасибо, интересно.
    Дорого очень только: камера (100 * 2) + сервер (3 видяхи 1080 = 3 * 40 + ...) +…

    Как сэкономить. Кейс из опыта — откажитесь от реалтайма, то есть записывайте кадры с камеры на диск, когда идет состав. Потом запускайте распознавалку на кадрах, когда прошел.
    Дальше пилите распознавалку, чтобы без НСети (подумайте, можно ли без нее — классикой побить) в идеале и все достаточно быстро (минуты) считалось на CPU (i5).
    Если от НС не отказываться, то максимум 1 видяха (или да — какой-нидь jetson рассмотреть), CPU можно слабее, он все равно участвовать не будет.


    1. Alex_Donchuk Автор
      11.03.2019 15:55

      Спасибо!


    1. Mirn
      12.03.2019 09:06

      на правах просто идеи:
      интересно, наверное, можно ещё сэкономить и на камере поставив 1д камеру:
      как например в статье:
      elm-chan.org/works/lcam/report.html
      (там же есть в ресурсах сканы поездов)
      а разную скорость скомпенсировать подстройкой по оси Х с обратной связью по коэффициенту приплюснутости колеса (стремясь к кругу).


      1. Alex_Donchuk Автор
        12.03.2019 09:30

        Линейная камера? У нас их надо ставить две под разным углом, т. к. в тележку утоплены некоторые элементы и их видно только по краям области съёмки. Если будем выходить на съёмку на высоких скоростях, то будем ставить такие, они умеют писать до 9 ГГц в 4к, если не ошибаюсь.


        1. Zolg
          12.03.2019 12:11

          10^9 Гц ?!?!?


          1. Alex_Donchuk Автор
            12.03.2019 12:21

            Сорян, не Г, а — к см. тут


  1. zxweed
    11.03.2019 16:28

    этого вполне хватает, чтобы предсказывать два 3-секционных локомотива не дольше чем за 2 мин.
    зачем предсказывать локомотивы?


  1. AlexanderG
    11.03.2019 16:58

    С точки зрения UX, мне кажется, очень не хватает прогресс-бара или прогноза времени расчета. Работникам несколько минут ждать, смотря на статичный экран и не зная, когда процесс завершится будет неудобно.


    1. Alex_Donchuk Автор
      11.03.2019 17:38

      Согласен! Планшет вообще использовать не будем, у бригадира рабочее место с компьютером.


  1. xaoc80
    11.03.2019 17:36

    Хотелось бы подробностей в части выборы модели Resnet50, декодера. Это, кажется, не самая быстрая сеть. Вы пробовали MobileNet, к примеру, в качестве энкодера? Есть какие-то результаты тестов, соображений?


    1. Alex_Donchuk Автор
      11.03.2019 17:42

      Пробовал несколько сетей, лучший рзультат показала se_resnext50 с scse блоком. Было мало времени на дальнейшие ресёчи, но потом обезательно пересмотрю DL.


  1. ramzes2
    11.03.2019 19:17

    tqdm-а не хватает в процессе обработки.


  1. senovr
    12.03.2019 09:20

    А более детально конфигурацию железа не расскажете?
    Заинтриговала материнка под 3 видеокарты, она видимо с 3-мя pcie-16x?


    1. Alex_Donchuk Автор
      12.03.2019 09:26

      Нет 8х 4х 4х, т. к. PCI Lanes у проца не хватает(тут стоит какая-то msi, модель не помню ищите по кол-ву слотов и по описанию кол-ва поддерживаемых видюх) А что бы вставить 4 карты нужно топовые мамки вроде rampage 6 apex и выше. Они смогут поддержать 16х, 8х, 8х, 8х и у них места хватает для бутерброда.


      1. lelik363
        12.03.2019 11:32

        Почему сразу на Jetsonе не делали?


        1. Alex_Donchuk Автор
          12.03.2019 11:40

          Поставка jetson TX2 может затянуться на пару месяцев. И я еще точно не знаю буду ли его использовать, а комп останется будем сетки на нём обучать.


  1. DMGarikk
    12.03.2019 11:28

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

    Это вам надо не на локомотивах, а на вагонах тренироваться, там для вашей системы огромное количество самых разнообразных вариаций дефектов колодок будет, и неравномерный износ и излом колодки пополам, и вообще её отсутствие и состояние «еще чуть чуть и фольга»
    ====
    Дефектовка это прикольно, только вот один из этапов реальной дефектовки это обстукиванием молотком, вы же не сможете это решить программным методом, тоесть всёравно останется ручной труд


    1. Alex_Donchuk Автор
      12.03.2019 11:37

      Я не видел что бы в ПТОЛ стучали, видимо это делаю в других местах. Но надо посмотреть в сторону ультрозвуковой дефектоскопии.


      1. DMGarikk
        12.03.2019 12:20

        Стучат в том числе для того чтобы определить что открутилось чтото или болтается от износа


        1. ybalt
          12.03.2019 12:50

          имхо стучат по буксе на предмет перегрева(звук другой) и по колесу — на предмет трещины.


          1. Alex_Donchuk Автор
            12.03.2019 12:54

            Буксу можно тепловизором глянуть.


            1. DMGarikk
              12.03.2019 12:56

              Уже давно такое применяется (ДИСК/ПОНАБ), стучат чтобы предотвратить начинающееся разрушение когда букса ещё не греется, но там уже всё внутри открутилось и скоро начнет подклинивать


          1. DMGarikk
            12.03.2019 12:55

            по буксе стучат чтобы определить, не отвинтилась ли внутри планка корончатой гайки или крепежная шайба… которая будет дребезжать внутри
            по колесу да, на предмет трещины, а также по местам крепления гасителей и по пружинам подвески
            еще кстати гаситель надо рукой подергать, бывает что он разваливается внутри и болтается, а снаружи этого не видно


  1. Alexander_vrn
    12.03.2019 14:34

    Большое спасибо автору за статью и, особенно, за технические подробности его решения. Так уж вышло, что мне неоднократно приходилось решать подобные задачи. Я имею в виду задачи контроля геометрических размеров вагонных тележек и прочих критичных элементов именно для РЖД, поэтому тема мне близка.
    Тут в комментариях задали правильный вопрос о практической значимости этого решения, чем оно лучше того, что было раньше. Дело в том, что в РЖД (и аналогичных госкорпорациях) заказывают музыку совсем не те люди, что эксплуатируют все эти инновационные штуки. Поэтому очень часто бывает такое, что приходит запрос типа: а вот сделайте нам систему дефектовки рам тележек, чтобы работало быстро и без человеческого фактора. Сейчас на тележку уходит, условно 40мин, это очень долго. Ок, сделали систему, которая все делает за 3 минуты, полностью автоматически. А к тому времени люди, что просили быстро, уже ушли куда-то по служебной лестнице, и, видимо, на их месте оказались другие, которые посмотрели и сказали: э-э-э..., да это очень дорого, да и зачем нам 3 минуты, если другой какой-то этап обслуживания тележек длится, условно говоря, два часа. Очевидно, что экономическая эффективность тут просто никак не считалась, поэтому и исполнителю не стоит этим заморачиваться. Дают тебе интересную задачу, если по деньгам устраивает, берешься и решаешь.
    Я за последние лет 15 уже несколько раз слышал об этой задаче, в самых разных вариациях. Но поработать над ней не удалось: или сроки были неадекватными, или бюджет, или и то, и другое.


    1. Alex_Donchuk Автор
      12.03.2019 15:18
      -1

      И вам большое спасибо за комментарий! Такие риски есть, но даст random и мне повезёт!


      1. Alexander_vrn
        12.03.2019 16:18
        +1

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


        1. Alex_Donchuk Автор
          12.03.2019 16:26

          А вдруг повезёт!


  1. LinearLeopard
    13.03.2019 15:50

    А поиграться с разбиением изображения на объекты пробовали?
    Что-то типо такого:

    На большую часть объектов можно забить, интересны только колодки
    image