Как программист датасаентистам кернелы писал |
||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2019-02-10 01:47 Мало кто верит, что современный data science-стек может быть построен не на Python, но такие прецеденты есть :). Стек Одноклассников формировался долгие годы, в первую очередь программистами, перешедшими в data science, но всё ещё остались близкими к проду, поэтому в его основе лежат открытые технологии JVM-стека: Hadoop, Spark, Kafka, Cassandra и т.д. Это помогает нам сокращать время и затраты на ввод моделей в эксплуатацию, но иногда создаёт и сложности. Например, при подготовке базовых решений для участников SNA Hackathon 2019 пришлось сжать волю в кулак и погрузиться в мир динамической типизации. Подробности (и лёгкий троллинг) под катом :)
Установка Какой-то питон найдётся почти на любой девелоперской машине. Нашёлся он и на моей, аж в двух экземплярах — 2.7 и 3.4. Порывшись в закромах памяти я вспомнил, что версию 3.4 поставил три года назад, после того, как на SNA Hackathon 2016 участники столкнулись с эпичными проблемами, пытаясь разложить в памяти полуторагигабайтный граф (по итогам получилось небольшое обучающее видео и отдельное соревнование), но сегодня это хозяйство уже морально устарело и нуждалось в обновлении. В мире Явы каждый проект при сборке указывает всё то, что хочет в себя вобрать, и с этим дальше и живёт. В теории всё просто и красиво, на практике же, когда тебе нужна библиотека А и библиотека Б, обязательно выяснится что им обеим нужна библиотека C, при этом двух разных несовместимых версий :). В тщетных попытках разорвать этот порочный круг некоторые библиотеки пакуют все свои зависимости в себя самих и прячут от остальных, а остальные крутятся, как могут. Что с этим в питоне? Проекта как такового нет, но есть «окружение», и в рамках каждого окружения можно сформировать независимую экосистему из пакетов определённых версий. При этом есть и инструменты для ленивых, с помощью которых локальным питоновским окружением управлять не сложнее, чем распределённым гетерогенным кластером Клаудеры или Хортона. Но взаимные конфликты версий пакетов никуда не денутся.Я сразу же столкнулся с тем, что релиз Pandas 0.24 перевёл приватный метод _maybe_box_datetimelike в публичный API, и неожиданно оказалось, что много кто его в прежнем виде юзал и теперь отвалился :) (и да, в мире Явы все то же самое). Но в итоге удалось всё починить, не считая страшных варнингов о новых деприкейшинах, заработало.Коллаборативный baseline Задачи на SNA Hackathon 2019 разделены на три направления — рекомендации по логам, по текстам и по картинкам. Начнём с логов (спойлер — мегапаттерн Cmd+C/Cmd+V со стэковерфлоу работает и с питоном). Данные были собраны с живого продакшина — каждому пользователю случайным образом, без взвешивания, показывался некоторый фид из его окружения, после чего в лог записывались все признаки на момент показа и итоговая реакция. Задача piece of cake: берём признаки, пихаем в логрег, профит! Но план зафэйлился на первом же этапе, на чтении данных. В теории, есть замечательный пакет Apache Arrow, который дожен был унифицировать работу с данными в разных экосистемах и, в том числе, позволить читать «паркетные» файлы из питона без спарка. На практике же оказалось. что даже с чтением простых вложенных структур у него проблемы, и наша красивая иерархия превратилась в плоское убожество :(. Но были и положительные стороны. Jupyter, в целом, порадовал, он почти такой же удобный, хоть и не такой няшный, как Zeppelin. Даже скала-ядро есть! Ну и скорость логистической регрессии на небольшом куске данных в памяти порадовала — до мощности распределённого варианта не дотягивает, но на четырёх признаках и паре сотен тысяч примеров учится мгновенно. Потом, правда, возникший было энтузиазм получил удар под дых: если необходимая трансформация данных (сгруппировать по ключу и собрать в список) отсутствует в стандартном списке и появляется apply или map, то скорость падает на порядки. В итоге, 80 % времени baselineа занимает не чтение данных, джоины, обучение модели и сортировка, а банальное составление списка.К слову, именно из-за этой особенности я всегда удивляюсь пользователям pySpark — ведь почти вся стандартная функциональность доступна в виде Spark SQL, который одинаков и в питоне, и в скале, а после появления первой питонячей юдф-ины с чем-то личным десятитысячеядерный кластер превращается в тыкву… Но, в итоге, все препятствия преодолены и для score 0.65 хватило девяти параграфов! Текстовый baseline Ну вот, теперь у нас задача посложнее — если логрег можно найти в сотне реализаций под все платформы, то уж разнообразие инструментов работы с текстами под питоном больше. К счастью, тексты уже идут не только в сыром виде, но и обработанные нашей штатной системой препроцессинга на базе спарка и Lucene. Поэтому можно сразу брать список токенов и не париться токенизацией/лематизацией/стемингом. Некоторое время я сомневался, что же взять: отечественный BigARTM или импортный Gensim. В итоге остановился на втором и скопипастил их doc2vec туториал :). Надеюсь, коллеги из команды BigARTM не преминут воспользоваться шансом и покажут преимущества своей библиотеки на конкурсе. У нас опять простой план: берём все тексты из теста, обучаем модель Doc2Vec, далее инферим её на трэйне и на её результатах учим логрег (стэкинг — наше всё!). Но, как обычно, сразу начались проблемы. Несмотря на относительно скромный объём текстов в обучающей выборке (всего полтора гига), при попытке втянуть их в пандас питон отожрал 20 (20, Карл!) гигабайтов памяти, ушел в своп и не вернулся. Пришлось есть слона по частям.При чтении всегда указываем, какие именно колонки поднять из паркета, что позволяет не читать сырой текст в память. Это экономит её использование вдвое, документы тестового множества грузятся в память для обучения без проблем. С обучающей выборкой такого трюка мало, поэтому за раз прогружаем не более одного «паркетного» файла. Далее в загруженном файле оставляем только ID из тех дней, которые хотим использовать для обучения, и уже на них инферим эмбединги. Логрег поверх этого работает так же быстро, и в итоге получаем 14 параграфов и score 0.54 :) Картиночный baseline Что может быть популярнее deep learning? Только котики! Поэтому для картиночного baseline-а мы составили гениально простой план: прогоняем на картинках из тестового множества детектор котиков, а потом ранжируем контент по полученному score :) И опять есть из чего выбирать. Классификация или детекция? pyTorch или Tensorflow? Главный критерий — простота реализации методом копипаста. And the winner is… YOLOv3 на MXNet :). Лаконичность их демки пленила с первого взгляда, но потом, как обычно, начались проблемы. С чего обычно начинается работа с большими данными? С оценки производительности и необходимого машинного времени! Хотелось сделать baseline максимально автономным, поэтому научили его работать напрямую с tar-файлом и быстро поняли, что при скорости извлечения из tar в tmpfs 200 фото в секунду на обработку 352 758 картинок понадобится порядка получаса, норм. Добавляем загрузку и предобработку фоток — 100 в секунду, примерно час на всё, норм. Добавляем вычисление нейросетки — 20 фоток в секунду, 5 часов, нуууу ок… Добавляем извлечение результата — 1 фотка в секунду, неделя, WTF? После пары часов танцев с бубнами приходит понимание, что NDArray, который мы наблюдаем, это ни разу ни numpy, а внутренняя структура MXNet-а, который проводит все вычисления лениво. Бинго! Что же делать? Любой начинающий диплернер знает, что всё дело в размере батча! Если MXNet вычисляет score лениво, то если мы сначала запросим их для пары десятков фото, а потом начнём их извлекать, то, быть может, обработка фоток пойдёт батчем? И да, после добавления батчинга со скоростью 10 фото в секунду удалось найти всех котиков :).Дальше применяем уже известную машинерию и за 10 параграфов получаем score 0.504 :). Выводы Когда одного мудрого сэнсея спросили «Кто победит, мастер по айкидо или по карате?», он ответил «Победит мастер». К примерно таким же выводам нас привёл и этот эксперимент: нет и не может быть идеального языка на все случаи жизни. С Python вы можете быстро собрать решение из готовых блоков, но попытка отойти от них при достаточно больших объёмах данных принесёт много боли. В Java и Scala вы тоже можете найти много готовых инструментов и легко реализуете собственные идеи, но сами языки будут более требовательны к качеству кода. Ну и, конечно, удачи всем участникам SNA Hackathon 2019!Источник: habr.com Комментарии: |
|