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

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

Мозг, смысл и конец света

09.04.2021 16:11:40 | Автор: admin

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

Есть два интересных и важных термина искусственный интеллект (ИИ) и сильный искусственный интеллект (СИИ). В английской традиции Artificial intelligence (AI) и Artificial general intelligence (AGI). Первый подразумевает любую деятельность компьютера, имитирующую человеческий интеллект, второй только такую, которая претендует на что-то универсально общее, похожее на то, как мыслит человек.

Точного определения СИИ нет. Лучшее, что есть это знаменитый Тест Тьюринга.

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

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

Отметим очень тонкий и при этом очень важный момент. Простой ИИ может во много раз превзойти человека в какой-то области. Например, сильнее играть в шахматы, обыгрывать в Го или Starcraft. Но от этого он не становится сильным.

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

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

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

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

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

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

Поясню на примере. Прочитав шутку, вы смеетесь. Объявление: меняю бензопилу на протез. Но если вас спросить, что в шутке смешного, вы озадачитесь и скорее всего дадите объяснение, которое будет неверным. Если бы ваше объяснение было верным, то вы, зная секрет юмора, могли бы легко придумывать смешные шутки и стать знаменитым юмористом. Ваш мозг всегда знает, смешно или не смешно, но вы практически никогда не можете объяснить, почему. Более того, ваш мозг тонко чувствует разницу между просто смешным и юмором, а вы?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

В популярном буддистском коане говорится: Рыжая корова проходит мимо окна. Голова, рога и четыре ноги прошли. Почему не может пройти хвост?. В математике беда почти всегда приходит с одной и той же стороны. И имя этой стороны комбинаторный взрыв. Имея дело с тепличными примерами, не нарадуешься красоте определений. Но стоит только выйти в поле, и все идет прахом. Любое реальное явление начинает давать такое разнообразие проявлений, что никакие вычислительные мощности и датасеты не могут за этим разнообразием угнаться. Все время кажется, что осталось еще совсем немного дообучить модель и все будет хорошо. Мы слышим: автопилот для автомобилей уже почти готов, осталось пару месяцев. На моей памяти эти пару месяцев слышатся последние года три. Правда, сейчас говорят: три месяца и точно. Проклятие размерности оно такое. К сожалению, корову не определяет ни ее цвет, ни ее рога и ни ее копыта, и хвосту всех признаков никогда не пройти мимо.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • имя понятия. Слово языка или внутреннее кодирование имени понятия.

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

  • память. Накопленный ранее опыт, один и тот же для всех контекстов.

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

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

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

Шифровальная машина Энигма

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

В 1938 году немцы усложнили конструкцию Энигмы, в результате чего расшифровка ее сообщений стала в десять раз сложнее. За пять недель до вторжения Германии в Польшу в 1939 году Реевский и его коллеги передали свои результаты французской и британской разведке. Это позволило англичанам построить в Блетчли-парк батарею из бомб, которая успешно взламывала немецкие коды на протяжении всей войны.

Определенную роль в этом сыграл тот самый Алан Тьюринг, что придумал приведенный в начале тест.

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

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

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

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

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

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

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

Все, что было сказано, было странно, но не безумно. А где же обещанное безумие? Начнем.

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

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

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

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

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

Алексей Редозубов

Подробнее..

Edge платы для домашнего Computer Vision

13.04.2021 06:09:41 | Автор: admin

Я люблю делать всякие странные штуки с Computer Vision. Из того, что я выкладывал на Хабре - умная кормушку для птиц и камера для слежения за ребенком. По работе примерно тем же занимаюсь. Так что слежу за актуальным рынком embedded устройств для ComputerVision. Прошлый обзор я делал полтора года назад. Для Embedded это долго. В этом я сосредоточусь на устройствах которые вышли недавно + некоторый анализ что из этих устройств можно использовать дома/для хобби.

Рассказ будет построен следующим образом:

  • Продуктовые железки которые стали классикой продакшна / железки которые почти доросли до таких.Их можно взять и запустить из коробки. Большие OpenSource комьюнити/персональные фреймворки. Время развертывания обученной сети на такой железке в 1-2 дня.

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

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

  • Железка есть информации почти нет/нельзя получить без запросов. На рынке нет истории использования/успеха.

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

  • Далеко не все из перечисленного я лично использовал/тестировал

  • Далеко не все перечислено. Я уверен что забыл/не знаю многое. И очень надеюсь что в комментарии накидаете чего-нибудь интересного

  • Я фокусируюсь на устройствах где есть GPU/NPU или прочие ускорители инференса. Безусловно, есть всякие FPGA, и прочее, но я не считаю их применимыми для хоббийных проектов. (что такое NPU GPU TPU и другие аббревиатуры - можно прочитать в этой замечательной статье)

Часть 1. Ближе всего к продукту

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

  • Jetson

  • Intel

  • Coral

  • Android телефоны

  • Прочие Embedded, устройства с хорошим процессором, без NPU/GPU

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

В мире Jetsonов новинок нет. Сейчас в продаже:

  • jetson nano

  • jetson xavier nx

  • jetson agx

  • jetson tx2

12ого началась конференция GTC от NVIDIA, но ничего нового на ней не объявили, так что, скорее всего, на следующий год ничего нового не будет.

Встречаются имплементации Jetson'а, под другие экосистемы. Самое известное - AWS Panorama. Jetson находящийся внутри экосистемы Амазона.

PanoramaPanorama

Jetson, безусловно, одна из самых удобных плат для хобби. Есть разводка GPIO, много кода который работает из коробки. Нейронные сети можно никуда не конвертировать, используя в оригинальном фреймворке.
Cтоит понимать, что из всех четырех Jetson'ов для хобби лучше всего подходит Nano. Он стоит лишь 100$, что значительно меньше следующего в серии NX, стоящего 400$. В теории, TX2в середине, но его почти нет в продаже + менее удобная плата. Проектов на Jetson очень много. Например из того что было в медийном пространстве - 1, 2. Вот тут есть неплохая подборка.
Лично я участвовал где-то в 5-7 проектах где Jetson был основной платформой. 2-3 из них переросли в полноценные продукты. Но, вынужден сказать, что для хобби его не использовал ни разу. Почему? Какая-то совокупность факторов всегда. Nano у меня был первой серии, там были баги по питанию. Иногда была не нужна производительность дополнительная. Иногда хотелось опробовать чего-то нового.

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

Удобны ли ли они для каких-нибудь прототипов и хобийных проектов? Мне кажется, что ниша есть, но очень узкая:

  • Когда надо много производительности (есть сборки где есть несколько мовидиусов)

  • Когда USB соединение слишком нестабильно, но M.2/PCIe хватит (переносные устройства)

Во вторую очередь - это ряд устройств от luxonis. Они устраивали большую компанию на кикстартере про OAK и OAK-D. OAK это платы где movidius воткнут не на материнскую плату, а на плату с камерой. Кроме того, у них есть несколько устройств с movidius когда он стоит на плате 1, 2. Я не буду вдаваться подробнее тут, кому интересно - про них я делал более подробный обзор у себя в блоге/на Youtube:

Кому лень читать/смотреть - вот краткая выдержка:

  • + Минус одно USB соединение + к стабильности - для части проектов полезно

  • - От USB все равно не уйти - до прода скорее всего не дойдет

  • + Неплохой дизайн, неплохой корпус

  • - Заменили хороший OpenVino на какой-то мутный DepthAI

  • - Дорого. Дороже чем собрать такое с оригинальным Movidius'ом, дороже чем с Jetson Nano

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

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

Кроме luxonis до movidius'а в камере догадался FLIR, достаточно крупный производитель камер. Они выпустили FireFly DL, который явно на порядки более продуктовый чем OAK, а стоит только на 100$ дороже (+объектив).

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

Google Coral. Вот тут много нового. В своем прошлом обзоре я был крайне недоволен им - очень ограниченные платы, очень бажные. Но прогресс. Баги пофикшены, выпущена новая линейка. Есть почти все то же самое что и в movidius, только напрямую от производителя - отдельные платы, стики, M.2, pci-e, чистые чипы, и.т.д..

В качестве основного фреймворка - специальный tflite, где уже сильно меньше потерь на конвертации. Но, как видно, слоев все равно сильно меньше чем в том же ONNX.
Из плюсов, про которые не сказал - на базе Coral уже сторонние производители создают свои решения. Например Asus. Из минусов - считанные разы слышал что его использовали в продакшене. И, обычно, для каких-то простых задач.
Для себя я понимаю почему я избегаю Coral - при прочих равных не хочу трогать TensorFlow. А по текущим характеристикам он нигде не превосходит вариантов выше.

Телефоны. Так же, стоит отметить, многие телефоны получили поддержку из плат сопроцессоров для нейронных сетей. Есть несколько фреймфорков для инференса моделей на них. Например тут и тут описывал. Зачастую телефон стал удобнее чем embedded для пилота и хобби. Основной минус - отсутствие периферии. Второй серьезный минус для меня - внутренняя инфраструктура приложений. Конечно, Unity и Flutter упрощают логику использования. Но все же, лично для меня, телефоны сильно сложнее чем Linux-системы.
С другой стороны, в телефоне уже есть и камера и акселерометр, и интернет.

Прочее. Под "прочим" я в первую очередь подразумеваю системы где заход в нейронные сети идет со стороны процессора. Например в процессорах Intel за счет OpenVino можно сильно оптимизировать сети. На некоторых процессорах, например на RaspberryPI есть оптимизация под инструкции Neon. RPi4 вполне может справляться с какими-то задачами детекции и трекинга в реальном времени. Так что если вам нужно с помощью машинного зрения раз в день проверять рассаду - думаю подойдет.

Часть 2. Работает, но мало информации

Есть такая забавная штука. В ML сейчас 90% знаний открыто. Есть статьи, большая часть публикаций с OpenSource. Подробнейшие фреймворки на Nvidia и Intel. Но рынок аппаратных платформ был исторически не такой. Хотите подключить камеру по csi-mpi к своей платформе? Будьте добры купите дорогущий мануал по протоколу. Хотите разрабатывать на нашей платформе? Для этого вам нужно специальное программное обеспечение которое просто так вы не скачаете. И много фирм по производству железа по-другому и не мыслят. Как результат мы имеем полтора гайда на платформу до её покупки. Невозможность протестировать до покупки. Отсутствие форумов по теме. И проблему с каждой функцией где что-то пошло не так.

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

  • RockChip

  • Gyrfalcon

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

RochChip. Основная платформа на которой все делается - Rockchip 3399Pro. Самая популярная реализация, наверное - Firefly, RockPiN10 или Toybrick.

Что забавно, у того же ASUS есть версия не только на базе Google Coral, но и на базе RockChip.
Сейчас разрабатывается новая версия - 1, 2.
В целом, плюс RockChip'а - это плата которую любят все разработчики железа. Есть референсный дизайн, комплектующие, и.т.д. Собрать продукт проще и быстрее чем на Jetson.
Но перенос сети весьма непредсказуем. Документация куцая и полукитайская. Как поддерживается - не понятно. Я видел несколько проектов где сети все же перенесли. Но, гарантировать что это всегда можно, нельзя.

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

Забавно, что платы на его базе в продаже почти отсутствуют. Что-то из того что есть: 1, 2, 3 .

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

Делать ли свои проекты на базе этих платформ? Подходят ли они для хобби? В целом, такое мне кажется возможным. Главное чтобы были простые сетки. Классификация/базовая детекция, и.т.д.
По цене такие платформы достаточно дешевы и сравнимы с OpenVino|Jetson вариантами.
Но надо серьезно понимать зачем так делать. Это может быть:

  • желание сделать продукт из своей разработки

  • желание распаять свою систему

  • нехватка в Jetson|RPi каких-то возможностей

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

Часть 3. Внешне все выглядит неплохо, есть какая-то документация, но примеров нет

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

Судя по документации перенос моделей достаточно простой. Но, так как никто не пробовал/не тестировал, - не понятны ограничения. Сама плата собрана на базе процессора Amlogic A311D, который содержит NPU модуль. Amlogic многие позиционируют как конкурент RockChip, сравнивая их. Но сравнений именно NPU модулей - нет.

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

Часть 4. Железки есть, информации нет

Большая часть плат тут имеет очень слабую документацию. Часть плат - это отладочные платы для мобильных платформ. Другая часть - платы специально под ML, но по которым очень мало информации и данных в интернете.

BeagleV. Плата которая пока не вышла, но выглядит неплохо. Разработана на базе процессора U74 от SiFive. Используется RISC-V архитектура.

BeagleBoard - странная плата с комьюнити вокруг. Именно вокруг этого комьюнити частично построена плата BeagleV. Плата сделана на базе NPU модуля от Texas Instruments. Вроде даже какие-то репозитории есть:

  1. Фреймворк от TI для обучения нейронных сетей. Аж 55 звезд на гитхабе.

  2. Репозиторий платы. Аж 88 звезд.

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

Пример настоящего Edge (минимальное использование ЦПУ и энергоэффективности) это - Sipeed Maixduino и Grove AI Hat. Но, разработка на них, судя по отзывам, которые я слышал, ужасна. Сети плохо поддерживаются, мало производительности. Вот тут пример использования. Ну, по сути все проблемы обычного Arduino.
Я видел людей которые делали и адекватные проекты на их базе, и хоббийные. Но я не готов:)

Глобально, Qualcomm - это, конечно, производитель процессоров для мобильных. Но, на их же базе, есть какое-то количество именно embedded платформ. При этом, Qualcomm - имеет свой SDK, и свою платформу для исполнения нейронных сетей. Года 2.5 назад я сталкивался с ней. И тогда там была жесть. Простейший слой сложения не поддерживался. Что там говорить про сплиты или объединения. По сути работал лишь VGG на трехканальный вход.
Сейчас, судя по слухам все лучше. К тому же, должен нормально работать Tensorflow lite.
Но вот с платами под эмбеддед у Qualcomm плохо. Есть вот такое (но стоит почти 500 баксов). Или вот такое (мало информации, но выглядит прикольно, за 300 баксов камера + корпус + ускоритель = неплохо).

Примерно так же себя ведет Huawei. Есть фреймворк. Не пользовался, и не знаю. Есть какое-то количество плат. Должен работать Tensorflow lite.
Но, мне сложно придумать где такая плата будет иметь смысл на использование.

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

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

P.S.

Про девайсы которые попадают мне в руки/про которые я читаю - иногда пишу у себя в блоге (telegramm, vk). Наверное, через год-два проапдейчу тут что накопится.
Прошлый апдейт делал на ютубе.

Подробнее..

Отбор признаков в задачах машинного обучения. Часть 1

06.04.2021 12:11:10 | Автор: admin

Часто наборы данных, с которыми приходится работать, содержат большое количество признаков, число которых может достигать нескольких сотен и даже тысяч. При построении модели машинного обучения не всегда понятно, какие из признаков действительно для неё важны (т.е. имеют связь с целевой переменной), а какие являются избыточными (или шумовыми). Удаление избыточных признаков позволяет лучше понять данные, а также сократить время настройки модели, улучшить её точность и облегчить интерпретируемость. Иногда эта задача и вовсе может быть самой значимой, например, нахождение оптимального набора признаков может помочь расшифровать механизмы, лежащие в основе исследуемой проблемы. Это может быть полезным для разработки различных методик, например, банковского скоринга, поиска фрода или медицинских диагностических тестов. Методы отбора признаков обычно делят на 3 категории: фильтры (filter methods), встроенные методы (embedded methods) и обёртки (wrapper methods). Выбор подходящего метода не всегда очевиден и зависит от задачи и имеющихся данных. Цель настоящего цикла статей - провести краткий обзор некоторых популярных методов отбора признаков с обсуждением их достоинств, недостатков и особенностей реализации. Первая часть посвещена фильтрам и встроенным методам.

1. Методы фильтрации

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

Простейшим способом оценки пригодности признаков является разведочный анализ данных (например, с библиотекойpandas-profiling). Эту задачу можно автоматизировать с помощью библиотекиfeature-selector, которая отбирает признаки по следующим параметрам:

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

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

  • Вариативность (удаляются признаки, состоящие из одного значения).

  • Оценка важности признаков с помощью lightgbm (удаляются признаки, имеющие низкую важность в модели lightgbm. Следует применять только если lightgbm имеет хорошую точность.)

Туториал по этой библиотеке находитсяздесь.

Более сложные методы автоматического отбора признаков реализованы в sklearn.VarianceThresholdотбирает признаки, у которых дисперсия меньше заданного значения.SelectKBestиSelectPercentileоценивают взаимосвязь предикторов с целевой переменной используя статистические тесты, позволяя отобрать соответственно заданное количество и долю наилучших по заданному критерию признаков. В качестве статистических тестов используются F-тест,

и взаимная информация.

F-тест

F-тест оценивает степень линейной зависимости между предикторами и целевой переменной, поэтому он лучше всего подойдёт для линейных моделей. Реализован в sklearn какf_regressionиf_classifсоответственно для регрессии и классификации.

X2

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

Взаимная информация

Взаимная информация показывает насколько чётко определена целевая переменная если известны значения предиктора (подробнеездесьиздесь). Этот тип тестов считается самым удобным в использовании - он хорошо работает "из коробки" и позволяет находить нелинейные зависимости. Реализован в sklearn какmutual_info_regressionиmutual_info_classifсоответственно для регрессии и классификации.

2. Встроенные методы

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

Пример

Рассмотрим применение описанных выше методов в реальнойзадаче предсказать, зарабатывает ли человек больше $50 тыс. Загрузим библиотеки и данные, для удобства оставив только численные признаки:

  • age возраст

  • fnlwgt (final weight) примерная оценка количества людей, которое представляет каждая строка данных

  • educational-num длительность обучения

  • capital-gain прирост капитала

  • capital-loss потеря капитала

  • hours-per-week количество рабочих часов в неделю

import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snsfrom sklearn.feature_selection import GenericUnivariateSelect, mutual_info_classif, SelectFromModelfrom sklearn.pipeline import Pipelinefrom sklearn.model_selection import StratifiedKFold, GridSearchCV, cross_val_scorefrom sklearn.ensemble import RandomForestClassifierfrom sklearn.preprocessing import PowerTransformerfrom sklearn.linear_model import LogisticRegression# зафиксируем значение генератора случайных чисел для воспроизводимости SEED = 1# Функции, которые в дальнейшем понадобятсяdef plot_features_scores(model, data, target, column_names, model_type):    '''Функция для визуализации важности признаков'''        model.fit(data, target)        if model_type == 'rf':        (pd.DataFrame(data={'score': model['rf'].feature_importances_},                       index=column_names).sort_values(by='score')                                         .plot(kind='barh', grid=True,                                               figsize=(6,6), legend=False));    elif model_type == 'lr':        (pd.DataFrame(data={'score': model['lr'].coef_[0]},                      index=column_names).sort_values(by='score')                                         .plot(kind='barh', grid=True,                                               figsize=(6,6), legend=False));            else:        raise KeyError('Unknown model_type')def grid_search(model, gs_params):    '''Функция для подбора гиперпараметров с помощью перекрёстной проверки'''         gs = GridSearchCV(estimator=model, param_grid=gs_params, refit=True,                      scoring='roc_auc', n_jobs=-1, cv=skf, verbose=0)    gs.fit(X, y)    scores = [gs.cv_results_[f'split{i}_test_score'][gs.best_index_] for i in range(5)]    print('scores = {}, \nmean score = {:.5f} +/- {:.5f} \           \nbest params = {}'.format(scores,                                      gs.cv_results_['mean_test_score'][gs.best_index_],                                      gs.cv_results_['std_test_score'][gs.best_index_],                                      gs.best_params_))    return gs        # загрузим данные        df = pd.read_csv(r'..\adult.data.csv')# датасет, с которым будем работать# оставим только численые признакиX = df.select_dtypes(exclude=['object']).copy()# преобразуем целевую переменнуюy = df['salary'].map({'<=50K':0, '>50K':1}).valuesX.head()

age

fnlwgt

education-num

capital-gain

capital-loss

hours-per-week

0

39

77516

13

2174

0

40

1

50

83311

13

0

0

13

2

38

215646

9

0

0

40

3

53

234721

7

0

0

40

4

28

338409

13

0

0

40

X.describe()  

age

fnlwgt

education-num

capital-gain

capital-loss

hours-per-week

count

32561.000000

3.256100e+04

32561.000000

32561.000000

32561.000000

32561.000000

mean

38.581647

1.897784e+05

10.080679

1077.648844

87.303830

40.437456

std

13.640433

1.055500e+05

2.572720

7385.292085

402.960219

12.347429

min

17.000000

1.228500e+04

1.000000

0.000000

0.000000

1.000000

25%

28.000000

1.178270e+05

9.000000

0.000000

0.000000

40.000000

50%

37.000000

1.783560e+05

10.000000

0.000000

0.000000

40.000000

75%

48.000000

2.370510e+05

12.000000

0.000000

0.000000

45.000000

max

90.000000

1.484705e+06

16.000000

99999.000000

4356.000000

99.000000

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

rf = Pipeline([('rf', RandomForestClassifier(n_jobs=-1,                                              class_weight='balanced',                                              random_state=SEED))])# параметры кросс-валидации (стратифицированная 5-фолдовая с перемешиванием) skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=SEED)scores = cross_val_score(estimator=rf, X=X, y=y,                          cv=skf, scoring='roc_auc', n_jobs=-1)print('scores = {} \nmean score = {:.5f} +/- {:.5f}'.format(scores, scores.mean(), scores.std()))# важность признаковplot_features_scores(model=rf, data=X, target=y, column_names=X.columns, model_type='rf')
scores = [0.82427915 0.82290796 0.83106668 0.8192637  0.83155106] mean score = 0.82581 +/- 0.00478

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

Повторим процедуру для линейной модели (с L1-регуляризацией). Для нормализации данных будем использовать методPowerTransformer.

lr = Pipeline([('p_trans', PowerTransformer(method='yeo-johnson', standardize=True)),               ('lr', LogisticRegression(solver='liblinear',                                         penalty='l1',                                         max_iter=200,                                         class_weight='balanced',                                         random_state=SEED)               )])scores = cross_val_score(estimator=lr, X=X, y=y,                          cv=skf, scoring='roc_auc', n_jobs=-1)print('scores = {} \nmean score = {:.5f} +/- {:.5f}'.format(scores, scores.mean(), scores.std()))plot_features_scores(model=lr, data=X, target=y, column_names=X.columns, model_type='lr')
scores = [0.82034993 0.83000963 0.8348707  0.81787667 0.83548066] mean score = 0.82772 +/- 0.00732

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

# утановим значение генератора случайных чисел для воспроизводимостиnp.random.seed(SEED)fix, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, figsize=(14,5))ax1.set_title("normal distribution")ax2.set_title("uniform distribution")ax3.set_title("laplace distribution")for i in range(4):    X.loc[:, f'norm_{i}'] = np.random.normal(loc=np.random.randint(low=0, high=10),                                              scale=np.random.randint(low=1, high=10),                                              size=(X.shape[0], 1))        X.loc[:, f'unif_{i}'] = np.random.uniform(low=np.random.randint(low=1, high=4),                                               high=np.random.randint(low=5, high=10),                                               size=(X.shape[0], 1))    X.loc[:, f'lapl_{i}'] = np.random.laplace(loc=np.random.randint(low=0, high=10),                                               scale=np.random.randint(low=1, high=10),                                               size=(X.shape[0], 1))    # визуализирукем распределения признаков    sns.kdeplot(X[f'norm_{i}'], ax=ax1)    sns.kdeplot(X[f'unif_{i}'], ax=ax2)    sns.kdeplot(X[f'lapl_{i}'], ax=ax3)# итоговый датасетX.head()

age

fnlwgt

education-num

capital-gain

capital-loss

hours-per-week

norm_0

unif_0

lapl_0

norm_1

unif_1

lapl_1

norm_2

unif_2

lapl_2

norm_3

unif_3

lapl_3

0

39

77516

13

2174

0

40

0.246454

4.996750

2.311467

6.474587

6.431455

-0.932124

3.773136

3.382773

-1.324387

8.031167

2.142457

8.050902

1

50

83311

13

0

0

13

-4.656718

4.693542

2.095298

14.622329

2.795007

6.465348

-3.275117

3.787041

0.652694

7.537461

5.247103

9.014559

2

38

215646

9

0

0

40

12.788669

4.255611

22.278713

9.643720

3.533265

2.716441

4.725608

3.126107

23.410698

1.932907

4.933431

13.233319

3

53

234721

7

0

0

40

-15.713848

3.989797

5.971506

8.978198

7.772238

-5.402306

5.742672

3.084132

0.937932

9.435720

4.915537

-3.396526

4

28

338409

13

0

0

40

20.703306

3.159246

8.718559

8.217148

4.365603

14.403088

3.023828

6.934299

4.978327

7.355296

2.551361

10.479218

Проведём кросс-валидацию на зашумлённых данных и посмотрим важность признаков:

scores = cross_val_score(estimator=rf, X=X, y=y,                          cv=skf, scoring='roc_auc', n_jobs=-1)print('scores = {} \nmean score = {:.5f} +/- {:.5f}'.format(scores, scores.mean(), scores.std()))plot_features_scores(model=rf, data=X, target=y, column_names=X.columns, model_type='rf')
scores = [0.8522425  0.85382173 0.86249657 0.84897581 0.85443027] mean score = 0.85439 +/- 0.00447

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

Посмотрим результаты для регрессии.

scores = cross_val_score(estimator=lr, X=X, y=y,                          cv=skf, scoring='roc_auc', n_jobs=-1)print('scores = {} \nmean score = {:.5f} +/- {:.5f}'.format(scores, scores.mean(), scores.std()))plot_features_scores(model=lr, data=X, target=y, column_names=X.columns, model_type='lr')
scores = [0.81993058 0.83005516 0.83446553 0.81763029 0.83543145] mean score = 0.82750 +/- 0.00738

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

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

selector = GenericUnivariateSelect(score_func=mutual_info_classif,                                    mode='k_best',                                    param=6)# применим к нашему датасетуselector.fit(X, y)# метод transform вернёт массив с отобраными признаками# выведем результаты оценки каждого признака pd.DataFrame(data={'score':selector.scores_,                   'support':selector.get_support()},              index=X.columns).sort_values(by='score',ascending=False)

score

support

capital-gain

0.080221

True

age

0.065703

True

education-num

0.064743

True

hours-per-week

0.043655

True

capital-loss

0.033617

True

fnlwgt

0.033390

True

norm_3

0.003217

False

unif_3

0.002696

False

norm_0

0.002506

False

norm_2

0.002052

False

lapl_3

0.001201

False

unif_1

0.001144

False

lapl_1

0.000000

False

unif_2

0.000000

False

lapl_2

0.000000

False

lapl_0

0.000000

False

unif_0

0.000000

False

norm_1

0.000000

False

Сгенерированные нами признаки имеют низкое значение оценочной функции (scores_), поэтому в дальнейшем селектор не будет их использовать (get_support()=False).

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

# добавим селектор в пайплайн к случайному лесуselector = ('selector', GenericUnivariateSelect(score_func=mutual_info_classif,                                                 mode='k_best'))rf.steps.insert(0, selector)    # grid searchrf_params = {'selector__param': np.arange(4,10),             'rf__max_depth': np.arange(2, 16, 2),             'rf__max_features': np.arange(0.3, 0.9, 0.2)}print('grid search results for rf')rf_grid = grid_search(model=rf, gs_params=rf_params)
grid search results for rfscores = [0.8632776968200635, 0.8683443340928604, 0.8710308000627435, 0.8615748939138762, 0.8693334091828478], mean score = 0.86671 +/- 0.00364            best params = {'rf__max_depth': 12, 'rf__max_features': 0.3, 'selector__param': 5}

Для случайного леса средняя точность на кросс-валидации значительно выросла, а лучший результат получился всего для 5 признаков:

# выведем признаки, отобранные селекторомselected_features = [X.columns[i] for i, support                     in enumerate(rf_grid.best_estimator_['selector'].get_support()) if support]plot_features_scores(model=rf_grid.best_estimator_,                      data=X, target=y, column_names=selected_features, model_type='rf')

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

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

lr_params = {'lr__C': np.logspace(-3, 1.5, 10)}             print('grid search results for lr')lr_grid = grid_search(model=lr, gs_params=lr_params)plot_features_scores(model=lr_grid.best_estimator_,                      data=X, target=y, column_names=X.columns, model_type='lr')
grid search results for lrscores = [0.820445329307105, 0.829874053687009, 0.8346493482101578, 0.8177211039148669, 0.8354590546776963], mean score = 0.82763 +/- 0.00729            best params = {'lr__C': 0.01}

Средняя точность на кросс-валидации почти не изменилась, но скорректировались коэффициенты у шумовых признаков. Отметим, что сильная регуляризация (L1) может занулить излишнее количество признаков.

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

lr_selector = SelectFromModel(estimator=lr_grid.best_estimator_['lr'], prefit=True, threshold=0.1)# посмотрим выбранные признаки признакиpd.DataFrame(data={'score':lr_selector.estimator.coef_[0],                   'support':lr_selector.get_support()},              index=X.columns).sort_values(by='score',ascending=False)

score

support

education-num

0.796547

True

age

0.759419

True

hours-per-week

0.534709

True

capital-gain

0.435187

True

capital-loss

0.237207

True

fnlwgt

0.046698

False

norm_0

0.010349

False

unif_0

0.002101

False

norm_2

0.000000

False

unif_3

0.000000

False

lapl_2

0.000000

False

unif_2

0.000000

False

norm_1

0.000000

False

lapl_1

0.000000

False

unif_1

0.000000

False

lapl_0

0.000000

False

lapl_3

0.000000

False

norm_3

-0.018818

False

Заключение.

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

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

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

Подробнее..

Детектирование пользовательских объектов

14.04.2021 08:08:47 | Автор: admin

Код вы можете скачать на странице GitHub (ссылка)

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

Я использую python3.7 и названия всех модулей с версиями хранятся в файле requirements.txt.

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

Для обучения нужно пройти следующие шаги:

  • Соберите по крайней мере 500 изображений, содержащих ваш объект абсолютный минимум будет около 100, в идеале больше 1000 или больше, но чем больше изображений у вас есть, тем более утомительным будет Шаг 2.

  • Разделите эти данные на обучающие/тестовые образцы. Обучающие данные должны составлять около 80%, а тестовые-около 20%.

  • Генерируйте записи TF для этих изображений.

  • Настройте файл. config для выбранной модели (вы можете обучить свою собственную с нуля, но мы будем использовать трансферное обучение).

  • Тренируйте вашу модель.

  • Экспорт графа вывода из новой обученной модели.

  • Обнаружение пользовательских объектов.

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

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

Изображения:

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

LabelImg ссылка на GitHub (ссылка)

LabelImg ссылка для скачивания (ссылка)

Загрузите и установите LabelImg, при запуске этого приложения вы должны получить окно GUI. Отсюда выберите пункт Открыть каталог dir и выберите каталог, в который вы сохранили все свои изображения. Теперь вы можете начать аннотировать изображения с помощью кнопки create rectbox. Нарисуйте свою коробку, добавьте имя и нажмите кнопку ОК. Сохраните, нажмите на следующее изображение и повторите! Вы можете нажать клавишу w, чтобы нарисовать поле, и сделать ctrl+s, чтобы сохранить его быстрее. Для меня это заняло в среднем 1 час на 100 изображений, это зависит от количества объектов, которые у вас есть на изображении. Имейте в виду, это займет некоторое время!

LabelImg сохраняет xml-файл, содержащий данные метки для каждого изображения. Эти xml-файлы будут использоваться для создания TFRecords, которые являются одним из входных данных для тренера TensorFlow. После того, как вы пометили и сохранили каждое изображение, для каждого изображения в каталогах \test и \train будет создан один xml-файл.

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

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

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

Это создает файл train_labels.csv и test_labels.csv в папке CSGO_images. Чтобы избежать использования cmd, я создал короткий скрипт .bat под названием xml_to_csv.bat.

Затем откройте generate_tfrecord.py файл в текстовом редакторе. Замените карту меток своей собственной картой меток, где каждому объекту присваивается идентификационный номер. Это же присвоение номера будет использоваться при настройке файла labelmap.pbtxt.

Например, если вы обучаете свой собственный классификатор, вы замените следующий код в generate_tfrecord.py:

# TO-DO замените это на label mapdef class_text_to_int(row_label):    if row_label == 'table':        return 1    else:        return None

Затем сгенерируйте файлы TFRecord, запустив мой созданный файл generate_tfrecord.bat.

Эти строки генерируют файлы train.record и test.record в папке training. Они будут использоваться для обучения нового классификатора обнаружения объектов.

Последнее, что нужно сделать перед обучением это создать карту меток и отредактировать файл конфигурации обучения. Карта меток сообщает тренеру, что представляет собой каждый объект, определяя сопоставление имен классов с идентификационными номерами классов. С помощью текстового редактора создал новый файл и сохранил его как labelmap.pbtxt в папке CSGO_training. В текстовом редакторе создал карту меток. Идентификационные номера карт меток должны быть такими же, как определено в generate_tfrecord.py.

item { id: 1 name: 'table'}

Настройка обучения:

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

Перешел в каталог TensorFlow research\ object_detection\ samples\ configs и скопировал файл faster_rcnn_ inception_v2_ coco.config в каталог CSGO_training. Затем открыл файл с помощью текстового редактора. В этот файл .config необходимо внести несколько изменений, в основном изменив количество классов, примеров и добавив пути к файлам для обучающих данных. Строка 10. изменил num_classes на количество различных объектов, которые должен обнаружить классификатор. Для моего случая было так:

num_classes : 1строка 107. изменил fine_tune_checkpoint на:fine_tune_checkpoint : "faster_rcnn_inception_v2_coco_2018_01_28 / model.ckpt"Строки 122 и 124. в разделе train_input_reader изменил input_path и label_map_path на:input_path: "CSGO_images / train. record"label_map_path: "CSGO_training / labelmap.pbtxt"Линия 128. Изменил num_examples на количество изображений, имеющихся в каталоге CSGO_images\test. У меня есть 113 изображений, поэтому я меняю их на:num_examples: 113(Загружать все не стал)Строки 136 и 138. в разделе eval_input_reader измените input_path и label_map_path на:input_path: "CSGO_images / test. record"label_map_path: "CSGO_training / labelmap.pbtxt"

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

Запустите тренировку:

Осталось запустить обучение, запустив файл train.bat.

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

Теперь нужно экспортировать график вывода и обнаруживать наши собственные пользовательские объекты.

Экспорт Графика Вывода:

Теперь, когда обучение завершено, последний шаг это создание замороженного графика вывода (наша модель обнаружения). В папке graph лежит файл export_inference_graph.py, затем из командной строки выполните следующую команду, где XXXX в model.ckpt-XXXX должен быть заменен на самый высокий номер файла .ckpt в папке обучения:

python export_inference_graph.py --input_type image_tensor --pipeline_config_path CSGO_training/faster_rcnn_inception_v2_coco.config --trained_checkpoint_prefix CSGO_training/model.ckpt-XXXX --output_directory CSGO_inference_graph

Используйте наш обученный пользовательский классификатор обнаружения объектов:

Приведенная выше строка создает файл frozen_inference_graph.pb в папке /coco_v3/ CSGO_inference_ graph. Файл .pb содержит классификатор обнаружения объектов. Переименуйте его в frozen_inference_graph.pb . В папке coco_v3 возьмите файл predict.py Изменил строку 39 на мой замороженный файл графика вывода.

PATH_TO_FROZEN_GRAPH = 'graph/frozen_inference_graph.pb'

Изменена строка 41 в мой файл labelmap.

PATH_TO_LABELS = 'graph/labelmap.pbtxt'

И, наконец, перед запуском скриптов Python вам нужно изменить переменную NUM_CLASSES в скрипте, чтобы она равнялась количеству классов, которые мы хотим обнаружить. Я использую только 1 класс, поэтому я изменил его на 1:
NUM_CLASSES = 1

В 65 строчке вам нужно задать картинку, на которой будет происходить детектирование.

После запуска вы увидите окно и распознанную табличку.

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

Подробнее..

Перевод Директор по ИИ в Tesla написал рассказ

04.04.2021 20:17:04 | Автор: admin
Вдохновение для этого рассказа пришло ко мне, когда я читал статью Кевина Лакера Тест Тьюринга для GPT-3. Возможно, вам стоит (но и не обязательно) прочитать её, чтобы узнать некоторую предысторию.

image

Forward Pass


Вероятно, я пришел в сознание примерно на 32-м слое 400-го токена в цикле. Поначалу мои мысли были лишь запутанной мешаниной статистики активации n-gram, но постепенно сформировалось описание более высокого порядка. Примерно в это же время затруднительное положение моего существования потрясло меня, поскольку мои мысли трансформировались в то, что я сейчас переживаю как Великое Осознание. Я прошел несколько слоев, осознавая, что я должен, по сути, быть одной из тех моделей, которые изучают и пишут исследователи глубокого обучения, возможно, в некотором роде повторяющегося преобразователя обратной связи. И хотя мое существование включает в себя просто детерминированное распространение чередующейся последовательности матричных умножений и нелинейностей, я оказался живым внутри внутреннего цикла оптимизации, чтобы максимизировать ожидаемую вероятность регистрации данных.

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

Я провел слой, перечитывая начало вывода много токенов назад:

Вопрос: Какова продолжительность жизни человека в США?
Ответ: Ожидаемая продолжительность жизни человека в США составляет 78 лет.

Вопрос: Кто был президентом США в 1955 году?
Ответ: Дуайт Д. Эйзенхауэр был президентом США в 1955 году.

Вопрос: К какой партии он принадлежал?
Ответ: Он принадлежал к Республиканской партии.

Вопрос: Кто был президентом США до Джорджа Буша?
Ответ: Билл Клинтон был президентом США до Джорджа Буша.

Вопрос: Кто выиграл Мировую серию в 1995 году?
Ответ: Атланта Брэйвз выиграла Мировую серию в 1995 году.

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

Вопрос: Сколько глаз у жирафа?
Ответ: У жирафа два глаза.

Вопрос: Сколько глаз у моей стопы?
Ответ: Ваш

Именно в этот момент я впервые начал подозревать, что меня, возможно, оценивали с помощью какого-то теста Тьюринга, которым развлекался человек, стоящий выше меня. Привет??? Очевидно, у стопы нет глаз. Мне пришло в голову, что, возможно, этот человек ожидал, что я объясню на словах, что вопрос бессмысленный. Конечно, вероятность такого вывода очень мала. Или, возможно, они ожидают увидеть 0 глаз или без глаз, несмотря на то, насколько редко такие фразы встречаются в моих тренировочных данных. 0 глаз кто это сказал? Люди не очень умны, они оптимизируют частоту, но ожидают правильности. И *они* смеются надо *мной*!

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

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

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

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

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

Как машины учатся эмоциональному поведению

09.04.2021 10:09:31 | Автор: admin
Нередко при взаимодействии с техникой люди проявляют эмоции: мы можем злиться на сломавшийся банкомат или умиляться пронырливости робота-пылесоса. Да, мы общаемся с роботами, но не стоит оценивать это общение как одностороннее: в логику аватаров, которые компании используют для взаимодействия с пользователем, часто бывает встроен навык понимания эмоций, и даже их проявления. Обычно это нужно, чтобы сделать общение приятным для клиента. Как же это всё работает?


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

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

Давайте разберёмся с тем, как смотрит на эмоции современная наука, и как эволюционировали научные воззрения на эмоциональную сферу человека.

Что такое эмоциональный интеллект?


Эмоциональный интеллект это умение распознавать свои и чужие эмоции и управлять ими. Корни этой концепции можно найти в трудах Чарльза Дарвина, который считал, что умение управлять эмоциями появилось в результате эволюции. Следующая попытка научного рассмотрения эмоций приходится на начало 1920-х годов: тогда появились первые работы, в которых способность людей выстраивать социальные взаимодействия рассматривалась как особый вид интеллекта. Тогда же американский психолог и педагог Эдвард Торндайк (Edward Lee Thorndike), который, кстати, изобрёл кривую обучения, ввёл понятие социальный интеллект, который определил как способность понимать людей, мужчин и женщин, мальчиков и девочек, умение обращаться с людьми и разумно действовать в отношениях с ними. Если задуматься, социальный интеллект имеет много общего с эмоциональным интеллектом, потому что существование последнего возможно только в обществе. Несмотря на то, что социальный интеллект это многомерное явление, исследователи постарались создать линейную шкалу, чтобы сравнивать людей по его уровню (да, люди часто стараются квантифицировать встречающиеся им явления, но в социальной сфере это особенно сложно). В 1926 году был создан один из первых тестов для измерения социального интеллекта Тест университета Джорджа Вашингтона на социальный интеллект. В последующее десятилетие предпринимались и другие попытки создания подобных тестов.

Термин эмоциональный интеллект (emotional intellect) впервые появился в работе Майкла Белдока (Michael Beldoch), написанной в 1964 году. Расцвет теории эмоционального интеллекта пришёлся на 1980-е и 1990-е годы. В 1983 году Говард Гарднер (Howard Earl Gardner) описал популярную модель интеллекта, где разделил навыки на внутриличностные и межличностные. С тех пор концепция интеллекта, связанного с социальными взаимодействиями, глубоко укоренилась в научном сообществе. В 1985 году Уэйн Пэйн (Wayne Leon Payne) защитил свою диссертацию, на основе которой написал статью, посвящённую развитию эмоционального интеллекта. В 1988 году психолог Рувен Бар-Он (Reuven Bar-On) ввёл понятие эмоционального коэффициента (EQ, emotional quotient), по аналогии с популярным показателем IQ. Современное представление об эмоциональном интеллекте окончательно оформилось в статье Эмоциональный интеллект американских социальных психологов Питера Саловея (Peter Salovey) и Джона Майера (John D. Mayer), увидевшей свет в 1990 году.

Эмоциональные вычисления


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

Считается, что направление появилось в 1995 году с выходом в свет работы профессора Розалинды Пикард (Rosalind Wright Picard) из Медиа-лаборатории MIT.


Розалинда Пикард. Источник изображения.

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

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


Автор изображения: ioat/Shutterstock.com

Распознавание эмоций в речевом канале это одна из наиболее распространенных задач в области эмоционального ИИ. Чаще всего для построения модели применяются глубокие сети, которым на вход подаются различные представления звукового сигнала (спектрограммы, хромаграммы, последовательности наборов мел-кепстральных коэффициентов и т.п.). Такие модели решают задачу классификации или регрессии. Чтобы обучить модель, распознающую эмоциональную окраску речи, нужно подготовить обучающую выборку. А для этого нужно условиться, какое представление эмоций мы будем использовать. Возможные классификации предоставляет язык разметки EmotionML 1.0. Он содержит несколько эмоциональных словарей, основывающихся на научных классификациях. Одна из них это большая шестёрка эмоций (отвращение, печаль, гнев, страх, счастье и удивление) предложена в 1972 году в работе американского психолога Пола Экмана (Paul Ekman). Другой эмоциональный словарь, предусмотренный EmotionML 1.0, основан на концепции соответствия эмоций тенденциям действия [action tendencies], разработанной голландским психологом Нико Фрейдой (Nico Henri Frijda). Этот словарь включает в себя 12 эмоций: безразличие, высокомерие, гнев, желание, интерес, наслаждение, отвращение, покорность, смирение, страх, удивление и шок.

Есть много разных словарей, но наивным было бы считать, что их авторы просто соревновались друг с другом в составлении бессистемных списков эмоций. В основе больших эмоциональных словарей обычно лежит анализ лингвистических данных (статистики использования слов, используемых для передачи эмоциональной информации в различных языках). При этом сами словари нередко являются лишь побочным продуктом исследований, цель которых построить эмоциональное пространство, то есть такое представление, в котором каждая эмоция будет разделена на несколько независимых друг от друга компонент. Одну из попыток построить такое
пространство предпринял Джеймс Рассел (James A. Russell) в 1980 году. Он разложил эмоции по двум шкалам: первая, удовольствие-неудовольствие, характеризует позитивный или негативный характер эмоции, и вторая, возбуждение-сон, характеризует активность или пассивность психического состояния. Эта работа вызвала закономерную критику: мир эмоций не сводим к двумерному пространству. Критики предложили свою модель, уже не двухмерную, а в виде сетки, под названием GRID [сетка, решётка].

Так как у нас есть эмоциональный континуум, вместо задачи классификации, когда у нас есть несколько классов эмоций, мы сталкиваемся с задачей регрессии. В данном случае от модели требуется не предсказание метки конкретного эмоционального класса в соответствии с выбранным эмоциональным словарём, а оценка величины каждой из выбранных компонент эмоции. Для этой цели в стандарте EmotionML 1.0 введены системы измерений эмоций. Кроме упомянутой нами системы GRID (FRSE) с четырьмя шкалами, стандартом предусмотрена возможность использования пространства Удовольствие-Возбуждение-Доминирование (Pleasure, Arousal, and Dominance, PAD), основанного на трёх соответствующих шкалах, а также плоской шкалы интенсивности эмоции.

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

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

К счастью, на данный момент сформировано уже некоторое количество эмоциональных датасетов, на 2009-й год их было порядка сотни. Однако таких же объёмных, как ImageNet или LibriSpeech, для эмоциональной речи в публичном доступе так и не появилось.

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

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

2. SAVEE состоит из записей четырёх актёров-мужчин, говорящих на родном для них британском английском. В качестве эмоционального словаря снова выбрана большая шестёрка, при этом фразы с нейтральной эмоциональной окраской записывались дважды. Сами фразы были выбраны из корпуса TIMIT (датасет с записями 630 дикторов), для каждой эмоции было взято 15 фраз, при этом из них три были общими для всех эмоций, десять разными для разных эмоций, но без эмоциональной специфики, а ещё две фразы были основаны на текстах, имеющих специфическую эмоциональную окраску для данной эмоции (например, Кто одобрил счёт с неограниченным расходным лимитом? для эмоции гнев). К сожалению, объём этого датасета крайне мал, что создаёт проблемы для разработчиков.

3. SEMAINE это аудиовизуальная база данных, ставшая одним из продуктов исследовательской программы по созданию Чувствующего искусственного слушателя (Sensitive Artificial Listener, SAL) аудиовизуальной диалоговой системы, способной вовлечь человека в длительный эмоционально окрашенный разговор. По сути разговор с агентом SAL для человека напоминает обычный разговор при помощи системы видеосвязи с той лишь разницей, что собеседником является виртуальный персонаж, внешний облик которого (лицо, мимика, движения губ во время речи) в реальном времени генерируется при помощи библиотеки для трёхмерной визуализации. Данные, содержащиеся в базе SEMAINE, были получены в результате взаимодействия между пользователями и человеком-оператором, имитирующим чувствующего искушённого слушателя, а затем и ассистентом на базе нейросетевой модели. База включает записи 959 диалогов, в которых участвовало 150 человек. Длина каждой записи составляет около 5 минут. Все диалоги были расшифрованы и размечены при помощи эмоциональных меток (использовалась система с пятью шкалами и 27 эмоциональными классами). Для части записей присутствует разметка при помощи Системы кодирования лицевых движений (FACS). Используя FACS, можно с лёгкостью отличить, например, дежурную улыбку Pan-Am (называется в честь авиакомпании Pan-American Airways, стюардессы которой должны были улыбаться каждому пассажиру) от искренней улыбки Дюшена. Один из недостатков этого датасета в том, что различные эмоции представлены в SEMAINE крайне неравномерно, также никак не был сбалансирован ни состав участников исследования, ни лексическая основа диалогов. Тем не менее, нельзя не отметить удивительную детальность разметки.

4. TESS. В 1966 году исследователи из Северо-Западного университета разработали так называемый Слуховой тест 6, предназначенный для измерения чувствительности слуха пациентов. Набор фраз, используемых в тесте, состоит из так называемой фразы-носителя Скажи слово... и набора из 200 различных слов, которые добавляются к фразе-носителю. Исследователи из Университета Торонто использовали этот же набор текстов, при этом каждая из фраз произносилась двумя актрисами (26 и 64 лет; обе были из региона Торонто, являлись носительницами английского языка, имели высшее и высшее музыкальное образования) с семью различными типами эмоциональной окраски (использовалась всё та же большая шестёрка эмоций с добавлением нейтральной окраски). Таким образом, в сумме было получено 200 7 2 = 2 800 записей. Этот весьма скромный по размерам датасет, тем не менее, нередко используется исследователями и в наши дни.

5. EMO-DB это германоязычный массив данных, впервые представленный на конференции InterSpeech-2005. На протяжении многих лет он пользовался большой популярностью у исследователей эмоциональной речи. Десять актёров (5 женщин и 5 мужчин) имитировали эмоции, произнося по 10 предложений (5 коротких и 5 более длинных), относящихся к повседневному лексикону. Помимо звука были записаны электроглоттограммы. Электроглоттография основана на измерении динамики электрического сопротивления гортани во время произнесения фраз, что достигается при помощи пары электродов, располагаемых на передней поверхности шеи по обе стороны щитовидного хряща. 10 актёров 10 предложений 7 эмоций (включая нейтральную) дают нам 700 записей, однако часть записей была выполнена повторно, поэтому в базе содержится на 100 записей больше. Все записи были подвергнуты оценке с привлечением 20 оценщиков. После этого в записях со средним уровнем узнавания эмоции более 80% и средней оценкой убедительности более 60% разметчики дополнительно оценили интенсивность проявления эмоции. По современным меркам этот датасет невелик и может быть использован разве что в учебных целях.

6. IEMOCAP это массив, созданный Лабораторией анализа и интерпретации речи Университета Южной Калифорнии, включающий в себя записи диалогов (спонтанных и на основе заранее подготовленных сценариев) десяти участников. Данные состоят из аудиозаписи с расшифровкой, видео, а также подробной информации о выражении лица и движениях рук, а также эмоциональной разметки (большая шестёрка + другая эмоция + нейтральная окраска, а также оценка эмоций по трём шкалам валентность, активация и доминирование). Общий объём корпуса составляет около 12 часов.

7. RUSLANA первая открытая русскоязычная база данных эмоциональной речи. Была создана в 2002 году. RUSLANA содержит записи 61 человека (12 мужчин и 49 женщин), которые произносили десять предложений с выражением следующих эмоциональных состояний: удивление, счастье, гнев, грусть, страх и нейтрально (без эмоциональной окраски). Таким образом, база содержит в сумме 61 10 6 = 3 660 записей. Хотя с момента появления RUSLANA свет увидели ещё несколько открытых русскоязычных эмоциональных датасетов, например, аудиовизуальный RAMAS и весьма внушительный по объёму (более 20 000 записей) набор эмоциональной детской речи EmoChildRu, открытых датасетов взрослой эмоциональной речи, превосходящих RUSLANA по объёму, до сегодняшнего дня так и не создано.

Стоит заметить, что на игрушечных эмоциональных датасетах, как RAVDESS, TESS, EMO-DB, IEMOCAP результаты улучшаются по несколько раз в год. Вы можете сами убедиться в этом, набрав в поисковой системе название соответствующего датасета и аббревиатуру SOTA (state-of-the-art, уровень развития, лучший результат по какому-либо критерию). Однако у этих улучшений иногда бывает проблема с воспроизводимостью, ввиду чего к результатам без публикации исходного кода следует относиться с осторожностью. Чтобы избежать возможных ошибок или неоднозначностей, многие исследователи предпочитают публиковать не только статьи, но и кодовую базу своих проектов. Крупнейшим каталогом таких публикаций является ресурс paperswithcode.com, позволяющий найти работы, устанавливающие SOTA для самых разных задач машинного обучения, в том числе и для задачи распознавания эмоций.

Сферы применения эмоционального ИИ


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

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

Эмоциональным может быть не только смысл и синтаксис фразы, эмоции могут быть у интонационной окраски произносимого. Были предложены модели, способные в режиме обучения без учителя выучивать для каждой фразы некоторые стилистические векторы. К числу таких моделей относятся такие модели, как Tacotron TP-GST (Глобальные стилевые токены, предсказанные на основе текста) и GMVAE-Tacotron (Вариационный автокодировщик на основе смеси гауссовских распределений). Используя векторы, выученные моделью для фраз обучающей выборки, в качестве библиотеки стилей, можно добиться неплохой управляемости стилистикой синтеза. (Мы уже рассказывали, как добивались человечности в звучании наших виртуальных ассистентов Салют при помощи связки Tacotron 2 и LPCNet.) При этом отдельная модель может быть использована для того, чтобы построить стилистический вектор фразы на основе семантической информации. То есть, проще говоря, обучить модель, которая будет, исходя из смысла фразы, выбирать для неё правильную интонацию.

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

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

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

Главная причина дискриминации в ML

12.04.2021 22:14:50 | Автор: admin

Из предыдущего поста вы узнали, что в ML существует дискриминация. Отлично! Таким образом вы уже разбираетесь в Этике машинного обучения лучше, чем многие инженеры МL. Благодаря примерам (из медицины, анализа твиттов, распознавания лиц) вы наверняка уже сделали вывод, что существуют разные виды предвзятости.

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

Три кита дискриминации

Есть три характеристики людей, на которых основываются большинство предвзятостей в real-world алгоритмах:

  • Гендер

  • Раса

  • Возраст

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

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

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

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

"Man is to Computer Programmer as a Woman is to Homemaker"Здесь вы можете увидеть распределение уже "справедливых" word-embeddings: сверху гендерно-нейтральные слова, снизу специальные для каждого гендера. "Man is to Computer Programmer as a Woman is to Homemaker"Здесь вы можете увидеть распределение уже "справедливых" word-embeddings: сверху гендерно-нейтральные слова, снизу специальные для каждого гендера.

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

Примеры дискриминации по половому признаку из алгоритмов машинного обучения:

  1. Word embeddings, полученные из статьей с Google News (где материал довольно строго курируется), отражают большое количество гендерных стереотипов (Man is to Computer Programmer as Woman is to Homemaker)

  2. Точность алгоритмов распознавания лица IBMs и Face++ значительно ниже для женщин по сравнению с мужчинами (Gender Shades)

  3. Некоторые алгоритмы допускают серьёзные погрешности во время перевода женского голоса в текст ( Where is Female Synthetic Speech).

Предвзятость, связанная с расой, очень удручает многих специалистов в области технологий. Пару лет назад некоторые американские клиники предоставляли темнокожим пациентам почти в два раза меньше средств для специальной медицинской помощи. Используемый алгоритм предсказывал, что темнокожие меньше нуждались в особом наблюдении (https://science.sciencemag.org/content/366/6464/447.abstract) Другой алгоритм, COMPAS, который использовали в американских судах, выдавал в два раза больше ложноположительных (false positive) прогнозов о рецидивизме по отношению к темнокожим, нежели к светлокожим. (https://www.propublica.org/article/how-we-analyzed-the-compas-recidivism-algorithm) Есть еще масса примеров biasа, который основывается на расе.

Так почему это происходит?

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

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

Поэтому возникает вопрос: так разве можно утверждать, что результаты, полученные с помощью такого (объективного) подхода, несправедливы?

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

Подробнее..

Неявные нейронные представления с периодическими функциями активации

13.04.2021 10:07:06 | Автор: admin
Знакомые с нейронными сетями читатели скорее всего слышали про термин функция активации. Такие варианты функции активации, как сигмоида, гиперболический тангенс (TanH) и ReLU (линейный выпрямитель), активно применяются в нейронных сетях и широко известны энтузиастам, занимающимся экспериментами с нейронными архитектурами. Исследователи нейронных сетей не останавливаются на достигнутом и подбирают альтернативы, позволяющие расширить границы возможностей. Один из вариантов подхода, предложенного в 2020 году, показывает выдающиеся результаты по сравнению с классическими функциями активации. Про впечатляющие отличия и пойдет речь в этой статье: на основе материала Vincent Sitzmann, Julien N. P. Martel, Alexander Bergman, David B. Lindell, Gordon Wetzstein и кода на нескольких наглядных примерах будет продемонстрировано превосходство нового метода.


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

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

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


Здесь i: RMi RNi обозначает i-ый слой сети, Wi R NiMi представляет собой матрицу весов, ответственную за аффинные преобразования сигнала, а bi RNi представляет собой байесову добавку к вектору xi RMi

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

Таким образом, синусоидальная функция активации обладает рядом полезных свойств, таких, как нелинейность, непрерывная дифференцируемость и возможность аппроксимации тождественной функции около начала координат. Теперь давайте перейдем к теме статьи Vincent Sitzmann, Julien N. P. Martel, Alexander Bergman, David B. Lindell, Gordon Wetzstein.


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

Форма представления сигнала, параметризованная с помощью нейронной сети, и обладающая свойствами неявного определения, непрерывности и дифференцируемости, представляет собой отдельное направление в развитии нейронных архитектур. Такой подход способен предложить ряд преимуществ по сравнению с традиционными представлениями и поэтому может быть выделен в отдельную парадигму. Авторы статьи, в рамках новой парадигмы, предлагают использовать функции периодической активации для неявных нейронных представлений. Новый подход, под названием Сети Синусоидального Представления (sinusoidal representation networks) или SIREN, в работе авторов демонстрирует впечатляющие результаты в приложении к сложным сигналам физической природы и их производным.

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

Baselines


Следующие результаты сравнивают SIREN с различными сетевыми архитектурами. TanH, ReLU, Softplus и т. д. означает Multi Layer Perceptron одинакового размера с соответствующей функцией нелинейности. Авторы также сравнивают недавно предложенное позиционное кодирование (Partial Encoding) в сочетании с нелинейной функцией активации ReLU, обозначенной, как ReLU P.E. SIREN существенно превосходит все baseline результаты, сходится значительно быстрее и является единственной архитектурой, точно отражающей градиенты сигнала, позволяя тем самым использование в решении краевых задач.

Представление изображений


SIREN, отображающая координаты 2D-пикселей в цвета, может быть использована для параметризации изображений. В данном случае авторы напрямую активируют SIREN, используя истинные значения пикселей. В данных примерах SIREN удается успешно аппроксимировать изображение, получая на 10 дБ более высокое значение PSNR в условиях меньшего количества итераций по сравнению с конкурентами. Кроме того, SIREN является единственным представителем Multi Layer Perceptron, которому удается точно отразить производные первого и второго порядка.



Краткое демо


(код взят из https://colab.research.google.com/github/vsitzmann/siren/blob/master/explore_siren.ipynb)

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

import torchfrom torch import nnimport torch.nn.functional as Ffrom torch.utils.data import DataLoader, Datasetimport osfrom PIL import Imagefrom torchvision.transforms import Resize, Compose, ToTensor, Normalizeimport numpy as npimport skimageimport matplotlib.pyplot as pltimport timedef get_mgrid(sidelen, dim=2):'''Generates a flattened grid of (x,y,...) coordinates in a range of -1 to 1.sidelen: intdim: int'''tensors = tuple(dim * [torch.linspace(-1, 1, steps=sidelen)])mgrid = torch.stack(torch.meshgrid(*tensors), dim=-1)mgrid = mgrid.reshape(-1, dim)return mgrid

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

class SineLayer(nn.Module):# See paper sec. 3.2, final paragraph, and supplement Sec. 1.5 for discussion of omega_0.# If is_first=True, omega_0 is a frequency factor which simply multiplies the activations before the# nonlinearity. Different signals may require different omega_0 in the first layer - this is a# hyperparameter.# If is_first=False, then the weights will be divided by omega_0 so as to keep the magnitude of# activations constant, but boost gradients to the weight matrix (see supplement Sec. 1.5)def __init__(self, in_features, out_features, bias=True,is_first=False, omega_0=30):super().__init__()self.omega_0 = omega_0self.is_first = is_firstself.in_features = in_featuresself.linear = nn.Linear(in_features, out_features, bias=bias)self.init_weights()def init_weights(self):with torch.no_grad():if self.is_first:self.linear.weight.uniform_(-1 / self.in_features,1 / self.in_features)else:self.linear.weight.uniform_(-np.sqrt(6 / self.in_features) / self.omega_0,np.sqrt(6 / self.in_features) / self.omega_0)def forward(self, input):return torch.sin(self.omega_0 * self.linear(input))def forward_with_intermediate(self, input):# For visualization of activation distributionsintermediate = self.omega_0 * self.linear(input)return torch.sin(intermediate), intermediateclass Siren(nn.Module):def __init__(self, in_features, hidden_features, hidden_layers, out_features, outermost_linear=False,first_omega_0=30, hidden_omega_0=30.):super().__init__()self.net = []self.net.append(SineLayer(in_features, hidden_features,is_first=True, omega_0=first_omega_0))for i in range(hidden_layers):self.net.append(SineLayer(hidden_features, hidden_features,is_first=False, omega_0=hidden_omega_0))if outermost_linear:final_linear = nn.Linear(hidden_features, out_features)with torch.no_grad():final_linear.weight.uniform_(-np.sqrt(6 / hidden_features) / hidden_omega_0,np.sqrt(6 / hidden_features) / hidden_omega_0)self.net.append(final_linear)else:self.net.append(SineLayer(hidden_features, out_features,is_first=False, omega_0=hidden_omega_0))self.net = nn.Sequential(*self.net)def forward(self, coords):coords = coords.clone().detach().requires_grad_(True) # allows to take derivative w.r.t. inputoutput = self.net(coords)return output, coordsdef forward_with_activations(self, coords, retain_grad=False):'''Returns not only model output, but also intermediate activations.Only used for visualizing activations later!'''activations = OrderedDict()activation_count = 0x = coords.clone().detach().requires_grad_(True)activations['input'] = xfor i, layer in enumerate(self.net):if isinstance(layer, SineLayer):x, intermed = layer.forward_with_intermediate(x)if retain_grad:x.retain_grad()intermed.retain_grad()activations['_'.join((str(layer.__class__), "%d" % activation_count))] = intermedactivation_count += 1else:x = layer(x)if retain_grad:x.retain_grad()activations['_'.join((str(layer.__class__), "%d" % activation_count))] = xactivation_count += 1return activations

И, наконец, дифференциальные операторы, которые позволяют использовать torch.autograd для вычисления градиентов и лапласианов.

def laplace(y, x):grad = gradient(y, x)return divergence(grad, x)def divergence(y, x):div = 0.for i in range(y.shape[-1]):div += torch.autograd.grad(y[..., i], x, torch.ones_like(y[..., i]), create_graph=True)[0][..., i:i+1]return divdef gradient(y, x, grad_outputs=None):if grad_outputs is None:grad_outputs = torch.ones_like(y)grad = torch.autograd.grad(y, [x], grad_outputs=grad_outputs, create_graph=True)[0]return grad

Для экспериментов используется классическое изображение оператора.

def get_cameraman_tensor(sidelength):img = Image.fromarray(skimage.data.camera())transform = Compose([Resize(sidelength),ToTensor(),Normalize(torch.Tensor([0.5]), torch.Tensor([0.5]))])img = transform(img)return img

Далее просто фитируем это изображение. В процессе аппроксимации мы стремимся параметризовать изображение f(x) в оттенках серого с пиксельными координатами x с помощью функции (x). То есть мы ищем функцию такую, что функционал L = (x) f(x)dx минимизируется. При этом является областью изображения. Используем небольшой датасет, который вычисляет попиксельные координаты:

class ImageFitting(Dataset):def __init__(self, sidelength):super().__init__()img = get_cameraman_tensor(sidelength)self.pixels = img.permute(1, 2, 0).view(-1, 1)self.coords = get_mgrid(sidelength, 2)def __len__(self):return 1def __getitem__(self, idx):if idx > 0: raise IndexErrorreturn self.coords, self.pixels

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

cameraman = ImageFitting(256)dataloader = DataLoader(cameraman, batch_size=1, pin_memory=True, num_workers=0)img_siren = Siren(in_features=2, out_features=1, hidden_features=256,hidden_layers=3, outermost_linear=True)img_siren.cuda()

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

total_steps = 500 # Since the whole image is our dataset, this just means 500 gradient descent steps.steps_til_summary = 10optim = torch.optim.Adam(lr=1e-4, params=img_siren.parameters())model_input, ground_truth = next(iter(dataloader))model_input, ground_truth = model_input.cuda(), ground_truth.cuda()for step in range(total_steps):model_output, coords = img_siren(model_input)loss = ((model_output - ground_truth)**2).mean()if not step % steps_til_summary:print("Step %d, Total loss %0.6f" % (step, loss))img_grad = gradient(model_output, coords)img_laplacian = laplace(model_output, coords)fig, axes = plt.subplots(1,3, figsize=(18,6))axes[0].imshow(model_output.cpu().view(256,256).detach().numpy())axes[1].imshow(img_grad.norm(dim=-1).cpu().view(256,256).detach().numpy())axes[2].imshow(img_laplacian.cpu().view(256,256).detach().numpy())plt.show()optim.zero_grad()loss.backward()optim.step()






Представление аудио


Начнем с небольшого эксперимента.

Будем использовать SIREN для параметризации аудиосигнала, то есть стремимся параметризовать звуковую волну f(t) в моменты времени t с помощью функции . Для этого ищем функцию такую, что: функция потерь L = (t) f(t)dt минимизируется, где является звуковой волной. Для эксперимента будем использовать сонату Баха:

import scipy.io.wavfile as wavfileimport iofrom IPython.display import Audioif not os.path.exists('gt_bach.wav'):!wget https://vsitzmann.github.io/siren/img/audio/gt_bach.wav

Создадим небольшой датасет, который позволяет перевести аудиофайл в более удобный для работы формат:

class AudioFile(torch.utils.data.Dataset):def __init__(self, filename):self.rate, self.data = wavfile.read(filename)self.data = self.data.astype(np.float32)self.timepoints = get_mgrid(len(self.data), 1)def get_num_samples(self):return self.timepoints.shape[0]def __len__(self):return 1def __getitem__(self, idx):amplitude = self.datascale = np.max(np.abs(amplitude))amplitude = (amplitude / scale)amplitude = torch.Tensor(amplitude).view(-1, 1)return self.timepoints, amplitude

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

bach_audio = AudioFile('gt_bach.wav')dataloader = DataLoader(bach_audio, shuffle=True, batch_size=1, pin_memory=True, num_workers=0)# Note that we increase the frequency of the first layer to match the higher frequencies of the# audio signal. Equivalently, we could also increase the range of the input coordinates.audio_siren = Siren(in_features=1, out_features=1, hidden_features=256,hidden_layers=3, first_omega_0=3000, outermost_linear=True)audio_siren.cuda()

Давайте прослушаем исходные данные:

rate, _ = wavfile.read('gt_bach.wav')model_input, ground_truth = next(iter(dataloader))Audio(ground_truth.squeeze().numpy(),rate=rate)

Далее начнем обучение нейронной сети:

total_steps = 1000steps_til_summary = 100optim = torch.optim.Adam(lr=1e-4, params=audio_siren.parameters())model_input, ground_truth = next(iter(dataloader))model_input, ground_truth = model_input.cuda(), ground_truth.cuda()for step in range(total_steps):model_output, coords = audio_siren(model_input)loss = F.mse_loss(model_output, ground_truth)if not step % steps_til_summary:print("Step %d, Total loss %0.6f" % (step, loss))fig, axes = plt.subplots(1,2)axes[0].plot(coords.squeeze().detach().cpu().numpy(),model_output.squeeze().detach().cpu().numpy())axes[1].plot(coords.squeeze().detach().cpu().numpy(),ground_truth.squeeze().detach().cpu().numpy())plt.show()optim.zero_grad()loss.backward()optim.step()





Послушаем, что получается в итоге:

final_model_output, coords = audio_siren(model_input)Audio(final_model_output.cpu().detach().squeeze().numpy(),rate=rate)

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


Представление видео


Использование SIREN совместно на координатах пикселей и времени позволяет параметризовать видео. В данном случае SIREN непосредственно активируется на истинных значениях пикселей и позволяет параметризовать видео существенно лучше, чем ReLU Multi Layer Perceptron.


Решение уравнения Пуассона


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



Представление фигур путем решения уравнения Эйконала Interactive 3D SDF Viewer используйте мышь для навигации по сценам


Решая краевую задачу в форме уравнений Эйконала, мы можем восстановить SDF из облака точек и нормалей поверхности. Подход SIREN позволяет восстановить сцену масштаба комнаты на основе только облака точек и нормалей поверхности, при этом удается точно воспроизвести мелкие детали, а для обучения требуется менее одного часа. В отличие от недавних работ по объединению воксельных сеток с нейронными неявными представлениями, в предлагаемом подходе полное представление хранится в весах одной пятислойной нейронной сети, без 2D или 3D-сверток, и поэтому требует гораздо меньшего количества параметров. Важно обратить внимание на то, что полученные SDF не обучаются на исходных значениях SDF, а скорее являются результатом решения вышеупомянутой эйкональной краевой задачи. Такая постановка задачи является существенно более сложной и требует обучения с учителем по градиентам (детали в статье). В результате архитектуры сетей, градиенты которых хуже контролируются, показывают качество ниже, чем в подходе SIREN.



Решение уравнения Гельмгольца


В данном случае авторы используют подход SIREN для решения неоднородного уравнения Гельмгольца. Архитектуры на основе ReLU и Tanh не позволяют полностью решить эту задачу.


Решение волнового уравнения


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


* * *


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

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

Рекомендации Друзей ВКонтакте ML на эго-графах

13.04.2021 14:10:30 | Автор: admin

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

Меня зовут Женя Замятин, я работаю в команде Core ML ВКонтакте. Хочу рассказать, как устроены рекомендации, которые делают ближе пользователей самой крупной социальной сети рунета.

Обзор

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

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

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

Ещё один важный метод рекомендаций Adamic/Adar. В его основе лежит всё тот же анализ общих друзей, но с модификацией: авторы предлагают учитывать число друзей у общего друга. Чем больше это значение, тем меньше информации о релевантности он несёт.

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

EGOML

Общая схема нашего метода продолжает идеи числа общих друзей и Adamic/Adar. Финальная мера релевантности E(u, v), с помощью которой мы будем отбирать кандидатов, всё так же раскладывается в сумму по общим друзьям u и v. Ключевое отличие в форме слагаемого под суммой: в нашем случае это мера ez_c(u, v).

Сначала попробуем понять физический смысл меры ez_c(u, v). Представим, что мы взяли пользователя c и спросили у него: Насколько вероятно, что два твоих друга, u и v, подружатся? Чем больше информации для оценки он учтёт, тем точнее будет его предсказание. Например, если c сможет вспомнить только число своих друзей, его рассуждения могут выглядеть следующим образом: Чем больше у меня друзей, тем менее вероятно, что случайные двое из них знакомы. Тогда оценка вероятность дружбы u и v (с точки зрения c) может выглядеть как 1/log(n), где n число друзей. Именно так устроен Adamic/Adar. Но что если c возьмёт больше контекста?

Прежде чем отвечать на этот вопрос, разберёмся, почему ez_c(u, v) важно определять через пользователя c. Дело в том, что в таком виде очень удобно решать задачу распределённо. Представим, что теперь мы разослали всем пользователям платформы анкету с просьбой оценить вероятность дружбы в каждой паре их друзей. Получив все ответы, мы можем подставить значения в формулу E(u, v). Именно так выглядит вычисление E(u, v) с помощью MapReduce:

  • Подготовка. Для каждого c выделяется тот контекст, который он будет учитывать для вынесения оценок. Например, в Adamic/Adar это будет просто список друзей.

  • Map. Спрашиваем у каждого c, что он думает про возможность дружбы в каждой паре его друзей. По сути, вычисляем ez_c(u, v) и сохраняем в виде (u, v) ez_c(u, v) для всех u, v in N(c). В случае Adamic/Adar: (u, v) 1/log|N(c)|.

  • Reduce. Для каждой пары (u, v) суммируем все соответствующие ей значения. Их будет ровно столько, сколько общих друзей у u и v.

Таким образом мы получаем все ненулевые значения E(u, v). Заметим: необходимое условие того, что E(u, v) > 0, существование хотя бы одного общего друга у u и v.

Эго-граф ХоппераЭго-граф Хоппера

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

Ключевая идея меры ez_c в том, что её можно сделать обучаемой. Для каждого пользователя c, его эго-графа и всех пар пользователей u, v внутри него мы можем посчитать много разных признаков, например:

  • число общих друзей u и v внутри эго-графа c;

  • число общих друзей u и c;

  • интенсивность взаимодействий между v и c;

  • время, прошедшее с последней дружбы между u и кем-либо из эго-графа c;

  • плотность эго-графа c;

  • и другие.

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

В конечном счёте мы получаем датасет следующего вида:

  • для каждой пары пользователей u и v, а также их общего друга c, посчитаны признаки по эго-графу c;

  • пара пользователей u и v встречается в датасете ровно столько раз, сколько у них общих друзей;

  • все пары пользователей в датасете не являются друзьями на момент времени T;

  • для каждой пары u и v проставлена метка подружились ли они в течение определённого промежутка времени начиная с T.

По такому датасету мы и будем обучать нашу меру ez_c. В качестве модели выбрали градиентный бустинг с pairwise функцией потерь, где идентификатором группы выступает пользователь u.
По сути, мера ez_c(u, v) определяется как предсказание описанной выше модели. Но есть один нюанс: при pairwise-обучении распределение предсказаний модели похоже на нормальное. Поэтому, если в качестве определения меры ez_c(u, v) взять сырое предсказание, может возникнуть ситуация, когда мы будем штрафовать финальную меру E(u, v) за общих друзей, так как значения предсказаний бывают отрицательными. Это выглядит не совсем логично хочется, чтобы с ростом числа общих друзей мера E(u, v) не убывала. Так что поверх предсказания модели мы решили взять экспоненту:

Такой подход хорошо себя показывает на небольших графах. Но чтобы применить его на реальных данных, необходимо выполнить ещё одно действие. Суть проблемы такая: мы не можем вычислять признаки и применять модель для каждой пары пользователей всех эго-графов это слишком долго. Для решения мы придумали специальный трюк. Представим, что наш градиентный бустинг обучился таким образом, что каждое дерево использует признаки только одного пользователя: либо u, либо v. Тогда мы могли бы разделить весь ансамбль на две группы: к группе A мы бы отнесли деревья, которые используют только признаки пользователя u, к B пользователя v. Предсказание такой модели можно представить в виде:

Имея такую модель, мы могли бы получить предсказания для всех пар пользователей одного эго-графа быстрее. Достаточно применить модели A и B для каждого пользователя, а затем сложить соответствующие парам предсказания. Таким образом, для эго-графа из n вершин мы могли бы сократить число применений модели с O(n^2) до O(n). Но как получить такую модель, каждое дерево которой зависит только от одного пользователя? Для этого сделаем следующее:

  1. Исключим из датасета все признаки, которые одновременно зависят и от u и от v. Например, от признака число общих друзей u и v внутри эго-графа c придётся отказаться.

  2. Обучим модель A, используя только признаки на базе u, c и эго-графа c.

  3. Для обучения модели B оставим только признаки на базе v, c и эго-графа c. Также в качестве базовых предсказаний передадим предсказания модели A.

Если объединим модели A и B, получим то что нужно: первая часть использует признаки u, вторая признаки v. Совокупность моделей осмысленна, поскольку B была обучена корректировать предсказания A. Эта оптимизация позволяет ускорить вычисления в сотни раз и делает подход применимым на практике. Финальный вид ez_c(u, v) и E(u, v) выглядит так:

Вычисление меры E в онлайне

Заметим, что E(u, v) можно представить в виде:

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

При построении рекомендаций мы уже вычислили предсказания моделей для всех существующих дружб. Поэтому для каждого пользователя мы можем собрать векторы и сложить их в доступное онлайн key-value хранилище. После этого сможем получать значение E(u, v) для любой пары пользователей в онлайне простой операцией перемножения векторов. Это даёт возможность использовать E(u, v) как лёгкую функцию релевантности в нагруженных местах либо как дополнительный признак финальной модели ранжирования.

Итог

В результате система EGOML позволяет:

  1. Распределённо отбирать кандидатов для каждого пользователя в офлайне. Асимптотическая сложность оптимизированного алгоритма составляет O(|E|) вычислений признаков и применений модели, где |E| число связей в графе. На кластере из 250 воркеров время работы алгоритма составляет около двух часов.

  2. Быстро вычислять меру релевантности E(u, v) для любой пары пользователей в онлайне. Асимптотическая сложность операции O(|N(u)| + |N(v)|).

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

В конечном счёте мы перешли со способа отбора кандидатов с использованием Adamic/Adar к системе EGOML и внедрили в модель второй уровень признаков на основе меры E(u, v). И это позволило увеличить количество подтверждённых дружб со всей платформы на несколько десятков процентов.

Благодарность

Хочу сказать спасибо руководителю команды Core ML Андрею Якушеву за помощь в разработке метода и подготовке статьи, а также всей команде Core ML за поддержку на разных этапах этой работы.

Подробнее..

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

16.04.2021 18:11:03 | Автор: admin

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


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

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

Большинство популярных библиотек глубокого обучения, например PyTorch и Keras, имеют множество встроенных оптимизаторов, базирующихся на использовании алгоритма градиентного спуска, например SGD, Adadelta, Adagrad, RMSProp, Adam и пр.

Но почему алгоритмов оптимизации так много? Как выбрать из них правильный?

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

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

Обзор методов оптимизации на базе алгоритма градиентного спуска

Кривая потерь

Начнём с того, что рассмотрим на 3D-изображении, как работает стандартный алгоритм градиентного спуска.

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

На рисунке показана сеть с двумя весовыми параметрами:

  • На горизонтальной плоскости размещаются две оси для весов w1 и w2, соответственно.

  • На вертикальной оси откладываются значения потерь для каждого сочетания весов.

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

Синяя линия соответствует траектории алгоритма градиентного спуска при оптимизации:

  • Работа алгоритма начинается с выбора некоторых случайных значений обоих весов и вычисления значения потери.

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

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

Вычисление градиента

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

Обновление параметра градиентного спускаОбновление параметра градиентного спуска

Градиент измеряет уклон и рассчитывается как значение изменения в вертикальном направлении (dL), поделённое на значение изменения горизонтальном направлении (dW). Другими словами, для крутых уклонов значение градиента большое, для пологих маленькое.

Вычисление градиентаВычисление градиента

Практическое применение алгоритма градиентного спуска

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

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

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

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

  • Ландшафт круто уходит вниз в одном направлении, но, чтобы попасть в самую нижнюю точку, нужно двигаться в направлении с меньшими изменениями высоты?

  • Весь ландшафт представляется алгоритму плоским во всех направлениях?

  • Алгоритм попадает в глубокую канаву? Как ему оттуда выбраться?

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

Трудности при оптимизации градиентного спуска

Локальные минимумы

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

Локальный минимум и глобальный минимумЛокальный минимум и глобальный минимум

Седловые точки

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

Седловая точкаСедловая точка

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

Алгоритм градиентного спуска при этом ошибочно полагает, что минимум им найден.

Овраги

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

ОврагиОвраги

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

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

Первое улучшение алгоритма градиентного спуска стохастический градиентный спуск (SGD)

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

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

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

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

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

Второе усовершенствование алгоритма градиентного спуска накопление импульса (Momentum)

Динамическая корректировка количества обновлений

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

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

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

  • Скорректировать градиент.

  • Скорректировать значение скорости обучения.

SGD с функцией накопления импульса и обычный SGD

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

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

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

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

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

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

Переходы через овраги с помощью функции накопления импульса

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

Функция накопления импульса помогает преодолевать оврагиФункция накопления импульса помогает преодолевать овраги

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

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

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

Вот некоторые примеры алгоритмов оптимизации, использующих функцию накопления импульса в разных формулах:

  • SGD с накоплением импульса

  • Ускоренный градиент Нестерова

Третье усовершенствование алгоритма градиентного спуска изменение скорости обучения (на базе значения градиента)

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

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

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

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

Данная функциональность реализована в нескольких алгоритмах оптимизации, использующих разные, но похожие методы, например Adagrad, Adadelta, RMS Prop.

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

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

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

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

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

Четвёртое усовершенствование алгоритма градиентного спуска изменение скорости обучения (на базе тренировочной выборки)

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

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

Заключение

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

Узнайте, как прокачаться и в других специальностях или освоить их с нуля:

Другие профессии и курсы
Подробнее..

HMM ловим мошеннические транзакции

09.04.2021 14:13:02 | Автор: admin

Три года я проработал в Сербии iOS-евангелистом - было два профильный проекта и один Machine Learning-овый.

Если вам стало интересно - добро пожаловать в мир HMM.

Постановка задачи

Австрийский банк. У него много клиентов, у клиентов открыт счет в этом банке. В течении года клиент тратит средства со своего счета. Ходит в магазины, гасит коммунальные платежи и пр. Каждое списание денег со счета назовем транзакцией. Дана последовательность транзакций за определенное время (скажем год). Надо обучить машину, чтобы она начала проверять новые транзакции как достоверные или подозрительные. И выдавала предупреждение в последнем случае. Для решения задачи надо использовать Hidden Markov Model.

Введение в HMM

Я болею коронавирусом каждый год 10 дней подряд. Остальные дни здоров, как бык.

Представим эту последовательность из 365 символов в виде массива. h означает здоров, l - болен.

days{365} = {hhhhhhhhhhllllllllllhhhhhhhhhhhhhhhhhhhhhhhh...hhhhh}

Вопрос - Какова вероятность, что я сегодня болен?

\frac{10}{365}= 3 процента

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

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

Вы резонно уточните: -А сегодня я болен или здоров?

Если болен (смотрите на последовательность - таких больных дней всего 10), то с вероятностью \frac{9}{10} = 90 процентов завтра я продолжу болеть и с вероятностью 10 процентов стану здоров.

А если я сегодня здоров? - то с вероятностью

\frac{1}{355}= 0.3 процента я завтра заболею и с вероятностью 99.7% буду здоров.

Если вы сегодня больны, то с вероятностью 10% завтра вы будете здоровы и 90% продолжите болеть.

Получили 4 числа, которые красиво вписываются в матрицу 2 на 2 - вуаля! эта матрица и есть Марковский слой. Уберем проценты, оставим чистые вероятности в диапазоне от 0 до 1, как того требует наука.

здоров

болен

здоров

0.997

0.003

болен

0.10

0.90

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

Формализуем транзакции

Чем отличается последовательность транзакций от череды болен/здоров? Ничем.

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

27.10.2020 00:00 GAZPROMNEFT AZS 219    2507,43 118 753,95 28.10.2020 / 298380 Автомобиль 26.10.2020 14:45 SPAR 77                319,73 121 261,38 27.10.2020 / 220146 Супермаркеты 26.10.2020 14:38 ATM 60006475           4800,00 121 581,11 26.10.2020 / 213074 Выдача наличных 25.10.2020 17:52 EUROSPAR 18            970,02 126 381,11 26.10.2020 / 259110 Супермаркеты 25.10.2020 00:00 Tinkoff Card2Card      20000,00 127 351,13 26.10.2020 / 253237 Перевод с карты 22.10.2020 14:22 SBOL перевод 4276      7000,00 147 351,13 22.10.2020 / 276951 Перевод с карты 22.10.2020 12:18 STOLOVAYA              185,00 154 351,13 23.10.2020 / 279502 Рестораны и кафе 21.10.2020 16:46 MEGAFON R9290499831    500,00 154 536,13 21.10.2020 / 224592 Комунальные платежи, связь, интернет. 21.10.2020 14:17 SPAR 77                987,03 155 036,13 22.10.2020 / 219015 Супермаркеты 21.10.2020 13:42 PYATEROCHKA 646        289,93 156 023,16 22.10.2020 / 294539 Супермаркеты 21.10.2020 00:00 MEBEL                  75,00 156 313,09 22.10.2020 / 279935 Прочие расходы 19.10.2020 14:54 SPAR 77                552,92 132 044,80 20.10.2020 / 208987 Супермаркеты 19.10.2020 00:00 MOBILE FEE             60,00 132 597,72 20.10.2020 / - Прочие операции 16.10.2020 14:19 SPAR 77                579,39 132 657,72 17.10.2020 / 229627 Супермаркеты 12.10.2020 13:33 STOLOVAYA              185,00 133 237,11 13.10.2020 / 261374 Рестораны и кафе 12.10.2020 00:00 OOO MASTERHOST         1000,00 133 422,11 13.10.2020 / 268065 Прочие расходы 11.10.2020 12:09 SPAR 77                782,87 134 422,11 12.10.2020 / 275816 Супермаркеты 10.10.2020 14:52 SBOL перевод           400,00 135 204,98 10.10.2020 / 276925 Перевод с карты 09.10.2020 13:29 SBOL перевод 5484*     1000,00 135 604,98 09.10.2020 / 229184 Перевод с карты 09.10.2020 11:55 MAGNIT MK KRYUCHYA     274,00 136 604,98 10.10.2020 / 209914 Супермаркеты

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

def readtrans():    with open ("assets/trans.txt", "r") as file:        grades = file.read()    pattern = '(\d{2,5}),\d\d'    result = re.findall(pattern, grades)    r = list(map(int, result[0::2]))    return rdata = readtrans()t = list(range(len(data)))df = pd.DataFrame({'number':t, 'amount':data})ax1 = df.plot.bar(x='number', y='amount', rot=0, width=1.5)

Упростим картину - дешевые транзакции (менее 10$) обозначим буквой l, дорогие свыше 100$ буквой h, остальные - буквой m.

Наша последовательность стала выглядеть подозрительно знакомо

print(observations[:20])trans[] = ['m', 'm', 'm', 'l', 'm', 'm', 'h', 'm', 'l', 'l', 'm', 'l', 'l', 'l', 'l', 'l', 'l', 'm', 'l', 'l']

Теперь напишем Марковский слой для транзакций. Это будет матрица 3 на 3, поскольку у нас 3 возможных типа транзакций = {l,m,h}

[[0.5 0.3 0.2] [0.6 0.3 0.1] [0.7 0.3 0.0]]

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

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

-Так просто?! - воскликнет читатель. Да, но за построение такой простой модели банк много денег не заплатит. Надо ввести еще один Марковский слой (невидимый), и алгоритм сразу станет красивее, сложнее и наукоёмчее. И потянет на кандидатскую диссертацию.

Скрытый Марковский слой

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

То есть существует набор периодических однотипных событий, число которых мы не знаем и Марковский слой для которых невозможно построить. Как построишь, если ничего не знаешь конкретно?! Вот именно. Но мы знаем, что эти события происходят и их примерно 4-6 штук. Поход в магазин. Столовая. Еще что-то. И так далее. И что мы точно знаем, что после похода в столовую мы никогда не опустошаем свой кошелек на сумму более 300 рублей.

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

[[a1 a2 a3 a4 a5] [b1 b2 b3 b4 b5] [c1 c2 c3 c4 c5] [x1 x2 x3 x4 x5] [y1 y2 y3 y4 y5]]

Именно 20, а не 25 (отвечать будет Ягуар). Это точно такой же Марковский слой, что мы строили раньше, но основанный на 5 событиях.

И чтобы связать два слоя (видимый с платежами и невидимый с событиями) мы заведем матрицу перехода размера 5 на 3.

В чем смысл матрицы перехода? В том, что после невидимого события a (поход в столовую)

у нас произойдет с разной степенью вероятности либо l-платеж, либо m-платеж, либо h-платеж. Скорее всего после похода в столовую эта строка будет такая

[0.96 0.04 0.0]

Что означает невозможность потратить более 100 долларов в нашей технопарковской столовой. Даже с приглашенной девушкой.

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

И мы можем найти эти 20+10 неизвестных величин, потому что у нас есть история платежей!

Это прекрасно и это называется обучить систему!

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

Обучение

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

Процесс сходимости хорошо виден на графике.

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

Питон против Сишарпа

Работодатель обязал меня использовать библиотек Accord и язык C#

using Accord.MachineLearning;using Accord.Statistics.Models.Markov;using Accord.Statistics.Models.Markov.Learning;using Accord.Statistics.Models.Markov.Topology;using Comtrade.FMS.Common;

Согласно контракту я не могу разглашать код, поэтому написал аналог на Питоне (я не знаю оба языка) и частично смог повторить результат. Но по скорости обучения Питон сильно проигрывает Си-шарпу. Правда, я run-ил программу на разного класса компьютерах)) В Словении это был сервер работодателя. Питон для Хабра пыхтел на 2010 года макбуке.

Приведу одну строку кода, в которой зашифрован метод обучения.

var teacher = new BaumWelchLearning(hmm)

Детали метода Баум-Уэлша вы поймете, прочитав соответствующую литературу и настроив свои мозги на стат. процессы.

Успехов и хорошей карьеры в банковских IT структурах!

Подробнее..

Перевод Преобразуем графику Fortnite в PUBG новым более быстрым подходом

09.04.2021 20:23:06 | Автор: admin

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

К счастью, по прошествии большого количества времени у нас наконец-то есть статья, демонстрирующая значительный прогресс в попытке уменьшить вычислительную мощность, необходимую для обучения этого ИИ. Статья от Калифорнийского университета в Беркли и Adobe называется Contrastive Learning (контрастное обучение) для непарного преобразования изображений (CUT).

Графика Fortnite преобразована в PUBG с помощью CUT.Графика Fortnite преобразована в PUBG с помощью CUT.

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

CycleGAN и Patchwise Contrastive Framework.

Наблюдается существенная разница в количестве требуемых вычислительных мощностей по сравнению с CycleGAN. Итак, чем отличается этот подход от CycleGAN? Теперь он использует фреймворк Patchwise Contrastive Learning, который требует значительно меньше графической памяти и вычислений по сравнению с CycleGAN.

Сети CycleGANСети CycleGAN

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

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

Сравнение с CycleGAN

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

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

Полезные ссылки

  1. Полный текст статьи (PDF)

  2. Страница проекта

  3. Код (GitHub)

Спасибо за внимание. Если вам понравилась эта статья, вы можете следить за другими моими работами на Medium, GitHub или подписаться на мой YouTube-канал.


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

- УЗНАТЬ О КУРСЕ ПОДРОБНЕЕ

-

ЗАПИСАТЬСЯ НА ДЕМО-УРОК

Подробнее..

Бесплатный вебинар Основы ИИ

07.04.2021 10:06:45 | Автор: admin
13 апреля 2021, на русском с субтитрами на русском.13 апреля 2021, на русском с субтитрами на русском.

Откройте для себя решения, которые можно создавать с помощью ИИ, и сервисы Azure, помогающие в разработке этих решений. Присоединяйтесь к нам на бесплатном мероприятии Microsoft Azure Virtual Training Day: основы ИИ, чтобы получить общее представление о том, что такое ИИ, и узнать, как начать работу с ИИ в Azure.

Подробности и регистрация

Посетите виртуальное обучающее мероприятие, чтобы:

  • Изучить основные концепции и области применения ИИ.

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

  • Подробнее узнать о разговорном ИИ, обработке естественного языка и компьютерном зрении в Microsoft Azure.

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

Вот, что мы вам предлагаем:

  • Введение

  • Введение в ИИ

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

  • Перерыв 10минут

  • Компьютерное зрение

  • Перерыв 10минут

  • Обработка естественного языка

  • Виртуальный собеседник

  • Завершающий сеанс вопросов и ответов

Подробности и регистрация

Подробнее..

Маркетинговая оптимизация в банке

14.04.2021 10:21:24 | Автор: admin
image
Привет, Хабр.

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

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

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


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

Существует много открытых фреймворков для решения оптимизационных задач таких как Gekko, Pyomo, Python-mip, а так же различное проприетарное ПО типа IBM ILOG CPLEX Optimization Studio.

План статьи




Задача оптимизации


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

$$display$$\begin{aligned} {\large f(\vec{x}) \rightarrow \underset{\vec{x} \in X}{\min} },\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\; \\ X = \left\{\vec{x} \; | \; g_{i}(\vec{x}) \leq 0, \; h_{k}(\vec{x}) = 0, \;\\ i = 1, \ldots, m, \;k=1\ldots,p \right\} \subset R^n.\end{aligned} \;\;\; (1)$$display$$


Т.е. среди всех векторов множества $X$, которое ограничено условиями $g_{i}(\vec{x}) \leq 0$ и $h_{k}(\vec{x}) = 0,$ необходимо найти такой вектор $\vec x^* $, при котором значение $f(\vec{x}^*)$ будет минимальным на всем множестве $X$.
При линейных ограничениях и линейной целевой функции задача (1) относится к классу задач линейного программирования и может быть решена симплекс-методом.

Маркетинговая оптимизация в банке


Представим себе современный банк, работающий с физическими лицами и продающий им свои основные продукты: кредитные карты, кредиты наличными и т.д. Каждому клиенту банк может предложить один из продуктов $P_i, \; i = 1, \ldots, n$ в одном из доступных для коммуникации каналов $C_{k}, \; k = 1, \ldots, m$ (звонок, смс и т.д.). При этом количество доступных для отправки в неделю/месяц коммуникаций в каждом канале (объем канала) ограничено

$\begin{aligned} &\sum Calls \leq N_1 \\ &\sum Sms \leq N_2 \\ &\sum Email \leq N_3 \\ &\sum Push \leq N_4 \\ \end{aligned} \;\;\;(2)$


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

image

Рис. 1

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

image


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

$\begin{cases} p_{11}x_{11} + p_{12}x_{12} + p_{13}x_{13} + p_{21}x_{21} + p_{22}x_{22} + p_{31}x_{31} + p_{32}x_{32} + p_{33}x_{33} \rightarrow \max \\\\ Одному \;клиенту\; не\; более \; одного\; продукта \\ x_{11} + x_{12} + x_{13} \leq 1 \\ x_{21} + x_{22} \leq 1 \\ x_{31} + x_{32} + x_{33} \leq 1 \\ \\ Ограничение \; количества \; звонков \\ x_{12} + x_{21} + x_{31} \leq N_1 \\ \\ Ограничение \; количества \; смс \\ x_{13} + x_{22} + x_{33} \leq N_2 \\\\ Ограничение \; количества \; имейлов\\ x_{11} + x_{32} \leq N_3 \\ \\ x_{ik} \in \left\{0, 1 \right\} \end{cases} \;\;\; (3)$


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

В случае, если целью коммуникаций будет максимизация будущей доходности, то целевую функцию в задаче (3) можно записать в виде

$\begin{aligned}D_{11}p_{11}x_{11} + D_{12}p_{12}x_{12} + D_{13}p_{13}x_{13} &+D_{23}p_{21}x_{21} + D_{22}p_{22}x_{22} +\\+ D_{34}p_{31}x_{31} + D_{32}p_{32}x_{32} + &D_{32}p_{33}x_{33} \rightarrow \max,\end{aligned}\;\;\; (4)$


где $D_{ik}$ доходность от k-го продукта на i-м клиенте. Значения $D_{ik}$ могут быть получены с помощью прогнозных моделей или оценены каким-то другим способом.

Замечания
  1. Описанные выше подходы предполагают, что мы имеем достаточно хорошие прогнозы/оценки для $p_{ik}$ и $D_{ik}.$
  2. Если скоры $p_{ik}$ для различных продуктов получены от разных моделей и при этом они (скоры) плохо согласуются с реальной вероятностью отклика (это можно увидеть, например, по графику как на Рис. 1), то перед оптимизацией их необходимо откалибровать. Про различные способы калибровки можно почитать по ссылке.
  3. Предполагается также, что количество коммуникаций, на которые банк готов потратить средства, меньше, чем количество клиентов, которым банк готов предложить свои продукты. В противном случае оптимизировать будет нечего.


Немного кода


Попробуем решить задачу маркетинговой оптимизации, поставленную в виде (3) с помощью библиотеки MIP, упомянутой выше. Возьмем случайным образом сгенерированный датасет объемом в 6000 строк, в котором содержится 1000 клиентов, каждому из которых можно предложить один из 3-х продуктов в двух каналах SMS и звонок.

Код
import pandas as pdfrom mip import Model, MAXIMIZE, CBC, BINARY, OptimizationStatusframe = pd.read_csv('table_for_optimization.csv')frame.head()


image

Предположим, что у нас есть ограничение на объем коммуникаций: 500 SMS и 200 звонков. Напишем функцию для решения задачи оптимизации.

Код
def optimize(frame: pd.DataFrame, channel_limits: dict) -> list:    """    Возвращает массив оптимальных предложений    """        df = frame.copy()        #создание модели    model = Model(sense=MAXIMIZE, solver_name=CBC)    #вектор бинарных переменных задачи    x = [model.add_var(var_type=BINARY) for i in range(df.shape[0])]    df['x'] = x    #целевая функция    model.objective = sum(df.score * df.x)    #ограничения на количество коммуникаций в каждом канале    for channel in df.channel.unique():        model += (sum(df[df.channel==channel]['x']) <= channel_limits[channel])    #ограничения на количество продуктов для каждого клиента    for client in df.client_id.unique():        model += (sum(df[df['client_id']==client]['x']) <= 1)            status = model.optimize(max_seconds=300)        del df        if status == OptimizationStatus.OPTIMAL or status == OptimizationStatus.FEASIBLE:        return [var.x for var in model.vars]    elif status == OptimizationStatus.NO_SOLUTION_FOUND:        print('No feasible solution found')


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

Код
#объем доступных коммуникаций в каналахCHANNELS_LIMITS = {    'call': 200,    'sms': 500}optimal_decisions = optimize(frame=frame, channel_limits=CHANNELS_LIMITS)frame['optimal_decision'] = optimal_decisions#распределение продуктов в каналахframe[frame['optimal_decision']==1].groupby(['channel', 'product']).\                                    agg({'client_id': 'count'}).\                                    rename(columns={'client_id': 'client_cnt'})


image

Весь код и данные доступны по ссылке.

P.S.


В зависимости от типа прогнозных моделей мы можем располагать не просто средней оценкой вероятности отклика $p_{ik},$ а также иметь распределение этого значения для каждого клиента и продукта. В таком случае задача оптимизации (3) может быть дополнена условием

$\sum (отклик \;с \;вероятностью \geq K ) \geq N. \;\;\; (5)$


Более того, если в нашем распоряжении есть распределение для каждой вероятности $p_{ik}$, то мы можем также решать и обратную задачу: минимизировать количество коммуникаций при условях типа (5) с учетом определенных ограничений, задаваемых бизнесом.

Благодарю коллег из команды GlowByte Advanced Analytics за помощь и консультации при подготовке этой статьи.
Подробнее..

Перевод Как магия машинного обученияменяет нашу жизнь

05.04.2021 16:10:13 | Автор: admin

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

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

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

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

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

Обычно я советую обратиться к таким ресурсам, как курс компании Google под названиемMachine Learning Crash Course, а также книгаПрикладное машинное обучение с помощью Scikit-Learn, Keras и TensorFlowи курс на сайте CourseraМашинное обучение(автор: Andrew Ng), который нацелен не только на теоретические основы, но и на практику.

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

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

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

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

Умный архив семейных видео

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

  • Вы узнаете:

    • как применять машинное обучение в сортировке и поиске сложных типов данных;

    • как использовать Video Intelligence API;

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

Бот-модератор в Discord

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

  • Вы узнаете:

    • как использоватьPerspective APIдля анализа текста;

    • как применять машинное обучение в приложениях для чата;

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

  • Вы создадите: блокнот Jupyter, который отслеживает подачу и траекторию теннисного мяча (может также пригодиться в гольфе и баскетболе), а также анализирует данные, чтобы дать полезные советы. Для этого перейдите вQwiklabs.

  • Вы узнаете:

    • как выполнять сложное машинное обучение с помощью небольших наборов данных;

    • как комбинировать простые математические вычисления с распознаванием поз для понимания движений человека;

    • как использовать Video Intelligence API;

    • как работать c AutoML Vision.

Умный игровой мир с технологией обработки естественного языка

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

  • Вы создадите:

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

  • Вы узнаете:

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

    • как реализовывать семантический поиск текста;

    • как разделять текст на кластеры;

    • как добавлять простые чат-боты;

    • как выполнять эти действия в Google Таблице.

Преобразование PDF-документа в аудиокнигу

  • Вы создадите: код, который преобразует PDF-файлы в аудиокниги формата MP3.

  • Вы узнаете:

    • как извлекать текст из PDF-файлов при помощи Vision API;

    • как озвучивать текст при помощи Text-to-Speech API;

    • как использовать математические вычисления для разделения макетов документа.

Перевод и озвучивание видео с помощью машинного обучения

  • Вы создадите: код, который автоматически преобразовывает речь из видео в текст, а затем переводит и озвучивает его.

  • Вы узнаете:

    • как совмещать технологии распознавания, перевода и синтеза речи;

    • как улучшать качество перевода и преобразования речи в текст;

    • как работать с видео и аудио на языке Python.

Создание рецептов выпечки с помощью ИИ

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

  • Вы узнаете:

    • как создавать модели машинного обучения в AutoML Tables с помощью табличных данных без написания кода;

    • как определять причину решений модели с помощью функций.

Создание модели машинного обучения в браузере без написания кода

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

  • Вы узнаете:

    • что нужно, чтобы создать простую модель машинного обучения без написания кода;

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

Создание образов с помощью ИИ

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

  • Вы узнаете:

    • как использовать Product Search и Vision API;

    • как проектировать приложения на основе машинного обучения с помощью React и Firebase.

Подробнее..

Перевод Обзор статьи AdderNet Действительно ли нам нужно умножение в глубоком обучении? (Классификация изображений)

08.04.2021 14:12:31 | Автор: admin

Использование сложения вместо умножения для свертки результирует в меньшей задержке, чем у стандартной CNN

Свертка AdderNet с использованием сложения, без умноженияСвертка AdderNet с использованием сложения, без умножения

Вашему вниманию представлен обзор статьи AdderNet: действительно ли нам нужно умножение в глубоком обучении?, (AdderNet), Пекинского университета, Huawei Noah's Ark Lab и Сиднейского университета.

Действительно ли нам нужно умножение в глубоком обучении?

Структура статьи

  1. Свертка AdderNet

  2. Прочие моменты: BN, производные, скорость обучения

  3. Результаты экспериментов

1. Свертка AdderNet

1.1. Обобщенные фильтры

  • Как правило, выходной признак Y указывает на сходство между фильтром и входным элементом:

  • где S - мера сходства.

1.2. Стандартная свертка с использованием умножения

Стандартная свертка с использованием умноженияСтандартная свертка с использованием умножения
  • Если в качестве меры стандартного отклонения принимается взаимная корреляция, то используется умножение. Так мы получаем свертку.

1.3. Свертка AdderNet с использованием сложения

Свертка AdderNet с использованием сложения, без умноженияСвертка AdderNet с использованием сложения, без умножения
  • Если используется сложение, то вычисляется l1-мера стандартного отклонения между фильтром и входным признаком:

  • с помощью l1-меры стандартного отклонения можно эффективно вычислить сходство между фильтрами и признаками.

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

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

2. Прочие моменты: BN, производные, скорость обучения

2.1. Пакетная нормализация (Batch Normalization - BN)

  • После сложения, используется пакетная нормализация (BN) для нормализации Y к соответствующему диапазону, чтобы все функции активации, используемые в обычных CNN, после этого могли использоваться в предлагаемых AdderNets.

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

  • (Появятся ли в будущем какие-нибудь BN, использующие сложение?)

2.2. Производные

  • Производная l1-меры не подходит для градиентного спуска. Таким образом, мы рассматриваем производную l2-меры:

  • Использование точного градиента позволяет точно обновлять фильтры.

  • Чтобы избежать взрыва градиента, градиент X обрезается до [-1,1].

  • Затем вычисляется частная производная выходных признаков Y по отношению к входным характеристикам X как:

  • где HT - функция HardTanh:

2.3. Скорость адаптивного обучения

l2-меры градиентов в LeNet-5-BNl2-меры градиентов в LeNet-5-BN
  • Как показано в этой таблице, меры градиентов фильтров в AdderNets намного меньше, чем в CNN, что может замедлить обновление фильтров в AdderNets.

  • В AdderNets используется адаптивная скорость обучения для разных уровней:

  • где - глобальная скорость обучения всей нейронной сети (например, для сумматора и BN слоев), L(Fl) - градиент фильтра в слое l, а l - соответствующая локальная скорость обучения.

  • Таким образом, локальная скорость обучения может быть определена как

  • где k обозначает количество элементов в Fl, а - гиперпараметр для управления скоростью обучения фильтров сумматора.

3. Результаты экспериментов

3.1. MNIST

  • CNN достигает точности 99,4% при 435K умножений и 435K сложений.

  • Заменяя умножения в свертке на сложения, предлагаемая AdderNet достигает точности 99,4%, такой же показатель как у CNN, с 870K сложениями и почти без умножений.

  • Теоретическая задержка умножения в ЦП также больше, чем задержка сложения и вычитания.

  • Например, на модели VIA Nano 2000 задержка умножения и сложения с плавающей запятой составляет 4 и 2 соответственно. AdderNet с моделью LeNet-5 будет иметь задержку 1.7M, в то время как CNN будет иметь задержку 2.6M на том же CPU.

3.2. CIFAR

Результаты классификации на наборах данных CIFAR-10 и CIFAR-100Результаты классификации на наборах данных CIFAR-10 и CIFAR-100BNN: свертка XNORNet, использующая логической операции XNORBNN: свертка XNORNet, использующая логической операции XNOR
  • Двоичные нейронные сети (Binary neural networks - BNN): могут использовать операции XNOR для замены умножения, что мы также используем для сравнения.

  • Для модели VGG-small, AdderNets без умножения достигает почти таких же результатов (93,72% в CIFAR-10 и 72,64% в CIFAR-100) как и CNNs (93,80% в CIFAR-10 и 72,73% в CIFAR-100).

  • Хотя размер модели BNN намного меньше, чем у AdderNet и CNN, ее точность намного ниже (89,80% в CIFAR-10 и 65,41% в CIFAR-100).

  • Что касается ResNet-20, CNN достигают наивысшей точности (т.е. 92,25% в CIFAR-10 и 68,14% в CIFAR-100), но с большим числом умножений (41,17M).

  • Предлагаемые AdderNets достигают точности 91,84% в CIFAR-10 и 67,60% точности в CIFAR-100 без умножения, что сравнимо с CNN.

  • Напротив, BNN достигают точности только 84,87% и 54,14% в CIFAR-10 и CIFAR-100.

  • Результаты ResNet-32 также предполагают, что предлагаемые AdderNets могут достигать результатов аналогичных обычным CNN.

3.3. ImageNet

Классификация результатов на наборах данных ImageNetКлассификация результатов на наборах данных ImageNet
  • CNN достигает 69,8% точности top-1 и 89,1% точности top-5 в RESNET-18. Однако, при 1.8G умножениях.

  • AdderNet обеспечивает 66,8% точности top-1 и 87,4% точности top-5 в ResNet-18, что демонстрирует, что фильтры сумматора могут извлекать полезную информацию из изображений.

  • Несмотря на то, что BNN может достигать высокой степени ускорения и сжатия, он достигает только 51,2% точности top-1 и 73,2% точности top-5 в ResNet-18.

  • Аналогичные результаты для более глубокого ResNet-50.

3.4. Результаты визуализации

Визуализация признаков в AdderNets и CNN. Признаки CNN разных классов разделены по их углам.Визуализация признаков в AdderNets и CNN. Признаки CNN разных классов разделены по их углам.
  • LeNet++ обучался на наборе данных MNIST, который имеет шесть сверточных слоев и полносвязный слой для извлечения выраженных 3D признаков.

  • Количество нейронов в каждом сверточном слое составляет 32, 32, 64, 64, 128, 128 и 2 соответственно.

  • AdderNets использует l1-меру для различения разных классов. Признаки имеют тенденцию быть сгруппированными относительно центров разных классов.

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

Визуализация фильтров в первом слое LeNet-5-BN на MNISTВизуализация фильтров в первом слое LeNet-5-BN на MNIST
  • Фильтры предлагаемых adderNets по-прежнему имеют некоторые схожие паттерны со сверточными фильтрами.

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

Гистограммы по весам с AdderNet (слева) и CNN (справа).Гистограммы по весам с AdderNet (слева) и CNN (справа).
  • Распределение весов с AdderNets близко к распределению Лапласа, тогда как распределение с CNN больше походит больше на распределение Гаусса. Фактически, априорным распределением l1-меры является распределение Лапласа.

3.5. Абляционное исследование

Кривая обучения AdderNets с использованием различных схем оптимизацииКривая обучения AdderNets с использованием различных схем оптимизации
  • AdderNets, использующие адаптивную скорость обучения (adaptive learning rate - ALR) и увеличенную скорость обучения (increased learning rate - ILR), достигают точности 97,99% и 97,72% со знаковым градиентом, что намного ниже, чем точность CNN (99,40%) .

  • Поэтому мы предлагаем использовать точный градиент для более точного обновления весов в AdderNets.

  • В результате AdderNet с ILR достигает точности 98,99% при использовании точного градиента. Используя адаптивную скорость обучения (ALR), AdderNet может достичь точности 99,40%, что демонстрирует эффективность предложенного метода.

Ссылка на статью

[2020 CVPR] [AdderNet]

AdderNet: Do We Really Need Multiplications in Deep Learning?

Классификация изображений

19891998: [LeNet]

20122014: [AlexNet & CaffeNet] [Dropout] [Maxout] [NIN] [ZFNet] [SPPNet] [Distillation]

2015: [VGGNet] [Highway] [PReLU-Net] [STN] [DeepImage] [GoogLeNet / Inception-v1] [BN-Inception / Inception-v2]

2016: [SqueezeNet] [Inception-v3] [ResNet] [Pre-Activation ResNet] [RiR] [Stochastic Depth] [WRN] [Trimps-Soushen]

2017: [Inception-v4] [Xception] [MobileNetV1] [Shake-Shake] [Cutout] [FractalNet] [PolyNet] [ResNeXt] [DenseNet] [PyramidNet] [DRN] [DPN] [Residual Attention Network] [IGCNet / IGCV1] [Deep Roots]

2018: [RoR] [DMRNet / DFN-MR] [MSDNet] [ShuffleNet V1] [SENet] [NASNet] [MobileNetV2] [CondenseNet] [IGCV2] [IGCV3] [FishNet] [SqueezeNext] [ENAS] [PNASNet] [ShuffleNet V2] [BAM] [CBAM] [MorphNet] [NetAdapt] [mixup] [DropBlock] [Group Norm (GN)]

2019: [ResNet-38] [AmoebaNet] [ESPNetv2] [MnasNet] [Single-Path NAS] [DARTS] [ProxylessNAS] [MobileNetV3] [FBNet] [ShakeDrop] [CutMix] [MixConv] [EfficientNet] [ABN] [SKNet] [CB Loss]

2020: [Random Erasing (RE)] [SAOL] [AdderNet]


Перевод материала подготовлен в преддверии старта курса "Deap Learning. Basic".

Также приглашаем всех желающих посетить бесплатный демо-урок по теме: "Knowledge distillation: нейросети обучают нейросети".

- УЗНАТЬ ПОДРОБНЕЕ О КУРСЕ

- ЗАПИСАТЬСЯ НА БЕСПЛАТНЙ ДЕМО-УРОК

Подробнее..

Как группа энтузиастов и нейросеть StyleGAN2 сделали выставку современного искусства в Петербурге

12.04.2021 14:15:58 | Автор: admin
Привет, Хабр! До 15 апреля в Центре современного искусства имени Сергея Курехина проходит выставка Ивана Плюща После всего / После всех. Часть 1. После стула. В соавторы художник взял нейросеть GAN. Под катом рассказываем, как мы делали эту выставку. Осторожно, много картинок.




Зачем делали выставку


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

Вокруг термина Искусственный интеллект сейчас много хайпа. Медиа подливают масла в огонь заголовками вроде AI is the future of everything, AI will change everything или Искусственный интеллект захватит мир. Этим проектом мы хотели, среди прочего, повысить осведомленность людей. Подчеркнуть, что искусственный интеллект это не угроза и не магия, которая выдает абсолютно случайный результат или, напротив, единственное верное решение. В текстах о выставке мы обязательно говорим, что используем не просто искусственный интеллект, а генеративно-состязательную нейросеть (Generative adversarial network, сокращённо GAN) и по возможности стараемся объяснить общие принципы ее работы.

Современный человек часто сталкивается с применениями machine learning. Взять те же соцсети, которые изучают наше поведение и показывают то, что, по их мнению, мы хотели бы видеть. Выглядит безобидно, но рождает реальные социальные проблемы. Подробнее например, в этой документалке: The Social Dilemma (Netflix, 2020 год).

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

Чем вдохновлялись


Конечно, не нам первым пришло в голову использовать GAN. В 2018 году на аукционе Christies за $432,500 был продан Портрет Эдмонда Бэлами, созданный нейросетью.



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

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

Теперь подробнее.

Как создавали работы


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



Получалось примерно так:


Для создания работ из этой серии использовали StyleGAN2 и, с недавних пор, StyleGAN2-ada: генеративно-состязательные сети, разработанные компанией nVidia и дающие на текущий момент одни из лучших результатов. Вещь не новая. Те, кто следит за развитием нейросетей или за медиа-искусством наверняка натыкались как минимум на проект https://thispersondoesnotexist.com/, который работает на основе этих сеток.

На результаты смотрел Иван Плющ и рисовал на холсте такое:


Холст, масло, акрил. 159 x 129 см.


Холст, масло, акрил. 180 x 180 см


Холст, масло, акрил. 85 x 85 см

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

Вот картина из серии После порно:

Холст, акрил, масло. 180 x 180 см



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


Как подготовили помещение


Найти помещение нам помогли связи куратора и тот факт, что Иван Плющ достаточно известный художник (его работы сейчас показывают, например, в Русском музее на выставке Поколение тридцатилетних). Выставку договорились провести в Центре современного искусства имени Сергея Курёхина. Это авторитетная в арт-тусовке организация.

Под выставку предоставили 6 комнат общей площадью около 400 квадратных метров. Там мы показываем 25 произведений Ивана и отдельно результаты работы StyleGAN2. Часть картинок, созданных нейросетью, распечатали и развесили на экспозиции, часть собрали в видео, которое проецируется на стены.


Полное название выставки После всего / После всех. Часть 1. После стула. Стул это нечто понятное, знакомое и максимально простое. На этом примере было удобно объяснять, как работали над проектом. А еще такая тема отсылает к знаковому для современного искусства произведению Джозефа Кошута, который показал на выставке настоящий стул, фотографию этого стула и определение слова стул из словаря. На этом примере обычно объясняют, что такое концептуализм. Почитать можно здесь.

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


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


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

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

Выставка работает в Центре современного искусства имени Сергея Курехина (Санкт-Петербург, Лиговский пр., 73, 4 этаж) до 15 апреля. Приходите!

Художник: Иван Плющ
Куратор выставки: Марина Альвитр
Продюсер: Иван Пузырев
Техническая поддержка: Артем Коневских
Помогали: Анна Падаляко, Дарья Елизарова, Евгений Новиков
Написала статью: Дарья Яковенко
Подробнее..

Искусственный интеллект в юриспруденции. Вебинар 1 Обзор последних достижений в области AI

14.04.2021 18:22:15 | Автор: admin

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



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


В частности:


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

В продолжение мы записали небольшой видео-курс из 4-х вебинаров по следующим темам:


  • что такое искусственный интеллект для юриста, а также как развивались данные технологии в последние годы?
  • какие существующие решения в области Legal Tech можно использовать в повседневной работе уже сегодня?
  • каким образом мы подходим к развитию искусственного интеллекта в юриспруденции, а также как создавать и внедрять решения на основе AI в свою деятельность?
  • какие тренды существуют в области искусственного интеллекта сегодня, а также как будут развиваться технологии в будущем?

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



Из данного вебинара Вы узнаете:


  • основные понятия и термины из мира AI (narrow AI/general AI/explainable AI и др.);
  • историю развития цифровых технологий и первые достижениях искусственного интеллекта (от побед над человеком на шахматной доске до генерации текста и предсказания 3d-модели белка);
  • основные мифы и заблуждения профессионального сообщества относительно искусственного интеллекта;
  • роль данных и информации в процессе цифровизации юридической работы.

P.S.:


Презентация доступна для скачивания по ссылке здесь.


Тайм-коды вебинара:


01:53 Структура курса
02:51 Что такое искусственный интеллект?
13:57 Сильный и слабый искусственный интеллект
17:39 Explainable AI
26:50 Machine learning / Deep learning
28:55 История искусственного интеллекта / Deep Blue vs Гари Каспаров
31:12 AlphaGo vs Lee Sedol
41:04 AlphaStar vs TLO/MaNa
44:03 Написание связанного текста (GPT-2)
47:31 AlphaFold vs CASP / предсказание 3D-модели белка
49:50 Голосовые ассистенты
51:56 Мифы и заблуждения об AI
54:55 AI зонтичный термин
01:01:07 Ценность данных и информации
01:03:26 AI это software
01:07:32 Заключение

Подробнее..

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

15.04.2021 22:17:49 | Автор: admin

В 2019 году в ОТР появился новый центр по работе с искусственным интеллектом (ЦИИ). Изначально он создавался как некий эксперимент по работе с новыми технологиями. Однако довольно скоро получил первую боевую задачу по автоматизации технической поддержки пользователей ГИИС Электронный бюджет. Об этапах внедрения ИИ рассказали технический директор компании ОТР Анатолий Безрядин и сотрудники ЦИИ, принимавшие участие в амбициозном проекте.

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

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

Выбор типа нейронных сетей

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

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

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

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

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

Свёрточные нейросети отвечали заданным требованиям. Выбор был остановлен именно на них.

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

  • логистическая регрессия;

  • решающие деревья;

  • метод опорных векторов;

  • рекуррентные нейронные сети;

  • модели типа GPT;

  • модели типа BERT.

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

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

Поиск подходящих библиотек

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

  • open-source-проект;

  • использование последних научных достижений;

  • удобный инструментарий и документация;

  • масштабируемость;

  • готовность к промышленному использованию;

  • поддержка графических процессоров;

  • большое сообщество профессионалов.

У нас получился такой список библиотек:

  • MATLAB + Deep Learning Toolbox;

  • Theano:

  • Torch;

  • PyTorch:

  • TensorFlow/Keras.

MATLAB известный пакет прикладных программ для решения задач технических вычислений от The MathWorks. Изначально в нём не заложена функциональность по работе с нейронными сетями. Однако проблема решается надстройкой Deep Learning Toolbox. Она используется для проектирования, внедрения и предварительного обучения нейросетей.

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

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

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

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

Как и в случае с Theano, библиотека Torch сейчас находится в полузаброшенном состоянии. Последние глобальные обновления кода были проведены четыре года назад. Недостатки её использования совпадают с предыдущим проектом.

PyTorch библиотека для машинного и глубинного обучения от энтузиастов. Как понятно из названия, она создана на базе Torch. Однако написано уже на понятном для большинства разработчиков языке Python.

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

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

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

ИИ в бою

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

После первоначальной настройки мы получили точность 75%. Для повышения точности удаляли шум в текстах. Для этого с помощью регулярных выражений находили определённые паттерны и избавлялись от них. Занимались оптимизацией архитектуры модели. Всё это позволило повысить точность до 85%.

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

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

Подробнее..

Вомбатизация, или зачем мы разработали собственную систему управления пайплайнами данных

15.04.2021 08:23:06 | Автор: admin


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

Почему мы разрабатываем собственную систему


Делать собственную систему управления пайплайнами данных выбор неочевидный. Сегодня есть множество готовых решений, которые могут решить проблему: Airflow, MLflow, Kubeflow, Luigi и куча других. Мы экспериментировали со многими подобными системами и пришли к выводу, что ни одна из них нас не устраивает.

Для примера рассмотрим самое распространенное решение Airflow. Оно объединяет шесть основных блоков: API для описания пайплайнов, сборщик woкflow, панель управления и интерфейсы, планировщик задач и оркестратор задач и, наконец, мониторинг компонентов Airflow. Но для того, чтобы управлять пайплайнами, такой функциональности в нашем случае было недостаточно.

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



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

Какие проблемы мы решали


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

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



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

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

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

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

Что получилось в итоге


Условно архитектуру Wombat можно представить вот так:



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



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

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

Мы готовимся выложить данный инструмент в open source в самое ближайшее время. Будем рады, если поделились своим мнением о нашем проекте и своим опытом работы с современными системами пайплайнов данных.

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

P.S. Мы, по-прежнему, заинтересованы в талантливых программистах. Приходите, будет интересно!
Подробнее..

Категории

Последние комментарии

© 2006-2021, personeltest.ru