Добрый день!
Да, мы так регулярно делаем. Например базовая архитектура нашего сервера разметки именно так и устроена — cv-blog.ru/?p=368
У нас форматы входа и выхода одинаковы => на вход разметки можно подавать предразмеченые кадры алгоритма. В том же посте видео о том как мы это делаем.
С биасом как-то не боремся. Обычно если это так критично — просто с нуля размечаем. Не помню даже когда такое было в последний раз.
Вопрос — почему? Кто знает — пишите в комментариях
Если я правильно понял вы подключаетесь напрямую к ip камере («Они подключены к одной единственной ip-камере»). У вас не являются идентичными кадры которые попадаю на вход обоих алгоритмов. Может меняться компрессия потока, может где-то пропуск кадра случаться, и.т.д. Резные кадры => чуть отличающиеся хэши.
Чтобы убедиться что проблема не в этом — запишите несколько суток видео и прогоните на обоих ваших комплексах.
Но, конечно, может и в других местах проблема возникать. Например вы используете разные видюхи для запуска (TensorRT под разные видеокарты имеет несколько разные алгоритмы оптимизаций, могут какие-то знаки после запятой изменяться).
Что-то очень поверхностная статья. С кучей очень спорных утверждений
Однако, этот способ, скорее всего, подойдет только крупным компаниям с собственным штатом дата-аналитиков.
Очень часто наоборот, правильная интеграция in-house разметки бывает основным продуктом. И её надо делать до разработки по DataScince.
Очень часто переходы между разными вариантами разметки — весьма гладкие и непрерывные. Вообще, я вот тут чуть более подробно рассказываю, в том числе большое число вариантов которых тут нет — youtu.be/fwbHkVka3G4
Монументально!
Вообще вопрос конвертации я даже не пробовал затрагивать, там всегда какой-то ад творится. И на эту тему очень мало информации опубликовано, особенно по потерям производительности при конвертации.
Любопытно. А не проще ли было сделать обучение сразу на TensorFlow? Мне в таких ситуациях кажется, что перенос обучения зачастую проще чем перенос модели…
Артур, привет! Спасибо!
Это очень от фреймворка будет зависеть все же. И тут каждый раз надо будет разбираться заново. Для того же OpenVino (а значит всего того что на его базе) большинство известных слоёв конвертируются без проблем. Например вот или вот.
Так же у них есть большой набор готовых моделей, которые автоматически конвертируются.
Мне кажется, что это обусловлено тем, что в OpenVino не нужно лишний раз данные гонять в память видюхи и назад => они просто берут процессорную реализацию слоя и в целом она работает из коробки. NMS, Deformable Convolution, например, есть. Но будет ли это у них работать и на проце и на их GPU — не знаю. Вроде SSD мы как-то запускали на IntelNuc с GPU и там работало, значит NMS по крайней мере был.
Если мы перейдём к какому-нибудь TensorRT, то там все ещё более-менее норм, но многое уже не из коробки. Но для того кто куду и c++ знает это вроде как не сложно. Я сам весьма поверхностно на ней умею писать. Коллега который хорошо разбирается — OpenPose'овскую обработку поз года три назад где-то за неделю перенёс на куду. Сетка инферелась на TensorRT, а потом напрямую кудой данные обрабатывались.
Формальный список слоёв там достаточно уныл. Но для большинства распространённых есть уже готовые «плагины». Например NMS, или гайд по добавлению Deformable Convolution.
Но с тем же tensorRT существует такая штука как tf-trt слои которые можно он исполняет на TensorRT, а то для чего реализации нет — на tensorflow. В целом, какой-нибудь SSD на JetsonNano давал усадку процентов на 20, если его через TfTRT было делать, но работал из коробки.
Мне кажется что очень просто в OpenCV добавить новый слой. Но, боюсь, что для каких-то реализаций его нужно писать для каждого инференса свой писать.
А вот чем дальше — тем будет хуже. Однажды мы переносили какую-то сетку на SnapDragon-овский сопроцессор для нейронок (ещё до того как TFlite был адекватен), и там не было даже слоя ADD. При этом его нельзя было добавить.
И каждый раз для каждого фреймворка/каждой железки приходилось заново разбираться, если что-то редкое есть.
В целом, обычно логика такая:
Иногда слой можно выполнить на основном процессоре. Особенно это просто сделать если есть разделяемая память для процессора и GPU|TPU модуля
Иногда готовые слои можно найти в интернете, может кто-то их уже написал
Иногда можно подменить слой на что-нибудь ещё. Чаще всего это для ReLu работает хорошо
Иногда можно что-нибудь подтьюнить в сетке и дообучить её уже в более простой конфигурации, где нет плохого слоя, но работает не всегда
Но, реально, из того что я перечислил в статье — у большинства фреймворков я не знаю как слой добавить:) Для тех же TensorFlow.JS или ONNX.JS. Так что однажды когда я попал в ситуацию что что-то не сконвертилось, просто взял другую сетку ¯\_(ツ)_/¯
ONNX это лишь формат записи сети. ONNX может исполняться и через OpenCV и через OpenVino и через TensorRT. Сконвертировать из ONNX в любой другой формат — обычно не сложно.
ONNX runtime собственно и инферит на оптимальном оборудовании (то что там используется базовый формат ONNX опять же не проблема). Там автоматически подключен и TensorRT и OpenVino и другие ускорители. В этом плане — он более всеобъемлющ чем чистый OpenCV. Так как в OpenCV нет и RockChip и AMD-шного инференса, и других приблуд именно для инференса.
Но мне OpenCV ближе — так как я его понимаю лучше.
И даже писал не настолько халтурные статьи на Хабре (1, 2).
Тут освещено от силы четверть процесса, не имеющего отношения к заголовку, на тему которого миллионы статей только на хабре (1,2,3,4,5, 6, 7, 8). Но в среднем статья воспроизводит любой базовый гайд с первой страницы гугла по настройке камеры.
Ну блин, есть некоторая границы халтуры же. Я понимаю что перевод. Но ведь можно же такое не переводить, а хоть немножко погуглить хотя бы на том ресурсе где публикуетесь.
Хорошо что у прошлого питание переделали. Там это было слабое место + очень логика не понятна (там можно было запитываться от мини usb, который по протоколу питания не тянул Nano). Но в целом стало лучше, надо бы в мой гайд по embedded платформам добавить.
Монументально!
Подборка методов очень крутая. Про большую часть не знал.
Любопытно, что не увидел ни одного метода на базе МРТ. Его не используют так как разрешение плохое? Или он просто бессмысленный?
Боже. Вообще растения — самый треш для 3D. Даже для хороших сканеров.
Но если пробовать натянуть готовую модельку — то это наверное сильно проще. Мы часто для анализа параметров 3D объектов так делали. Но это сильно более стабильные объекты чем растения были.
Ну, там не всегда трассировка. Есть напрямую сетки которые в воксельный объем проецируют. Только вот у таких задач есть одна проблема — не понятно зачем на практике оно.
На прошлом коллоквиуме новогоднем, который Лемпицкий устраивает, я общался с автором одного из State-of-art алгоритмов на тот период (к сожалению не помню как его звали, помню что из Германии группа). И у них это прямо проблема. Очень мало где реально нужны эти алгоритмы. Они смогли какую-то задачу придумать чтобы на практике попробовать, и это был большой прогресс.
Но на практике проще либо использовать нормальный 3D на вход, либо использовать какой-нибудь SLAM алгоритм. Либо, если объект фиксированный, то использовать известную 3д модель, и её натягивать.
Класс. Для 2012 года прекрасно. То что я в 2010-2011 году запускал было сильно хуже.
Но согласитесь, что тот же «Consistent Video Depth Estimation» — неплохой прогресс с тех пор?:)
С учётом того что это первый пост автора — мне кажется это банально реклама.
И вот обидно же. Белорусской фирме сейчас надо пиарить не приложение с подсчётом машин, а с подсчётом людей в толпе. Чтобы считать размер митингов. Тогда могли бы сколько угодно кривых сравнений делать.
Мне кажется, что в любом случае, как бы хорошая модель не была — для детей её придётся дообучать. Слишком мало детей в обучающих датасетах.
По поводу того что старая работала лучше — сейчас в OpenVino есть 3 или даже 4 разные модели для детекции лиц. И они на разные условия работы/разные скорости имеют. Так что может вы просто разные использовали.
Про OpenVino скажу лишь что когда он только появился — я пробовал его ставить и всё было сильно хуже. В последние разы когда ставил было как-то быстрее.
Но я действительно не понимаю почему они не сделают нормальное тестирование. Почему нужно только на диск системный ставить — в упор не понимаю…
С другой стороны, на мой взгляд, я не встречал ещё ни одной платформы, которая бы из коробки без единого бага работала. Может быть только хорошие Android и Ios телефоны предсказуемы.
Следующая по качеству — Raspberry Pi 4-ая + OpenCV/Tf lite. Если ничего левого не ставить и использовать только стандартные сети — работает из коробки.
Но не всегда производительности хватает.
Спасибо. Ну, там всё несколько хитрее, если я правильно понял. Не всегда всё это дело ассоциированно именно с тем что что-то на лицо натянул. И совсем правильные системы должны сердцебиение контролировать (кстати, такие есть).
Но у меня то цель была основная сделать детектор просыпания + немного развлечься, что в целом я успешно и провернул.
Я не спорю, что включает:)
Но всё же и RANSAK — это чисто логический алгоритм перебора гипотез и поиска оптимальной, а OpticalFlow, где нет нейронок — либо алгоритмы дифференциального анализа, либо опять же, какая-то логика, либо матан.
В матчинге вы сами говорите что KNN, который сложно назвать ML.
Так что в базовом пайплайне ни SVM ни Boost'инговых алгоритмов не вижу.
Но я только к заголовку придираюсь, всё остальное — ок:)
Но причём тут машинное обучение? И RANSAK и OpticalFlow — достаточно классические алгоритмы (Ок, OF можно сделать через нейронки, но тут это не рассмотренно). Плюс набор эмпирик чтобы всё попристойне выглядело.
По заголовку я надеялся будет какой-нибудь очередной подход без RANSAK, типо этого.
Смотрите, VGG — это очень жирная архитектура. Плюс, ваш подход поиска мяча будет очень нестабилен как только камера попадёт в другой зал, как только будет меняться освещение, камера, форма игроков, и.т.д.
Вашу задачу сильно проще решать через детекцию нейросетью + трекинг того что задетектированно. Сейчас существует очень много подходов которые это реализуют (более полно я их тут освещал). Скорее всего вам будет достаточно самого обычного Sort, который подключается одной строчкой.
В качестве детектора действительно неплохо брать YoloV4, но он будет работать на хороших вычислителях. Если у вас слабое устройство, то легче использовать Tiny Yolov4. Про всё это дело хорошая статья на Хабре есть.
Сейчас достаточно много неплохих архитектур, в целом с вашей задачей любая справиться.
Да, мы так регулярно делаем. Например базовая архитектура нашего сервера разметки именно так и устроена — cv-blog.ru/?p=368
У нас форматы входа и выхода одинаковы => на вход разметки можно подавать предразмеченые кадры алгоритма. В том же посте видео о том как мы это делаем.
С биасом как-то не боремся. Обычно если это так критично — просто с нуля размечаем. Не помню даже когда такое было в последний раз.
Если я правильно понял вы подключаетесь напрямую к ip камере («Они подключены к одной единственной ip-камере»). У вас не являются идентичными кадры которые попадаю на вход обоих алгоритмов. Может меняться компрессия потока, может где-то пропуск кадра случаться, и.т.д. Резные кадры => чуть отличающиеся хэши.
Чтобы убедиться что проблема не в этом — запишите несколько суток видео и прогоните на обоих ваших комплексах.
Но, конечно, может и в других местах проблема возникать. Например вы используете разные видюхи для запуска (TensorRT под разные видеокарты имеет несколько разные алгоритмы оптимизаций, могут какие-то знаки после запятой изменяться).
Очень часто наоборот, правильная интеграция in-house разметки бывает основным продуктом. И её надо делать до разработки по DataScince.
Очень часто переходы между разными вариантами разметки — весьма гладкие и непрерывные. Вообще, я вот тут чуть более подробно рассказываю, в том числе большое число вариантов которых тут нет — youtu.be/fwbHkVka3G4
Вообще вопрос конвертации я даже не пробовал затрагивать, там всегда какой-то ад творится. И на эту тему очень мало информации опубликовано, особенно по потерям производительности при конвертации.
Любопытно. А не проще ли было сделать обучение сразу на TensorFlow? Мне в таких ситуациях кажется, что перенос обучения зачастую проще чем перенос модели…
Это очень от фреймворка будет зависеть все же. И тут каждый раз надо будет разбираться заново. Для того же OpenVino (а значит всего того что на его базе) большинство известных слоёв конвертируются без проблем. Например вот или вот.
Так же у них есть большой набор готовых моделей, которые автоматически конвертируются.
Мне кажется, что это обусловлено тем, что в OpenVino не нужно лишний раз данные гонять в память видюхи и назад => они просто берут процессорную реализацию слоя и в целом она работает из коробки. NMS, Deformable Convolution, например, есть. Но будет ли это у них работать и на проце и на их GPU — не знаю. Вроде SSD мы как-то запускали на IntelNuc с GPU и там работало, значит NMS по крайней мере был.
Если мы перейдём к какому-нибудь TensorRT, то там все ещё более-менее норм, но многое уже не из коробки. Но для того кто куду и c++ знает это вроде как не сложно. Я сам весьма поверхностно на ней умею писать. Коллега который хорошо разбирается — OpenPose'овскую обработку поз года три назад где-то за неделю перенёс на куду. Сетка инферелась на TensorRT, а потом напрямую кудой данные обрабатывались.
Формальный список слоёв там достаточно уныл. Но для большинства распространённых есть уже готовые «плагины». Например NMS, или гайд по добавлению Deformable Convolution.
Но с тем же tensorRT существует такая штука как tf-trt слои которые можно он исполняет на TensorRT, а то для чего реализации нет — на tensorflow. В целом, какой-нибудь SSD на JetsonNano давал усадку процентов на 20, если его через TfTRT было делать, но работал из коробки.
Мне кажется что очень просто в OpenCV добавить новый слой. Но, боюсь, что для каких-то реализаций его нужно писать для каждого инференса свой писать.
А вот чем дальше — тем будет хуже. Однажды мы переносили какую-то сетку на SnapDragon-овский сопроцессор для нейронок (ещё до того как TFlite был адекватен), и там не было даже слоя ADD. При этом его нельзя было добавить.
И каждый раз для каждого фреймворка/каждой железки приходилось заново разбираться, если что-то редкое есть.
В целом, обычно логика такая:
Но, реально, из того что я перечислил в статье — у большинства фреймворков я не знаю как слой добавить:) Для тех же TensorFlow.JS или ONNX.JS. Так что однажды когда я попал в ситуацию что что-то не сконвертилось, просто взял другую сетку ¯\_(ツ)_/¯
ONNX runtime собственно и инферит на оптимальном оборудовании (то что там используется базовый формат ONNX опять же не проблема). Там автоматически подключен и TensorRT и OpenVino и другие ускорители. В этом плане — он более всеобъемлющ чем чистый OpenCV. Так как в OpenCV нет и RockChip и AMD-шного инференса, и других приблуд именно для инференса.
Но мне OpenCV ближе — так как я его понимаю лучше.
И даже писал не настолько халтурные статьи на Хабре (1, 2).
Тут освещено от силы четверть процесса, не имеющего отношения к заголовку, на тему которого миллионы статей только на хабре (1,2,3,4,5, 6, 7, 8). Но в среднем статья воспроизводит любой базовый гайд с первой страницы гугла по настройке камеры.
Ну блин, есть некоторая границы халтуры же. Я понимаю что перевод. Но ведь можно же такое не переводить, а хоть немножко погуглить хотя бы на том ресурсе где публикуетесь.
Подборка методов очень крутая. Про большую часть не знал.
Любопытно, что не увидел ни одного метода на базе МРТ. Его не используют так как разрешение плохое? Или он просто бессмысленный?
Но если пробовать натянуть готовую модельку — то это наверное сильно проще. Мы часто для анализа параметров 3D объектов так делали. Но это сильно более стабильные объекты чем растения были.
На прошлом коллоквиуме новогоднем, который Лемпицкий устраивает, я общался с автором одного из State-of-art алгоритмов на тот период (к сожалению не помню как его звали, помню что из Германии группа). И у них это прямо проблема. Очень мало где реально нужны эти алгоритмы. Они смогли какую-то задачу придумать чтобы на практике попробовать, и это был большой прогресс.
Но на практике проще либо использовать нормальный 3D на вход, либо использовать какой-нибудь SLAM алгоритм. Либо, если объект фиксированный, то использовать известную 3д модель, и её натягивать.
Так что решил вообще не трогать этот сегмент.
Но согласитесь, что тот же «Consistent Video Depth Estimation» — неплохой прогресс с тех пор?:)
И вот обидно же. Белорусской фирме сейчас надо пиарить не приложение с подсчётом машин, а с подсчётом людей в толпе. Чтобы считать размер митингов. Тогда могли бы сколько угодно кривых сравнений делать.
По поводу того что старая работала лучше — сейчас в OpenVino есть 3 или даже 4 разные модели для детекции лиц. И они на разные условия работы/разные скорости имеют. Так что может вы просто разные использовали.
Но я действительно не понимаю почему они не сделают нормальное тестирование. Почему нужно только на диск системный ставить — в упор не понимаю…
С другой стороны, на мой взгляд, я не встречал ещё ни одной платформы, которая бы из коробки без единого бага работала. Может быть только хорошие Android и Ios телефоны предсказуемы.
Следующая по качеству — Raspberry Pi 4-ая + OpenCV/Tf lite. Если ничего левого не ставить и использовать только стандартные сети — работает из коробки.
Но не всегда производительности хватает.
Но у меня то цель была основная сделать детектор просыпания + немного развлечься, что в целом я успешно и провернул.
Но всё же и RANSAK — это чисто логический алгоритм перебора гипотез и поиска оптимальной, а OpticalFlow, где нет нейронок — либо алгоритмы дифференциального анализа, либо опять же, какая-то логика, либо матан.
В матчинге вы сами говорите что KNN, который сложно назвать ML.
Так что в базовом пайплайне ни SVM ни Boost'инговых алгоритмов не вижу.
Но я только к заголовку придираюсь, всё остальное — ок:)
Но причём тут машинное обучение? И RANSAK и OpticalFlow — достаточно классические алгоритмы (Ок, OF можно сделать через нейронки, но тут это не рассмотренно). Плюс набор эмпирик чтобы всё попристойне выглядело.
По заголовку я надеялся будет какой-нибудь очередной подход без RANSAK, типо этого.
Вашу задачу сильно проще решать через детекцию нейросетью + трекинг того что задетектированно. Сейчас существует очень много подходов которые это реализуют (более полно я их тут освещал). Скорее всего вам будет достаточно самого обычного Sort, который подключается одной строчкой.
В качестве детектора действительно неплохо брать YoloV4, но он будет работать на хороших вычислителях. Если у вас слабое устройство, то легче использовать Tiny Yolov4. Про всё это дело хорошая статья на Хабре есть.
Сейчас достаточно много неплохих архитектур, в целом с вашей задачей любая справиться.