CV в пайплайне распознавания
ценников товаров
Трюки и хитрости
Николай Маслович, Metacommerce, 2020
2011 — год основания
107 сотрудников
2 офиса (Россия, Европа)
Резидент IT-кластера
Фонда «Сколково»
Мультиканальный мониторинг
ассортимента и цен
Создано с содействием инвестиций
Фонда развития интернет-инициатив
Собираем в день 3,6 терабайт
сырых данных о 100 млн. товаров
Нам доверяют
О компании
2
Про меня
3
● CV & ML специалист в R&D отделе
● 1.5 года
● НИТУ МИСиС: Прикладная Математика
@maslovich
Про задачи
4
Проблематика мониторинга цен продуктового ритейла:
● 100 товарных позиций в день с помощью блокнота и ручки
● 100% ручной мониторинг
● 200 – 300 ценников в день с человека
● Полностью ручной ввод в систему ценообразования
● Ошибки ручного поиска товаров
Про задачи
5
Результат работы R&D отдела по автоматизации:
● 12 000 ценников в день на человека
● Полный контроль качества исполнения
● Качество распознавания 99%+
● Удешевление процессов в 7 раз
Как мы это сделали
Детекция Сегментация Распознавание
6
Пайплайн
Наше окружение
torch
cv2
tf
pandas
jupyter
flask
numpy
server
docker
.deb
7
Работа на сервере
Как разрабатывать код и обучать модели на
локальном сервере?
8
Работа на сервере
9
Если нет своего сервера...
● Vast.ai https://vast.ai
Цены заметно ниже, чем на amazon, google
Максимально простое использование
Дорогой трафик
10
Executable python
● click module https://click.palletsprojects.com
● jobs | disown
● screen, tmux https://help.ubuntu.ru/wiki/screen,
https://linuxize.com/post/getting-started-with-tmux/
● Прогресс-бары https://github.com/tqdm/tqdm
11
Как создавать скрипты с CLI и запускать без
остановки после разрыва ssh?
Чтение и сохранение данных
Как быстро и просто хранить и обрабатывать
данные?
12
Чтение и сохранение данных
● pathlib.Path вместо os
Стандартная библиотека в
python >= 3.4
13
Чтение и сохранение данных
● ujson вместо json
https://pypi.org/project/ujson/
14
Чтение и сохранение данных
● ilio вместо with open
https://github.com/gowhari/ilio
15
CV
16
Чтение и сохранение данных
● Используйте turbojpeg для открытия и
сохранения jpeg
17
Сравнение opencv и turbojpeg на чтении
# turbo
Total time: 26.819
Avg. time: 0.001788
# cv2
Total time: 45.458
Avg. time: 0.003031
18
Чтение и сохранение данных
● Храните табличные данные в parquet
формате для экономии места.
19
https://towardsdatascience.com/the-best-f
ormat-to-save-pandas-data-414dca023e0d
20
Чтение и сохранение данных
● Для хранения большого числа файлов
используйте шардинг
21
folder/abcdef.jpg folder/a/b/c/abcdef.jpg
Слишком много кода!
Это всё конечно хорошо, но...
22
Организация кода
Как разрабатывать код в команде без
копипаста и боли?
23
● python-package и установка как гит-сабмодуль.
● при разработке pip install -e submodule/
Организация кода
● Для кода всегда используйте git. Даже если вам нужна только “бэкап”
функциональность
● Никогда не используйте git для хранения датасетов
● Сформируйте .gitignore для всех ML-проектов и копипастьте его
● Не забывайте использовать info/exclude
● Всегда используйте только ssh подключения
24
Эксперименты
Как организовать код эксперимента, не
ограничивая гибкость и сохранить
воспроизводимость?
25
Эксперименты
● Cata... jupyter + .py
Код в PyCharm
Параметры в Jupyter с %autoreload
Свой велосипед лучше, если чаще всего вы меняете код, а не параметры.
26
А теперь про нейроночки
torch
cv2
tf
pandas
jupyter
flask
numpy
go
tf
torch
27
Чистка данных
Как без переразметки убрать часть ошибок в
разметке и улучшить скор?
28
4 6 0 7 0 6 4 2 2 1 4 5 5
Чистка данных
1. Train
Обучаем модель на том, что есть. Если данных достаточно много, то
обучаем не боясь оверфита
29
Чистка данных
1. Train
2. Peel
Выкидываем часть данных, на которых сеть показывает плохой
результат (например 5% квантиль или даже все с неидеальным скором)
30
Чистка данных
1. Train
2. Peel
3. Repeat
Файнтюним / обучаем с нуля модель на новом датасете. Повторяем, пока
число примеров с плохим скором не перестанет значительно меняться /
качество на валидации станет падать.
Работает, если разметка имеет значительные изъяны, например
отсутствует часть последовательности
31
Про pytorch и подводные камни
32
Про pytorch и подводные камни
● Denormal values
https://discuss.pytorch.org/t/conv2d-is-very
-slow-on-trained-weights-vs-random-weights/4337
7
33
%Total OwnTime TotalTime Function (filename:line)
80.00% 34.93s 34.93s forward (torch/nn/modules/conv.py:320)
Про pytorch и подводные камни
● .pt vs .pth
● Saving optimizer
● Initialization
torch.save({
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict':
optimizer.state_dict(),
'loss': loss,
...
}, PATH)
34
torch_utils.py
Маски для сегментатора
1. Генерация на лету vs чтение с диска
2. Если число классов <= 8, можно хранить в битах с помощью
np.(un)packbits
3. npz vs npy vs sparse
35
Хранить или создавать на лету? Если
хранить, то в чём?
“Липкая” сегментация
Объекты одного класса находятся близко
друг к другу
36
“Липкая” сегментация
● Грубая сегментация:
Обвести сегмент через opencv черным цветом
На постпроцессинге увеличить размер bounding box-a
37
“Липкая” сегментация
● Точная сегментация:
Прининцип watershed:
from scipy import ndimage as ndi
distance = ndi.distance_transform_edt(mask).astype(np.float32)
Нормируем на максимальное значение
mask = np.max(np.stack(distances), axis=0)
Подбираем пороговое значение на постпроцессинге, уменьшая пока не
появится слипание
38
“Липкая” сегментация
Ground truth без трешхолда
“Умный” трешхолд
39
Пропущенная разметка в многоклассовой
сегментации
Как сказать нейросетке, чтобы она не училась
на ложно-отсутствующей разметке?
40
Пропущенная разметка в многоклассовой
сегментации
● Кастомный loss
В датагенераторе добавить к сэмплу маску индексов
Отобрать из предиктнутой маски и GT маски каналы для обучения
41
Секция про наш pipeline
torch
cv2
tf
pandas
jupyter
flask
numpy
go
tf
torch
Та самая SOTA с медиума
Конвейер
данных
42
Обучение на “больших данных”
★ Много ресурсов, мало профита
★ Систематические ошибки
★ Отбор лучшего решения
★ Устойчивость модели
43
● Noise - первое обучение
● Fine4Test - валидация
● Fine4Train - дообучение
● Устойчивые метрики
Разметка данных
Как просто и гибко размечать данные с
изображениями?
44
Разметка данных
● VIA (VGG Image
Annotator)
http://www.robots.ox.ac.uk/
~vgg/software/via/
● Файловый сервер
45
46
Шасси
● Uwsgi + flask (НЕ flask only)
https://uwsgi-docs.readthedocs.io/en/latest/,
https://flask.palletsprojects.com/
@before_first_request
47
На чем деплоить модели в прод?
Production Stories
OCR Detection
48
OCR Наименований товаров
● Что не зашло:
Tesseract – не справляется с текстом “in the wild”, только текст как
картинка/скан. Только консольный интерфейс
Google OCR – недостаточное качество. Систематические ошибки.
Возможные просадки качества. Дороговизна, даже с трюками
49
OCR Наименований товаров
● Что не зашло:
AlexNet на стероидах с MSE-Loss
Обучение на малых и точных данных
50
OCR Наименований товаров
● Что зашло:
ResNet-18-UNet и efficientNet-b3-UNet
GRCNN, T=3. 77 символов, 32x1600x3, 201 Ts
Отсутствие сложных замен символов
Levenshtein distance (Needleman–Wunsch algorithm)
https://en.wikipedia.org/wiki/Needleman–Wunsch_algorithm,
https://biopython.org
MSE + CTC magic
51
OCR: CTC
● 2 * n + 1
● Горизонтальная конкатенация и паддинг черным справа
● pytorch: collate_fn
● Грязная разметка работает
● Confidence: warp_ctc, CTCDecoder
https://github.com/SeanNaren/warp-ctc,
https://github.com/githubharald/CTCDecoder
● Best path decoding
52
https://www.youtube.com/watch?v=eYIL4TMAeRI
OCR: CTC
● Использовать confidence для пропуска ручной модерации
53
Production Stories
Detection OCR
54
Детекция ценников товаров
● FPN Mask-RCNN ResNet-50, custom anchors, 2 classes
● Пропуск всего трафика по избранным магазинам
● Tensorpack
https://github.com/tensorpack/tensorpack/tree/master/examples
/FasterRCNN
55
56
57
...
Спасибо за внимание
● Делитесь с коммьюнити своими трюками
● Участвуйте в обсуждениях в ODS Slack
● Дьявол в деталях
58

CV в пайплайне распознавания ценников товаров: трюки и хитрости Николай Маслович

  • 1.
    CV в пайплайнераспознавания ценников товаров Трюки и хитрости Николай Маслович, Metacommerce, 2020
  • 2.
    2011 — годоснования 107 сотрудников 2 офиса (Россия, Европа) Резидент IT-кластера Фонда «Сколково» Мультиканальный мониторинг ассортимента и цен Создано с содействием инвестиций Фонда развития интернет-инициатив Собираем в день 3,6 терабайт сырых данных о 100 млн. товаров Нам доверяют О компании 2
  • 3.
    Про меня 3 ● CV& ML специалист в R&D отделе ● 1.5 года ● НИТУ МИСиС: Прикладная Математика @maslovich
  • 4.
    Про задачи 4 Проблематика мониторингацен продуктового ритейла: ● 100 товарных позиций в день с помощью блокнота и ручки ● 100% ручной мониторинг ● 200 – 300 ценников в день с человека ● Полностью ручной ввод в систему ценообразования ● Ошибки ручного поиска товаров
  • 5.
    Про задачи 5 Результат работыR&D отдела по автоматизации: ● 12 000 ценников в день на человека ● Полный контроль качества исполнения ● Качество распознавания 99%+ ● Удешевление процессов в 7 раз
  • 6.
    Как мы этосделали Детекция Сегментация Распознавание 6 Пайплайн
  • 7.
  • 8.
    Работа на сервере Какразрабатывать код и обучать модели на локальном сервере? 8
  • 9.
  • 10.
    Если нет своегосервера... ● Vast.ai https://vast.ai Цены заметно ниже, чем на amazon, google Максимально простое использование Дорогой трафик 10
  • 11.
    Executable python ● clickmodule https://click.palletsprojects.com ● jobs | disown ● screen, tmux https://help.ubuntu.ru/wiki/screen, https://linuxize.com/post/getting-started-with-tmux/ ● Прогресс-бары https://github.com/tqdm/tqdm 11 Как создавать скрипты с CLI и запускать без остановки после разрыва ssh?
  • 12.
    Чтение и сохранениеданных Как быстро и просто хранить и обрабатывать данные? 12
  • 13.
    Чтение и сохранениеданных ● pathlib.Path вместо os Стандартная библиотека в python >= 3.4 13
  • 14.
    Чтение и сохранениеданных ● ujson вместо json https://pypi.org/project/ujson/ 14
  • 15.
    Чтение и сохранениеданных ● ilio вместо with open https://github.com/gowhari/ilio 15
  • 16.
  • 17.
    Чтение и сохранениеданных ● Используйте turbojpeg для открытия и сохранения jpeg 17
  • 18.
    Сравнение opencv иturbojpeg на чтении # turbo Total time: 26.819 Avg. time: 0.001788 # cv2 Total time: 45.458 Avg. time: 0.003031 18
  • 19.
    Чтение и сохранениеданных ● Храните табличные данные в parquet формате для экономии места. 19
  • 20.
  • 21.
    Чтение и сохранениеданных ● Для хранения большого числа файлов используйте шардинг 21 folder/abcdef.jpg folder/a/b/c/abcdef.jpg
  • 22.
    Слишком много кода! Этовсё конечно хорошо, но... 22
  • 23.
    Организация кода Как разрабатыватькод в команде без копипаста и боли? 23 ● python-package и установка как гит-сабмодуль. ● при разработке pip install -e submodule/
  • 24.
    Организация кода ● Длякода всегда используйте git. Даже если вам нужна только “бэкап” функциональность ● Никогда не используйте git для хранения датасетов ● Сформируйте .gitignore для всех ML-проектов и копипастьте его ● Не забывайте использовать info/exclude ● Всегда используйте только ssh подключения 24
  • 25.
    Эксперименты Как организовать кодэксперимента, не ограничивая гибкость и сохранить воспроизводимость? 25
  • 26.
    Эксперименты ● Cata... jupyter+ .py Код в PyCharm Параметры в Jupyter с %autoreload Свой велосипед лучше, если чаще всего вы меняете код, а не параметры. 26
  • 27.
    А теперь пронейроночки torch cv2 tf pandas jupyter flask numpy go tf torch 27
  • 28.
    Чистка данных Как безпереразметки убрать часть ошибок в разметке и улучшить скор? 28 4 6 0 7 0 6 4 2 2 1 4 5 5
  • 29.
    Чистка данных 1. Train Обучаеммодель на том, что есть. Если данных достаточно много, то обучаем не боясь оверфита 29
  • 30.
    Чистка данных 1. Train 2.Peel Выкидываем часть данных, на которых сеть показывает плохой результат (например 5% квантиль или даже все с неидеальным скором) 30
  • 31.
    Чистка данных 1. Train 2.Peel 3. Repeat Файнтюним / обучаем с нуля модель на новом датасете. Повторяем, пока число примеров с плохим скором не перестанет значительно меняться / качество на валидации станет падать. Работает, если разметка имеет значительные изъяны, например отсутствует часть последовательности 31
  • 32.
    Про pytorch иподводные камни 32
  • 33.
    Про pytorch иподводные камни ● Denormal values https://discuss.pytorch.org/t/conv2d-is-very -slow-on-trained-weights-vs-random-weights/4337 7 33 %Total OwnTime TotalTime Function (filename:line) 80.00% 34.93s 34.93s forward (torch/nn/modules/conv.py:320)
  • 34.
    Про pytorch иподводные камни ● .pt vs .pth ● Saving optimizer ● Initialization torch.save({ 'epoch': epoch, 'model_state_dict': model.state_dict(), 'optimizer_state_dict': optimizer.state_dict(), 'loss': loss, ... }, PATH) 34 torch_utils.py
  • 35.
    Маски для сегментатора 1.Генерация на лету vs чтение с диска 2. Если число классов <= 8, можно хранить в битах с помощью np.(un)packbits 3. npz vs npy vs sparse 35 Хранить или создавать на лету? Если хранить, то в чём?
  • 36.
    “Липкая” сегментация Объекты одногокласса находятся близко друг к другу 36
  • 37.
    “Липкая” сегментация ● Грубаясегментация: Обвести сегмент через opencv черным цветом На постпроцессинге увеличить размер bounding box-a 37
  • 38.
    “Липкая” сегментация ● Точнаясегментация: Прининцип watershed: from scipy import ndimage as ndi distance = ndi.distance_transform_edt(mask).astype(np.float32) Нормируем на максимальное значение mask = np.max(np.stack(distances), axis=0) Подбираем пороговое значение на постпроцессинге, уменьшая пока не появится слипание 38
  • 39.
    “Липкая” сегментация Ground truthбез трешхолда “Умный” трешхолд 39
  • 40.
    Пропущенная разметка вмногоклассовой сегментации Как сказать нейросетке, чтобы она не училась на ложно-отсутствующей разметке? 40
  • 41.
    Пропущенная разметка вмногоклассовой сегментации ● Кастомный loss В датагенераторе добавить к сэмплу маску индексов Отобрать из предиктнутой маски и GT маски каналы для обучения 41
  • 42.
    Секция про нашpipeline torch cv2 tf pandas jupyter flask numpy go tf torch Та самая SOTA с медиума Конвейер данных 42
  • 43.
    Обучение на “большихданных” ★ Много ресурсов, мало профита ★ Систематические ошибки ★ Отбор лучшего решения ★ Устойчивость модели 43 ● Noise - первое обучение ● Fine4Test - валидация ● Fine4Train - дообучение ● Устойчивые метрики
  • 44.
    Разметка данных Как простои гибко размечать данные с изображениями? 44
  • 45.
    Разметка данных ● VIA(VGG Image Annotator) http://www.robots.ox.ac.uk/ ~vgg/software/via/ ● Файловый сервер 45
  • 46.
  • 47.
    Шасси ● Uwsgi +flask (НЕ flask only) https://uwsgi-docs.readthedocs.io/en/latest/, https://flask.palletsprojects.com/ @before_first_request 47 На чем деплоить модели в прод?
  • 48.
  • 49.
    OCR Наименований товаров ●Что не зашло: Tesseract – не справляется с текстом “in the wild”, только текст как картинка/скан. Только консольный интерфейс Google OCR – недостаточное качество. Систематические ошибки. Возможные просадки качества. Дороговизна, даже с трюками 49
  • 50.
    OCR Наименований товаров ●Что не зашло: AlexNet на стероидах с MSE-Loss Обучение на малых и точных данных 50
  • 51.
    OCR Наименований товаров ●Что зашло: ResNet-18-UNet и efficientNet-b3-UNet GRCNN, T=3. 77 символов, 32x1600x3, 201 Ts Отсутствие сложных замен символов Levenshtein distance (Needleman–Wunsch algorithm) https://en.wikipedia.org/wiki/Needleman–Wunsch_algorithm, https://biopython.org MSE + CTC magic 51
  • 52.
    OCR: CTC ● 2* n + 1 ● Горизонтальная конкатенация и паддинг черным справа ● pytorch: collate_fn ● Грязная разметка работает ● Confidence: warp_ctc, CTCDecoder https://github.com/SeanNaren/warp-ctc, https://github.com/githubharald/CTCDecoder ● Best path decoding 52 https://www.youtube.com/watch?v=eYIL4TMAeRI
  • 53.
    OCR: CTC ● Использоватьconfidence для пропуска ручной модерации 53
  • 54.
  • 55.
    Детекция ценников товаров ●FPN Mask-RCNN ResNet-50, custom anchors, 2 classes ● Пропуск всего трафика по избранным магазинам ● Tensorpack https://github.com/tensorpack/tensorpack/tree/master/examples /FasterRCNN 55
  • 56.
  • 57.
  • 58.
    Спасибо за внимание ●Делитесь с коммьюнити своими трюками ● Участвуйте в обсуждениях в ODS Slack ● Дьявол в деталях 58