Русский
Русский
English
Статистика
Реклама

Машинное обучение

Расчет факторов в антифроде. Доклад Яндекса

04.07.2020 12:05:52 | Автор: admin
Антифрод сервис по поиску и нивелированию случаев эксплуатации других, общедоступных сервисов Яндекса. Три года назад мы начали проектировать платформу, позволяющую быстро и легко развернуть антифрод где угодно в компании. Сложность задачи в том, что многим сервисам нужны максимально строгие гарантии по скорости, надежности и качеству; часть из них оперирует очень большими объемами данных. Команде антифрода, в свою очередь, важна гибкость системы, простота поддержки и выразительность факторов, на которых будет строиться машинное обучение.


Руководитель антифрода Андрей Попов выступил с докладом о том, как мы смогли выполнить все эти противоречивые требования. Центральная тема доклада модель вычисления сложных факторов на потоке данных и обеспечение отказоустойчивости системы. Также Андрей кратко описал следующую, еще более быструю итерацию антифрода, которую мы сейчас разрабатываем.

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

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

Что такое антифрод?


Что вообще такое антифрод? Думаю, проще всего показать.

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

С чем вообще борется антифрод? Пара примеров.

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



Или, например, накрутка отзывов. Такой отзыв можно увидеть у организации на Картах, которая ставят пластиковые окна. За этот отзыв она же сама и заплатила.

Верхнеуровнево архитектура антифрода выглядит так: некоторый набор сырых событий попадают в саму система антифрод как в черный ящик. На выходе из него генерируются размеченные события.

У Яндекса много сервисов. Все они, особенно большие, так или иначе сталкиваются с разными видами фрода. Поиск, Маркет, Карты и десятки других.

Где мы были еще года два-три назад? Каждая команда выживала под натиском фрода как могла. Она генерировала свои команды антифрода, свои системы, которые не всегда работали хорошо, были не очень удобны для взаимодействия с аналитиками. И главное, они были слабо проинтегрированы между собой.

Я хочу рассказать, как мы это решили созданием единой платформы.



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

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

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

Расскажу немного про то, как мы классифицируем антифроды.



Это может быть офлайн-система, которая считает часы, дни и тяжелые офлайн-процессы: например, сложные кластеризации или сложное переобучение. Этой части я практически не буду касаться в докладе. Есть near real-time-часть, которая работает за единицы минут. Это некая золотая середина, у нее быстрая реакция и тяжеловесные методы. В первую очередь я остановлюсь на ней. Но не менее важно сказать, что на этом этапе мы используем данные с этапа уровнем выше.

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

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

Я практически не буду касаться самих ML-методов. В основном я буду рассказывать о платформах, создающих фичи, которые мы потом используем в обучении.

Кому это может быть интересно? Очевидно, тем, кто пишет антифрод или борется с мошенниками. Но также и тем, кто просто запускает поток данных и считает фичи, считает ML. Так как мы сделали достаточно общую систему, может быть, что-то из этого вам будет интересно.

Какие у системы требования? Их достаточно много, вот некоторые из них:

Большой поток данных. Мы обрабатываем сотни миллионов событий за пять минут.
Полностью конфигурируемые фичи.
Декларативный язык описания факторов.
Конечно же, кросс-ДЦ и exactly-once-обработка данных, которая нужна для некоторых сервисов. Удобная инфраструктура как для аналитиков, которые подбирают итоговые фичи, обучают модели и подобное, так и для разработчиков, которые поддерживают систему.
И, конечно, скорость.

Дальше расскажу про каждый из этих пунктов в отдельности.

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

Все совпадения с реальными сервисами, естественно, случайны. Рассмотрим в первую очередь near real-time-версию, так как онлайн конкретно здесь не нужен при первом приближении.

Большие данные



В Яндексе есть классический способ решения проблем с большими данными: использовать MapReduce. Мы используем нашу собственную реализацию MapReduce, называется YT. Кстати, у Максима Ахмедова сегодня вечером рассказ про нее. Вы можете использовать вашу реализацию либо опенсорсную реализацию вроде Hadoop.

Почему мы сразу не используем онлайн-версию? Она не всегда нужна, может усложнять пересчеты в прошлое. Если мы добавили новый алгоритм, новые фичи, мы хотим часто пересчитать данные в прошлое, чтобы изменить вердикты по ней. Сложнее использовать тяжеловесные методы думаю понятно, почему. И онлайн-версия по ряду причин может быть более требовательна по ресурсам.

Если мы используем MapReduce, получается примерно такая схема. Мы используем некий минибатчинг, то есть делим на максимально маленькие куски батчей. В данном случае это одна минута. Но те, кто работает с MapReduce, знают, что меньше этого размера, наверное, уже возникают слишком большие оверхеды самой системы накладные расходы. Условно, она не сможет справляться с обработкой за одну минуту.

Дальше мы над этим набором батчей запускаем набор Reduce и получаем размеченный батч.



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

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

Как следствие, нам нужна большая история данных, в которой мы будем хранить эти статистики.



Давайте попробуем в лоб. У нас есть одна минута и большая старая история. Мы пускаем ее на вход Reduce и на выход выдаем обновленную историю и размеченный лог, данные.

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



Заменим это на некий key-value store. Это вновь наша собственная реализация, key-value-хранилище, но она хранит данные в памяти. Наверное, ближайший аналог какой-нибудь Redis. Но у нас тут получается небольшое преимущество: наша реализация key-value store очень сильно проинтегрирована с MapReduce и кластером MapReduce, на котором это запускается. Получается удобная транзакционность, удобная передача данных между ними.

Но общая схема что мы в каждом джобе этого Reduce будем ходить в этот key-value storage, обновлять данные и записывать обратно после формирования вердикта по ним.

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

Конфигурируемые фичи


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

Давайте разобьем на три этапа:
Extract, где мы изымаем данные для данного ключа и из лога.
Merge, где мы сливаем эти данные со статистикой, которая находится в истории.
Build, где мы формируем итоговое значение фичи.

Давайте, например, посчитаем процент детективов, прочитанных пользователем.



Если пользователь читает слишком много детективов, он слишком подозрительный. Никогда непонятно, чего от него ждать. Тогда Extract изъятие количества детективов, которые прочел пользователь в этом батче. Merge взятие всех детективов, всех этих данных из батчей за месяц. И Build это какая-то сумма.

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

А если мы хотим посчитать разные значения, например, количество различных авторов, которых читает пользователь?





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



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

Давайте, например, введем вот такие разрезы пользователь, автор и жанр.



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

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

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



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



И мы можем обратно это вернуть пользователю, чтобы понять, что конкретно этот пользователь имеет связь с автором, который нам кажется подозрительным.

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

Как это сделать в парадигме MapReduce? Давайте сделаем несколько последовательных редьюсов и зависимости между ними.



У нас получается граф редьюсов. Он влияет на то, по каким срезам мы считаем фичи, какие джойны вообще допустимы, на количество потребляемы ресурсов: очевидно, чем больше редьюсов, тем больше ресурсов. И Latency, throughput.

Построим, например, такой граф.



То есть разобьем на два этапа редьюсы, которые у нас есть. На первом этапе мы посчитаем параллельно разные редьюсы по разным разрезам наши пользователи, авторы и жанр. И нам нужен какой-то второй этап, где мы соберем фичи из этих разных редьюсов и примем итоговый вердикт.

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

Здесь важно, что у нас нет вот такой зависимости:



То есть у нас фактически получается конвейер. То есть первый этап следующего батча может работать параллельно со вторым этапом первого батча.

А как в этом сделать трехстадийную статистику, которую я приводил выше, если у нас всего два этапа? Очень просто. Мы можем считать первое значение на первом этапе батча N.



Второе значение на первом этапе батча N+1, и итоговое значение нужно считать на втором этапе батча N+1. Таким образом, при переходе между первым этапом и вторым будут, может быть, не совсем точные статистики для батча N+1. Но обычно этого достаточно для подобных расчетов.



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



К этому добавляется то, что мы называем отношениями между событиями. Часто у нас в логах или в данных, которые нам посылаются, появляются дубликаты. Это могут быть либо технические события, либо роботное поведение. Мы такие дубликаты также обнаруживаем. Или, например, какие-то связанные события. Скажем, у вас в системе показываются рекомендации книг, и пользователи кликают по этим рекомендациям. Чтобы итоговые статистики, которые влияют на ранжирование, не портились, нам нужно следить, что если мы отфильтруем показ, то должны отфильтровать и клик по текущей рекомендации.

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

Язык описания фич


Расскажу немного про язык описания всего этого.



Можно не вчитываться, это для примера. Начинали с трех основных компонент. Первое описание единиц данных в истории, вообще говоря, произвольного типа.



Это какая-то фича, nullable-число.



И какое-то правило. Что мы называем правилом? Это набор условий на этих фичах и что-то еще. Было у нас три отдельных файла.

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

Язык получается императивный: мы описываем, как посчитать данные, а не декларативный, когда мы бы описывали бы, что нам нужно посчитать. Это тоже не очень удобно, достаточно легко допустить ошибку и высокий порог входа. Новые люди приходят, но не совсем понимают, как с этим вообще работать.

Решение давайте сделаем свой DSL. Он более понятно описывает наш сценарий, он проще для новых людей, он более высокоуровневый. Вдохновение мы брали у SQLAlchemy, C# Linq и подобного.

Приведу пару примеров, аналогичных тем, которые я приводил выше.



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



Если мы считаем количество различных авторов, то делаем группировку по пользователю, задаем distinct авторов. К этому можем добавить какие-нибудь условия, например окно расчета или лимит на количество значений, которые мы храним из-за ограничения памяти. В итоге считаем count, количество ключей в нем.



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



К этому мы потом можем добавить условие фильтрации. То есть фильтр у нас может быть, например, таким: лояльность не слишком высокая и количество процентов детективов между 80 из 100.

Что мы для этого используем под капотом?



Под капотом мы используем самые современные технологии, напрямую из 70-х годов, такие как Flex, Bison. Может быть, слышали. Они генерируют код. У нас файл с кодом проходит через наш лексер, который сгенерирован во Flex, и через парсер, который сгенерирован в Bison. Лексер генерирует терминальные символы или слова в языке, парсер генерирует синтаксические выражения.

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

Что в итоге? Это сложнее, чем может показаться с первого взгляда. Нужно потратить много ресурсов, продумать такие мелочи, как приоритеты операций, крайние случаи и подобное. Нужно изучить редкие технологии, которые вряд ли вам пригодятся в реальной жизни, если вы не пишете компиляторы, конечно. Но в итоге это того стоит. То есть если у вас, как и у нас, большое количество аналитиков, которые часто приходят их других команд, то в итоге это дает существенное преимущество, потому что им становится проще работать.

Надежность


Некоторые сервисы требуют отказоустойчивости: кросс-ДЦ и exactly-once-обработку. Нарушение может вызывать расхождение статистик и потери, в том числе денежные. Наше решение для MapReduce такое, что мы считаем данные в каждый момент времени только на одном кластере и синхронизируем их на второй.



Например, как бы мы вели себя здесь? Есть лидер, follower и message broker. Можно считать, что это условная кафка, хотя тут, конечно, собственная реализация.



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

Раз в какое-то время мы, естественно, должны сделать репликацию. То есть мы собираем снапшоты, собираем ченжлоги изменения за каждый батч. И то, и то синхронизируем на второй кластер follower. И также поднимаем историю, которая находится в таком горячем состоянии. Напомню, что история здесь хранится в памяти.

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

Почему бы вообще не считать на двух кластерах параллельно? Внешние данные могут отличаться на двух кластерах, поставлять их могут внешние сервисы. Что вообще такое внешние данные? Это что-то, что с вот этого более высокого уровня поднимается. То есть сложные кластеризации и подобное. Либо просто вспомогательные для расчетов данные.

Нам нужно согласованное решение. Если мы будем параллельно считать вердикты с использованием разных данных и периодически переключаться между результатами из двух разных кластеров, согласованность между ними будет сильно падать. И, конечно же, экономия ресурсов. Так как мы в каждый момент времени используем ресурсы CPU только на одном кластере.

А что со вторым кластером? Когда мы работаем, он практически простаивает. Давайте использовать его ресурсы для полноценного препрода. Под полноценным препродом я тут подразумеваю полноценную инсталляцию, которая принимает тот же поток данных, работает с теми же объемами данных и т. д.



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

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

(00:25:12)

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

К этому добавляются преимущества B2B-тестирования. То есть мы все выкатываем, естественно, сначала на препрод. Полностью сравниваем любые отличия, и, таким образом, не ошибемся, минимизируем вероятность, что мы можем ошибиться при выкатке на прод.

Немного про планировщик. Понятно, что у нас есть какие-то машины, которые запускают задачу в MapReduce. Это некие воркеры. Они регулярно синхронизируют свои данные в Cross-DC Database. Это просто состояние того, что они успели посчитать на данный момент.



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



Переподняться с него и продолжить работу. Продолжить ставить задачи на этом MapReduce.



Понятно, что в случае переподнятия этих задач, некоторое множество из них может перезапуститься. Поэтому здесь есть очень важное свойство для нас: идемпотентность, возможность перезапускать каждую операцию без последствий.

То есть весь код должен быть написан так, чтобы это нормально работало.



Немножко расскажу про exactly-once. Мы выносим вердикт согласованно, это очень важно. Используем технологии, которые дают нам такие гарантии, и мониторим, естественно, все расхождения, сводим их к нулю. Даже когда кажется, что это уже сведено, периодически возникает очень хитрая проблема, которую мы не учли.

Инструменты


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



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



Или, например, дашборд проблем, где мы сразу на одной странице видим все проблемы всех антифродов разных сервисов, которые к нам подключены. Здесь видно, что на препроде у нашего сервиса Книги сейчас явно что-то не так. Но сработает мониторинг, и дежурный будет на это смотреть.



Что мы вообще мониторим? Очевидно, лаг системы крайне важен. Очевидно, время работы каждой отдельной стадии и, конечно же, фильтрация отдельных правил. Это бизнесовое требование.

Возникают сотни графиков, дашборды. Например, на этом дашборде видно, что контуру сейчас было достаточно плохо, что мы набрали существенный лаг.

Скорость


Расскажу про переход в онлайн-часть. Тут проблема в том, что лаг в полноценном контуре может достигать единиц минут. Это в контуре на MapReduce. В некоторых случаях нам нужно банить, обнаруживать мошенников быстрее.

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



Допустим, у нас есть балансер с данными от сервиса и какое-то количество воркеров, на которые мы шардируем данные от балансера. Есть внешние данные, которые мы здесь используем, они очень важны, и набор вот этих историй. Напомню, что каждая такая история у нас разная для разных редьюсов, потому что в ней разные ключи.

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



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

Тогда мы из этого key-value storage считаем данные на оба воркера из истории, мы его обновим по-разному и возникнет гонка при попытке записать обратно.

Решение: давайте сделаем предположение, что можно разделить чтение и запись, что запись может происходить с небольшой задержкой. Обычно это не сильно важно. Под небольшой задержкой я здесь подразумеваю единицы секунд. Это важно, в частности, по той причине, что наша реализация этой key-value store занимает больше времени на запись данных, чем на чтение.

Будем обновлять статистики с отставанием. В среднем это работает более-менее хорошо, с учетом того, что мы будем хранить на машинах кэшированное состояние.



И другая вещь. Для простоты сольем вот эти истории в одну и пошардируем ее по типу и по ключу разреза. У нас есть какая-то единая история.

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

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



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

Здесь у него меняется его предназначение. Он больше не принимает вердикты. Вместо этого он просто принимает updates из Reader, смешивает их и правильно применяет к истории.

Понятно, что здесь нужна компонента, координатор, которая распределяет эти updates между ридерами и райтерами.

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



Что мы вообще получили? Аналитики стали делать работу быстрее и одинаково для всех сервисов. Это повысило качество и связанность всех систем. Можно переиспользовать данные между антифродами разных сервисов, а новые сервисы получают качественный антифрод быстро.



Пара мыслей в конце. Если вы будете писать нечто подобное, сразу подумайте про удобство аналитиков в части поддержки и расширяемости данных систем. Делайте конфигурируемым все что можно, это вам понадобится. Иногда свойств кросс-ДЦ и exactly-once бывает сложно достичь, но можно. Если вам кажется, что уже достигли, перепроверьте. Спасибо за внимание.
Подробнее..

Камера, мотор, панорама как создаются 3D-фото автомобилей в приложении Авто.ру

30.06.2020 10:05:46 | Автор: admin


Чем лучше удастся рассмотреть потенциальную покупку перед оплатой, тем меньше шансов столкнуться с неприятными сюрпризами после, вопреки недобросовестным продавцам и недостаточно подробным описаниям. Чтобы ожидания пользователей чаще совпадали с реальностью, всё больше онлайн-магазинов внедряют 3D-фото на карточки своих товаров: одежда, электроника и даже маркетплейсы. Спрос на панорамные фото автомобилей был только делом времени и технологий, ведь в отличие от обуви или телефона, съёмка машины требует намного больше места и усилий.

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

Что было до


Крупные автодилеры начали массово использовать панорамы где-то в 2017 году. Строго говоря, это были не совсем панорамы: вокруг автомобиля строили целые съёмочные павильоны или замкнутые рельсы, по которым толкали камеру, пока она не возвращалась на место старта, на выходе видео, где машина видна со всех сторон. В 2018 мы поддержали этот формат на Авто.ру и наблюдали процесс подготовки: дилеры закупают оборудование ценой в сотни тысяч рублей, возводят вспомогательные приспособления камера, мотор! Красивые фото и видео приятно рассматривать даже если не собираешься приобретать автомобиль. Неудивительно, что частные продавцы стали интересоваться, можно ли повторить такое в домашних условиях.

Технологии развивались, процесс упрощался, но для создания качественной панорамы всё ещё требовалась если не профессиональная камера, то, как минимум, топовый смартфон. К 2019 году мы поставили себе амбициозную цель сделать панорамную съёмку авто доступной почти каждому владельцу смартфона: простой и быстрой, не требующей дополнительных затрат, специального оборудования и профессиональных навыков.

И сделали.

Как это работает


В двух словах так: пользователь снимает видео в нашем приложении, а оно обрабатывает полученные кадры с использованием технологий компьютерного зрения и машинного обучения очищает от шумов, выравнивает изображение, склеивает панораму. Звучит просто, но если представить, каким образом человек идёт с телефоном вокруг автомобиля, удерживая его в кадре, задача начнёт обрастать подробностями: например, телефон шатается из стороны в сторону, несмотря на оптическую стабилизацию. На пути могут возникнуть препятствия столбы, деревья, заборы и объект съёмки пропадёт из кадра. А походка или скорость шага могут привести к неравномерности съёмки ниже ещё вернёмся к тому, как боремся с этими и подобными шумами.

Итак, вы открыли приложение, нажали кнопку Панорама в форме редактирования объявления, обошли автомобиль с включённой камерой, тщательно следуя всем инструкциям. Что дальше?



Шаг 0. Снятое видео отправляется к нам на сервера: во-первых, зачем экспериментировать, справится ли ваше устройство с не самыми лёгкими расчётами, если можем взять это на себя. Во-вторых, чем больше вычислительных мощностей, тем быстрее сгенерируется панорама. Запускается классический для задач Structure from Motion алгоритм обработки видео, который умеет одновременно делать всё, что потребуется для моделирования: позиционировать камеру в пространстве, понимать, где находился объект, и оценивать его размеры.

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

Можно было бы попробовать определить позицию камеры с помощью гироскопа и других встроенных в телефон датчиков, но они накапливают ошибку измерения с течением времени: чем дольше видео тем больше ошибка. Поэтому мы пытаемся восстановить точки в трёхмерном пространстве: сравнивая соседние кадры, собираем общую трёхмерную модель траектории движения камеры. Опытные читатели могут возразить почему не попробовать делать сегментацию на разных кадрах? маска может получиться разная, возникнет дрожание объекта.

Шаг 2. Для опорных кадров алгоритм ищет соседние: выбирает таким образом, чтобы они равномерно (по углу обхода), покрывали панораму. То есть точки, существующие в реальном 3D-мире, не рассчитываются для каждого нового кадра, а ищутся на соседних.

Параллельно алгоритм* подбирает параметры камеры: после нахождения опорных точек оптимизирует систему линейных уравнений (минимизирует ошибку определения положения), по которым эти точки проецируются на кадры, где были найдены. Решая такую систему уравнений, требуем, чтобы параметры камеры на каждом кадре были одинаковы, позиция от кадра к кадру разная, а точка в 3D-профайле тоже опять-таки на всех кадрах должна быть одинаковая. Для кадров, где опорных точек не было, соответственно, определяются только позиции камеры.

*Мы уже ссылались на эту статью выше: больше деталей, математические подробности.

Шаг 3. Облако точек есть: как понять, какие из них относятся к машине? Технология, помогающая по кадрам создавать облако точек и находить позицию камеры, довольно известна. Мы для решения этой задачи используем opensfm. Однако следом отрабатывает наша собственная технология, позволяющая сделать фильтрацию облака точек и выравнивание позиции камеры. Эвристика следующая:

Объект должен быть вытянут: машина в любом сечении больше длинная, чем высокая.
Облако точек плотное: автомобиль едва ли просвечивает.
Всё, что вне траектории камеры (а она теперь известна) шум.
Машина обычно стоит на земле плотное скопление точек в нижней части кадра также обычно имеет характерную форму.

Итого: ищем некий параллелепипедообразный (bbox) объект, в который входит как можно больше точек из облака. Если таких объектов оказалось более одного (в кадр попал столб или что-то ещё), сегментация оставит только центральный.

Кстати, развеем популярный миф. Неоднородный фон самый лучший:

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

Шаг 4. Избавиться от шумов. Основные вызванные матрицей телефона, расфокус и motion blur. Из-за них на разных кадрах нельзя точно определить одинаковую точку например, из-за блюра 3 пикселя в разную сторону накапливается ошибка нахождения этой точки в трёхмерном пространстве.

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

Лучше один раз увидеть:



Шаг 5. От облака точек возвращаемся к понятной человеческому глазу картинке: панораме.

Когда мы саппроксимировали bounding box машины, можно оценить, насколько много именно её попало на разные кадры и отбраковать неудачные. Если известно местоположение объекта, все нужные точки легко спроецировать на каждый кадр, обрезать его до нужных размеров. Параллельно алгоритм восстанавливал параметры камеры: он знает, когда картинку нужно отмасштабировать (приблизить/удалить) или повернуть.

Для безопасности продавца не забываем скрыть номера: в России мы были одними из первых, кто реализовал эту опцию. Тут тоже есть нюанс: если искать номер на каждом сыром кадре возникнет дрожание, и есть шанс, что где-то что-то упустим. Поэтому наш алгоритм ищет номер на готовой 3D-модели и проецирует его на панораму.

Конечно, если подходящих кадров недостаточно, придётся переснять видео, но мы очень стараемся извлечь максимум из исходников.

Шаг 6. Готовая панорама отправляется в объявление.



Немного цифр для масштаба


Сейчас для создания панорамы используется около 60 опорных кадров, приклеиваются к ним ещё около 120. Для этого выбирается по 15 соседних кадров, для них вычисляются позиции камеры и облако совпавших точек. Количества кадров не случайны: так не страдает ни качество панорамы, ни скорость сборки. Первые панорамы, где мы ещё не нащупали баланс, собирались по 40 минут, что, конечно, недопустимо.
Обычно съёмка панорамы автомобиля происходит где-то за минуту. На смартфонах видео такой длительности после съёмки занимает от 100 до 300 МБ, что с условием загрузки на наши сервера было бы серьёзным стопором для пользователя. Поэтому в рамках проекта мы стали на лету менять битрейт и формат съёмки, тем самым сократив размер файла видео до приемлемых 2040 мегабайт, без потерь в размере картинки или качества для компьютерного зрения.
С другой стороны, нам пришлось провести адаптацию выдачи объявлений с панорамами, т.к. пользователи не готовы ждать загрузки 56 мегабайт на каждое, учитывая, что за сессию поиска автомобиля они просматривают десятки и даже сотни объявлений. Для решения этой проблемы мы перекодируем полученный результат под разные разрешения и форматы файлов от простого сета .jpeg до достаточно редкого .webm, в некоторых случаях сокращая размер скачиваемой панорамы до 150 КБ.
На данный момент у нас на сайте можно встретить больше 3000 панорам автомобилей, созданных как дилерами (мы не забыли и про них), так и обычными продавцами.
Будущие покупатели видят в выдаче живые объявления с панорамами и залипают на них до 30% дольше. Конверсия звонков продавцу для автомобиля с панорамой также растёт.

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

Товар != автомобиль. Надеемся, что наш опыт окажется полезным и для других сфер ритейла: простое, быстрое и бесплатное создание 3D-модели для объявления облегчит жизнь продавцам, возможность тщательно осмотреть предмет сделки поможет покупателям.
Подробнее..

MLHCI что исследуют на стыке машинного обучения и человеко-компьютерного взаимодействия

03.07.2020 16:05:03 | Автор: admin
Многие убеждены, что область Human Computer Interaction (HCI или человеко-компьютерное взаимодействие) сводится только к проектированию сайтов или приложений, а основная задача специалиста удовлетворить пользователей, увеличивая на несколько пикселей кнопку лайка. В посте мы хотим показать, что это совсем не так, и рассказать, что происходит в HCI на стыке с исследованиями машинного обучения и искусственного интеллекта. Возможно, это позволит читателям посмотреть на эту область с новой для себя стороны.

Для обзора мы взяли труды конференции CHI: Conference on Human Factors in Computing Systems за 10 лет, и с помощью NLP и анализа сетей социтирования посмотрели на темы и области на пересечении дисциплин.




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

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

Время от времени мы слышим вопросы, как это направление связано (и связано ли вообще) с машинным обучением и анализом данных. Чтобы ответить на них, мы обратились к исследованиям последних лет, представленным на конференции CHI.

В первую очередь мы расскажем, что происходит в таких областях, как xAI и iML (eXplainable Artificial Intelligence и Interpretable Machine Learning) со стороны интерфейсов и пользователей, а также как в HCI изучают когнитивные аспекты работы специалистов data science, и приведем примеры интересных работ последних лет в каждой области.

xAI и iML


Методы машинного обучения интенсивно развиваются и что важнее с точки зрения обсуждаемой области активно внедряются в автоматизированное принятие решений. Поэтому исследователи все чаще обсуждают вопросы: как пользователи, не являющиеся специалистами в машинном обучении, взаимодействуют с системами, где подобные алгоритмы применяются? Один из важных вопросов такого взаимодействия: как сделать, чтобы пользователи доверяли решениям, принятым на основе моделей? Поэтому с каждым годом все более горячей становится тематика интерпретируемого машинного обучения (Interpretable Machine Learning iML) и объяснимого искусственного интеллекта (eXplainable Artificial Intelligence XAI).

При этом, если на таких конференциях, как NeurIPS, ICML, IJCAI, KDD, обсуждают сами алгоритмы и средства iML и XAI, на CHI в фокусе оказываются несколько тем, связанных с особенностями дизайна и опытом использования этих систем. Например, на CHI-2020 этой тематике были посвящены сразу несколько секций, включая AI/ML & seeing through the black box и Coping with AI: not agAIn!. Но и до появления отдельных секций таких работ было достаточно много. Мы выделили в них четыре направления.

Дизайн интерпретирующих систем для решения прикладных задач


Первое направление это дизайн систем на основе алгоритмов интерпретируемости в различных прикладных задачах: медицинских, социальных и т. д. Такие работы возникают в очень разных сферах. Например, работа на CHI-2020 CheXplain: Enabling Physicians to Explore and Understand Data-Driven, AI-Enabled Medical Imaging Analysis описывает систему, которая помогает врачам исследовать и объяснять результаты рентгенографии органов грудной клетки. Она предлагает дополнительные текстовые и визуальные пояснения, а также снимки с таким же и противоположным результатом (поддерживающие и противоречащие примеры). Если система предсказывает, что на рентгенографии видно заболевание, то покажет два примера. Первый, поддерживающий, пример это снимок легких другого пациента, у которого подтверждено это же заболевание. Второй, противоречащий, пример это снимок, на котором заболевания нет, то есть снимок легких здорового человека. Основная идея сократить очевидные ошибки и уменьшить число обращений к сторонним специалистам в простых случаях, чтобы ставить диагноз быстрее.


CheXpert: автоматизированное выделение областей + примеры (unlikely vs definitely)



Разработка систем для исследования моделей машинного обучения


Второе направление разработка систем, которые помогают интерактивно сравнивать или объединять несколько методов и алгоритмов. Например, в работе Silva: Interactively Assessing Machine Learning Fairness Using Causality на CHI-2020 была представлена система, которая строит на данных пользователя несколько моделей машинного обучения и предоставляет возможность их последующего анализа. Анализ включает построение причинно-следственного графа между переменными и вычисление ряда метрик, оценивающих не только точность, но и честность (fairness) модели (Statistical Parity Difference, Equal Opportunity Difference, Average Odds Difference, Disparate Impact, Theil Index), что помогает находить перекосы в предсказаниях.


Silva: граф связей между переменными + графики для сравнения метрик честности + цветовое выделение влиятельных переменных в каждой группе

Общие вопросы интерпретируемости моделей


Третье направление обсуждение подходов к задаче интерпретируемости моделей в целом. Чаще всего это обзоры, критика подходов и открытые вопросы: например, что понимать под интерпретируемостью. Здесь хотелось бы отметить обзор на CHI-2018 Trends and Trajectories for Explainable, Accountable and Intelligible Systems: An HCI Research Agenda, в котором авторы рассмотрели 289 основных работ, посвященных объяснениям в искусственном интеллекте, и 12 412 публикаций, цитирующих их. С помощью сетевого анализа и тематического моделирования они выделили четыре ключевых направления исследований 1) Intelligent and Ambient (I&A) Systems, 2) Explainable AI: Fair, Accountable, and Transparent (FAT) algorithms and Interpretable Machine Learning (iML), 3) Theories of Explanations: Causality & Cognitive Psychology, 4) Interactivity and Learnability. Кроме того, авторы описали основные тренды исследований: интерактивное обучение и взаимодействие с системой.

Пользовательские исследования


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

Инструментов и алгоритмов интерпретации появилось очень много, поэтому возникает вопрос: как понять, какой же алгоритм выбрать? В работе Questioning the AI: Informing Design Practices for Explainable AI User Experiences как раз обсуждаются вопросы мотивации использования объясняющих алгоритмов и выделяются проблемы, которые при всем многообразии методов еще не решены в достаточной степени. Авторы приходят к неожиданному выводу: большинство существующих методов построены так, что отвечают на вопрос почему (почему у меня такой результат), в то время как пользователям для принятия решений нужен еще и ответ на вопрос почему нет (почему не другой), а иногда что сделать, чтобы результат изменился.

В работе говорится также о том, что пользователям нужно понимать, каковы границы применимости методов, какие у них есть ограничения и это нужно явно внедрять в предлагаемые инструменты. Более ярко эта проблема показана в статье Interpreting Interpretability: Understanding Data Scientists' Use of Interpretability Tools for Machine Learning. Авторы провели небольшой эксперимент со специалистами в области машинного обучения: показали им результаты работы нескольких популярных инструментов для интерпретации моделей машинного обучения и предложили ответить на вопросы, связанные с принятием решения на основе этих результатов. Оказалось, что даже специалисты слишком доверяют подобным моделям и не относятся к результатам критически. Как любой инструмент, объясняющие модели можно использовать неправильно. При разработке инструментария важно учитывать это, привлекая накопленные знания (или специалистов) в области человеко-компьютерного взаимодействия, чтобы учитывать особенности и потребности потенциальных пользователей.

Data Science, Notebooks, Visualization


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

Поэтому предметом этой области HCI становится разработка новых способов визуализации неопределенности в предсказаниях моделей, создание систем для сравнения анализа, проведенного разными способами, а также анализ работы аналитиков с инструментами, например с Jupyter notebooks.

Визуализация неопределенности


Визуализация неопределенности одна из особенностей, которые отличают научную графику от презентационной и бизнес-визуализации. Довольно долго ключевым в последних считался принцип минималистичности и фокуса на основных трендах. Однако это приводит к чрезмерной уверенности пользователей в точечной оценке величины или прогноза, что может быть критичным, особенно, если мы должны сравнивать прогнозы с разной степенью неопределенности. Работа Uncertainty Displays Using Quantile Dotplots or CDFs Improve Transit Decision-Making анализирует, насколько способы визуализации неопределенности в предсказании для точечных графиков и кумулятивных функций распределения помогают пользователям принимать более рациональные решения на примере задачи оценки времени прибытия автобуса по данным мобильного приложения. Что особенно приятно, один из авторов поддерживает пакет ggdist для R с различными вариантами визуализации неопределенности.


Примеры визуализации неопределенности (https://mjskay.github.io/ggdist/)

Однако часто встречаются и задачи визуализации возможных альтернатив, например, для последовательностей действий пользователя в веб-аналитике или аналитике приложений. Работа Visualizing Uncertainty and Alternatives in Event Sequence Predictions анализирует, насколько графическое представление альтернатив на основе модели Time-Aware Recurrent Neural Network (TRNN) помогает экспертам принимать решения и доверять им.

Сравнение моделей


Не менее важный, чем визуализация неопределенности, аспект работы аналитиков сравнение того, как часто скрытый выбор исследователем разных подходов к моделированию на всех его этапах может вести к различным результатам анализа. В психологии и социальных науках набирает популярность предварительная регистрация дизайна исследования и четкое разделение эксплораторных и конфирматорных исследований. Однако в задачах, где исследование в большей степени основано на данных, альтернативой могут стать инструменты, позволяющие оценить скрытые риски анализа за счет сравнения моделей. Работа Increasing the Transparency of Research Papers with Explorable Multiverse Analyses предлагает использовать интерактивную визуализацию нескольких подходов к анализу в статьях. По сути, статья превращается в интерактивное приложение, где читатель может оценить, что изменится в результатах и выводах, если будет применен другой подход. Это кажется полезной идеей и для практической аналитики.

Работа с инструментами организации и анализа данных


Последний блок работ связан с исследованием того, как аналитики работают с системами, подобными Jupyter Notebooks, которые стали популярным инструментом организации анализа данных. Статья Exploration and Explanation in Computational Notebooks анализирует противоречия между исследовательскими и объясняющими целями, изучая найденные на Github интерактивные документы, а в Managing Messes in Computational Notebooks авторы анализируют, как эволюционируют заметки, части кода и визуализации в итеративном процессе работы аналитиков, и предлагают возможные дополнения в инструменты, чтобы поддерживать этот процесс. Наконец, уже на CHI 2020 основные проблемы аналитиков на всех этапах работы, от загрузки данных до передачи модели в продакшн, а также идеи по улучшению инструментов обобщены в статье Whats Wrong with Computational Notebooks? Pain Points, Needs, and Design Opportunities.


Преобразование структуры отчетов на основе логов выполнения (https://microsoft.github.io/gather/)

Подводя итог


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

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

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

04.07.2020 16:09:21 | Автор: admin
Это подборка материалов по теме программирования, компьютерного железа и ПО для автомобильных аудиоинтерфейсов. Всех заинтересовавшихся темой, приглашаем под кат.


Фото Jefferson Santos / Unsplash

Как программируют музыку. Прежде чем взять и влиться в тему музыкального программирования, стоит осмотреться. Предлагаем вашему вниманию компактный обзор специализированных инструментов. Первый из них называется Csound наследник семейства MUSIC-N, прямиком из Bell Labs 1960-х годов. В середине 80-х его доработал специалист из MIT, а теперь на Csound играет легендарный BT. Расскажем о его особенностях, приведем примеры использования, плюс обсудим SuperCollider и Pure Data, принадлежащих все к тому же языковому семейству MUSIC-N.

Кто занимается дипфейк-аудио. Обсуждаем Neural Voice Puppetry разработку сотрудников Мюнхенского технического университета и Института информатики Общества Макса Планка. По записи голоса и фотографии она синтезирует речь и моделирует мимику. Аналогичное решение сингапурских коллег может нативно прикрутить реплики одного человека к видеозаписи с совершенно другим лицом. Рассказываем, где применяют такие наработки (конечно, не там, где вы подумали) и вспоминаем другие проекты по теме быстрого редактирования аудио.

Реверс-инжиниринг-пост. Вслед за материалами о Sound Blaster 1.0 и Innovation SSI-2001 наш свежий разбор того, что удалось выяснить энтузиастам об усилителе в Nintendo Game Boy Color.



В статье мы напоминаем, чем известна эта консоль, показываем структуру чипа (схема выше), объясняем особенности транзисторов, использованных резисторов и конденсаторов, а еще даем компактный обзор других реверс-инжиниринг-проектов по теме легендарного Game Boy.

Если дэт-метал, то нейросетевой. Заменят ли алгоритмы музыкантов? Это вопрос, к которому мы возвращаемся в очередной раз. Обсуждаем возможности разработок по теме синтезатор NSynth Super, систему ИИ Dadabots, тематический стартап Jukedeck и инструментарий OpenAI.

Аудиобиблиотеки для машинного обучения. Чтобы реализовать что-то похожее на вышеописанные проекты, потребуется собрать солидный массив записей например, для обучения собственных нейронок. Рассказываем про четыре библиотеки, распространяющих аудиоконтент по лицензии Creative Commons. Это значит, что его можно использовать даже в коммерческих проектах.

Не отвлекаться за рулем. В одном из недавних материалов мы разобрались, как и почему автомобильные инфотейнмент-системы провоцируют ДТП. На этот раз обсуждаем альтернативу в виде голосовых ассистентов. Говорим о примерах их внедрения на стороне автопроизводителей, исследованиях и потенциальных рисках, от которых будет не так и просто избавиться.


Фото Miguel ngel Hernndez / Unsplash

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

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



Дополнительные материалы:

Домашнее аудио от песенных вечеров до механических проигрывателей
Как домашнее аудио становилось действительно массовым
Как развивалось домашнее аудио: эра винила


Подробнее..

Перевод Чеклист для проекта по машинному обучению

07.07.2020 12:09:02 | Автор: admin
image

В этом посте я собрал чеклист, на который я постоянно ссылаюсь, работая над комплексным проектом по машинному обучению.

Зачем мне вообще нужен чеклист?

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

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

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

Как говорит Атул Гаванде в своей книге The Checklist Manifesto,
объем и сложность того, что мы знаем, превзошли нашу индивидуальную способность правильно, безопасно и надежно предоставлять свои преимущества.
Итак, позвольте мне провести вас по этому четкому и краткому списку действий, которые уменьшат вашу рабочую нагрузку и улучшат ваши результаты

Чеклист проектов по машинному обучению


Вот 8 шагов, которые вы должны выполнить почти в каждом проекте. Некоторые из шагов могут быть выполнены взаимозаменяемо по порядку.

1. Определите проблему с точки зрения высокого уровня


Это чтобы понять и сформулировать бизнес-логику проблемы. Это должно сказать вам:

  • характер проблемы (контролируемая/неконтролируемая, классификационная/регрессионная),
  • тип решений, которые вы можете разработать
  • какие показатели вы должны использовать для измерения производительности?
  • является ли машинное обучение правильным подходом к решению этой проблемы?
  • ручной подход к решению проблемы.
  • неотъемлемые предпосылки проблемы

2. Определите источники данных и получите данные


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

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

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

3. Первоначальная разведка данных


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

Шаги:

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

4. Исследовательский анализ данных для подготовки данных


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

  • Написание функций для преобразования данных и автоматизации процесса для предстоящих пакетов данных.
  • Напишите функции для очистки данных (вменяя пропущенные значения и обрабатывая резко отличающиеся значения)
  • Напишите функции для выбора и проектирования особенностей удалите избыточные особенности, отформатируйте преобразование объектов, и другие математические преобразования.
  • Масштабирование особенностей (features) стандартизация особенностей (features) .

5. Разработайте базовую модель, а затем изучите другие модели, чтобы отобрать лучшие


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

  • Обучите несколько часто используемых моделей, таких как модель наивного байеса, модель линейной регрессии, SVM и т. д., используя параметры по умолчанию.
  • Измерьте и сравните производительность каждой модели с базовой и со всеми остальными.
  • Используйте N-кратную перекрестную проверку для каждой модели и вычислите среднее и стандартное отклонение показателей эффективности по N-кратным показателям.
  • Изучите особенности, которые оказывают наибольшее влияние на цель.
  • Проанализируйте типы ошибок, которые допускают модели при прогнозировании.
  • Проектируйте функции по-разному.
  • Повторите вышеупомянутые шаги несколько раз (методом проб и ошибок), чтобы убедиться, что мы использовали правильные функции в правильном формате.
  • Составьте шорт-лист лучших моделей на основе их показателей эффективности.

6. Точно настройте свои модели из шорт-листа и проверьте наличие методов ансамбля


Это должен быть одним из решающих шагов, когда вы приближаетесь к своему окончательному решению. Основные пункты должны включать:

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

7. Документируйте код и сообщайте свое решение


Процесс коммуникации многообразен. Вы должны иметь в виду все существующие и потенциальные заинтересованные стороны. Поэтому основные пункты включают в себя:

  • Документируйте код, а также ваш подход ко всему проекту.
  • Создайте информационную панель, например, voila, или проницательную презентацию с визуализацией, которая не требует пояснений.
  • Напишите блог/отчет о том, как вы анализировали особенности, тестировали различные преобразования и т. д. Опишите свое обучение (неудачи и методы, которые сработали)
  • Закончите с основным результатом и будущим объемом (если таковые имеются)

8. Разверните свою модель в продакшен, мониторинг


Если ваш проект требует тестирования развертывания на реальных данных, вы должны создать веб-приложение или REST API для использования на всех платформах (web, Android, iOS). Основные пункты (будут варьироваться в зависимости от проекта) включают в себя:

  • Сохраните вашу окончательную обученную модель в файл h5 или pickle.
  • Обслуживайте свою модель с помощью веб-сервисов, Вы можете использовать Flask для разработки этих веб-сервисов.
  • Подключите источники входных данных и настройте конвейеры ETL.
  • Управляйте зависимостями с помощью pipenv, docker/Kubernetes (на основе требований масштабирования)
  • Вы можете использовать AWS, Azure или Google Cloud Platform для развертывания своего сервиса.
  • Делайте мониторинг производительности на реальных данных или просто для людей, чтобы они могли использовать вашу модель со своими данными.

Примечание. Чеклист может быть адаптирован в зависимости от сложности вашего проекта.

image

Узнайте подробности, как получить востребованную профессию с нуля или Level Up по навыкам и зарплате, пройдя платные онлайн-курсы SkillFactory:



Читать еще


Подробнее..

Перевод Использование методов анализа графов для поиска аномалий

07.07.2020 10:10:24 | Автор: admin
Несмотря на то, что описание данных с помощью графов практикуется еще с позапрошлого столетия, использование их в решении повседневных задач по анализу данных лишь набирает обороты. Хотя основное внимание уделяется, как водится, графовым эмбеддингам и сверточным сетям, маленькие шаги предпринимаются и в алгоритмах по поиску аномалий или антифроде. Основная обзорная статья, на которую ссылается большинство специалистов в своих в докладах и публикациях, Graph based anomaly detection and description: a survey от авторов Leman Akoglu, Hanghang Tong, Danai Koutra (Akoglu, 2015). Мы в CleverDATA решили рассказать Хабру об этом практически единственном материале по теме и предлагаем вашему вниманию его саммари.

Первый граф Российского царства Борис Петрович Шереметев. Аномалий не обнаружено.

Во вступлении авторы отвечают на вопрос: В чем же преимущества поиска аномалий с использованием теории графов?:

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

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

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

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


Поиск аномалий в графах без свойств, приписанных вершинам и/или ребрам


Для простых графов выделяют три направления структурных подходов: поиск аномалий на основе признаков узлов, диад узлов, триад, эгонетов (egonet), на основе сообществ и на основе метрик близости (proximity): pagerank, personalized pagerank, simrank. При этом предлагается для решения задачи поиска аномалий на графе использовать обычные алгоритмы (например, Isolation Forest, или если есть разметка, то стандартные классификаторы), но на основе графовых признаков.

Пример Эгонета

Отдельно описывается подход с признаками эгонетов подграфов, включающих целевой узел, и его ближайших соседей. Авторы, ссылаясь на статью 2010 года (Akoglu, 2010) (в статье будет очень много таких ссылок, гиперссылки на некоторые я дал в тексте, но более подробные ссылки, например, с указанием страниц, вы найдёте в списке литературы в конце этой статьи), предлагают искать характерные для графа паттерны эгонетов с выраженной зависимостью между характеристиками, а эгонеты, не соответствующие этим паттернам, считать аномальными, и, таким образом, считать аномальными их центральные узлы. Поскольку всевозможных показателей на основе эгонетов может быть много, авторы в этой же статье обосновывают свой выбор подгруппы таких показателей, наилучшим образом отражающие свойства графа (например, число треугольников, общий вес ребер). Расстояние между паттернами и между эгонетом и паттерном предлагается измерять, как отклонение характеристики этого эгонета от характерной зависимости, соответствующей паттерну.

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

Также авторы описывают и другие подходы:

  • кластеризация узлов на основании сходства их ближайшего окружения; предлагается реорганизация матрицы смежности для получения более плотных и менее плотных блоков (Chakrabarti 2004; Rissanen, 1999);
  • матричная факторизация; предлагается аналог Non-negative matrix factorization (NMF) (Tong and Lin 2011).

Поиск аномалий в графах с узлами и/или ребрами, обладающими свойствами


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

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

Также перечисляются и другие возможности: SAX (Symbolic Aggregate approXimation) (Lin et al., 2003), MDL-binning (Minimum description length) (Kontkanen and Myllymki, 2007) и дискретизация по минимуму энтропии (Fayyad and Irani, 1993). Авторы этой статьи (Eberlie and Holder, 2007) иначе подходят к определению аномалии в графовых данных, считая аномальными те подграфы, которые похожи по отношению к условно нормальному графу в определенных пределах. Такой подход авторы обосновывают тем, что самые успешные мошенники будут стараться максимально подражать реальности. Они также предлагают учитывать стоимость модификации показателя и формулируют показатели аномальности с учетом этой стоимости (чем меньше стоимость, тем более аномальным является показатель).

Поиск аномалий для графов с атрибутированными узлами рассматривается и в основанный на поиске сообществ парадигме. Предлагается подразделять графы на сообщества. Далее, в рамках каждого сообщества, искать аномалии по атрибутам. Например, курильщик в команде по бейcболу. Курильщик не является аномалией для общества в целом, но в своем сообществе является. Другой подход (Mller, 2013) основывается на выборе пользователем (аналитиком) набора узлов, для которых далее определяется подпространство показателей, схожих для них. А аномалиями в таком подходе являются узлы, которые структурно принадлежат к кластеру этих узлов, но в выбранном подпространстве показателей находятся далеко от них.

Отдельно рассматриваются методы semi-supervised, в предположении, что какая-то часть узлов размечена как нормальные и аномальные, а остальные узлы можно классифицировать, используя соответствующие методики, а в самом простом случае им можно присваивать метки соседних с ними узлов. Перечисляются основные подходы: iterative classification algorithm, gibbs sampling (подробнее про эти подходы пишут здесь), loopy belief propagation, weighted-vote relational network classifier.

Поиск аномалий в динамическом графе


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

  1. выделяется некоторое сжатие или интегральная характеристика каждого статического графа;
  2. вычисляется расстояние последовательно идущих графов;
  3. аномальными принимаются те графы, для которых расстояние выше порога.

В качестве мер расстояния предлагаются:

  • maximum common subgraph (MCS) distance;
  • error correcting graph matching distance, то есть расстояние, измеряющее, сколько шагов нужно сделать, чтобы из одного графа сделать другой;
  • graph edit distance (GED), то же, что и предыдущее, но возможны лишь топологические изменения;
  • расстояния между матрицами смежности (например, Хэмминга);
  • различные расстояния на основе весов ребер;
  • расстояния между спектральным представлением графов (распределениями собственных векторов);
  • описывается также и более экзотическая мера: эвклидово расстояние между перроновскими собственными векторами графа.

В статье от Bunke et al. (2006) авторы предлагают считать расстояние не только между последовательно идущими графами, но вообще между всеми графами в последовательности, и потом применять многомерное шкалирование, переводя графы в двумерное пространство. Далее выбросы ищутся в этом двумерном пространстве.

Описан также следующий способ работы с динамическими графами (Box and Jenkins, 1990): графу ставится в соответствие некое число (расчетный показатель) и далее применяются стандартные методы поиска аномалий во временных рядах. Например, расхождения с моделью ARIMA.

В статье Akoglu and Faloutsos (2010) авторы осуществляют следующую последовательность операций:

  1. выделяют для каждого узла графа для каждого момента времени F-признаков;
  2. для каждого признака с временным окном W считают корреляционные матрицы между узлами;
  3. выделяют собственные векторы и далее рассматривают лишь первый собственный вектор;
  4. параллельно выделяют типичное поведение собственных векторов корреляционной матрицы (для этого делается еще одно SVD-разложение над матрицей изменения всех собственных векторов корреляционной матрицы во времени);
  5. сравнивают (через косинусное произведение) с реальным поведением этого вектора, получая таким образом показатель аномальности рассматриваемого временного окна.

Матричное разложение используется также и в статье Rossi (2013):

  1. аналогично предыдущему подходу выделяется по F-признаков на узел на каждый временной промежуток;
  2. для каждого временного промежутка производится NMF-разложение, при котором каждому узлу ставится в соответствие роль;
  3. далее мониторится изменение ролей каждого узла.

Матричное разложение для интерпретации результатов


Отдельно хочется отметить приведенные авторами методы аппроксимации матриц альтернативные по отношению к давно известным SVD, PCA, NMF: CUR (Drineas et al., 2006), CMD (Sun et al. 2007b) и Colibri (Tong et al. 2008). Основным преимуществом этих методов является интерпретируемость, поскольку в отличии от SVD, переводящего точки в другое пространство, эти методы оставляют пространство нетронутым, лишь сэмплируя точки из него. Наиболее простым из них является CUR, у которого авторы отмечают два недостатка: в нем точки выбираются из матрицы с повторением. В CMD удается убрать этот недостаток, однако как и в CUR, этому методу присуща линейная избыточность, которую удается избежать авторам алгоритма Colibri. Хотя методы были изобретены именно для решения задач поиска аномалий в графах методами матричной аппроксимации, их использование может быть перспективным и для других задач.

В задачах, обсуждаемых в этом обзоре, эти подходы применяются по следующему принципу: производится аппроксимация и оценивается, насколько различные столбцы/строки отличаются у аппроксимированной матрицы от изначальной. Также авторы отмечают метод NrMF (Tong and Lin 2011), модификация NMF, в котором ограничение на неотрицательность накладывается на матрицу остатков R, поскольку именно в ней сосредоточена основная информация по отличию апроксимации от изначальной матрицы, а отрицательные значения в таком случае было бы сложно интерпретировать. Тем не менее, до конца не ясно, почему нельзя аналогичным образом использовать SVD для декомпозиции, последующей реконструкции и последующим расчетом отличия от изначальной матрицы.


Определение узлов, связывающих аномальные


При анализе результатов может возникнуть задача определить узлы, связанные с аномальными. Так, например, как аномальный может быть определен узел, который подвергся DDoS-атаке, в то время как атакующие узлы не определены. Или как аномальные могут быть определены члены какой-то группировки, в то время как люди, руководящие ими, не определены как аномальные. Для решения этой задачи авторы предлагают несколько подходов, основной идеей которых является выделение подграфа из полного графа, который содержит аномальные узлы и узлы, лучше всего их связывающие.

  1. Определение связного подграфа (connection subgraph) (Faloutsos et al., 2004). Проблему предлагается решать в терминах электротехники, присваивая одному узлу положительный потенциал, а другим узлам нулевой, и смотреть, как будет течь ток между ними, если присвоить ребрам некое сопротивление.
  2. Center-Piece Subgraphs (CePS) (Tong and Faloutsos, 2006). В отличие от предыдущего метода предпринимается попытка выделить лишь k-узлов из всех аномальных, поскольку совершенно не обязательно все узлы заданы. При этом k необходимо задавать.
  3. Dot2Dot (Akoglu et al., 2013b; Chau et al., 2012). В этом подходе авторы решают задачу группировки выбранных узлов и уже далее выделяют узлы, их связывающие.

Примеры поиска аномалий в различных сферах


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

Телекоммуникации. Целью являются люди, пользующиеся услугами бесплатно. Cortes et al. (2002) искали подграфы, тесно связанные с ключевым узлом по параметрам числа и продолжительности звонков. Наблюдения, которые авторы обнаружили: фродовые аккаунты оказались связаны, то есть нарушители или сами звонили друг другу, или звонили на одни и те же телефоны. Второе наблюдение нарушителей можно обнаружить по схожести их подграфов, определенных предложенным образом.

Онлайн-аукцион. Нарушители создают себе фейковые аккаунты и накручивают им рейтинги. Их не получается отследить по обычным агрегатным показателям, но возможно увидеть по графу. Аккаунты нарушителей более связаны с фейковыми аккаунтами, чем с хорошими аккаунтами. Фейки связаны примерно в равной степени с аккаунтами нарушителей и с хорошими. Последние в основном связаны с подобными себе аккаунтами. Pandit et al. (2007) решают эту задачу через приведение к реляционным марковским сетям (relational markov networks) и далее классифицируют узлы через Loopy Belief Propagation (метки класса итеративно распространяются по графу).

Транзакции. McGlohon et al. (2009) решают эту задачу через реляционную (relational) классификацию в предположении, что нарушители будут близко расположены друг к другу. То есть аналогично подходу из предыдущего примера.

Брокеры, которые жульничают с ценными бумагами. Здесь Neville et al. (2005) анализируют мультимодальный граф, выделяя подграфы, включающие человека под подозрением, его коллег, фирмы, с которыми он связан и т. п. Они рассчитывают агрегированные атрибуты и приписывают их центральному узлу. Далее используют реляционные вероятностные деревья (relational probability trees (Neville et al. 2003)) для реляционной классификации.

Поиск фейковых постов на форумах, дающих заведомо ложную информацию. Авторы описывают несколько подходов, с использованием признакового описания, анализа текста и графовых методов. Графовые методы, использованные Wang et al. (2011a), применялись для ситуации, когда в задаче присутствуют обзоры какого-то товара. В предложенном ими алгоритме предлагалось присваивать рецензентам показатели степени доверия им, их обзорам достоверности и товарам показатели надежности. Все эти показатели взаимосвязаны. Так, насколько можно доверять рецензенту, зависит от того, насколько у него достоверные обзоры. Надежность товаров зависит от степени доверия рецензентам, которые его описывают, а достоверность обзоров зависит от надежности товара, по которым они пишутся, и от доверия их авторам. Предлагаемый алгоритм сначала их случайно инициализирует, а затем итеративно улучшает оценку.

Трейдинг. Мошенники сначала совершают большое число транзакций друг с другом по какому-то типу акций, увеличивая их привлекательность, а затем, когда акции повышаются в цене, распродают их другим трейдерам. Оба этих последовательных инцидента можно отследить по графовым данным. В первом случае будет выделяться подграф, где нет никаких внешних транзакций (именуется черная дыра), а через временной промежуток этот же подграф преобразуется к подграфу, в котором сильно преобладают транзакции из подграфа в другую часть графа (именуется вулкан). Авторы ссылаются на работу Li et al. (2010).

Веб-ресурсы. Одним из первых подходов для борьбы с плохими веб-сайтами предлагалось распространение показателей надежности и ненадежности ресурсов. Если есть ссылка с одной страницы на другую, то для последней это увеличивает ее статус надежной. Если страница указывает на другую страницу, для которой известно, что она спам, то это снижает надежность изначальной страницы. Упоминается алгоритм TrustRank (Gyngyi et al., 2004) модификация PageRank для борьбы с веб-спамом. Для него требуется, чтобы изначально эксперты разметили часть сайтов, как надежные. Эти показатели далее распространяются по графу, постепенно затухая. Anti-TrustRank (Krishnan and Raj, 2006) следует этому же принципу, но с распространением показателей ненадежности от размеченных заведомо ненадежных сайтов. У обоих методов есть недостаток, что надежность делится по числу дочерних узлов. Benczr et al. (2005) предлагают совершенно иной подход: анализировать PageRank узла и соседних с ним. Распределение PageRank таких подграфов должно подчиняться некому степенному закону. Для тех же узлов, для которых распределение PageRank их соседей выбивается из этого закона, присваивается штраф. В работе (Castillo et al., 2007) предлагается сначала обучать классификатор на известных надежных и ненадежных страницах, а затем размывать результат скоринга остальных веб-сайтов по графу.

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

Атаки в компьютерных сетях. Sun et al. (2008) успешно применяют для решения этой задачи матричное разложение (CMD). Ding et al. (2012) используют подход основанный на поиске сообществ, выделяя в качестве подозрительных узлы-мосты между сообществами.

Заключение


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

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

Если вас интересует тема, то, чтобы получить больше информации, обязательно нужно идти в слак ODS (OpenDataScience), в каналы #network_analysis и #class_cs224w, смотреть курс Стэнфорда cs224w.

Еще недавно был прочитан курс по Knowledge Graphs. Ну и, конечно, нужно прочитать саму статью Graph based anomaly detection and description: a survey от авторов Leman Akoglu, Hanghang Tong, Danai Koutra (Akoglu, 2015), о которой идет речь в этом посте. Я перевел ее не всю, а только те фрагменты, которые счел важными, и понял в какой-то степени. Большинство авторов ссылаются именно на эту статью, потому что больше обзоров такого уровня и широты по теме нет. По крайней мере, я не нашел таких.

Список литературы

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

Перевод Генеративная зоология с нейронными сетями

05.07.2020 14:08:58 | Автор: admin
image

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

image

Примеры изображений, созданных GAN

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

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

Your browser does not support HTML5 video.

Я адаптировал код из статьи о прогрессивных GAN и обучил модель с помощью 12000 итераций, используя мощности Google Cloud (8 графических процессоров NVIDA K80) и весь набор данных PhyloPic. Общее время обучения, включая некоторые ошибки и эксперименты, составило 4 дня. Я использовал окончательную обученную модель для создания 50-килобайтных отдельных изображений, а затем потратил часы на просмотр результатов, категоризацию, фильтрацию и сопоставление изображений. Я также немного редактировал некоторые изображения, повернув их, чтобы все существа были направлены в одну и ту же сторону (чтобы добиться визуального удовлетворения). Этот практический подход означает, что то, что вы видите ниже это своего рода коллаборация между мной и нейронной сетью это была творческая работа, и я вносил в нее свои правки.

image

Летающие насекомые

Первое, что меня удивило, так это то, насколько эстетически приятными были результаты. Многое из этого, безусловно, является отражением хорошего вкуса художников, которые создали оригинальные изображения. Однако, были и приятные неожиданности. Например, кажется, что всякий раз, когда нейронная сеть входит в область неопределенности будь то мелкие кусочки, которые она еще не освоила, или полеты размытой биологической фантазии в изображении появляются хроматические аберрации. Это любопытно, потому что входной набор полностью выполнен в черно-белом цвете, а значит, цвет не может быть решением какой-либо генеративной проблемы, принятым при обучении модели. Любой цвет является чистым артефактом разума машины. Удивительно, что одним из факторов, постоянно вызывающих хроматические аберрации, являются крылья летающих насекомых. Это приводит к тому, что модель порождает сотни вариаций ярко окрашенных бабочек, подобных представленным выше. Интересно, может ли это быть полезным наблюдением если обучать модель, используя только черно-белые изображения, и при этом требовать вывода полноцветных изображений, то цветные пятна могут быть полезным способом для отображения областей, в которых модель не в состоянии точно отобразить тренировочный набор.

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

image

Птицы

image

Четвероногие

image

Динозавры

image

Рыбы

image

Жуки

image

Гоминиды

Странные вещи



Как только известные нам твари заканчиваются, мы встречаемся с незнакомыми вещами. Один из появившихся у меня вопросов заключался в следующем: будут ли появляться правдоподобные планы тела животных, которых в природе не существует (возможно, гибриды существ, входящих в набор входных данных)? С помощью тщательного поиска и небольшой парейдолии, я обнаружил сотни четвероногих птиц, змееголовых оленей и других фантастических чудовищ.

image

Чудища

Уходя еще дальше в неизвестность, модель породила странные абстрактные шаблоны и неидентифицируемые сущности, создающие некое ощущение их живости.

image

Абстрактные существа

image

Неидентифицируемые

Случайный отбор


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

image

image

Узнайте подробности, как получить востребованную профессию с нуля или Level Up по навыкам и зарплате, пройдя платные онлайн-курсы SkillFactory:



Читать еще


Подробнее..

Перевод В сообществе машинного обучения есть проблема токсичности

06.07.2020 20:09:26 | Автор: admin
Токсичность везде.

Во-первых, нарушен процесс независимой экспертизы (peer review). Четверть работ с конференции NeurIPS выкладывается на arXiv. В DeepMind есть исследователи, которые публично преследуют рецензентов, критикующих их представление ICLR. Кроме того, статьи известных институтов с arXiv принимаются на ведущих конференциях, даже если рецензенты решают отклонить работу. И наоборот, некоторые статьи с большинством положительных отзывов отклоняются (не хочу называть никаких имён, просто взгляните на страницу openreview ICRL этого года).

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

В-третьих, существует проблема поклонения. Каждая статья, имеющая отношение к Стэнфорду или DeepMind, превозносится как прорыв. Например, у BERT цитирований в семь раз больше, чем у ULMfit. Принадлежность к Google придаёт статье очень много доверия и известности. На каждой конференции ICML перед каждым плакатом DeepMind стоит толпа людей, независимо от содержания работы. Та же история с Zoom-встречами на виртуальной конференции ICLR 2020. Более того, NeurIPS 2020 собрала в два раза больше заявок, чем ICML, хотя обе конференции высшего уровня. Почему? Почему слово нейронный так превозносится? Далее, Бенгио, Хинтон и ЛеКун [лауреаты премии Тьюринга 2018 года за исследования в области ИИ прим. пер] действительно являются пионерами глубокого обучения, но называть их крёстными отцами ИИ безумие. Это уже становится культом.

В-четвёртых, Ян ЛеКун довольно мягко высказался о темах предвзятости и справедливости. Однако в ответ получил совершенно неадекватную токсичность и отрицательную реакцию. Избавиться от ЛеКуна и заткнуть человеку рот это не решение.

В-пятых, у машинного обучения и информатики в целом огромная проблема неравенства (diversity). На нашем факультете CS только 30% студентов и 15% профессоров женщины. Уход в отпуск по уходу за ребёнком во время аспирантуры или докторантуры обычно означает конец академической карьеры. Однако этим неравенством часто злоупотребляют как предлогом, чтобы оградить некоторых людей от любой формы критики. Сведение каждого негативного комментария в научной дискуссии к расе и полу создаёт токсичную среду. Люди боятся участвовать в дискуссиях, чтобы их не назвали расистами или сексистами, что, в свою очередь, усиливает проблему неравенства.

В-шестых, мораль и этика устанавливаются произвольно. В любой дискуссии доминирует внутренняя политика США. В этот самый момент тысячи уйгуров попадают в концентрационные лагеря, основанные на алгоритмах компьютерного зрения, изобретённых этим сообществом, и никому, кажется, вообще нет дела до этого. Добавление раздела Более широкое воздействие в конце каждой работы не решит эту проблему. Поднимаются кучи дерьма, когда какой-то исследователь не упомянут в статье. Между тем африканский континент с населением в 1 миллиард человек практически исключён из любого значимого обсуждения ML (кроме нескольких семинаров Indaba).

В-седьмых, распространена ментальность типа публикуйся или умри. Если ты не публикуешь 5+ статей в год на конференциях NeurIPS/ICML, ты неудачник. Исследовательские группы стали настолько большими, что научный руководитель даже не помнит имён всех аспирантов. Некоторые подают на NeurIPS более 50 работ в год. Единственной целью написания статьи стало добавление ещё одной статьи NeurIPS в резюме. Качество вторично; основной целью стало прохождение стадии предварительного просмотра.

Наконец, дискуссии стали неуважительными. Лауреат приза Гельмгольца от Международного общества нейронных сетей Юрген Шмидхубер обзывает вором члена Лондонского королевского общества Джеффри Хинтона, Эфиопско-американский и содиректор группы Ethical Artificial Intelligence Team в Google Тимнит Гебру обзывает белым супрематистом крёстного отца ИИ Яна ЛеКуна, Профессор Калтеха и директор исследований ИИ в Nvidia Анима Анандкумар обзывает сексистом исполнительного директора Geometric Intelligence и автора книг Гари Маркуса. Все подвергаются нападкам, но ничего не улучшается.

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

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

Из песочницы 9 ключевых алгоритмов машинного обучения простым языком

03.07.2020 20:16:17 | Автор: admin
Привет, Хабр! Представляю вашему вниманию перевод статьи 9 Key Machine Learning Algorithms Explained in Plain English автора Nick McCullum.

Машинное обучение (МО) уже меняет мир. Google использует МО предлагая и показывая ответы на поисковые запросы пользователей. Netflix использует его, чтобы рекомендовать вам фильмы на вечер. А Facebook использует его, чтобы предложить вам новых друзей, которых вы можете знать.

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

Эта статья познакомит вас с фундаментальными концепциями в области машинного обучения. А конкретнее, мы обсудим основные концепции 9ти самых важных алгоритмов МО на сегодняшний день.

Система рекомендаций(Recommendation system)


Для построения полноценной системы рекомендаций с 0, требуются глубокие знания в линейной алгебре. Из-за чего, если вы никогда не изучали эту дисциплину, вам может быть сложно понять некоторые концепции этого раздела.

Но не беспокойтесь scikit-learn библиотека Python позволяет довольно просто построить СР. Так что вам не потребуется таких уж глубоких познаний в линейной алгебре, чтобы построить рабочую СР.

Как работает СР?


Существует 2 основных типа система рекомендаций:

  • Основанная на контенте(Content-based)
  • Коллаборативная фильтрация(Collaborative filtering)

Основанная на контенте система дает рекомендации, которые базируются на схожести элементов, уже использованных вами. Эти системы ведут себя абсолютно так, как вы ожидаете СР будет себя вести.

Коллаборативная фильтрация СР предоставляет рекоммендации, основанные на знаниях о том как пользователь взаимодействует с элементами(*примечание: за основу взяты взаимодействия с элементами других пользователей, схожих по поведению с данным пользователем). Другими словами, они используют мудрость толпы(отсюда и коллаборативный в названии метода).

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

Коллаборативная фильтрация СР также обладает уникальной особенностью, которой нет в основанной на контенте ситстеме. А именно, у них есть способность обучаться фичам самостоятельно.

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

Существует 2 подкатегории коллаборативной фильтрации:

  • Основанная на модели
  • Основанная на соседстве

Хорошая новость: вам не обязательно знать разницу в этих двух типах коллаборативной фильтрации СР, чтобы быть успешным в МО. Достаточно просто знать, что существует несколько типов.

Подведем итог


Вот краткое резюме того, что мы узнали о системе рекомендаций в данной статье:

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

Линейная регрессия (Linear Regression)


Линейная регрессия используется для предсказаний некоторого значения y основываясь на некотором множестве значений x.

История линейной регрессии


Линейная регрессия(ЛР) была изобретена в 1800 году Френсисом Гальтоном. Гальтон был ученым, изучающим связь между родителями и детьми. А конкретнее, Гальтон исследовал связь между ростом отцов и ростом их сыновей. Первым открытием Гальтона стал тот факт, что рост сыновей, как правило, был приблизительно таким же как рост их отцов. Что не удивительно.

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

Гальтон даль этому феномену название регрессия. В частности, он сказал: " Рост сына имеет тенденцию к регрессии(или к смещению в направлении) среднего роста".

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

Математика линейной регрессии


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

Типичный пример такого подхода метод наименьших квадратов линейной регрессии, с помощью которого рассчитывают близость линии в направлении верх-низ.

Пример для иллюстрации:



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

Логистическая регрессия (Logistic Regression)


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

Что такое логистическая регрессия?


Логистическая регрессия это модель машинного обучения, использующаяся для решения задач классификации.

Ниже представлено несколько примеров классификационных задач МО:

  • Спам электронной почты(спам или не спам?)
  • Претензия по страховке автомобиля (выплата компенсации или починка?)
  • Диагностика болезней

Каждая из этих задач имеет четко 2 категории, что делает их примерами задач двоичной классификации.

Логистическая регрессия хорошо подходит для решения задач двоичной классификации мы просто назначаем разным категориям значения 0 и 1 соответственно.

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

Это изображение может помочь понять почему линейная регрессия плохо подходит для двоичной классификации:



На этом изображении ось у представляет вероятность того, что опухоль является злокачественной. Значения 1-у представляет вероятность, что опухоль доброкачественная. Как вы можете видеть, модель линейной регрессии очень плохо срабатывает для предсказания вероятности для большинства наблюдений в наборе данных.

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

Вот пример, который иллюстрирует сравнение линейной и логистической регрессионых моделей на одних и техже данных:



Сигмоида (The Sigmoid Function)


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

Для вас не обязательно досконально запоминать сигмоиду, чтобы преуспеть в МО. Но все-таки иметь некоторое представление об этой функции будет полезно.

Формула сигмоиды:



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

Использование логистической регрессионной модели для предсказаний


Чтобы использовать логистическую регрессию для предсказаний, вам, как правило, нужно точно определить точку отсечения. Эта точка отсечения обычно 0.5.

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

Использование матрицы ошибок для измерения эффективности логистической регрессии


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

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



В этой таблице TN означает истинно отрицательно, FN ложно отрицательно, FP ложно положительно, TP истинно положительно.

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

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

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

Подведем итог


В этом разделе у вас было первое знакомство с моделью МО логистической регрессией.
Вот краткое содержание того, что вы узнали о логистической регрессии:

  • Типы задач классификации, которые подходят для решения с помощью логистической регрессии
  • Логистическая функция (сигмоида) всегда дает значение от 0 до 1
  • Как использовать точки отсечения для предсказания с помощью модели логистической регрессии
  • Почему матрица ошибок полезна для измерения эффективности модели логистической регрессии

Алгоритм k-ближайших соседей (K-Nearest Neighbors)


Алгоритм k-ближайших соседей может помочь решить задачу классификации, в случае, когда категорий больше, чем 2.

Что из себя представляет алгоритм k-ближайших соседей?


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

Представьте, что у вас есть данные по высоте и весу футболистов и баскетболистов. Алгоритм k-ближайших соседей может быть использован для предсказания является ли новый игрок футболистом или баскетболистом. Чтобы это сделать, алгоритм определяет К точек данных, ближайших к объекту исследования.

Данное изображение демонстрирует этот принцип с параметром К = 3:



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

Как построить алгоритм К-ближайших соседей


Основные шаги для построения данного алгоритма:

  1. Соберите все данные
  2. Вычислите Евклидово расстояние от новой точки данных х до всех остальных точек в множестве данных
  3. Отсортируйте точки из множества данных в порядке возрастания расстояния до х
  4. Спрогнозируйте ответ, используя ту же категорию, что и большинство К-ближайших к х данных

Важность переменной К в алгоритме К-ближайших соседей


Хотя это может быть не очевидно с самого начала, изменение значения К в данном алгоритме изменит категорию, в которую попадет новая точка данных.

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

Представленная ниже иллюстрация отлично показывает этот эффект:



Плюсы и минусы алгоритма К-ближайших соседей


Чтобы подвести итог знакомства с этим алгоритмом, давайте коротко обсудим достоинства и недостатки его использования.

Плюсы:

  • Алгоритм прост и его легко понять
  • Тривиальное обучение модели на новых тренировочных данных
  • Работает с любым количеством категорий в задаче классификации
  • Легко добавить больше данных в множество данных
  • Модель принимает только 2 параметра: К и метрика расстояния, которой вы хотели бы воспользоваться (обычно это Евклидово расстояние)

Минусы:

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

Подведем итог


Краткое содержание того, что вы только что узнали о алгоритме К-ближайших соседей:

  • Пример задачи на классификацию(футболисты или баскетболисты), которую может решить алгоритм
  • Как данный алгоритм использует Евклидово расстояние до соседних точек для прогнозирования к какой категории принадлежит новая точка данных
  • Почему значения параметра К важно для прогнозирования
  • Плюсы и минусы использования алгоритма К-ближайших соседей

Дерево решений и Случайный лес (Decision Trees and Random Forests)


Дерево решений и случайный лес это 2 примера древовидного метода. Точнее, деревья решений это модели МО, используемые для прогнозирования через циклический просмотр каждой функции в наборе данных один за одним. Случайный лес это ансамбль (комитет) деревьев решения, которые используют случайные порядки объектов в наборе данных.

Что такое древовидный метод?


Перед тем, как мы нырнем в теоретические основы древовидного метода в МО, будет нелишним начать с примера.

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

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



У каждого дерева решений есть 2 типа элементов:

  • Узлы (Nodes): места, где дерево разделяется в зависимости от значения определенного параметра
  • Грани (Edges): результат разделения, ведущий к следующему узлу

Вы можете видеть, что на схеме есть узлы для прогноза (outlook), влажности (humidity) и ветра
(windy). И также грани для каждого потенциального значения каждого из этих параметров.

Вот еще парочка определений, которые вы должны понимать перед тем, как мы начнем:

  • Корень (Root) узел, с которого начинается разделение дерева
  • Листья (Leaves) заключительные узлы, которые предсказывают финальный результат

Теперь у вас есть базовое понимание что такое дерево решений. Мы рассмотрим как построить такое дерево с нуля в следующем разделе.

Как построить дерево решений с нуля


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

Чтобы ее разрешить, специалисты МО обычно используют множество деревьев решения, применяя случайные наборы характеристик, выбранных для разделения дерева на них. Другими словами, новые случайные наборы характеристик выбираются для каждого отдельного дерева, на каждом отдельном разделении. Эта техника называется случайные леса.

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

Выгоды использования случайного леса


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

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

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

Подведем итог


Итак, краткое содержание того, что вы только что узнали о деревьях решений и случайных лесах:

  • Пример задачи, решение которой можно спрогнозировать с помощью дерева решений
  • Элементы дерева решений: узлы, грани, корни и листья
  • Как использование случайного набора характеристик позволяет нам построить случайный лес
  • Почему использование случайного леса для декорреляции переменных может быть полезным для уменьшения дисперсии полученной модели

Метод опорных векторов(Support Vector Machines)


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

Что такое метод опорных векторов?


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

Как МОВ работает?


Давайте капнем поглубже в то, как действительно работает МОВ.

Нам дан набор тренировочных примеров, какждый из которого промаркирован как принадлежащий к одной из 2х категорий, и с помощью этого набора МОВ строит модель. Эта модель распределяет новые примеры в одну из двух категорий. Это делает МОВ невероятностным двоичным линейным классификатором.

МОВ использует геометрию для составления прогнозов по категориям. Конкретнее модель метода опорных векторов сопоставляет точки данных как точки в пространстве и разделяет на отдельные категории так, что они разделяются настолько широким разрывом, насколько возможно. Прогноз принадлежности новых точек данных к определенной категории основывается на том, с какой стороны разрыва находится точка.

Вот пример визуализации, который поможет вам понять интуицию МОВ:



Как вы можете наблюдать, если новая точка данных падает на левую от зеленой линии сторону, то она будет отнесена к красным, а если на правую то к синим. Эта зеленая линия называется гиперплоскостью, и является важным термином для работы с МОВ.

Давайте посмотрим следующее визуальное представление МОВ:



На этой диаграмме гиперплоскость обозначена как оптимальная гиперплоскость (optimal hyperplane). Теория метода опорных векторов дает такое определение оптимальной гиперплоскости это гиперплоскость, которая максимизирует поле между двумя ближайшими точками данных из разных категорий.

Как вы видите, граница поля действительно затрагивает 3 точки данных 2 из красной категории и 1 из синей. Эти точки, которые соприкасаются с границей поля, и называются опорными векторами откуда и пошло название.

Подведем итог


Вот краткий очерк того, что вы только что узнали о методе опорных векторов:

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

Метод К-средних (K-Means Clustering)


Метод К-средних это алгоритм машинного обучения без учителя. Это значит, что он принимает непомеченные данные и пытается сгруппировать кластеры подобных наблюдений ваших данных. Метод К-средних крайне полезен для решения реальных прикладных задач. Вот примеры нескольких задач, подходящих для этой модели:

  • Сегментация клиентов для маркетинговых групп
  • Классификация документов
  • Оптимизация маршрутов доставки для таких компаний, как Amazon, UPS или FedEx
  • Выявление и реагирование на криминальные локации в городе
  • Профессиональная спортивная аналитика
  • Прогнозирование и предотвращение киберпреступлений

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

Вот визуальное представление того, как это выглядит на практике:



Мы изучим математическую составляющую метода К-средних вследующем разделе этой статьи.

Как работает метод К-средних?


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

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

  • Вычисление центроида (центр тяжести) каждого кластера взяв средний вектор точек в этом кластере
  • Переотнести каждую точку данных к кластеру, центроид которого ближе всего к точке

Выбор подходящего значения К в методе К-средних


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

Для использования этого метода, первое, что вам необходимо сделать, это вычислить сумму квадратов отклонений(sum of squared errors) СКО для вашего алгоритма для группы значений К. СКО в методе К-средних определена как сумма квадратов расстояний между каждой точкой данных в кластере и центром тяжести этого кластера.

В качестве примера этого шага, вы можете вычислить СКО для значений К 2, 4, 6, 8 и 10. Далее вы захотите сгенерировать график СКО и этих значений К. Вы увидите, что отклонение уменьшается с увеличением значения К.

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

Как пример, вот график СКО относительно К. В этом случае, метод локтя предложит использовать значение К примерно равное 6.



Важно, что К=6 просто оценка приемлемого значения К. Не существует лучшего значения К в методе К-средних. Как и многие вещи в области МО, это очень зависящее от ситуации решение.

Подведем итог


Вот краткий очерк того, что вы только что узнали в этом разделе:

  • Примеры задач МО без учителя, которые возможно решить методом К-средних
  • Базовые принципы метода К-средних
  • Как работает метод К-средних
  • Как использовать метод локтя для выбора подходящего значения параметра К в данном алгоритме

Метод главных компонент (Principal Component Analysis)


Метод главных компонент используется для преобразования набора данных c множеством параметров в новый набор данных с меньшим количеством параметров и каждый новый параметр этого набора данных это линейная комбинация раннее существующих параметров. Эти преобразованные данные стремятся обосновать большую часть дисперсии оригинального набора данных с гораздо большей простотой.

Что такое метод главных компонентов?


Метод главных компонент (МГК) это техника МО, которая используется для изучения взаимосвязей между наборами переменных. Другими словами, МГК изучает наборы переменных для того, чтобы определить базовую структуру этих переменных. МГК еще иногда называют факторным анализом.

На основании этого описания вы можете подумать, что МГК очень схож с линейной регрессией. Но это не так. На самом деле, эти 2 техники имеют несколько важных отличий.

Различия линейной регрессии и МГК


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

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

Взгляните на метки осей на этом изображении. Главный компонент оси х объясняет 73% дисперсии в этом наборе данных. Главный компонент оси у объясняет около 23% дисперсии набора данных.

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

Подведем итог


Краткое содержание того, что вы только что узнали о методе главных компонент:

  • МГК пытается найти ортогональные факторы, которые определяют изменчивость в наборе данных
  • Разницу между линейной регрессией и МГК
  • Как выглядит ортогональные главные компоненты, визуализированные в наборе данных
  • Что добавление дополнительных главных компонент может помочь объяснить дисперсию более точно в наборе данных
Подробнее..

7 июля международный форум btechday Биометрия против пандемии

30.06.2020 14:13:12 | Автор: admin
Привет!

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



И здесь есть где развернуться решениям, основанным на биометрии. Распознавание голоса, лица, сетчатки глаза, бесконтактный анализ отпечатков пальцев и рисунка вен, анализ особенностей походки всё это постепенно становится привычным настоящим, и в какой-то мере необходимой технологией. Сегмент бесконтактных биометрических технологий в 2019 уже оценен экспертами почти в 6,2 млрд долларов, а до 2027 прогнозируется рост на 20,3% ежегодно.

Наш форум #btechday соберет ведущих разработчиков биометрических технологий и мировых экспертов будут спикеры из ID R&D, VisionLabs, NtechLab, РТ Лабс, BIOSMART, BI Solutions, группы компаний ЦРТ, Русского биометрического общества и не только. Будет два блока пленарный, с обсуждениями актуальных вызовов рынка, и технологический, непосредственно про решения и их реализацию. Обсудим опыт разных стран и компаний, кейсы применения ML и компьютерного зрения.

Участие бесплатное, программа мероприятия под катом.

10:00-11:30 Вызовы рынка


Пленарный блок

  • Ускорение трендов бесконтактных биометрических технологий как ответ на вызовы рынка в период пандемии.
  • Единая биометрическая система: трансформация в новых условиях.
  • Биометрия в масштабе страны.


11:30-18:00 Бесконтактный мир


Технологический блок

  • Повышение точности ML-алгоритмов при минимальных входящих данных.
  • Термобиометрия в real-time.
  • Распознавание в масках.
  • Технологии 3D-распознавания для смарт-устройств.
  • Новинки технологий распознавания речи.
  • Технологии бесконтактных отпечатков пальцев.
  • Технологии аутентификации по сетчатке глаза.
  • Как сделать real-time биометрию cost-effective?
  • Уязвимости технологий и систем.
  • Риски и уязвимости биометрической идентификации.
  • Мультифакторная биометрия.


Участие бесплатное, зарегистрироваться можно вот на этой странице.

Если вам интересны биометрические технологии и вы хотите знать, как их в скором времени будут совершенствовать и применять присоединяйтесь к форуму. Зарегистрироваться можно до 6 июля, 18:00.
Подробнее..

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

30.06.2020 18:10:31 | Автор: admin

Привет, Хабр! Как известно, топливом для машинного обучения являются наборы данных. В качестве источников для получения датасетов, которыми люди обычно пользуются и которые у всех на слуху, являются такие сайты как Kaggle, ImageNet, Google Dataset Search и Visual Genom, но довольно редко встречаю людей, которые для поиска данных используют такие сайты как Bing Image Search и Instagram. Поэтому в этой статье я покажу как легко получить данные с этих источников, написав две небольшие программы на Python.


Bing Image Search


Первое, что нужно сделать это перейти по ссылке нажать кнопку Get API Key и зарегистрироваться с помощью любой из предложенных социальных сетей(Microsoft, Facebook, LinkedIn или GitHub). После того, как процесс регистрации завершится вас перенаправят на страницу Your APIs, которая должна выглядеть подобным образом( то, что замазано, это и есть ваши API ключи) :


1


Переходим к написанию кода. Импортируем необходимые библиотеки :


from requests import exceptionsimport requestsimport cv2import os

Дальше нужно указать некоторые параметры: API ключ( нужно выбрать из двух предложенных ключей один), указать условия поиска, максимальное количество изображений на запрос, а также установим конечный URL :


subscription_key = "YOUR_API_KEY"search_terms = ['girl', 'man']number_of_images_per_request = 100search_url = "https://api.cognitive.microsoft.com/bing/v7.0/images/search"

Теперь напишем три небольшие функции, которые:
1) Создают для каждого условия поиска отдельную папку :


def create_folder(name_folder):    path = os.path.join(name_folder)    if not os.path.exists(path):        os.makedirs(path)        print('------------------------------')        print("create folder with path {0}".format(path))        print('------------------------------')    else:        print('------------------------------')        print("folder exists {0}".format(path))        print('------------------------------')        return path

2) Возвращает содержимое ответа сервера в JSON :


def get_results():    search = requests.get(search_url, headers=headers,                           params=params)    search.raise_for_status()    return search.json()

3) Записывает изображения на диск :


def write_image(photo):    r = requests.get(v["contentUrl"], timeout=25)    f = open(photo, "wb")    f.write(r.content)    f.close()

Далее мы перебираем изображения и пытаемся загрузить каждое отдельное изображение в выходную папку :


for category in search_terms:    folder = create_folder(category)    headers = {"Ocp-Apim-Subscription-Key": subscription_key}    params = {"q": category, "offset": 0,              "count": number_of_images_per_request}    results = get_results()    total = 0    for offset in range(0, results["totalEstimatedMatches"],                        number_of_images_per_request):        params["offset"] = offset        results = get_results()        for v in results["value"]:            try:                ext = v["contentUrl"][v["contentUrl"].                                          rfind("."):]                photo = os.path.join(category, "{}{}".                                     format('{}'.format(category)                                     + str(total).zfill(6), ext))                write_image(photo)                print("saving: {}".format(photo))                image = cv2.imread(photo)                if image is None:                    print("deleting: {}".format(photo))                    os.remove(photo)                    continue                total += 1            except Exception as e:                if type(e) in EXCEPTIONS:                    continue

Instagram


Импортируем библиотеки:


from selenium import webdriverfrom time import sleepimport pyautoguifrom bs4 import BeautifulSoupimport requestsimport shutil

Как вы можете видеть, я использую библиотеку selenium, поэтому нужно скачать geckodriver. В инстаграме поиск изображений будем осуществлять по хэштегу, допустим, возьмём хэштег #bird. По данному хэштегу можно найти около 26млн публикаций. Копируем ссылку, которая сформировалась в результате запроса и путь к geckodriver, и вставляем это соответственно в две строчки, которые представлены ниже:


browser=webdriver.Firefox(executable_path='/path/to/geckodriver')browser.get('https://www.instagram.com/explore/tags/bird/')

Дальше напишем 6 функций, которые:
1) Входит в инстаграм аккаунт. В строчках login.send_keys(' ') и password.send_keys(' ') необходимо вставить свой логин и пароль соответственно:


def enter_in_account():    button_enter = browser.find_element_by_xpath("//*[@class='sqdOP  L3NKy   y3zKF     ']")    button_enter.click()    sleep(2)    login = browser.find_element_by_xpath("//*[@class='_2hvTZ pexuQ zyHYP']")    login.send_keys('')    sleep(1)    password = browser.find_element_by_xpath("//*[@class='_2hvTZ pexuQ zyHYP']")    password.send_keys('')    enter = browser.find_element_by_xpath(        "//*[@class='                    Igw0E     IwRSH      eGOV_         _4EzTm                                                                                                              ']")    enter.click()    sleep(4)    not_now_button = browser.find_element_by_xpath("//*[@class='sqdOP yWX7d    y3zKF     ']")    not_now_button.click()    sleep(2)

2) Находит первый пост и нажимаем на него:


def find_first_post():    sleep(3)    pyautogui.moveTo(450, 800, duration=0.5)    pyautogui.click()

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


3) Получаем ссылку на публикацию и нажимаем на кнопку далее:


def get_url():    sleep(0.5)    pyautogui.moveTo(1740, 640, duration=0.5)    pyautogui.click()    return browser.current_url

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


4)Получаем html-код исходной страницы:


def get_html(url):    r = requests.get(url)    return r.text

5) Получаем URL изображения:


def get_src(html):    soup = BeautifulSoup(html, 'lxml')    src = soup.find('meta', property="og:image")    return src['content']

6) Скачиваем и сохраняем текущее изображение. В переменной filename нужно указать по какому пути будет сохраняться ваше изображение:


def download_image(image_name, image_url):    filename = 'bird/bird{}.jpg'.format(image_name)    r = requests.get(image_url, stream=True)    if r.status_code == 200:        r.raw.decode_content = True        with open(filename, 'wb') as f:            shutil.copyfileobj(r.raw, f)        print('Image sucessfully Downloaded')    else:        print('Image Couldn\'t be retreived')

Заключение


В заключении хотелось бы сказать про недостаток источников и реализации. Что касается самих ресурсов, то изображений с них можно собрать большое количество, но эти данные придётся сортировать, так как изображения не всегда подходят под те критерии поиска, которые вы задали. Что касается реализации, то в получении данных с инстаграма была задействована библиотека pyautogui, которая эмулирует действия пользователя, в результате чего, при выполнении программы вы не сможете задействовать ваш компьютер для решения других задач. Если будут предложения, как написать код лучше, прошу писать в комментарии.
Что касается написания кода, то всё было сделано на Ubuntu 18.04. Исходный код выложил на GitHub .

Подробнее..

FAISS Быстрый поиск лиц и клонов на многомиллионных данных

02.07.2020 12:23:15 | Автор: admin


Однажды в преддверии клиентской конференции, которую ежегодно проводит группа DAN, мы размышляли над тем, что интересного можно придумать, чтобы у наших партнеров и клиентов остались приятные впечатления и воспоминания о мероприятии. Мы решили разобрать архив из тысяч фотографий с этой конференции и нескольких прошлых (а всего их к тому моменту было 18): человек отправляет нам свою фотографию, а мы ему через пару секунд отправляем подборку фотографий с ним за несколько лет из наших архивов.

Велосипед мы не придумывали, взяли всем известную библиотеку dlib и получили эмбеддинги (векторные представления) каждого лица.

Добавили Telegram-бота для удобства, и всё было отлично. С точки зрения алгоритмов распознавания лиц всё работало на ура, но конференция завершилась, а расставаться с опробованными технологиями не хотелось. От нескольких тысяч лиц хотелось перейти к сотням миллионов, но конкретной бизнес-задачи у нас не было. Через некоторое время у наших коллег появилась задача, которая требовала работы с такими большими объемами данных.

Вопрос был в том, чтобы написать умную систему мониторинга ботов внутри сети Instagram. Тут наша мысль породила простой и сложный подходы:

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

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

Что дальше?


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

  1. Скорость и точность поиска
  2. Размер занимаемого данными места на диске
  3. Размер используемой RAM памяти.

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

Существуют известные и зарекомендовавшие себя технологии, такие как Annoy, FAISS, HNSW. Быстрый алгоритм поиска соседей HNSW , доступный в библиотеках nmslib и hnswlib, показывает state-of-the-art результаты на CPU, что видно по тем же бенчмаркам. Но его мы отсекли сразу, так как нас не устраивает количество используемой памяти при работе с действительно большими объемами данных. Мы стали выбирать между Annoy и FAISS и в итоге выбрали FAISS из-за удобства, меньшего использования памяти, потенциальной возможности использования на GPU и бенчмарков по результативности (посмотреть можно, например, здесь). К слову, в FAISS алгоритм HNSW реализован как опция.

Что такое FAISS?


Facebook AI Research Similarity Search разработка команды Facebook AI Research для быстрого поиска ближайших соседей и кластеризации в векторном пространстве. Высокая скорость поиска позволяет работать с очень большими данными до нескольких миллиардов векторов.

Основное преимущество FAISS state-of-the-art результаты на GPU, при этом его реализация на CPU незначительно проигрывает hnsw (nmslib). Нам хотелось иметь возможность вести поиск как на CPU, так и на GPU. Кроме того, FAISS оптимизирован в части использования памяти и поиска на больших батчах.

Source

FAISS позволяет быстро осуществлять операцию поиска k ближайших векторов для данного вектора x. Но как же этот поиск устроен под капотом?

Индексы


Главное понятие в FAISS это index, и, по сути, это просто набор параметров и векторов. Наборы параметров бывают совершенно разные и зависят от нужд пользователя. Векторы могут оставаться неизменными, а могут перестраиваться. Некоторые индексы доступны для работы сразу после добавления в них векторов, а некоторые требуют предварительного обучения. Имена векторов хранятся в индексе: либо в нумерации от 0 до n, либо в виде числа, влезающего в тип Int64.

Первый индекс, и самый простой, который мы использовали ещё на конференции, это Flat. Он лишь хранит в себе все вектора, а поиск по заданному вектору осуществляется полным перебором, поэтому обучать его не нужно (но об обучении ниже). На маленьком объеме данных такой простой индекс может вполне покрыть нужды поиска.

Пример:

import numpy as npdim = 512  # рассмотрим произвольные векторы размерности 512nb = 10000  # количество векторов в индексеnq = 5 # количество векторов в выборке для поискаnp.random.seed(228)vectors = np.random.random((nb, dim)).astype('float32')query = np.random.random((nq, dim)).astype('float32')

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

import faissindex = faiss.IndexFlatL2(dim)print(index.ntotal)  # пока индекс пустойindex.add(vectors)print(index.ntotal)  # теперь в нем 10 000 векторов

Теперь найдем 7 ближайших соседей для первых пяти векторов из vectors:

topn = 7D, I = index.search(vectors[:5], topn)  # Возвращает результат: Distances, Indicesprint(I)print(D)

Output
[[0 5662 6778 7738 6931 7809 7184] [1 5831 8039 2150 5426 4569 6325] [2 7348 2476 2048 5091 6322 3617] [3  791 3173 6323 8374 7273 5842] [4 6236 7548  746 6144 3906 5455]][[ 0.  71.53578  72.18823  72.74326  73.2243   73.333244 73.73317 ] [ 0.  67.604805 68.494774 68.84221  71.839905 72.084335 72.10817 ] [ 0.  66.717865 67.72709  69.63666  70.35903  70.933304 71.03237 ] [ 0.  68.26415  68.320595 68.82381  68.86328  69.12087  69.55179 ] [ 0.  72.03398  72.32417  73.00308  73.13054  73.76181  73.81281 ]]


Видим, что самые близкие соседи с расстоянием 0 это сами векторы, остальные отранжированы по увеличению расстояния. Проведем поиск по нашим векторам из query:

D, I = index.search(query, topn) print(I)print(D)

Output
[[2467 2479 7260 6199 8640 2676 1767] [2623 8313 1500 7840 5031   52 6455] [1756 2405 1251 4136  812 6536  307] [3409 2930  539 8354 9573 6901 5692] [8032 4271 7761 6305 8929 4137 6480]][[73.14189  73.654526 73.89804  74.05615  74.11058  74.13567  74.443436] [71.830215 72.33813  72.973885 73.08897  73.27939  73.56996  73.72397 ] [67.49588  69.95635  70.88528  71.08078  71.715965 71.76285  72.1091  ] [69.11357  69.30089  70.83269  71.05977  71.3577   71.62457  71.72549 ] [69.46417  69.66577  70.47629  70.54611  70.57645  70.95326  71.032005]]


Теперь расстояния в первом столбце результатов не нулевые, так как векторов из query нет в индексе.

Индекс можно сохранить на диск и затем загрузить с диска:

faiss.write_index(index, "flat.index")index = faiss.read_index("flat.index")

Казалось бы, всё элементарно! Несколько строчек кода и мы уже получили структуру для поиска по векторам высокой размерности. Но такой индекс всего с десятком миллионов векторов размерности 512 будет весить около 20Гб и занимать при использовании столько же RAM.

В проекте для конференции мы использовали именно такой базовый подход с flat index, всё было замечательно благодаря относительно маленькому объему данных, однако сейчас речь идет о десятках и сотнях миллионов векторов высокой размерности!

Ускоряем поиск с помощью Inverted lists



Source

Основная и наикрутейшая особенность FAISS IVF index, или Inverted File index. Идея Inverted files лаконична, и красиво объясняется на пальцах:

Давайте представим себе гигантскую армию, состоящую из самых разношерстных воинов, численностью, скажем, в 1 000 000 человек. Командовать всей армией сразу будет невозможно. Как и принято в военном деле, нужно разделить нашу армию на подразделения. Давайте разделим на $\sqrt{1 000 000} = 1000$ примерно равных частей, выбрав на роли командиров по представителю из каждого подразделения. И постараемся отправить максимально похожих по характеру, происхождению, физическим данным и т.д. воинов в одно подразделение, а командира выберем таким, чтобы он максимально точно представлял свое подразделение был кем-то средним. В итоге наша задача свелась от командования миллионом воинов к командованию 1000-ю подразделениями через их командиров, и мы имеем отличное представление о составе нашей армии, так как знаем, что из себя представляют командиры.

В этом и состоит идея IVF индекса: сгруппируем большой набор векторов по частям с помощью алгоритма k-means, каждой части поставив в соответствие центроиду, вектор, являющийся выбранным центром для данного кластера. Поиск будем осуществлять через минимальное расстояние до центроид, и только потом искать минимальные расстояния среди векторов в том кластере, что соответствует данной центроиде. Взяв k равным $\sqrt{n}$, где $n$ количество векторов в индексе, мы получим оптимальный поиск на двух уровнях сначала среди $\sqrt{n}$ центроид, затем среди $\sqrt{n}$ векторов в каждом кластере. Поиск по сравнению с полным перебором ускоряется в разы, что решает одну из наших проблем при работе с множеством миллионов векторов.


Пространство векторов разбивается методом k-means на k кластеров. Каждому кластеру в соответствие ставится центроида

Пример кода:

dim = 512k = 1000  # количество командировquantiser = faiss.IndexFlatL2(dim) index = faiss.IndexIVFFlat(quantiser, dim, k)vectors = np.random.random((1000000, dim)).astype('float32')  # 1 000 000 воинов

А можно это записать куда более элегантно, воспользовавшись удобной штукой FAISS для построения индекса:

index = faiss.index_factory(dim, IVF1000,Flat)Запускаем обучение:print(index.is_trained)   # False.index.train(vectors)  # Train на нашем наборе векторов # Обучение завершено, но векторов в индексе пока нет, так что добавляем их в индекс:print(index.is_trained)  # Trueprint(index.ntotal)   # 0index.add(vectors)print(index.ntotal)   # 1000000

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

D, I = index.search(query, topn) print(I)print(D)

Output
[[19898 533106 641838 681301 602835 439794 331951] [654803 472683 538572 126357 288292 835974 308846] [588393 979151 708282 829598  50812 721369 944102] [796762 121483 432837 679921 691038 169755 701540] [980500 435793 906182 893115 439104 298988 676091]][[69.88127  71.64444  72.4655   72.54283  72.66737  72.71834  72.83057] [72.17552  72.28832  72.315926 72.43405  72.53974  72.664055 72.69495] [67.262115 69.46998  70.08826  70.41119  70.57278  70.62283  71.42067] [71.293045 71.6647   71.686615 71.915405 72.219505 72.28943  72.29849] [73.27072  73.96091  74.034706 74.062515 74.24464  74.51218  74.609695]]


Но есть одно но точность поиска, как и скорость, будет зависеть от количества посещаемых кластеров, которое можно задать с помощью параметра nprobe:

print(index.nprobe)  # 1  заходим только в один кластер и ведем поиск только в нёмindex.nprobe = 16  # Проходим по топ-16 центроид для поиска top-n ближайших соседейD, I = index.search(query, topn) print(I)print(D)

Output
[[ 28707 811973  12310 391153 574413  19898 552495] [540075 339549 884060 117178 878374 605968 201291] [588393 235712 123724 104489 277182 656948 662450] [983754 604268  54894 625338 199198  70698  73403] [862753 523459 766586 379550 324411 654206 871241]][[67.365585 67.38003  68.17187  68.4904   68.63618  69.88127  70.3822] [65.63759  67.67015  68.18429  68.45782  68.68973  68.82755  69.05] [67.262115 68.735535 68.83473  68.88733  68.95465  69.11365  69.33717] [67.32007  68.544685 68.60204  68.60275  68.68633  68.933334 69.17106] [70.573326 70.730286 70.78615  70.85502  71.467674 71.59512  71.909836]]


Как видно, после увеличения nprobe имеем совсем другие результаты, топ наименьших расстояний в D стал лучше.

Можно брать nprobe равным количеству центроид в индексе, тогда это будет эквивалентно поиску полным перебором, точность будет наибольшая, но скорость поиска заметно уменьшится.

Ведем поиск по диску On Disk Inverted Lists


Отлично, первую проблему мы решили, теперь на десятках миллионов векторов мы получаем приемлемую скорость поиска! Но всё это бесполезно до тех пор, пока наш огромный индекс не умещается в RAM.

Конкретно для нашей задачи основное преимущество FAISS в возможности хранить Inverted Lists IVF индекса на диске, загружая в RAM только метаданные.

Как мы создаем такой индекс: обучаем indexIVF с нужными параметрами на максимально возможном объеме данных, который влезает в память, затем в обученный индекс по частям добавляем векторы (побывавшие в обучении и не только) и записываем на диск индекс для каждой из частей.

index = faiss.index_factory(512, ,IVF65536, Flat, faiss.METRIC_L2)

Обучение индекса на GPU осуществляем таким образом:

res = faiss.StandardGpuResources()index_ivf = faiss.extract_index_ivf(index)index_flat = faiss.IndexFlatL2(512)clustering_index = faiss.index_cpu_to_gpu(res, 0, index_flat)  #  0  номер GPUindex_ivf.clustering_index = clustering_index

faiss.index_cpu_to_gpu(res, 0, index_flat) можно заменить на faiss.index_cpu_to_all_gpus(index_flat), чтобы использовать все GPU вместе.

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

train_vectors = ...  # предварительно сформированный датасет для обученияindex.train(train_vectors)# Сохраняем пустой обученный индекс, содержащий только параметры:faiss.write_index(index, "trained_block.index") # Поочередно создаем новые индексы на основе обученного# Блоками добавляем в них части датасета:for bno in range(first_block, last_block+ 1):    block_vectors = vectors_parts[bno]    block_vectors_ids = vectors_parts_ids[bno]  # id векторов, если необходимо    index = faiss.read_index("trained_block.index")    index.add_with_ids(block_vectors, block_vectors_ids)    faiss.write_index(index, "block_{}.index".format(bno))

После этого объединяем все Inverted Lists воедино. Это возможно, так как каждый из блоков, по сути, является одним и тем же обученным индексом, просто с разными векторами внутри.

ivfs = []for bno in range(first_block, last_block+ 1):    index = faiss.read_index("block_{}.index".format(bno), faiss.IO_FLAG_MMAP)    ivfs.append(index.invlists)    # считать index и его inv_lists независимыми    # чтобы не потерять данные во время следующей итерации:    index.own_invlists = False# создаем финальный индекс:index = faiss.read_index("trained_block.index")# готовим финальные invlists# все invlists из блоков будут объединены в файл merged_index.ivfdatainvlists = faiss.OnDiskInvertedLists(index.nlist, index.code_size, "merged_index.ivfdata")ivf_vector = faiss.InvertedListsPtrVector() for ivf in ivfs:     ivf_vector.push_back(ivf)ntotal = invlists.merge_from(ivf_vector.data(), ivf_vector.size())index.ntotal = ntotal  # заменяем листы индекса на объединенныеindex.replace_invlists(invlists)  faiss.write_index(index, data_path + "populated.index")  # сохраняем всё на диск

Итог: теперь наш индекс это файлы populated.index и merged_blocks.ivfdata.

В populated.index записан первоначальный полный путь к файлу с Inverted Lists, поэтому, если путь к файлу ivfdata по какой-то причине изменится, при чтении индекса потребуется использовать флаг faiss.IO_FLAG_ONDISK_SAME_DIR, который позволяет искать ivfdata файл в той же директории, что и populated.index:

index = faiss.read_index('populated.index', faiss.IO_FLAG_ONDISK_SAME_DIR)

За основу был взят demo пример из Github проекта FAISS.

Мини-гайд по выбору индекса можно посмотреть в FAISS Wiki. Например, мы смогли поместить в RAM тренировочный датасет из 12 миллионов векторов, поэтому выбрали IVFFlat индекс на 262144 центроидах, чтобы затем масштабироваться до сотен миллионов. Также в гайде предлагается использовать индекс IVF262144_HNSW32, в котором принадлежность вектора к кластеру определяется по алгоритму HNSW с 32 ближайшими соседями (иными словами, используется quantizer IndexHNSWFlat), но, как нам показалось при дальнейших тестах, поиск по такому индексу менее точен. Кроме того, следует учитывать, что такой quantizer исключает возможность использования на GPU.

Спойлер:
Даже при использовании on disk inverted lists FAISS по возможности загружает данные в оперативную память. Так как RAM памяти на этапах тестов нам хватало, пусть и с трудом, а для масштабных тестов было необходимо иметь значительно больший запас данных здесь и сейчас, тесты на объемах свыше объема RAM не проводились. Но FAISS wiki и обсуждения данного подхода на Github говорят, что всё должно работать корректно.


Значительно уменьшаем использование дискового пространства с Product Quantization


Благодаря методу поиска с диска удалось снять нагрузку с RAM, но индекс с миллионом векторов всё равно занимал около 2 ГБ дискового пространства, а мы рассуждаем о возможности работы с миллиардами векторов, что потребовало бы более двух ТБ! Безусловно, объем не такой большой, если задаться целью и выделить дополнительное дисковое пространство, но нас это немного напрягало.

И тут приходит на помощь кодирование векторов, а именно Scalar Quantization (SQ) и Product Quantization (PQ). SQ кодирование каждой компоненты вектора n битами (обычно 8, 6 или 4 бит). Мы рассмотрим вариант PQ, ведь идея кодирования одной компоненты типа float32 восемью битами выглядит уж слишком удручающе с точки зрения потерь в точности. Хотя в некоторых случаях сжатие SQfp16 до типа float16 будет почти без потерь в точности.

Суть Product Quantization состоит в следующем: векторы размерности 512 разбиваются на n частей, каждая из которых кластеризуется по 256 возможным кластерам (1 байт), т.е. мы представляем вектор с помощью n байт, где n обычно не превосходит 64 в реализации FAISS. Но применяется такая квантизация не к самим векторам из датасета, а к разностям этих векторов и соответствующих им центроид, полученным на этапе генерации Inverted Lists! Выходит, что Inverted Lists будут представлять из себя кодированные наборы расстояний между векторами и их центроидами.

index = faiss.index_factory(dim, "IVF262144,PQ64", faiss.METRIC_L2)

Выходит, что теперь нам не обязательно хранить все векторы достаточно выделять n байт на вектор и 2048 байт на каждый вектор центроиды. В нашем случаем мы взяли $n = 64$, то есть $\frac{512}{64} = 8$ длина одного субвектора, который определяется в один из 256 кластеров.



При поиске по вектору x сначала обычным Flat квантайзером будут определяться ближайшие центроиды, а затем x так же разделяется на суб-векторы, каждый из которых кодируется номером одной из 256 соответствующей центроиды. И расстояние до вектора определяется как сумма из 64 расстояний между суб-векторами.

Что в итоге?


Мы остановили свои эксперименты на индексе IVF262144, PQ64, так как он полностью удовлетворил все наши нужды по скорости и точности поиска, а также обеспечил разумное использование дискового пространства при дальнейшем масштабировании индекса. Если говорить конкретнее, на данный момент при 315 миллионах векторов индекс занимает 22 Гб дискового пространства и около 3 Гб RAM при использовании.

Еще одна интересная деталь, которую мы не упоминали ранее, метрика, используемая индексом. По умолчанию расстояния между любыми двумя векторами считаются в евклидовой метрике L2, или более понятным языком, расстояния считаются как квадратный корень из суммы квадратов покоординатных разностей. Но задать метрику можно и другую, в частности, мы тестировали метрику METRIC_INNER_PRODUCT, или метрику косинусных расстояний между векторами. Косинусная она потому, что косинус угла между двумя векторами в Евклидовой системе координат выражается как отношение скалярного (покоординатного) произведения векторов к произведению их длин, а если все векторы в нашем пространстве имеют длину 1, то косинус угла будет в точности равен покоординатному произведению. В таком случае чем ближе расположены векторы в пространстве, тем ближе к единице будет их скалярное произведение.

Метрика L2 имеет непосредственный математический переход к метрике скалярных произведений. Однако при экспериментальном сравнении двух метрик сложилось впечатление, что метрика скалярных произведений помогает нам анализировать коэффициенты похожести изображений более удачным образом. К тому же эмбеддинги наших фотографий были получены с помощью InsightFace, в котором реализована архитектура ArcFace, использующая косинусные расстояния. Также есть и другие метрики в индексах FAISS, о которых можно почитать здесь.

пару слов о GPU
Обучение и использование индексов FAISS на GPU весьма ограничено в выборе параметров индекса, а при работе с гигантскими объемами данных высокой размерности использование если и будет возможным, то вызовет трудности, несопоставимые с полученным результатом. К тому же на GPU реализована только метрика L2.

Однако, стоит заметить, что для использования индекса с PQ квантилизацией на GPU требуется ограничить размер кода 56-ю байтами, либо в случае большего размера сменить float32 на float16, связано это с ограничениями на используемую память.

В итоге о FAISS на GPU мы думать перестали, потому что CPU реализация нас полностью устроила по скорости, и хотелось сохранить работу с метрикой скалярных произведений, что на GPU недоступно. Чтобы регулировать нагрузку на процессоры при работе с индексами, можно задать максимальное число используемых процессоров:

faiss.omp_set_num_threads(N)


Заключение и любопытные примеры


Итак, вернемся же к тому, с чего всё начиналось. А начиналось, напомним, с мотивации решить задачу поиска ботов в сети Instagram, а конкретнее искать дубликаты постов с людьми или аватарок в определенных множествах юзеров. В процессе написания материала стало понятно, что подробное описание нашей методологии поиска ботов тянет на отдельную статью, о чем мы расскажем в следующих публикациях, а пока ограничимся примерами наших экспериментов с FAISS.

Векторизовать картинки или лица можно по-разному, мы выбрали технологию InsightFace (векторизация изображений и выделение n-мерных фичей из них это отдельная долгая история). В ходе экспериментов с полученной нами инфраструктурой были обнаружены довольно интересные и забавные свойства.

Например, заручившись разрешением коллег и знакомых, мы загрузили в поиск их лица и быстро нашли фотографии, на которых они присутствуют:


Наш коллега попал на фотографию посетительницы Comic-Con, оказавшись на заднем фоне в толпе. Источник


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


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


В этом случае и фотограф неизвестен, и сфотографировали тайно!
Сразу вспомнилась подозрительная девушка с зеркальным фотоаппаратом, сидевшая в тот момент напротив:) Источник


Таким образом, путём нехитрых действий FAISS позволяет собрать на коленке аналог всем известного FindFace.

Другая интересная особенность: в индексе FAISS чем больше лица похожи друг на друга, тем ближе друг к другу расположены соответствующие им векторы в пространстве. Я решил повнимательнее изучить чуть менее точные результаты поиска по своему лицу и обнаружил до ужаса похожих на себя клонов:)


Некоторые из клонов автора.
Источники фото: 1, 2,3


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


Source

Благодарим за внимание и надеемся что этот материал будет полезен читателям Хабра!

Статья написана при поддержке моих коллег Артёма Королёва (korolevart), Тимура Кадырова и Арины Решетниковой.

R&D Dentsu Aegis Network Russia.
Подробнее..

MLOps Cook book, chapter 1

03.07.2020 10:08:54 | Автор: admin


Всем привет! Я CV-разработчик в КРОК. Уже 3 года мы реализуем проекты в области CV. За это время чего мы только не делали, например: мониторили водителей, чтобы во время движения они не пили, не курили, по телефону не разговаривали, смотрели на дорогу, а не сны или в облака; фиксировали любителей ездить по выделенным полосам и занимать несколько мест на парковке; следили за тем, чтобы работники носили каски, перчатки и т.п.; идентифицировали сотрудника, который хочет пройти на объект; подсчитывали всё, что только можно.


Я все это к чему?


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


Моделируем ситуацию


Представим, что мы устроились в молодую компанию N, деятельность которой связана с ML. Работаем мы над ML (DL, CV) проектом, потом по каким-либо причинам переключаемся на другую работу, в общем делаем перерыв, и возвращаемся к своей или чужой нейроночке.


  1. Наступает момент истины, нужно как-то вспомнить на чем ты остановился, какие гиперпараметры пробовал и, самое главное, к каким результатам они привели. Может быть множество вариантов, кто как хранил информацию по всем запускам: в голове, конфигах, блокноте, в рабочей среде в облаке. Мне довелось видеть вариант, когда гиперпараметры хранились в виде закомментированных строк в коде, в общем полет фантазии. А теперь представьте, что вы вернулись не к своему проекту, а к проекту человека, который покинул компанию и в наследство вам достался код и модель под названием model_1.pb. Для полноты картины и передачи всей боли, представим, что вы еще и начинающий специалист.
  2. Идем дальше. Для запуска кода нам и всем кто будет с ним работать необходимо создать окружение. Часто бывает, что и его нам в наследство также по каким-то причинам не оставили. Это тоже может стать нетривиальной задачей. На этот шаг не хочется тратить время, не так ли?
  3. Тренируем модель (например, детектор автомобилей). Доходим до момента, когда она становится очень даже ничего самое время сохранить результат. Назовем ее car_detection_v1.pb. Потом тренируем еще одну car_detection_v2.pb. Некоторое время спустя наши коллеги или мы сами обучаем ещё и ещё, используя различные архитектуры. В итоге формируется куча артефактов, информацию о которых нужно кропотливо собирать (но, делать мы это будем позже, у нас ведь пока есть более приоритетные дела).
  4. Ну вот и всё! У нас есть модель! Мы можем приступать к обучению следующей модели, к разработке архитектуры для решения новой задачи или можем пойти попить чай? А деплоить кто будет?

Выявляем проблемы


Работа над проектом или продуктом это труд многих человек. А с течением времени люди уходят и приходят, проектов становится больше, сами проекты становятся сложнее. Так или иначе, ситуации из описанного выше цикла (и не только) в тех или иных комбинациях будут встречаться от итерации к итерации. Все это выливается в трату времени, путаницу, нервы, возможно в недовольство заказчика, и в конечном счете в упущенные деньги. Хоть все мы обычно ходим по старым граблям, но полагаю, что никто при этом не хочет раз за разом переживать эти моменты.



Итак, мы прошли по одному циклу разработки и видим, что есть проблемы, которые необходимо решить. Для этого нужно:


  • удобно хранить результаты работы;
  • сделать простым процесс вовлечения новых сотрудников;
  • упростить процесс развертывания среды разработки;
  • настроить процесс версионирования моделей;
  • иметь удобный способ валидации моделей;
  • найти инструмент управления состоянием моделей;
  • найти способ доставки моделей в production.

Видимо необходимо придумать workflow, который бы позволял легко и удобно управлять этим жизненным циклом? У такой практики есть название MLOps


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


Можете почитать, что обо всем этом думают ребята из Google. Из статьи понятно, что MLOps, довольно, объемная штука.



Далее в своей статье я опишу лишь часть процесса. Для реализации я воспользуюсь инструментом MLflow, т.к. это open-source проект, для подключения необходимо небольшое количество кода и есть интеграция с популярными ml-фреймворками. Вы можете поискать на просторах интернета другие инструменты, например Kubeflow, SageMaker, Trains и т.д., и возможно, подобрать тот, который лучше подходит под ваши нужды.


"Cтроим" MLOps на примере использования инструмента MLFlow


MLFlow это платформа с открытым исходным кодом для управления жизненным циклом ml моделей (https://mlflow.org/).


MLflow включает четыре компонента:


  • MLflow Tracking закрывает вопросы фиксации результатов и параметров, которые к этому результату привели;
  • MLflow Project позволяет упаковывать код и воспроизвести его на любой платформе;
  • MLflow Models отвечает за деплой моделей в прод;
  • MLflow Registry позволяет хранить модели и управлять их состоянием в централизованном хранилище.

MLflow оперирует двумя сущностями:


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

Все шаги примера реализованы на операционной системе Ubuntu 18.04.


1. Разворачиваем сервер


Для того, чтобы мы могли легко управлять нашим проектом и получать всю необходимую информацию, развернем сервер. MLflow tracking server имеет два основных компонента:


  • backend store отвечает за хранение информации о зарегистрированных моделях (поддерживает 4 СУБД: mysql, mssql, sqlite, and postgresql);
  • artifact store отвечает за хранение артефактов (поддерживает 7 вариантов хранения: Amazon S3, Azure Blob Storage, Google Cloud Storage, FTP server, SFTP Server, NFS, HDFS).

В качестве artifact store для простоты возьмем sftp сервер.


  • создаем группу
    $ sudo groupadd sftpg
    
  • добавляем пользователя и устанавливаем ему пароль
    $ sudo useradd -g sftpg mlflowsftp$ sudo passwd mlflowsftp 
    
  • корректируем пару настроек доступа
    $ sudo mkdir -p /data/mlflowsftp/upload$ sudo chown -R root.sftpg /data/mlflowsftp$ sudo chown -R mlflowsftp.sftpg /data/mlflowsftp/upload
    
  • добавляем несколько строк в /etc/ssh/sshd_config
    Match Group sftpg ChrootDirectory /data/%u ForceCommand internal-sftp
    
  • перезапускаем службу
    $ sudo systemctl restart sshd
    

В качестве backend store возьмем postgresql.


$ sudo apt update$ sudo apt-get install -y postgresql postgresql-contrib postgresql-server-dev-all$ sudo apt install gcc$ pip install psycopg2$ sudo -u postgres -i# Create new user: mlflow_user[postgres@user_name~]$ createuser --interactive -PEnter name of role to add: mlflow_userEnter password for new role: mlflowEnter it again: mlflowShall the new role be a superuser? (y/n) nShall the new role be allowed to create databases? (y/n) nShall the new role be allowed to create more new roles? (y/n) n# Create database mlflow_bd owned by mlflow_user$ createdb -O mlflow_user mlflow_db

Для запуска сервера необходимо установить следующие python пакеты (советую создать отдельное виртуальное окружение):


pip install mlflowpip install pysftp

Запускаем наш сервер


$ mlflow server  \                 --backend-store-uri postgresql://mlflow_user:mlflow@localhost/mlflow_db \                 --default-artifact-root sftp://mlflowsftp:mlflow@sftp_host/upload  \                --host server_host \                --port server_port

2. Добавляем трекинг


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


Для примера я создал небольшой проект на github на Keras по сегментации всего, что есть в COCO датасете. Для добавления трекинга я создал файл mlflow_training.py.


Вот строки, в которых происходит самое интересное:


def run(self, epochs, lr, experiment_name):        # getting the id of the experiment, creating an experiment in its absence        remote_experiment_id = self.remote_server.get_experiment_id(name=experiment_name)        # creating a "run" and getting its id        remote_run_id = self.remote_server.get_run_id(remote_experiment_id)        # indicate that we want to save the results on a remote server        mlflow.set_tracking_uri(self.tracking_uri)        mlflow.set_experiment(experiment_name)        with mlflow.start_run(run_id=remote_run_id, nested=False):            mlflow.keras.autolog()            self.train_pipeline.train(lr=lr, epochs=epochs)        try:            self.log_tags_and_params(remote_run_id)        except mlflow.exceptions.RestException as e:            print(e)

Здесь self.remote_server это небольшая обвязка над методами mlflow.tracking. MlflowClient (я сделал для удобства), с помощью которых я создаю эксперимент и запуск на сервере. Далее указываю куда должны сливаться результаты запуска (mlflow.set_tracking_uri(self.tracking_uri)). Подключаю автоматическое логирование mlflow.keras.autolog(). На данный момент MLflow Tracking поддерживает автоматическое логирование для TensorFlow, Keras, Gluon XGBoost, LightGBM, Spark. Если вы не нашли своего фреймворка или библиотеки, то вы всегда можете логировать в явном виде. Запускаем обучение. Регистрируем теги и входные параметры на удаленном сервере.


Пара строк и вы, как и все желающие, имеете доступ к информации о всех запусках. Круто?


3. Оформляем проект


Теперь сделаем так, чтобы запустить проект было проще простого. Для этого добавим в корень проекта файл MLproject и conda.yaml.
MLproject


name: flow_segmentationconda_env: conda.yamlentry_points:  main:    parameters:        categories: {help: 'list of categories from coco dataset'}        epochs: {type: int, help: 'number of epochs in training'}        lr: {type: float, default: 0.001, help: 'learning rate'}        batch_size: {type: int, default: 8}        model_name: {type: str, default: 'Unet', help: 'Unet, PSPNet, Linknet, FPN'}        backbone_name: {type: str, default: 'resnet18', help: 'exampe resnet18, resnet50, mobilenetv2 ...'}        tracking_uri: {type: str, help: 'the server address'}        experiment_name: {type: str, default: 'My_experiment', help: 'remote and local experiment name'}    command: "python mlflow_training.py \            --epochs={epochs}            --categories={categories}            --lr={lr}            --tracking_uri={tracking_uri}            --model_name={model_name}            --backbone_name={backbone_name}            --batch_size={batch_size}            --experiment_name={experiment_name}"

MLflow Project имеет несколько свойств:


  • Name имя вашего проекта;
  • Environment в моем случае conda_env указывает на то, что для запуска используется Anaconda и описание зависимостей находится в файле conda.yaml;
  • Entry Points указывает какие файлы и с какими параметрами мы можем запустить (все параметры при запуске обучения автоматически логируются)

conda.yaml


name: flow_segmentationchannels:  - defaults  - anacondadependencies:  - python==3.7  - pip:    - mlflow==1.8.0    - pysftp==0.2.9    - Cython==0.29.19    - numpy==1.18.4    - pycocotools==2.0.0    - requests==2.23.0    - matplotlib==3.2.1    - segmentation-models==1.0.1    - Keras==2.3.1    - imgaug==0.4.0    - tqdm==4.46.0    - tensorflow-gpu==1.14.0

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


4. Запускаем обучение


Клонируем проект и переходим в директорию проекта:


git clone https://github.com/simbakot/mlflow_example.gitcd mlflow_example/

Для запуска вам необходимо установить библиотеки


pip install mlflowpip install pysftp

Т.к. в примере я использую conda_env на вашем компьютере должна быть установлена Anaconda (но и это можно обойти установив все необходимые пакеты самостоятельно и поигравшись с параметрами запуска).


Все подготовительные шаги закончены и мы можем приступить к запуску обучения. Из корня проекта:


$ mlflow run -P epochs=10 -P categories=cat,dog -P tracking_uri=http://server_host:server_port .

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


5. Оцениваем результаты обучения


После окончания обучения мы можем перейти в браузере по адресу нашего сервера http://server_host:server_port



Здесь мы видим список всех экспериментов (слева вверху), а также информацию по запускам (посередине). Мы можем посмотреть более подробную информацию (параметры, метрики, артефакты и какую-то доп. информацию) по каждому запуску.



По каждой метрике мы можем наблюдать историю изменения



Т.е. на данный момент мы можем анализировать результаты в "ручном" режиме, также вы можете настроить и автоматическую валидацию при помощи MLflow API.


6. Регистрируем модель


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



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



Для каждой модели мы можем добавить описание и выбрать одно из трех состояний (Staging, Production, Archived), впоследствии мы при помощи api можем обращаться к этим состояниям, что на ряду с версионированием дает дополнительную гибкость.



У нас также имеется удобный доступ ко всем моделям



и их версиям



Как и в предыдущем пункте все операции можно сделать при помощи API.


7. Деплоим модель


На данном этапе у нас уже есть натренированная (keras) модель. Пример, как можно её использовать:


class SegmentationModel:    def __init__(self, tracking_uri, model_name):        self.registry = RemoteRegistry(tracking_uri=tracking_uri)        self.model_name = model_name        self.model = self.build_model(model_name)    def get_latest_model(self, model_name):        registered_models = self.registry.get_registered_model(model_name)        last_model = self.registry.get_last_model(registered_models)        local_path = self.registry.download_artifact(last_model.run_id, 'model', './')        return local_path    def build_model(self, model_name):        local_path = self.get_latest_model(model_name)        return mlflow.keras.load_model(local_path)    def predict(self, image):        image = self.preprocess(image)        result = self.model.predict(image)        return self.postprocess(result)    def preprocess(self, image):        image = cv2.resize(image, (256, 256))        image = image / 255.        image = np.expand_dims(image, 0)        return image    def postprocess(self, result):        return result

Здесь self.registry это опять небольшая обвязка над mlflow.tracking.MlflowClient, для удобства. Суть в том, что я обращаюсь к удаленному серверу и ищу там модель с указанным именем, причем, самую последнюю production версию. Далее скачиваю артефакт локально в папку ./model и собираю модель из этой директории mlflow.keras.load_model(local_path). Всё теперь мы можем использовать нашу модель. CV (ML) разработчики могут спокойно заниматься улучшением модели и публиковать новые версии.


В заключение


Я представил систему которая позволяет:


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

Данный пример является игрушечным и служит точкой старта для выстраивания вашей собственной системы, которая, возможно, будет включать в себя автоматизацию оценки результатов и регистрации моделей (п.5 и п.6 соответственно) или вы добавите версионирование датасетов, или может ещё что-то? Я пытался донести мысль, что вам нужен MLOps в целом, MLflow лишь средство достижения цели.


Напишите какие проблемы, с которыми вы сталкивались, я не отобразил?
Что бы вы добавили в систему, чтобы она закрывала ваши потребности?
Какие инструменты и подходы используете вы, чтобы закрыть все или часть проблем?


P.S. Оставлю пару ссылок:
github проект https://github.com/simbakot/mlflow_example
MLflow https://mlflow.org/
Моя рабочая почта, для вопросов ikryakin@croc.ru


У нас в компании периодически проводятся различные мероприятия для ИТ-специалистов, например: 8-го июля в 19:00 по МСК будет проходить митап по CV в онлайн-формате, если интересно, то можете принять участие, регистрация здесь .

Подробнее..

Подборка статей о машинном обучении кейсы, гайды и исследования за июнь 2020

06.07.2020 18:16:50 | Автор: admin


Здесь вас ждёт список вышедших за июнь материалов на английском языке. Все они написаны без лишнего академизма, содержат примеры кода и ссылки на непустые репозитории. Большинство упомянутых технологий находятся в открытом доступе и не требуют сверхмощного железа для тестирования.

Image GPT

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



Face depixelizer

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


DeepFaceDrawing

Если работы с пиксельными изображениями недостаточно, и нужно составить фотографию с портретом человека по примитивному наброску, то и для этого уже появился инструмент на основе DNN. По замыслу создателей нужны только общие начертания, а не профессиональные эскизы модель далее сама восстановит лицо человека, которое будет совпадать с наброском. Система создана с использованиям фремворка Jittor, как обещают создатели, исходный код на Pytorch скоро тоже будет добавлен в репозиторий проекта.



PIFuHD

С реконструкциями лиц разобрались, что насчет остального тела? Благодаря развитию DNN, стало возможным 3D-моделирование фигуры человека на основе двухмерного фото. Основное ограничение было связано с тем, что точные прогнозы требуют анализировать широкий контекст и исходные данные в высоком разрешении. Многоуровневая архитектура модели и способность к сквозному обучению помогут решить эту проблему. На первом уровне для экономии ресурсов изображение анализируется целиком в низком разрешении. После этого формируется контекст, и на более детальном уровне модель оценивает геометрию, анализируя изображение с высоким разрешением.



RepNet

Многие вещи, которые нас окружают, состоят из циклов разной периодичности. Часто для того, чтобы понять суть явления, нужно проанализировать информацию о его повторяющихся проявлениях. С учетом возможностей видеосъемки зафиксировать повторения уже давно не сложно, проблема заключалась в их подсчете. Способ покадрового сравнения плотности пикселей в кадре часто не подходил из-за тряски камеры, или загораживания объектами, а также резкой разницей в масштабе и форме при приближении и отдалении. Теперь эту проблему решает модель, разработанная Google. Она определяет повторяющиеся действия на видео, в том числе и те, которые не использовались при обучении. В результате модель возвращает данные о периодичности повторяющихся действий, распознанных на видео. Колаб уже доступен.



SPICE model

Раньше чтобы определить высоту тона, приходилось полагаться на созданные вручную сложные алгоритмы обработки сигналов. Самая большая сложность заключалось в том, чтобы отделить изучаемый звук от фонового шума или звука аккомпонимирующих инструментов. Теперь для этой задачи доступна предобученная модель, которая определяет высокие и низкие частоты. Модель доступна для использования в вебе и на мобильных устройствах.

Детектор социального дистанцирования

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



Распознавание типовых документов

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

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

Израильский стартап Trigo делится опытом применения машинного обучения и компьютерного зрения для take-and-go ритейла. Компания является поставщиком системы, которая позволяет магазинам работать без кассы. Авторы рассказывают какие задачи перед ними стояли и объясняют, почему выбрали PyTorch в качестве фреймворка для машинного обучения, а Allegro AI Trains для инфраструктуры и как им удалось наладили процесс разработки.

На этом все, спасибо за внимание!
Подробнее..

Перевод Алгоритм MADDPG OpenAI

29.06.2020 14:12:48 | Автор: admin
Начинаем неделю с продолжения серии статей, подготовленных специально для базового и продвинутого курсов Математика для Data Science.

В конце статьи, поделимся с вами списком самых интересных материалов по этой теме.




Новый подход


Мультиагентное обучение с подкреплением это развивающаяся и богатая область исследований. Тем не менее постоянное применение одноагентных алгоритмов в мультиагентных контекстах ставит нас в затруднительное положение. Обучение усложняется по многим причинам, в особенности из-за:

  • Нестационарности между независимыми агентами;
  • Экспоненциального роста пространств действий и состояний.


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

Централизованное планирование


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

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

Децентрализованное выполнение


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

OpenAI


Исследователи из OpenAI, Калифорнийского университета в Беркли и Университета Макгилла, представили новый подход к мультиагентным настройкам с помощью Multi-Agent Deep Deterministic Policy Gradient. Такой подход, вдохновленный своим одноагентным аналогом DDPG, использует обучение вида актер-критик и показывает очень многообещающие результаты.

Архитектура


Данная статья предполагает, что вы знакомы с одноагентной версией MADDPG: Deep Deterministic Policy Gradients или DDPG. Чтобы освежить память, вы можете прочитать замечательную статью Криса Юна.

У каждого агента есть пространство наблюдений и непрерывное пространство действий. Также у каждого агента есть три компонента:

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


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

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


Архитектура MADDPG (Lowe, 2018)

Обучение


Во-первых, MADDPG использует воспроизведение опыта (experience replay) для эффективного off-policy обучения. На каждом промежутке времени агент хранит следующий переход:



Где мы храним совместное состояние, следующее совместное состояние, совместное действие и каждое из вознаграждений, полученных агентом. Затем мы берем набор таких переходов из experience replay для обучения нашего агента.

Обновления критика


Для обновления центрального критика агента мы используем lookahead TD-ошибку:



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

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

Обновления актеров


Подобно одноагентной DDPG мы используем deterministic policy gradient для обновления каждого параметра актера агента.



Где это актер агента.

Давайте немного углубимся в это выражение обновления. Мы берем градиент относительно параметров актера с помощью центрального критика. Самое важное, на что нужно обратить внимание, это то, что даже если у актера есть только локальные наблюдения и действия, во время обучения мы используем центрального критика, чтобы получать информацию об оптимальности его действий в рамках системы целиком. Так уменьшается эффект нестационарности, а политика обучения остается на более низком пространстве состояний!

Выводы из политик и ансамбли политик


Мы можем сделать еще один шаг в вопросе децентрализации. В предыдущих обновлениях мы предполагали, что каждый агент автоматически узнает действия других агентов. Однако, MADDPG предлагает делать выводы из политики других агентов, чтобы сделать обучение еще более независимым. Фактически каждый агент будет добавлять N-1 сетей для оценки истинности политики всех других агентов. Мы используем вероятностную сеть, чтобы максимизировать логарифмическую вероятность вывода наблюдаемого действия другого агента.



Где мы видим функцию потерь для i-ого агента, оценивающего политику j-ого агента с помощью регуляризатора энтропии. В результате, наше целевое Q-значение становится немного другим, когда мы заменяем действия агента своими прогнозируемыми действиями!



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

Ансамбли политик


В вышеописанном подходе есть одна большая проблема. Во многих мультиагентных настройках, особенно в конкурентных, агенты могут создавать политики, которые могут переобучиться на поведении других агентов. Это сделает политику хрупкой, нестабильной и, как правило, неоптимальной. Чтобы компенсировать этот недостаток, MADDPG обучает коллекцию из K подполитик для каждого агента. На каждом временном шаге агент случайным образом выбирает одну из подполитик для выбора действия. А затем выполняет его.

Градиент политики немного изменяется. Мы берем среднее значение по K подполитикам, используем линейность ожидания и распространяем обновления с помощью функции Q-значения.



Вернемся на шаг назад


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

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


Каждый компонент алгоритма служит определенной отдельной цели. Мощным алгоритм MADDPG делает следующее: его компоненты разработаны специально для преодоления серьезных препятствий, которые обычно встают перед мультиагентными системами. Дальше мы поговорим о производительности алгоритма.

Результаты


MADDPG был апробирован во многих средах. Полный обзор его работы можно найти в статье [1]. Здесь мы поговорим только о задаче кооперативной коммуникации.

Обзор среды


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

Сравнение


Для решения этой задачи в статье противопоставляются MADDPG и современные одноагентные методы. С использованием MADDPG видны значительные улучшения.

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

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

Заключение


Вот и все. Здесь мы рассмотрели новый подход к мультиагентному обучению с подкреплением. Конечно, существует бесконечное количество методов, относящихся к MARL, однако MADDPG обеспечивает прочный фундамент для методов, которые решают самые глобальные проблемы мультиагентных систем.

Источники


[1] R. Lowe, Y. Wu, A. Tamar, J. Harb, P. Abbeel, I. Mordatch, Multi-Agent Actor-Critic for Mixed Cooperative-Competitive Environments (2018).



Список полезных статей






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


Подробнее..

Материалы с митапа для аналитиков модель роста, AB-тесты, управление стоком и доставкой товаров

03.07.2020 12:17:33 | Автор: admin

Хабр, привет! Впоследний день июня прошёл наш митап дляаналитиков. Нанём выступали спикеры изЛеруа Мерлен, Ostrovok.ru и, конечно же, Авито. Обсуждали региональные A/B-тесты, управление выдачей товаров вбольшом интернет-магазине, предсказание профита отновых фичей и data science вдоставке.


Под катом видеозаписи выступлений стаймкодами и ссылки напрезентации.



Региональные A/B-тесты. Зачем нужны и как устроены Игорь Красовский, Авито


На примере задач изАвито Игорь рассказал, что такое региональные А/В-тесты, когда они нужны аналитику, какие алгоритмы и математика лежат вих основе и как измерить точность этих алгоритмов.



00:00 Представление спикера и темы
00:44 Длякаких задач можно применять региональные A/B-тесты
04:21 Омодели региональных А/B-тестов: этапы проведения теста, метрика близости контрольной и тестовой групп
09:51 Алгоритм подбора тестовой группы и оценка его точности
18:03 Что можно улучшить впредложенном процессе: точки роста


Посмотреть презентацию Игоря

Модель роста предсказываем профит отфич дляприоритизации Павел Михайлов, Ostrovok.ru


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


Скачать эксельку спримером модели роста.



00:00 Представление спикера и темы
01:10 Фреймворк ICE (impact, confidence, ease)
02:26 Что такое модель роста и как с её помощью измерить влияние фичи
05:55 Как построить простую модель роста снуля
18:55 Примеры гипотез, которые можно оценить спомощью модели роста
25:22 Как можно улучшать базовую модель и зачем вообще этим заниматься


Посмотреть презентацию Павла

Лучшие data-продукты рождаются вполях Марина Калабина, Леруа Мерлен


Большая часть интернет-заказов вЛеруа Мерлен собираются вторговых залах магазинов. Из-завысокой скорости оборота товаров это нередко приводило ктому, что заказ не получалось собрать. Тогда команда Data Accelerator придумала инструмент, который позволил автоматически находить проблемные артикулы и корректировать их количество передпубликацией насайте.



00:00 Представление спикера и темы
01:37 Леруаизмы термины длялучшего погружения вконтекст доклада
02:40 Как собирают заказы изинтернет-магазина, и какие проблемы могут возникнуть усборщика
04:07 Запуск подразделения Data Accelerator, чтобы принимать data-driven решения
04:46 Продукт гарантированный сток: его цели и процесс реализации
13:34 Итоги внедрения гарантированного стока


Посмотреть презентацию Марины

Как data science Авито Доставке помогал Дима Сергеев, Авито


Ежедневно наАвито продаётся несколько миллионов самых разных товаров. Не длякаждого изних можно слёгкостью определить, сможет ли продавец положить его вкоробку размером 1208050 и отправить покупателю. Временами мы такие ошибки допускаем и предлагаем доставку там, где её быть заведомо не должно и наоборот. Дима рассказал отом, как мы сэтой проблемой справляемся и каких результатов получилось достичь.



00:00 Представление спикера и темы
01:11 История появления доставки вАвито и первые проблемы
06:32 Оценка масштабов неправильного определения возможности доставить товар
11:29 Классификация товаров как способ решить проблему: data science SWAT спешит напомощь
17:44 Первые успехи и побочные эффекты
25:47 Ближайшие планы


Посмотреть презентацию Димы

До встречи на новых митапах!

Подробнее..

Книга Глубокое обучение в картинках. Визуальный гид по искусственному интеллекту

30.06.2020 16:15:52 | Автор: admin
imageПривет, Хаброжители! Глубокое обучение стало мощным двигателем для работы с искусственным интеллектом. Яркие иллюстрации и простые примеры кода избавят вас от необходимости вникать в сложные аспекты конструирования моделей глубокого обучения, делая сложные задачи доступными и увлекательными.

Джон Крон, Грант Бейлевельд и замечательный иллюстратор Аглаэ Бассенс используют яркие примеры и аналогии, которые позволяют объяснить, что такое глубокое обучение, почему оно пользуется такой популярностью и как эта концепция связана с другими подходами к машинному обучению. Книга идеально подойдет разработчикам, специалистам по обработке данных, исследователям, аналитикам и начинающим программистам, которые хотят применять глубокое обучение в своей работе. Теоретические выкладки прекрасно дополняются прикладным кодом на Python в блокнотах Jupyter. Вы узнаете приемы создания эффективных моделей в TensorFlow и Keras, а также познакомитесь с PyTorch.

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


СЕТЬ ПРОМЕЖУТОЧНОЙ ГЛУБИН НА ОСНОВЕ KERAS


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

Первые несколько этапов создания сети промежуточной глубины в блокноте Jupyter intermediate_net_in_keras.ipynb идентичны этапам создания ее предшественницы неглубокой сети. Сначала загружаются те же самые зависимости Keras, точно так же вносится и обрабатывается набор данных MNIST. Как можно увидеть в листинге 8.1, самое интересное начинается там, где определяется архитектура нейронной сети.

Листинг 8.1. Код, определяющий архитектуру нейронной сети с промежуточной глубиной

model = Sequential()model.add(Dense(64, activation='relu', input_shape=(784,)))model.add(Dense(64, activation='relu'))model.add(Dense(10, activation='softmax'))

Первая строка в этом фрагменте кода, model = Sequential(), та же, что и в предыдущей сети (листинг 5.6); это экземпляр объекта модели нейронной сети. В следующей строке начинаются расхождения. В ней мы заменили функцию активации sigmoid в первом скрытом слое функцией relu, как было рекомендовано в главе 6. Все остальные параметры первого слоя, кроме функции активации, остались прежними: он все так же состоит из 64 нейронов, и прежней осталась размерность входного слоя 784 нейрона.

Другое существенное изменение в листинге 8.1 по сравнению с неглубокой архитектурой в листинге 5.6 заключается в наличии второго скрытого слоя искусственных нейронов. Вызовом метода model.add() мы без всяких усилий добавляем второй слой Dense с 64 нейронами relu, оправдывая слово intermediate (промежуточная) в имени блокнота. Вызвав model.summary(), можно увидеть, как показано на рис. 8.9, что этот дополнительный слой добавляет 4160 дополнительных обучаемых параметров, по сравнению с неглубокой архитектурой (см. рис. 7.5). Параметры можно разбить на:

  • 4096 весов, соответствующих связям каждого из 64 нейронов во втором скрытом слое с каждым из 64 нейронов в первом скрытом слое (64 64 = 4096);
  • плюс 64 смещения, по одному для каждого нейрона во втором скрытом слое;
  • в результате получается 4160 параметров: nпараметров = nw + nb = 4096 + 64 =
    = 4160.

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

Листинг 8.2. Код компиляции нейронной сети с промежуточной глубиной

model.compile(loss='categorical_crossentropy',                      optimizer=SGD(lr=0.1),                      metrics=['accuracy'])

image

Эти строки из листинга 8.2:

  • задают функцию стоимости на основе перекрестной энтропии: loss='categorical_crossentropy' (в неглубокой сети использовалась квадратичная стоимость loss='mean_squared_error');
  • задают метод стохастического градиентного спуска для минимизации стоимости: optimizer=SGD;
  • определяют гиперпараметр скорости обучения: lr=0.1(1);
  • указывают, что в дополнение к обратной связи о потерях, которая предлагается библиотекой Keras по умолчанию, мы также хотим получить обратную связь о точности модели: metrics=['accuracy'](2).

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

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

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

model.fit(X_train, y_train,              batch_size=128, epochs=20,              verbose=1,              validation_data=(X_valid, y_valid))

Единственное, что изменилось в обучении промежуточной сети по сравнению с неглубокой сетью (см. листинг 5.7), это уменьшение на порядок гиперпараметра epochs с 200 до 20. Как вы увидите далее, более эффективная промежуточная архитектура требует намного меньше эпох для обучения.

image

На рис. 8.10 представлены результаты первых четырех эпох обучения сети. Как вы наверняка помните, наша неглубокая архитектура достигла плато на уровне 86%-й точности на проверочных данных после 200 эпох. Сеть промежуточной глубины значительно превзошла ее: как показывает поле val_acc, сеть достигла 92.34%-й точности уже после первой эпохи обучения. После третьей эпохи точность превысила 95%, а к 20-й эпохе, похоже, достигла плато на уровне около 97.6%. Мы серьезно продвинулись вперед!

Разберем подробнее вывод model.fit(), показанный на рис. 8.10:

  • Индикатор процесса, показанный ниже, заполняется в течение 469 циклов обучения (см. рис. 8.5):
    60000/60000 [==============================]
  • 1s 15us/step означает, что на все 469 циклов обучения в первую эпоху потребовалась 1 секунда, в среднем по 15 микросекунд на цикл.
  • loss показывает среднюю стоимость на обучающих данных для эпохи. Для первой эпохи она равна 0.4744 и от эпохи к эпохе уверенно уменьшается методами стохастического градиентного спуска (SGD) и обратного распространения, а в конечном итоге уменьшается до 0.0332 к двадцатой эпохе.
  • acc точность классификации на обучающих данных в данную эпоху. Модель правильно классифицировала 86.37% после первой эпохи и достигла уровня выше 99% к двадцатой. Поскольку модель может переобучиться, не следует особо удивляться высокой точности в этом параметре.
  • К счастью, стоимость на проверочном наборе данных (val_loss), как правило, тоже уменьшается и в конечном итоге достигает плато на уровне 0.08 в ходе последних пяти эпох обучения.
  • Одновременно с уменьшением стоимости на проверочных данных растет точность (val_acc). Как уже упоминалось, точность на проверочных данных составила 97.6%, что значительно выше 86% у нашей неглубокой сети.

ИТОГИ


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

Более подробно с книгой можно ознакомиться на сайте издательства
Оглавление
Отрывок

Для Хаброжителей скидка 25% по купону Глубокое обучение

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Подробнее..

Из песочницы На пороге квантового сознания

07.07.2020 14:13:48 | Автор: admin
Предпосылки появления ИИ, превосходящего мозг человека:

  • закон Мура для квантовых компьютеров;
  • появление языков программирования для квантовых компьютеров;
  • квантовый компьютер похож на работу интуиции, воли и сознания человека почти мгновенный перебор всех возможных вариантов решения задачи и выбор оптимального ответа;
  • запрет клонирования квантовых состояний аналогичен невозможности клонировать наше сознание;
  • квантовый ИИ должен дополнять классический ИИ, также как в мозге человека различные его структуры работают как единый механизм;
  • любой классический ИИ обучается решению только одной задачи и работает эффективнее человека только в узком сегменте деятельности. Так например, обученная модель ИИ лучше играет в шахматы, но при этом не способна делать что-либо другое. Квантовый ИИ должен тиражировать подходы к решению различных типов задач, ускоряя процесс обучения новой задачи.

Предположим...


Постоянного Я человека не существует. Я индивида возникает в ответ на взаимодействие человека с миром и необходимо ему для более эффективной работы с окружающим миром. В различных состояниях возникает разное Я: во сне одно Я, наяву другое Я.

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

image

Перенос человеческого сознания на машинный носитель


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

Стремительное развитие ИИ и появление квантового компьютера, технология которого уже развивается по закону Мура, ставит вопрос о появлении сознания у компьютера. Долгое время считалось, что самосознание компьютера (в смысле осознания собственных действий и способности самостоятельно принимать решения) может возникнуть после достаточного развития и усложнения ИИ. Однако не все функции мозга могут быть транслированы на классический ИИ. Нейронная сеть может обучиться одному навыку и похоже не способна транслировать свой опыт на другие сферы деятельности. Кроме того в задачах связанным с большим количеством вариантов решений (с перебором) время нахождения оптимального решения крайне велико, что по эффективности не сопоставимо с нашим мозгом. Т.о. классический компьютер возможно является только частью комплексного устройства, обязательно включающего в себя часть, работающей на квантовых принципах. По мере развития человеческого мозга качественный скачек в его эволюции, выделивший человека от других животных, вероятно связан с появлением той части коры головного мозга, работа которой основана на квантовых принципах.

Современные технологии ИИ шли примерно тем же путем что и эволюция живого на Земле: сначала появились сначала химические сети, а затем более быстрые нейронные сети, но по прежнему выполняющие одну единственную функцию. Жизненно важная часть информации записывались в генетическую последовательность, чтобы не повторять обучение в процессе жизни одного организма каждый раз, а передавать лучшие практики из поколения в поколение. В какой то момент эволюции произошел квантовый скачек, когда появился квантовый параллелизм в мозге человека, который позволил не обучаться последовательно каждому навыку, а анализировать, обобщать и находить лучшее решение с точки зрения эволюции практически мгновенно.

Мы называем сознанием некую высшую функцию мозга, которая делает выбор, принимает решение. Сознание непосредственно связано с мыслительной деятельностью, прогнозированием и моделированием, оценкой и анализом ситуации, воображением и выбором, т.е. это комплексная многомерная работа мозга и она связанна с перебором и анализом всех возможных вариантов. Рассмотрим простой пример человеку захотелось съесть кусочек торта В некий момент времени в организме человеке стало не хватать сахара и он посылает сигнал поступает в мозг возникает мысль: Я хочу торт. На самом деле сознание интерпретировало первоначальную потребность: Нужен сахар. Почему этот процесс проходит через этап осознавания этой потребности? Можно было бы, минуя сознательную часть мозга, отправить человека к холодильнику и достать оттуда торт. Человеку как бы дается право принять окончательное решение: есть или не есть торт. При этом появляется возможность смоделировать ситуацию, спрогнозировать возможные последствия, определить его важности, отранжировать потребности, определить насколько оно сейчас своевременно и пр. т.е. подумать над этим и принять решение.

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

В нашем мозге можно выделить две составные части аналогичные двум типам существующих компьютеров: классическую и квантовую.

Для того чтобы понять какие участки человеческого мозга основаны на квантовых явлениях, сначала обозначим классические. Очевидно, первые в этом списке будут части мозга, ответственные за обработку сигналов идущих от органов восприятия: аналог ИИ по распознаванию образов. На вход подаются сигналы из внешнего мира, на выходе картинка образ объекта, с которым работают другие участки мозга. Часть сигналов обрабатывается бессознательным автоматическими элементами нашего компьютера. Вся древняя часть мозга области связанные с процессами обеспечения жизнедеятельности организм это классический компьютер, область бессознательного, наработанная тысячелетней эволюцией.

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

(Про возникновение сознания в процессе обучения в своих работах писал еще Э.Шредингер)

Классическая нейронная сеть нашего мозга (а их у нас миллиарды) обучается только одному навыку и никак не влияет на работу других нейронных сетей.

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

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

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

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

см. Нейроны сознания Е.Н. СОКОЛОВ
Подробнее..

Перевод Тренды в Data Scienсe 2020

26.06.2020 18:17:05 | Автор: admin
image

Google Trends по запросу data science

Краткое изложение


  • По нашим оценкам, вакансии в advanced analytics насчитывают почти 1 миллион человек во всем мире, 291 тысяча из них в США.
  • За последние два года дефицит работ в области data science значительно сократился были наняты около 800 тысяч специалистов, однако на данный момент десятки вакансий так и остаются нетронутыми, причем подавляющее большинство из них в США.
  • Самый большой спрос на рабочих в области advanced analytics в области залива Сан- Франциско с самыми высокими зарплатами и самым большим количеством вакансий, за ней следуют крупные городские центры вроде Нью-Йорка, Бостона, Вашингтона и Сиэтла.
  • Средняя заработная плата по стране у data scientists остается выше $100,000 эта тенденция просматривается почти во всех штатах, удовлетворенность работой и престиж также остаются на высоком уровне.
  • Для подготовки специалистов в advanced analytics было создано больше ста образовательных программ.

image

Узнайте подробности, как получить востребованную профессию с нуля или Level Up по навыкам и зарплате, пройдя платные онлайн-курсы SkillFactory:




Вступление


Вот уже последние несколько лет data science является одним из самых ярких трендов в бизнесе. В 2012 году Harvard Business Review назвали работу data scientists самой сексуальной работой 21-го века. Многочисленные отчеты (1, 2, 3, 4) писали, что мир сталкивается с огромным дефицитом data scientists. Создавались буткемпы и университетские программы, чтобы решить вопросы, связанные с огромным спросом на навыки в этой области.

К advanced analytics мы относим всех, кто сам относит себя к data scientist, специалистам по машинному обучению или ИИ-исследователю.

Спрос и предложение data scientists май 2020


Общее число рабочих в области advanced analytics



На сегодняшний день в мире насчитывается чуть менее одного миллиона рабочих в области advanced analytics (см. раздел методологии ниже), из которых 290 тысяч или же примерно 30% приходится на Соединенные Штаты Америки. На данный момент численность data scientists значительно превосходит численность инженеров по машинному обучению и исследователей ИИ как в США, так и во всем мире, однако и инженеры, и исследователи являются новыми на рынке труда и в будущем могут значительно вырасти.

image

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

Открытые и дефицитные вакансии


На сегодняшний день на LinkedIn открыты около 86 тысяч вакансий в сфере advanced analytics, большая часть (53.4 тысячи) приходится на США. Интересно отметить, что США представляет собой непропорционально большое число открытых вакансий (62%) по сравнению с долей рабочих в advanced analytics во всем мире (30%), хоть это и можно списать на ложную методологию сбора данных (см. раздел методологии ниже).

image

Количество открытых ролей advanced analytics по сравнению с общим числом профессиональных сотрудников advanced analytics

Мы можем использовать число открытых вакансий (по сравнению с количеством имеющихся сотрудников) в качестве приблизительного показателя, чтобы понять сколько всего работников недостает. Из приведенного ниже графика видно, что открытых вакансий по всему миру на 9% больше, чем непосредственно сотрудников, в то время как в США это число достигает примерно 18.7%.


Сокращение дефицита


Сегодня в США насчитывают примерно 53 тысячи свободных рабочих мест в области advanced analytics. Однако, в августе 2018 года LinkedIn опубликовал отчет на тот момент дефицит составлял около 151 тысячи рабочих мест. За последние два года дефицит значительно сократился по всему миру была нанята примерно 831 тысяча профессионалов в области advanced analytics (см. ниже).

image

Apteo оценивает общее количество продвинутых аналитиков с течением времени

image

Дефицит продвинутых аналитиков в 2018 году по сравнению с 2020 годом

Распределение открытых вакансий и недостаток рабочих по городам США


Общее число специалистов и вакансий


Никого не удивит, что наибольшая часть работников в advanced analytics находятся в районе залива Сан-Франциско примерно 45.7 тысяч человек, как и наибольшее количество открытых вакансий около 8 тысяч. На втором месте идет Нью-Йоркская агломерация около 38.8 тысяч сотрудников и 5.9 тысяч вакансий. На третьем месте район Большого Бостона 15.9 тысяч сотрудников и 3.3 тысячи вакансий.

Самая высокая доля на душу населения


На первом месте район залива Сан-Франциско 5.9 тысячи человек на миллион. На втором месте идет Сиэтл 4.3 тысячи на миллион, завершает Бостон 3.2 тысячи на миллион.

Наибольшая нехватка рабочей силы


Наибольший процент (39.2%) открытых вакансий в городе Вашингтон.

image

Расширенная аналитика сотрудников и вакансий по городам

image

Заработная плата и удовлетворенность работой в США



Заработная плата в этой сфере варьируется по всей Америке. Основываясь на данных из различных источников, мы подсчитали, что средняя зарплата специалистов достигает примерно $114,000 в год, что соответствует примерно $14,000 в районе залива Сан-Франциско.

В 2020 году работа в data science заняла третье место по Америке по версии Glassdoor (сразу после Front End Engineer и Java Developer). С 2016 по 2019 года data scientists занимали первое место.

image

Образовательные программы и требуемые навыки


Для удовлетворения потребностей в бизнесе появилось множество новых образовательных программ. На данный момент существует как минимум 79 буткемпов, 62 программы бакалавриата и 111 магистерских программ, ориентированных на data science. Ниже мы перечислим наиболее упоминаемые программные средства и навыки для специалистов в области advanced analytics

Top Tools


  • Python
  • SQL
  • R
  • Spark
  • Cloud
  • AWS
  • Java
  • Tensorflow


Top Skills


  • Machine Learning / Regression
  • Statistics
  • Research
  • Prediction
  • Visualization
  • Recommendation
  • Optimization
  • Deep Learning
  • Natural Language Processing


image

Образовательные программы

Вывод


Очевидно, что data science продолжает быть крайне востребованной и на сегодняшний день. В то время как мир, судя по всему, быстро удовлетворяет этот спрос, по-прежнему существует острая нехватка рабочих в области advanced analytics. Интересно то, что возникают и новые должности типа инженера по машинному обучению (machine learning engineer) или ИИ-исследователя (A.I. researcher), и вполне вероятно, что для них потребуются дополнительные сотрудники, поскольку все больше компаний работают над внутренним продвижением data science.

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

Методология


Расчет занятости и дефицита


Для идентификации data scientists и открытых вакансий в data science, мы провели поиск по ключевым словам на LinkedIn по трем наиболее распространенным названиям вакансий, которые мы ассоциируем с математической, инженерной и аналитической работой, в которой, по нашему мнению, и заключается работа data scientist при помощи премиум аккаунта генерального директора и соучредителя Apteo Шанифа Дханани. Названия вакансий следующие data scientist, инженер по машинному обучению и исследователь искусственного интеллекта.

Data scientist и инженер по машинному обучению также могут быть связаны с такими ключевыми словами как data science и инженер МО, поэтому для предотвращения двойного подсчета мы использовали бинарный поиск искали ровно один термин за раз, исключая все остальные термины. Например, мы соединили результаты из следующих двух запросов для поиска data scientists:

data science -data scientist -machine learning engineer -ml engineer -ai researcher and data scientist -data science -machine learning engineer -ml engineer -ai researcher

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

Источники информации:

  • Данные поиска работ на LinkedIn, полученные 1-го мая 2020 года.
  • Google (численность населения)



Расчет заработной платы


Единого правдивого источника для расчета заработной платы просто не существует. Правительство США, рекрутинговые компании и независимые отчеты публикуют разные значения о заработной плате advanced analytics. Для наших отчетов мы собрали как можно больше независимых значений как на государственном, так и на национальном уровне и использовали среднее значение.

Источники информации:




Рост занятости


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

Источники информации:




Образовательные программы и требуемые навыки



Следует снова проговорить, что было сложно оценить образовательные программы. В каждом университете свое название для программы по data science, поэтому нам приходилось субъективно определять, какие программы включать в список, а какие исключать из него. Мы попытались отобрать те программы, основанные на математической строгости, вычислительной работе и аналитике. Мы исследовали различные отчеты и агрегаторы для сбора данных по университетским программам, а также различные буткемпы для определения суммарных показателей для 2020-го года.

Источники информации:


Читать еще


Подробнее..

Нейронные сети на страже правил дорожного движения

06.07.2020 10:05:56 | Автор: admin


Нарушения правил дорожного движения (ПДД) водителями несут для организаций операционные, репутационные и правовые риски.
Ранее для выявления нарушений анализировали видеозаписи из служебных автомобилей. Это рутинный и трудоёмкий процесс, так как очень большие объёмы видео обрабатывались вручную. Было принято решение автоматизировать данный процесс и создать модель выявления нарушений ПДД для формирования риск-ориентированной подборки видео.
В первую очередь, было решено искать такие грубые нарушения ПДД как пересечение двойной сплошной линии и проезд на красный сигнал светофора.
Для сегментации изображения и обнаружения дорожной разметки была использована свёрточная нейронная сеть архитектуры U-Net. Данная архитектура представляет собой последовательность слоёв свёртки и пулинга, которые сперва уменьшают пространственное разрешение картинки, а затем увеличивают его, предварительно объединив с данными картинки и пропустив через другие слои свёртки.
Для обучения модели был нужен обучающий датасет. К сожалению, все найденные датасеты из открытого доступа состояли из фотографий дорог не из России. Результаты обучения модели на зарубежных дорогах были неутешительными: модель зачастую просто отказывалась воспринимать нашу отечественную дорожную разметку как разметку. Поэтому было принято решение заняться созданием обучающей выборки самостоятельно. Из видео с регистраторов было нарезано около 1500 скриншотов и с помощью сервиса Supervise.ly на них разметили дорожное полотно (рис.1).



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



На рисунке 2 показано как работает U-Net: сверху оригинальная запись с лобового стекла, снизу пример работы нейронной сети, где зеленые области это маска дорожной разметки, а тонкие красные линии аппроксимация разметки в прямую.
Модель очень хорошо себя показала при обработке большинства видео с регистраторов, однако нельзя не отметить, что возникли сложности при анализе заснеженной дороги или видео снятого в темное время суток в некоторых случаях разметку просто не видно.
Для определения наличия светофоров и автомобилей использовали предобученную нейросеть Darknet + Yolo v3. Эта нейронная сеть является улучшенной версией архитектуры YOLO, что расшифровывается как You Only Look Once. Главная особенность YOLO v3 заключается в том, что у нее на выходе присутствует три слоя, каждый из которых рассчитан на детектирование объектов различного размера.
Основная особенность данной архитектуры по сравнению с другими заключается в том, что большая часть систем применяют нейронную сеть несколько раз к разным частям изображения, а в YOLO нейронная сеть применяется ко всему изображению сразу и один раз. Сеть делит изображение на своеобразную сетку и предсказывает bounding boxes (параллелепипеды, ограничивающие найденные объекты) и вероятности того, что там есть эти искомые объекты для каждого участка.
Достоинства данного подхода состоят в том, что просматривая изображение целиком, YOLO при детектировании и распознавании объекта учитывает контекст изображения. Также YOLO обладает явными преимуществами в быстродействии: она в тысячу раз быстрее чем R-CNN и в несколько сотен раз быстрее чем Fast R-CNN.



Пример работы YOLO представлен на рисунке 3. Анализ изображения происходит покадрово, все найденные красные светофоры корректно детектируются нейронной сетью.
Обучение целых двух нейросетей требует наличия достаточно мощного компьютера, особенно в части видеокарты, т.к. используются вычисления именно на GPU. Мы использовали процессор Core i7 восьмого поколения, видеокарту nvidia gtx1080 и 32 ГБ оперативной памяти. Таких системных характеристик было вполне достаточно для реализации проекта.
По результатам использования моделей выявления нарушений ПДД, можно сказать, что это был успешный проект. На вход скрипту было подано видео с авторегистратора за один месяц общей длительностью 7 часов 11 минут, время инференса модели (обработки входящих видео) составило 25 минут. По окончанию обработки всех видеофайлов было нарезано 112 фрагментов по 8 секунд (15 минут суммарно), из которых сэкономили почти 7 часов, без труда определили нарушения.
Свои вопросы можете направить на электронный адрес: newtechaudit123@yandex.ru
Подробнее..
Категории: Машинное обучение

Категории

Последние комментарии

© 2006-2020, personeltest.ru