company_banner

Deep Learning, теперь и в OpenCV



    Данная статья является кратким обзором возможностей dnn — модуля OpenCV, предназначенного для работы с нейросетями. Если вам интересно, что это такое, что оно умеет и как быстро работает, добро пожаловать под кат.

    Пожалуй, многие согласятся, что OpenCV является наиболее известной библиотекой компьютерного зрения. За долгое время своего существования она приобрела обширную аудиторию пользователей и стала, де-факто, стандартом в области компьютерного зрения. Множество алгоритмов, работающих «из коробки», открытость исходного кода, замечательная поддержка, большое сообщество пользователей и разработчиков, возможность пользоваться библиотекой на языках C, C++, Python (а также Matlab, C#, Java) под различными операционными системами — это далеко не полный список того, что позволяет OpenCV оставаться востребованной. Но OpenCV не стоит на месте — постоянно добавляется функционал. И сегодня я хочу рассказать о новых возможностях OpenCV в области Deep Learning.

    Загрузка и получение результатов (предсказаний) с помощью моделей, созданных в любом из трех популярных фреймворков (Caffe, TensorFlow, Torch), быстрая работа на CPU, поддержка основных слоев нейронных сетей и, как всегда, кроссплатформенность, открытость исходного кода и поддержка — об этом я собираюсь рассказать в данной статье.

    Прежде всего, хотелось бы представиться. Меня зовут Рыбников Александр. Я являюсь инженером компании Intel и занимаюсь реализацией функциональности Deep Learning в библиотеке OpenCV.

    Пару слов о том, как устроена OpenCV. Эта библиотека представляет собой набор модулей, каждый из которых связан с определенной областью компьютерного зрения. Существует стандартный набор модулей — так сказать, «must have» для любой задачи компьютерного зрения. Реализуя известные алгоритмы, данные модули хорошо проработаны и протестированы. Все они представлены в основном репозитории OpenCV. Также существует репозиторий с дополнительными модулями, реализующими экспериментальную или новую функциональность. Требования к экспериментальным модулям, по понятным причинам, мягче. И, как правило, когда какой-то из таких модулей становится достаточно развитым, сформировавшимся и востребованным, он может быть перенесен в основной репозиторий.

    Данная статья связана с одним из модулей, совсем недавно занявшим почетное место в основном репозитории — с модулем dnn (далее просто dnn).

    (N+1)-й фреймворк для deep learning, это вообще зачем?


    Зачем вообще понадобился Deep Learning в OpenCV? В последние годы во многих областях глубокое обучение (в некоторых источниках глубинное обучение) показывает результаты, значительно превосходящие аналогичные у классических алгоритмов. Это касается и области компьютерного зрения, где масса задач решается с применением нейронных сетей. В свете данного факта кажется логичным дать пользователям OpenCV возможность работы с нейросетями.

    Почему был выбран путь написания чего-то своего вместо использования уже существующих реализаций? Этому есть несколько причин.

    Во-первых, так можно добиться легковесности решения. Оставляя только возможность выполнения прямого прохода (forward pass) по сети, можно упростить код, ускорить процесс установки и сборки.

    Во-вторых, имея свою реализацию, можно свести внешние зависимости к минимуму. Это упростит распространение приложений, использующих dnn. И, если ранее в проекте использовалась библиотека OpenCV, не составит труда добавить в такой проект поддержку глубоких сетей.

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

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

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

    Основные возможности


    Основная возможность dnn заключается, конечно же, в загрузке и запуске нейронных сетей (inference). При этом модель может быть создана в любом из трех фреймворков глубокого обучения — Caffe, TensorFlow или Torch; способ ее загрузки и использования сохраняется независимо от того, где она была создана.

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

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

    Поддерживаются все основные слои: начиная от базовых (Convolution и Fully connected) и заканчивая более специализированными — всего более 30.

    Список поддерживаемых слоев
    AbsVal
    AveragePooling
    BatchNormalization
    Concatenation
    Convolution (with dilation)
    Crop
    DetectionOutput
    Dropout
    Eltwise
    Flatten
    FullConvolution
    FullyConnected
    LRN
    LSTM
    MaxPooling
    MaxUnpooling
    MVN
    NormalizeBBox
    Padding
    Permute
    Power
    PReLU
    PriorBox
    ReLU
    RNN
    Scale
    Shift
    Sigmoid
    Slice
    Softmax
    Split
    TanH

    Если вы не обнаружили в этом списке слой, который требуется именно вам, не стоит отчаиваться. Вы можете создать запрос на добавление поддержки интересующего вас слоя (и наша команда постарается помочь вам в ближайшее время), либо реализовать все самостоятельно и подать pull request.

    Кроме поддержки отдельных слоев, важна также и поддержка конкретных архитектур нейронных сетей. Модуль содержит примеры для классификации (AlexNet, GoogLeNet, ResNet, SqueezeNet), сегментации (FCN, ENet), детектирования объектов (SSD); многие из указанных моделей проверены на исходных датасетах, но об этом позднее.

    Сборка


    Если вы — опытный пользователь OpenCV, то можете смело пропустить этот раздел. Если нет, то я постараюсь максимально кратко рассказать о том, как же получить работающие примеры из исходного кода для Linux или Windows.

    Краткая инструкция по сборке
    Предварительно потребуется установить git (либо Git Bash для Windows), [cmake](http://cmake.org) и компилятор С++ (Visual Studio под Windows, Xcode на Mac, clang либо gcc под Linux). Если вы собираетесь использовать OpenCV из Python, то нужно также установить сам Python (подойдут последние версии 2.7.x или 3.x) и соответствующую ему версию numpy.

    Начнем с клонирования репозитория:

    mkdir git && cd git
    git clone https://github.com/opencv/opencv.git

    На Windows клонирование репозиториев также можно выполнить, например, с помощью TortoiseGit или SmartGit. Далее, приступим к генерации файлов для сборки:

    cd ..
    mkdir build && cd build
    cmake ../git/opencv -DBUILD_EXAMPLES=ON

    (для Windows здесь и далее нужно заменить cmake на полный путь до запускаемого файла cmake, например на «C:\Program Files\CMake\bin\cmake.exe» или использовать cmake GUI)

    Теперь непосредственно сборка:

    make -j5 (Linux)
    cmake --build . --config Release -- /m:5 (Windows)

    После этого dnn готов к использованию.
    Приведенная выше инструкция достаточно краткая, поэтому приведу также ссылки на пошаговые инструкции по установке OpenCV на Windows и Linux.

    Примеры использования


    По хорошей традиции, каждый модуль OpenCV включает в себя примеры использования. dnn — не исключение, примеры на С++ и Python доступны в поддиректории samples в репозитории с исходным кодом. В примерах присутствуют комментарии, да и в целом все достаточно просто.

    Приведу здесь краткий пример, выполняющий классификацию изображений с помощью модели GoogLeNet. На языке Python наш пример будет выглядеть следующим образом:

    import numpy as np
    import cv2 as cv
    
    # read names of classes
    with open('synset_words.txt') as f:
        classes = [x[x.find(' ') + 1:] for x in f]
    
    image = cv.imread('space_shuttle.jpg')
    # create tensor with 224x224 spatial size and subtract mean values (104, 117, 123) 
    # from corresponding channels (R, G, B)
    input = cv.dnn.blobFromImage(image, 1, (224, 224), (104, 117, 123))
    
    # load model from caffe
    net = cv.dnn.readNetFromCaffe('bvlc_googlenet.prototxt', 'bvlc_googlenet.caffemodel')
    # feed input tensor to the model
    net.setInput(input)
    # perform inference and get output
    out = net.forward() 
    # get indices with the highest probability
    indexes = np.argsort(out[0])[-5:] 
    for i in reversed(indexes):
        print('class:', classes[i], ' probability:', out[0][i])

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

    Выходной тензор интерпретируется как вектор вероятностей принадлежности изображения к тому или иному классу и имена для 5 классов с наибольшими вероятностями выводятся в консоль.

    Выглядит несложно, не так ли? Если записать то же самое на C++, код получится немного более длинным. Однако, самое главное — имена функций и логика работы с модулем — останутся одними и теми же.

    Точность


    Как понять, что одна натренированная модель лучше другой? Необходимо сравнить метрики качества для обеих моделей. Очень часто борьба на вершине рейтинга лучших моделей идет за доли процентов качества. Поскольку dnn читает и преобразует модели из различных фреймворков в свое внутреннее представление, возникают вопросы сохранения качества после преобразования модели: не «испортилась» ли модель после загрузки? Без ответов на эти вопросы, а значит без проверки сложно говорить о полноценном использовании dnn.

    Я провел тестирование моделей из имеющихся примеров для различных фреймворков и различных задач: AlexNet (Caffe), GoogLeNet (Caffe), GoogLeNet (TensorFlow), ResNet-50 (Caffe), SqueezeNet v1.1 (Caffe) для задачи классификации объектов; FCN (Caffe), ENet (Torch) для задачи семантической сегментации. Результаты приведены в Таблицах 1 и 2.
    Модель (исходный фреймворк)
    Опубликованное значение acc@top-5
    Измеренное значение acc@top-5 в исходном фреймворке
    Измеренное значение acc@top-5 в dnn
    Средняя разница на элемент между выходными тензорами фреймворка и dnn
    Максимальная разница между выходными тензорами фреймворка и dnn
    AlexNet (Caffe)
    80.2%
    79.1%
    79.1%
    6.5E-10
    3.01E-06
    GoogLeNet (Caffe)
    88.9%
    88.5%
    88.5%
    1.18E-09
    1.33E-05
    GoogLeNet (TensorFlow)
    89.4%
    89.4%
    1.84E-09
    1.47E-05
    ResNet-50
    (Caffe)
    92.2%
    91.8%
    91.8%
    8.73E-10
    4.29E-06
    SqueezeNet v1.1
    (Caffe)
    80.3%
    80.4%
    80.4%
    1.91E-09
    6.77E-06
    Таблица 1. Результаты оценки качества для задачи классификации. Измерения проводились на валидационном наборе ImageNet 2012 (ILSVRC2012 val, 50000 примеров).
    Модель (фреймворк)
    Опубликованное значение mean IOU
    Измеренное значение mean IOU в исходном фреймворке
    Измеренное значение mean IOU в dnn
    Средняя разница на элемент между выходными тензорами фреймворка и dnn
    Максимальная разница между выходными тензорами фреймворка и dnn
    FCN (Caffe)
    65.5%
    60.402874%
    60.402879%
    3.1E-7
    1.53E-5
    ENet (Torch)
    58.3%
    59.1368%
    59.1369%
    3.2E-5
    1.20
    Таблица 2. Результаты оценки качества для задачи семантической сегментации. Объяснение большой максимальной разницы для ENet далее в тексте.

    Результаты для FCN вычислены для валидационного набора сегментационной части PASCAL VOC 2012 (736 примеров). Результаты для ENet вычислены на валидационном наборе Cityscapes (500 примеров).

    Следует сказать несколько слов о том, какой смысл имеют указанные выше числа. Для задач классификации общепринятой метрикой качества моделей является точность для топ-5 ответов сети (accuracy@top-5, [1]): если правильный ответ имеется среди 5 ответов сети с максимальными показателями уверенности (confidence), то данный ответ сети засчитывается как верный. Соответственно, точность — это отношение числа верных ответов к числу примеров. Данный способ измерения позволяет учесть не всегда корректную разметку данных, когда, например, отмечается объект, занимающий далеко не центральное положение на кадре.

    Для задач семантической сегментации используются несколько метрик — попиксельная точность (pixel accuracy) и среднее по классам отношение пересечения к объединению (mean intersection over union, mean IOU) [5]. Попиксельная точность — это отношение количества правильно классифицированных пикселей к количеству всех пикселей. mean IOU — более сложная характеристика: это усредненное по классам отношение правильно отмеченных пикселей к сумме числа пикселей данного класса и числа пикселей, отмеченных как данный класс.

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

    Разницу между опубликованными и полученными в экспериментах числами можно объяснить тем, что авторы моделей проводят все вычисления с использованием GPU, в то время как я использовал CPU-реализации. Также было замечено, что различные библиотеки могут по-разному декодировать формат jpeg. Это могло сказаться на результатах для FCN, так как датасет PASCAL VOC 2012 содержит изображения именно данного формата, а модели для семантической сегментации оказываются достаточно чувствительны к изменению распределения входных данных.

    Как вы заметили, в Таблице 2 присутствует аномально большая максимальная разница выходов dnn и Torch для модели ENet. Меня также заинтересовал данный факт и далее я кратко расскажу о причинах его возникновения.

    Почему возникает большое различие между dnn и Torch для ENet?
    Модель ENet использует несколько операций MaxPooling. Данная операция выбирает максимальный элемент в окрестности каждой позиции и записывает в выходной тензор это максимальное значение, а также передает далее индексы выбранных максимальных элементов. Эти индексы далее используются операцией, в некотором смысле обратной данной — MaxUnpooling. Эта операция записывает элементы входного тензора в позиции выходного, соответствующие тем самым индексам. В этом месте и возникает большая ошибка: в определенной окрестности операция MaxPooling выбирает элемент с неправильным индексом; при этом разница между правильным выходом Torch и выходом dnn для данного слоя лежит в пределах вычислительной погрешности (10E-7), а разница в индексах соответствует соседним элементам окрестности. То есть, в результате небольшой флуктуации соседний элемент стал несколько больше, чем элемент с правильным индексом. Результат операции MaxUnpooling, при этом, зависит не только от выхода предыдущего слоя, но и от индексов соответствующей операции MaxPooling, которая располагается намного раньше (в начале вычислительного графа модели). Таким образом, MaxUnpooling записывает элемент с правильным значением в неверную позицию. В результате, накапливается ошибка.

    К сожалению, устранить данную ошибку не представляется возможным, так как первопричины ее появления связаны, скорее всего, с немного различающимися реализациями алгоритмов, использованных при тренировке и при inference и не связаны с наличием ошибки в реализации.
    Однако, справедливо отметить, что средняя ошибка на элемент выходного тензора остается низкой (см. Таблицу 2) — то есть ошибки в индексах возникают достаточно редко. Более того, наличие данной ошибки не приводит к ухудшению качества работы модели, о чем свидетельствуют числа в той же Таблице 2.

    Производительность


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

    Я провел замеры времени работы для различных моделей при их использовании — результаты в Таблице 3.
    Модель (исходный фреймворк)
    Разрешение изображения
    Производительность исходного фреймворка, CPU (библиотека акселерации); потребление памяти
    Производительность dnn, CPU (ускорение относительно исходного фреймворка); потребление памяти
    AlexNet (Caffe)
    227x227
    23.7 мс (MKL); 945 МБ
    14.7 мс (1.6x); 713 МБ
    GoogLeNet (Caffe)
    224x224
    44.6 мс (MKL); 197 МБ
    20.1 мс (2.2x); 172 МБ
    ResNet-50 (Caffe)
    224x224
    70.2 мс (MKL); 386 МБ
    58.8 мс (1.2x); 224 МБ
    SqueezeNet v1.1
    (Caffe)
    227x227
    12.4 мс (MKL); 113 МБ
    5.3 мс (2.3x); 38 МБ
    GoogLeNet (TensorFlow)
    224x224
    17.9 мс (Eigen); 310 МБ
    21.1 мс (0.8x); 135 МБ
    FCN (Caffe)
    различное (500x350 в среднем)
    3873.6 мс (MKL);
    4453 МБ
    1229.8 мс (3.1x);
    1332 МБ
    ENet (Torch)
    1024x512
    1105.0 мс; 828 МБ
    218.7 мс (5.1x); 190 МБ
    Таблица 3. Результаты замеров времени работы различных моделей. Эксперименты проводились с использованием Intel Core i7-6700k.

    Замеры времени производились с усреднением по 50-ти запускам и выполнялись следующим образом: для dnn использовался встроенный в OpenCV таймер; для Caffe использовалась утилита caffe time; для Torch и TensorFlow использовались существующие функции замера времени.

    Как следует из Таблицы 3, dnn в большинстве случаев превосходит по производительности оригинальные фреймворки. Актуальные данные по производительности dnn из OpenCV на различных моделях в сравнении с другими фреймворками также можно найти здесь.

    Дальнейшие планы


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

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

    Что касается производительности, то несмотря на многие выполненные оптимизации, у нас все еще есть идеи, как улучшить результаты. Одна из таких идей — уменьшить разрядность вычислений. Данная процедура носит название квантизации. Грубо говоря, выкинуть часть разрядов у входа и весов слоя перед вычислением сверток (fp32→fp16), либо вычислить масштабирующие коэффициенты, переводящие диапазон входных чисел в диапазон int или short. При этом возрастет скорость (за счет использования более быстрых операций с целыми числами), но, возможно, немного пострадает точность. Однако публикации и эксперименты в этой области показывают, что даже достаточно сильная квантизация в определенных случаях не приводит к заметному падению качества.

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

    Сейчас к релизу готовится нечто достаточно интересное. Думаю, немногие слышали о языке программирования Halide. Он не является Тьюринг-полным — некоторые конструкции реализовать на нем не получится; возможно поэтому он и не пользуется популярностью. Однако указанный недостаток является одновременно и его преимуществом — написанный на нем исходный код может быть автоматически превращен в высокооптимизированный под разные «железки»: CPU, GPU, DSP. При этом нет нужды быть гуру оптимизации — специальный компилятор все сделает за вас. Уже сейчас Halide позволяет получить ускорение некоторых моделей — и, например, семантическая сегментация с моделью ENet работает 25 fps для разрешения 512x256 на Intel Core i7-6700k (против 22 fps у dnn без Halide). И, что самое приятное, без переписывания кода можно задействовать интегрированную в процессор GPU, получив дополнительно еще пару кадров в секунду.

    В действительности, мы возлагаем большие надежды на Halide. Благодаря своим уникальным характеристикам он позволит получать ускорение работы, не требуя от пользователя дополнительных манипуляций. Мы стремимся к тому, чтобы для использования Halide вместе с OpenCV у пользователя не возникало необходимости в установке дополнительного программного обеспечения для использования Halide — принцип работы «из коробки» должен сохраняться. И, как показывают наши эксперименты, у нас есть все шансы реализовать это.

    Заключение


    Уже сейчас dnn имеет все, чтобы оказаться полезным. И с каждым днем все большее число пользователей открывает для себя его возможности. Тем не менее, нам еще есть над чем трудиться. Я продолжу свою работу над модулем, расширяя его возможности и совершенствуя функционал. Надеюсь, что данная статья оказалась для вас интересной и полезной.

    Если у вас есть вопросы, появились предложения, возникли проблемы или вы хотите внести свой вклад путем подачи pull request — добро пожаловать в github-репозиторий, а также на наш форум, где я и мои коллеги постараемся вам помочь. Если ни один из указанных способов не подошел, на нашем сайте можно найти дополнительные пути коммуникации. Я всегда буду рад сотрудничеству, конструктивным замечаниям и предложениям. Спасибо за внимание!

    P.S. Выражаю огромную благодарность моим коллегам за помощь в работе и написании данной статьи.

    Ссылки


    1. ImageNet Classification with Deep Convolutional Neural Networks
    2. Going deeper with convolutions
    3. Deep Residual Learning for Image Recognition
    4. SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size
    5. Fully Convolutional Networks for Semantic Segmentation
    6. ENet: A Deep Neural Network Architecture for Real-Time Semantic Segmentation
    7. SSD: Single Shot MultiBox Detector
    8. Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding
    9. OpenCV github
    10. Официальный сайт OpenCV
    11. Форум OpenCV
    12. Halide
    13. Caffe
    14. TensorFlow
    15. Torch
    Метки:
    Intel 148,58
    Компания
    Поделиться публикацией
    Похожие публикации
    Комментарии 22
    • +1
      Прекрасная новость! Количество типов слоев «из коробки» приятно удивляет.

      Действительно, думаю, что возможные сложности и подводные камни при встраивании в работу openCV-based приложений сторонних фреймворков для работы с DNN многих, как минимум, пугают.
      • 0
        Очень круто! Молодцы! Очень точно нишу нащупали. Надеюсь что взлетит этот подход.
        Да, с поддержкой. Caffe потихоньку умирает переходя в Caffe2. Поддержка на Caffe2 будет?
        • +2
          Это всё на CPU? Немного пролетел мимо понимания, как планируется использовать GPU-ускорители? Только за счёт Halide?
          • +1
            Сейчас dnn использует CPU. Использование GPU планируется добавить с помощью Halide и других бэкендов.
            • 0
              А на CPU для dnn используете самописные оптимизированные функции или какие-то библиотеки?
              • +1
                В данный момент используются собственные оптимизации — то есть модуль не нуждается в дополнительных библиотеках, чтобы работать также быстро, как указано в статье. В скором времени появится Halide как один из бэкендов.
          • +1
            Спасибо, будем стараться. Насчет caffe2 — это, на самом деле, вопрос приоритетов. Срочность добавления зависит от того, насколько этот фреймворк окажется популярным. Если мы поймем, что пользователям это нужно, или что есть много классных моделей, созданных в caffe2, то с радостью займемся реализаций поддержки. Ну а в долгосрочной перспективе мы, конечно же, за как можно больший охват фреймворков.
          • +1
            Интересно, запустится ли все это дело на Raspberry Pi
            • +1
              Предположительно, должно. Построение OpenCV выполняется, кроме многих других конфигураций, еще и для некоторого числа машин с ARM
              • 0
                Спасибо, обязательно попробую. Как раз есть Raspberry c камерой. Как я понимаю, такие проекты https://svds.com/tensorflow-image-recognition-raspberry-pi/ теперь будет проще делать.
                • +1
                  Да, однозначно. Портировать фреймворк теперь не нужно
                  • 0
                    Конкретно у tensorflow есть свое решение для работы в подобных условиях tfcompile — Using AOT compilation
                    • 0
                      Не знал о такой возможности у TF, спасибо. Они вообще молодцы, оптимизируют код под CPU, активно развивают фреймворк, оказывается, еще и о мобильных устройствах позаботились
            • 0
              Может, я не внимателен, но я не увидел UpSampling2D в списке слоев. Он как то по другому называется? Раз с статье упоминаются сети для сегментации — FCN и Enet.
              • +1
                Скорее всего речь о FullConvolution слое. Он используется для того, чтобы увеличить пространственные размерности в моделях для сегментации. И он же в разных источниках называется «In-network Upsampling», «Fractionally-strided convolution», «Backwards Convolution», «Deconvolution», «Upconvolution».
                • 0
                  Хотел еще уточнить, реализован ли FullConvolution при экспорте из tensorflow\keras? В tf-importer.cpp не обнаружил что-то похожего.
                  Мне сделать pull-request?

                  Если это важно, то я пытаюсь экспортировать несколько модифицированную версию U-net для сегментации.
                  • +1
                    В данный момент FullConvolution (Deconvolution) не читается при загрузке из tf. Но сам слой реализован (как и его загрузка из Caffe и Torch). Если у вас есть желание и возможность — pull request будет очень кстати. Вам потребуется добавить «конвертацию» параметров из TensorFlow формата в тот, что используется в dnn (для данного слоя фактически Caffe формат). «Конвертация» в кавычках, так как иногда соответствие между параметрами идентичное. Иногда же они могут быть связаны некоторой формулой. В этом и потерубется разобраться. Для удобства можно сохранить tf модель в текстовом виде — так вы сможете непосредственно увидеть имена и значения параметров.
              • 0
                Мы стремимся к тому, чтобы для использования Halide вместе с OpenCV у пользователя не возникало необходимости в

                … комфорте?!
                Не припомню ни одного случая, когда притянутый экзотический язык в какой-либо фреймворк, приносил пользу.
                • 0
                  У пользователя всегда останется выбор, использовать какой-то бэкенд или нет. На данный момент наши эксперименты показывают, что все, что потребуется, пользователю, это указать флаг при вызове cmake. Все остальное будет сделано в фоне. Halide действительно дает ускорение, и пользователю совершенно необязательно знать, как программировать на этом языке, чтобы использовать это ускорение. В любом случае — удобство для пользователей — это то, о чем мы (команда OpenCV) постоянно думаем. Пример тому: OpenCV 2.4 до сих пор фиксится, так как много пользовательского кода использует эту версию, хотя 3.3 уже готова к релизу.
                • 0
                  Вау! Проснулся утром, зашел на Хабр и нашел прямо то, что мне нужно в данный момент. Спасибо!
                  • 0
                    Всегда пожалуйста! Рад, что результаты моей работы будут вам полезны!

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

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