Как думают роботы. Интерпретация ML-моделей


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

slides-sborka-2020.pdf

Текстовая расшифровка (еще не вычитана):

У меня есть клевая майка, на груди написано «Я Промсофт, мощны мои лапищи». Это минутка рекламы. Я работаю в Промсофте, мы там делаем ML-модели и внедряем их в разный бизнес, который подвернется и согласится за это оплатить. Я первую ML-модель написал в 1986 году на четвертом фортране, на мейнфрейме. И до сих пор пытаюсь. Первый раз получилось не очень хорошо, сейчас уже лучше получается. Я преподаю в НГУ, иногда по случаю консультирую, ну и принимаю участие во всех ОДСовских движухах, которые тут в Новосибирске происходят, всячески их поддерживаю. Собственно про презентацию. План примерно такой. Сначала мы поговорим о чем это все, то есть что такое интерпретируемость, ну и что такое вообще ML-модели, кому и зачем нужно их интерпретировать, почему вообще нужно их интерпретировать, то есть что тут непонятно. Модель это же компьютерная программа, в компьютерной программе в код посмотрел и так ясно что она делает. Чем хорошая интерпретируемость отличается от плохой, посмотрим как это делают с табличками, как с картинками, ну и что почитать и какие хорошие инструменты есть для всего этого. Как вы может быть заметили, вещи вокруг стали умнее, то есть искусственный интеллект у нас в каждой буквально розетке. В бухгалтерской программе проводки автоматически сортируются по направлениям, в машинах пытаются встроить автопилот, чтобы он ездил за вас, а на заборах висят ящики, которые эти машины автоматически штрафуют и выписывают штрафы. Если вы еще не знали, то когда вам оформляют кредит и когда на вас подают в суд, зачастую решение о том, выдавать вам кредит или нет, почти всегда, а также подавать на вас в суд или нет, принимает алгоритм, то есть кадровый судебный скоринг. В Амазоне, например, был большой скандал, что у них там была программа, которая оценивает по резюме кандидатов и она отдавала предпочтение мальчикам, просто потому что мальчики на складе чаще устраивались, лучше работали. Она, соответственно, женщин минусовала, мальчиков плюсовала. В сегодняшней Америке это почти фашизм. Ну и рекомендательные системы торчат у нас из каждой веб-страницы. То есть умных алгоритмов у нас пруд-пруди вокруг. И сейчас все это делает то, что раньше делают люди. Вам продавец рекомендовал какой-нибудь товар, теперь вам алгоритм рекомендует какой-нибудь товар. Раньше вас андроайтер оценивал на предмет, можно ли вам дать кредит или нет, теперь алгоритм оценивает ваш кредит. Раньше вас HR-менеджер оценивал, подходите ли вы на работу. Теперь в крупных фирмах во многих резюме сортируют алгоритм. И поэтому мы должны применять к алгоритму, раз уж они выполняют функцию людей, те же самые требования, которые мы применяем к людям. Когда мы принимаем человека на работу, мы вообще-то пытаемся убедиться, что человек этот вменяемый, способен делать эту работу, и мы понимаем его мотивы. То есть если бы мы, например, наняли андроайтера оценивать кредитоспособность людей, и он бы оценивал цвет их пиджака. Людям в синем пиджаке давал кредит, а другим не давал бы кредит. Мы бы, наверное, были недовольны его работой. То же самое может делать алгоритм машинного обучения, но мы не узнаем, что он это делает. То есть у человека можно спросить, а почему ты ему не дал кредит, но он не в синем пиджаке. То же самое с алгоритмом произойдет с гораздо большей вероятностью, а проверить это гораздо труднее. Вообще машинное обучение это просто такая разновидность компьютерных программ. И компьютерные программы появились не сейчас, люди уже 80 лет как что-то программируют. И раньше как люди писали программу, какой-нибудь искусственный интеллект, они собирали данные, ученые выводили зависимости, рисовали графики, писали научные работы, рассказывали другим ученым. В конце концов придумывали, что вот если сделать вот так, если вот это оптимизировать, вот это растянуть, вот это синхронизировать, то программа начнет понимать человеческий голос. Программу написали, в основном протестировали, она почти не глючит, и те люди которые создали первые системы распознания голоса, те люди которые создали первые системы кредитного скоринга, те люди которые создали первые системы управления самодвижущимися машинами, они понимали как она работает до самых глубин. Ну и вообще, мы думаем, что мы понимаем, как работает наша программа, ну до тех пор, пока она маленькая, мы понимаем. Я больше 30 лет разрабатываю программное обеспечение и думаю, что... мне почти 50, всю жизнь этим занимаюсь. И я думаю, что по-настоящему большие программы, никто не понимает, как они работают. То есть, есть такая оценка, что человек способен примерно 10 тысяч строк кода программам понимать, как она работает. Дальше уже где-то этот темный лес для него загадка. То есть, в принципе, проблема понимания того, как работает программа, какая-нибудь сложная ЕРП, и в древности было, но для того, чтобы сделать достаточно сложную программу, нужны были тысячи людей и годы. Сейчас мы во всех этих умных алгоритмах используется машинное обучение. Машинное обучение метко передано вот этой картинкой справа. Как работает ваша система машинного обучения? Ну, говорит, мы сюда цепим данные, оттуда вытекает результат. А если результаты вытекают неправильно? Ну, мы, говорит, эту фигню лопатой копаем, пока она не начнет выдавать правильный результат. Когда-то давно, очень давно, то есть в начале 2000-х, фактически во времена, когда мамонты жили, были рекуррентные нейронные сети, так называемые эхосети, которые ровно так и строили. Их использовали для обработки временных рядов и звуков, то есть просто брали нейронную сеть, случайно генерировали соединения, случайно набрасывали веса и смотрели, может ли она что-нибудь полезное выдать на выходе или нет. Так делали, потому что не умели тогда обучать рекуррентные сети, но случайно их генерировали. То есть вот эта картинка, это просто точное описание того, как работали первые рекуррентные нейронные сети. А вообще о машинном обучении можно думать как о программировании с помощью примеров. Поэтому мы сейчас коснемся, вот как работает, допустим, нейронка внутри. В принципе, люди, которые создают нейронные сети, они понимают, как она работает. То есть здесь у нас есть входные данные, картинка, каждый пиксел этой картинки мы умножаем на какое-то число, как-то комбинируем с соседними пикселами картинки, получившиеся чиселки, преобразовываем в нелинейные функции, так делаем примерно 15 раз, и в результате у нас получается ответ кошечка или собачка. Если бы все понятно, но на вопрос, что же делает конкретное умножение, или как повлиял этот пиксел на решение кошечки или собачки, эта картинка не отвечает. Андрей Карпаты, который руководит разработкой искусственного интеллекта в Тесле, на одной из конференций назвал это программным обеспечением 2.0. То есть если раньше мы программное обеспечение писали в коде, нам нужно было его спроектировать, нам нужно было руками написать все эти ифы и умножения, и у нас получалась программа, то теперь мы программу обучаем на примерах. Мы ей даем кучу примеров фотографий размеченных и говорим, вот это вот, допустим, кошки, это собачки, а это автомобили. Пожалуйста, научись делать так же. Она говорит хорошо и делает. Это с одной стороны хорошо, потому что мы можем делать очень сложные программы очень быстро. То есть на то, чтобы построить первые программы распознавания голоса ушли, если я ничего не путаю, десятилетия. А теперь в принципе нейронную сеть на кошечки и собачки я на зимней школе Комтеху обучил за 5 минут, студентам показывал, и мы можем быстро делать очень сложные программы. Что плохо, никто не понимает, как они в результате работают. Мы раньше не понимали, как работают сложные программы, но раньше для этого нужно было усилие целой армии. То есть мы брали тысячу человек, они писали 5 лет какую-нибудь программу, мы переставали понимать, как она работает. А сейчас мы за 5 минут что-то обучили и уже не понимаем. Это вот освежающий прогресс. Может быть нам и не надо понимать, как работают алгоритмы машинного обучения, они ведь работают нормально. То есть они рекомендуют товары, они предсказывают на кого надо подавать в суд, на кого не надо, кому надо давать кредит или не надо. Но я думаю, что все-таки понимать нужно и вот почему. Во-первых, машинное обучение жульничает. И это не фигура речи. Например, если вы будете отличать по фотографии девочка или мальчик, вы можете, конечно, научить нейронную сеть отличать пол, а еще, может быть, нейронная сеть попытается выяснить общий тон фотографии. То есть у девочек он будет более теплый, более красивый, более аккуратная фотография, просто более четкая. А мальчики могут поставить более темную, более расплывчую, то им примерно все ровно. То есть нейронная сеть может давать правильный ответ и при этом ориентироваться совершенно на неправильные признаки. На цвет рамки, на тип фотоаппарата, которым сделана фотография, на время года, на фоновые шумы. Опять же, из примеров, из научных статей, ребята учили нейронную сеть отличать собак от волков. И в общем выучили, хорошо отличало, проблема только в том, что в реальности оно работало плохо, потому что все фотографии собак у них были на асфальте, все фотографии волков у них были на снегу. И таким образом нейронная сеть видела снег и решала, что ну кто на ней, только волки ходят по снегу. То же самое с собаками, если бы волк вышел на асфальт, то он естественная собака, потому что в обучающей выборке все собаки ходили по асфальту. Нейронная сеть может обучиться, не вообще алгоритм машинного обучения, может обучиться плохому. То есть оно реально есть в данных, но вы бы, например, не хотели, чтобы она этому училась. То есть как, например, с Амазоном и кадрами, она выучила, что мальчиков чаще принимают на работу, чем девочек. Вообще-то Амазон хотел бы, чтобы у него было равноправие. Амазон не хотел, чтобы у него был такой гендерный фашизм, но нейронная сеть посмотрела в истории и выучилась. Опять же алгоритмы машинного обучения склонны к тому, чтобы фиксировать происходящее. То есть представим себе, что у нас есть какой-нибудь небогатый район, и молодой человек оттуда пытается устроиться на работу, а алгоритм смотрит, ну из этого района всегда выходили одни бандиты, и это, наверное, бандиты. И мы его на работу не возьмем. Соответственно, он остался без работы, он идет в бандиты. При том, что у нас сейчас алгоритмы машинного обучения торчат действительно в каждом утюге, и их все шире и шире используют законодатели для того, чтобы принимать решения, это несет за собой риск того, что алгоритмы будут определять, как мы живем, при этом они сами не хотят, чтобы мы жили так или иначе, просто они пытаются зафиксировать происходящее. Затем алгоритмы машинного обучения могут очень странно работать. Если в обучающей выборке не было, например, лошадей, были только кошечки и собачки, и мы просим склассифицировать ее, у нее не было лошадей в обучающей выборке, у нее были кошки или собачки, она может ответить только кошка это или собачка. Еще алгоритмы машинного обучения плохо предсказуемы. То есть вы думаете, что она работает хорошо, она работает хорошо, но вы выносите ее на улицу, где немножко другое освещение, она перестает работать. Еще алгоритмы машинного обучения что-то знают, то есть вы дали ей кучу обучающих данных, оно в них разобралось, оно научило принимать решения. Вам бы хотелось узнать, что же оно такое выучило, чтобы сказать это другим людям, чтобы они тоже учитывали это в работе. В моей практике было такое, когда мы делали для коммерческой недвижимости модель, которая предсказывала цену коммерческой недвижимости по расположению, по характеристикам, и вообще-то владельцам коммерческой недвижимости тоже было интересно, слушай, а что на нее влияет, то есть как можно повысить стоимость коммерческой недвижимости, модель ведь знает это, расскажи нам. И еще часто бывает нужно улучшить модель, то есть, например, есть у нас модель, которая делает кредитный скоринг, определяет хорошо или плохо человек будет возвращать кредиты. Мы хотим, чтобы эта хорошая модель работала бы еще лучше. Как ее улучшить, как ее подкрутить? Не понимая, как она работает, на что она опирается, нам очень трудно будет ее улучшить. А еще бывают разборы полетов, то есть ни с того ни с сего модель машинного обучения выдала какую-то ерунду, а кто-то на вас за это подал в суд или вы потеряли кучу денег. И начинается разборка, почему она приняла это решение. Вот тут везде интерпретируемость модели машинного обучения всплывает и становится полезной. Проблема возникает не только у нас, проблема серьезная. И в 2018 году агентство DARPA, которое изобрело интернет и много других интересных вещей, оно объявило месячник объяснимый искусственного интеллекта. То есть, давайте, говорит, дадим кучу денег ученым, они придумают, как сделать так, чтобы искусственный интеллект, который мы используем во всех важных отраслях человеческой жизни, таких как медицина, финансы, законы, война, транспорт, он мог ответить на важные вопросы. То есть, почему она сделала так, а не иначе, в каких условиях ей можно пользоваться, в каких нет, когда на нее можно полагаться, когда нельзя и так далее. Они, насколько я помню, поставили цель к 2021 году эту интерпретируемость победить, продвинулись далеко, но, в общем, я бы сказал, что ВОЗ и ныне там. То есть, сейчас за два года здорово изменился ландшафт интерпретируемости, но в основном не за счет денег DARPA, а за счет того, что все крупные вендоры, такие как Amazon, Google, Microsoft, тоже озаботились этой интерпретируемостью, потому что к ним клиенты приходят и спрашивают, а почему у вас модель принимает такие решения, и стали ее внедрять в свои продукты. Вообще интерпретируемость не всегда нужна. Я в жизни несколько раз сталкивался с ситуацией, когда нас отдельно просили не делать интерпретацию модели машинного обучения. Во-первых, любая интерпретация, вообще любая работа дата-сайентиста стоит денег. Поэтому если влияние модели мало, то есть она рекомендует, допустим, что-то в интернет-магазине, вроде бы хорошо, затраты небольшие, прибыль тоже небольшая, что с ней возиться. Ее дешевле не трогать, действительно работает, пусть работает. Она не решает, будет человек жить или нет, надо ли его класть под вентиляцию легких или нет, есть у него пневмония или нет, неважная такая модель. И таких моделей много, с которыми можно пустить на самотек. Если она хорошо работает, ну хорошо, плохо работает, небольшая потеря. Бывают модели очень сложные, но они очень хорошо разработаны, и специалистов их прямо с института учат, как с такими моделями жить. И тут обычным специалистам и так тоже все понятно, их не нужно как-то специально интерпретировать. Бывает, что люди, опять же, со школы учатся интерпретировать модели, например, линейная модель. Линейная модель, ну это когда мы берем наши признаки, или сами их складываем и смотрим, чем больше получившаяся сумма, тем, допустим, лучше или хуже. Например, мы оцениваем стоимость квартиры в зависимости от близости к центру города, количества комнат и общей квадратуры. Тут проблема какая, что модель кажется очень простой и понятной, линейная модель. Допустим, добавили один квадратный метр, она стала дороже, допустим, на 3000 рублей. Проблема в том, что когда у нас признаков много, например, в скоринговой модели их может быть 100, 200, 300, 400, скоринговая имеется в виду кредитная скоринга, в голове удержать одновременное изменение 400 признаков невозможно. Это все равно, как если бы вы пытались представить себе движение точки в 400-мерном пространстве, то есть это за пределами того, что может человеческий мозг. Еще иногда мы хотим скрыть алгоритм. Однажды нас просили не делать интерпретируемость для скоринговой модели, потому что тогда люди поймут, почему дают кредит, почему не дают кредит, и начнут систему обманывать. Яндекс, например, не горит желанием, чтобы его ранжирование поисковое интерпретировали. Когда оценивают качество работы сотрудников, тоже стараются алгоритм оценки спрятать, потому что сотрудники начнут подстраиваться под алгоритм, а мы хотели бы, чтобы они что-нибудь полезное делали вместо этого. Но пока мы говорили про модели машинного обучения, что такое собственно модель машинного обучения? Модель машинного обучения – это какой-то алгоритм, которому мы показываем много данных, и чем больше данных мы ему показали, тем он лучше начинает отвечать на наши вопросы. Самый простой алгоритм машинного обучения – это КНН, то есть делает так, как делают похожие. Например, приходит к контррейтору человек и говорит «я хочу кредит», он смотрит на него и думает «а он похож на Клаву и Васю, Вася с Клавой не отдавали кредит и он, наверное, не отдаст». Это типичное решение с помощью алгоритма КНН, то есть ближайшие соседи. Проблема тут в том, что такое похоже. То есть для одного человека похоже – это с одинаковой формой лица, для другого – с одинаковым доходом, для третьего – с одинаковым ростом. Для того, чтобы у нас работали такие модели поиска ближайших соседей, нам надо каким-то образом определить похожесть. Это зачастую нетривиально. Линейные модели, про них говорил. Затем деревья, деревья решения. То есть, например, к нам приходит человек, мы смотрим, есть ли он молод, то проверяем, есть ли у него работа. Если работа есть – даем кредит, работа нет – не даем кредит. Если он не молод – проверяем, есть ли у него недвижимость. Если есть недвижимость – даем кредит, если нет недвижимости – не даем кредит. То есть такие деревья решений. Они хорошие, интерпретируемые, с ними все хорошо до тех пор, пока, во-первых, у них мало уровней, то есть, скажем, в три уровня человек еще способен понять, а в дереве спокойно может быть 150 уровней таких. И человек уже не способен понять, на самом деле, удержать в голове, что же это дерево делает. Во-вторых, деревья часто комбинируют. То есть берут, например, несколько деревьев, ну, допустим, 500 деревьев, и смотрят, что они отвечают в среднем. То есть, допустим, 500 разных деревьев обучили на данных, 300 деревьев сказали – это плохой заемщик, 200 деревьев сказали – это хороший заемщик, и мы отказали в результате взаимно. Интерпретировать все это, в принципе, возможно, распечатать все эти деревья и посмотреть на них на бумаге, но в практике это то, чем заниматься не следует. Это проблема ансамбля и моделей, когда несколько моделей объединяют вместе. Вроде бы модели все внутри простые, но понять, что же они делают, трудно. Ну и нейронные сети. Нейронные сети, по сути, свои. Это вот та самая куча линейной алгебры на картинке, которая была несколько слайдов назад. Мы берем вход, на что-то его умножаем, преобразуем в какую-нибудь функцию, опять на что-то его умножаем, и так много-много-много раз. В результате, вроде бы, получается хороший ответ. В принципе, все эти значения, все эти операции можно достать и распечатать, но их в нейронной сети может быть 10 миллионов, 50 миллионов или, например, миллиард этих операций в этой сети. И на практике мы сталкиваемся с тем, что, в принципе, все данные есть, а, по сути, чисто издевательство, никто не может понять, как она работает. Каким могло быть хорошее объяснение того, как работает алгоритм машинного обучения? Ну, они бывают, объяснения локальные и глобальные. Локальное объясняет решение алгоритма в данной конкретной точке. То есть, почему Маше не дали кредит? Маше не дали кредит, потому что она слишком старая, например. А почему Пете не дали кредит? Пете не дали кредит, потому что у него недвижимости нет. То есть, для разных точек причина решения модели может быть разная. Объяснение может быть глобальное. То есть, например, мы даем кредит чаще людям с хорошей кредитной стоимостью. Или мы даем кредит чаще тем, у кого большая зарплата. То есть, это общее поведение модели. Объясняет поведение модели в каждой конкретной точке. Более того, для каждого конкретного случая вообще-то может он противоречить, но в среднем модель себя ведет примерно так. Поскольку у нас в данных может быть много признаков, то есть, например, рост, вес, доход, доход родственников в поездке за границу, история штрафов и так далее и тому подобное. Хорошо, если наша модель не просто дает объяснение точное, но оно еще и селективное. То есть, оно выделяет самые важные причины, почему она отработала. Это как в том анекдоте про Наполеона, который после боя спрашивал батарею, почему пушка не стреляла. И говорит, ну, во-первых, не было пороха. Он говорит, достаточно. Остальные признаки уже не важны. То есть, хорошее объяснение, оно селективное. Оно отвечает, говорит нам только самые важные причины, почему было принято решение. Есть куча второстепенных причин, почему оно было принято. Но они нам, как правило, не интересны. Затем хорошее объяснение должно быть непротиворечивым. То есть, например, приходит человек, ему не дают кредит. Он говорит, а почему мне не дали кредит? Ну, потому что у вас большая кредитная нагрузка. А почему, говорит, Пете дали кредит? Ну, у Пети, конечно, тоже большая кредитная нагрузка, еще куча недвижимости, большая зарплата. Ну, то есть, вот такая вот история. И получается, что хорошее объяснение, оно не должно противоречить другим примерам. Ну и, наконец, хорошее объяснение должно быть информативным. То есть, прочитав его, можно что-то сделать. Например, в IT есть такое явление, что людей старше 45 лет с трудом где-то нанимают на работу в некоторых фирмах. У нас, например, это не так. Но во многих так. И получается, что я прихожу такой, мне смотрят, тебе 48 лет, свободен. А я что могу с этим сделать? То есть, если их модель забраковала меня по возрасту, я ведь не могу стать моложе. То есть, это совершенно не информативное для меня решение. То есть, если бы, допустим, меня забраковали, потому что я медленно печатаю или плохо отвечаю на вопросы теста, это понятно, я бы мог подучиться, выучить тесты, научиться быстрее печатать. Но это меня отфутболили по признаку, который я никак не контролирую. То есть, этот ответ модели, объяснение модели, оно не информативное. С ним ничего не поделаешь. Ну и объяснение хорошее должно быть понятным для пользователя. То есть, если ваш конкретный потребитель это продавец, которому, ну, допустим, в CRM-системах мы такое делали, он рекомендует вот этот продукт, попробуйте продать вот этому клиенту. И, в принципе, можно объяснить продавцу, почему именно этого клиента рекомендовали. Например, что он покупал что-то похожее, или, допустим, они недавно продали похожий объект, или у них уже три таких объекта, они, наверное, захотят четвертый. Но это объяснение должно быть в терминах того, что объекту объяснением будет пользоваться. Если вы ему скажете, ну, наш эмбейдинг объектов, умноженный на эмбейдинг этого пользователя, говорит, что косинусное расстояние между ними не очень большое, ну, это непонятное для пользователя объяснение, хотя оно формально верно. И, таким образом, хорошее объяснение, оно локальное, глобальное, селективное, непротиворечивое, информационное, понятное для пользователя. Дальше будет менее занудно, но это важная классификация. Как нам быть, если мы хотим, чтобы наши модели были объяснимы? А иногда мы очень хотим. Например, представим себе, что у нас есть модель, которая рекомендует лечение, то есть, приоритизирует больных с ковидом, которые поступили в госпиталь. То есть, по рентгеновскому снимку она говорит, вот этого давай ему в первую очередь, а этот, в общем, недельку полежит, ничего с ним не станет. И у этой модели есть, например, данные по выживаемости. И по этим данным, например, показано, что люди с астмой, на самом-то деле, выживают чаще, чем люди без астмы. Их модели привозят человека с астмой, она говорит, ну, этот с астмой, мы его отправим отлеживаться, с ним ничего не будет, они вообще живучие астматики. Причина тут, конечно, ровно наоборот. То есть, у астматиков риск выше, и поэтому с ними больше возятся, поэтому они чаще выживают, что врачи на них чаще смотрят. Соответственно, если мы позволим модели принимать такие решения, она просто начнет убивать людей, поэтому нам бы хорошо проконтролировать, чем она руководствуется, если мы хотим доверять ей такие важные для людей решения. Ну, во-первых, мы можем поступить, как в свое время поступило американское агентство по контролю за, я не знаю как, FDA, по контролю за препаратами и медицинской техникой. Они просто взяли и запретили сложные модели. Типа, если у вас модель сложнее, чем линейная модель, то мы ее при сертификации зарубим. Это, конечно, не сработало, потому что люди стали делать сложную модель, на которой работают признаки, а потом на ней работает простая линейная модель, ну и вроде как формально все соблюдено, но на практике, как ни понимали люди, почему она работает, так и не понимают. Но потом мы можем посмотреть внутрь моделей, то есть рассмотреть веса, порисовать деревья, иногда это помогает, иногда нет. Во все промышленные библиотеки машинного обучения встроена функция распечатать важность. Скажи, какие признаки для тебя важны, а какие нет. Можно туда посмотреть. Можно построить так называемые суррогатные модели технологии LIME, я про нее расскажу. Есть научно обоснованный подход, как объяснять модели SHAP для нейронок свои проблемы. И есть специальный класс моделей, которые изначально построены так, чтобы быть объяснимыми, понятными. Вообще в отрасли бытует мнение, что модель может быть либо хорошей, либо объяснимой. То есть хочешь объяснимую, хорошую модель, выбери одну из двух. Мы на самом-то деле, моя практика этого не подтверждает. То есть можно сделать достаточно хорошую объяснимую модель, но правда надо за этим специально следить, с этим возиться. Она сама по себе, но с неба не упадет объяснимая модель. Петрий, у меня есть вопрос насчет расстояния между эмбеддингов. Как бы ты их стал интерпретировать? На самом-то деле, есть специальная библиотека, которая визуализирует эмбеддинги. Ты СМЕ ты имеешь в виду? Нет, нет, нет. Когда я рисую, у меня сейчас видно только слайды, то есть я могу в другое окно переключиться, попытаться найти эту штуку. Я ее как раз когда готовился, думал включать, не включать. Думаю, ведь никто не спросит про эмбеддинги, правильно? Мы до сих пор видим слайды, если ты переключился на что-то еще, то мы этого не видим. Да, это очень удобно. Сейчас. Давай, Дим, я скину ссылку. Идея какая? Что мы можем построить граф, допустим, у нас есть несколько точек. Допустим, ты, я, Ваня Комаров, кто-то еще, и для нас есть эмбеддинги. И мы можем посмотреть расстояние между нашими эмбеддингами, в этом пространстве эмбеддингов, и построить такой граф смежности. Этот граф смежности, на удивление, хорошо показывает, что там у модели на уме. Для неконтекстных эмбеддингов это точно. Я бы вот так делал. Я ссылку скину в чат. Это, по сути, кластеризация? По сути, мы показываем, смотри, у нас эмбеддинг, он же определяет некоторое пространство, в котором у нас все точки расположены. Близко расположенные точки, они друг друга отписывают. То есть, например, предположим, что у нас есть лук, и рядом у него у нас есть репчатый, допустим, чеснок, и мы понимаем, что модель думает о луке, как об овоще. Или рядом у нас со словом лук расположен арбалет и, например, пистолет. И мы понимаем, что о луке думает как о оружии. То есть, по окружению модели, по ближайшему ее контексту в эмбеддинге, мы можем примерно понять, как ее внутренняя, выученная ей антология устроена. Но это вот самое лучшее, что пока я по эмбеддингам встречал, по интерпретации эмбеддингов. Можно эти сни нарисовать, да, конечно. Вопрос в чате. Зачитать или прочитаешь сам? Да я чата не вижу. Тогда зачитаю. Вопрос. Можно ли как-то Монте-Карло прикрутить для интерпретации? На Bootstrap, например, для начала, а там дальше внутрь? Ну, дословно. Собственно говоря, на Bootstrap, конечно, можно. Bootstrap это обычно, чтобы оценить ответ модели. Для тех, кто не знает, что такое Bootstrap вообще, то есть у нас есть какая-то сложная модель, мы даем ей на вход под выборки, то есть вот есть наши данные, мы из наших данных случайно выбрали. Данных мало. Мы не можем оценить точно средние, допустим, этих данных. Мы берем, выбираем половину этих данных случайно, меряем среднее, выбираем еще раз половину случайно, меряем среднее. Так что раз мы намерили, и у нас получилось, насколько наше среднее будет болтаться, в зависимости от того, какие данные нам попадутся. И мы говорим, что вот мы Bootstrap оценили распределение среднего номера. Для интерпретируемости мы можем делать как? Ну, вот я опять же фантазирую. Смотрите, что мы берем, я как раз сегодня думал о том, как можно искать закладки в моделях. То есть это немножко не в эту тему. В модели при обучении можно вообще-то заложить закладки. То есть в компьютер, в фантастике, наверное, вам попадался какой-нибудь фильм, где человеку можно сказать специальную фразу, его перемкнет. Его перемкнет, он начнет стрелять направо и налево, или там пойдет и застрелит президента, или еще что-нибудь. Так вот, в принципе, в модель машинного обучения такую закладку тоже можно вставить. То есть, например, вы поручили мне обучить модель для распознавания людей по фотографии, я ее обучил, она всех людей распознает, вот конкретно меня ни в каком виде не узнает. То есть это реально сделать. И для того, чтобы найти вот такую закладку, на самом-то деле, один из способов это подавать на вход модели случайный шум и смотреть на аномалии распределения ответа. То есть, ну вот это вот так можно использовать. Но именно для интерпретирования, насколько я понимаю, так не делают. Ну и для выявления закладок, я не знаю, делает ли кто так или нет, это открытая тема, я вообще-то в безопасности ММЛи не очень, сразу скажу, я не настоящий сварщик. То есть мне приходится решать такие проблемы, но это сейчас быстро развивающаяся тема, я могу просто что-то не знать наверняка. Вот, ответил ли я на вопрос? Ну, это я не знаю, вопрос я просто зачитывал, поэтому напишите там в чатике, кто задавал вопрос, Андрей, напиши, ответили или нет. Если нет, то можешь ворваться в эфир и доспросить. Вот, вполне, написали. Написали, что вполне ответили. Отлично, я попробую дальше. В свое время вообще линейная регрессия получила название регрессии из работы Гамильтона, который строил модель, как рост ребенка зависит от роста родителей. Ну и он, если я правильно помню, выяснил примерно так, что мы берем рост женщины, рост мужчины с разным весом и в принципе рост ребенка определяется средним ростом по популяции и средним родителей, мамы и папы. То есть, грубо говоря, у высоких детей родители регрессируют к среднему росту, у низких детей дети скорее выше их, у высоких скорее ниже их, то есть происходит регрессия к среднему. Поэтому модель называется линейная регрессия. И вот тут мы зададим вопрос такой, что у нас важнее для предсказания роста ребенка? То есть есть у нас средний рост по популяции, рост мамы или рост папы? В принципе получается, что сильнее всего рост ребенка определяет не рост мамы или папы, а средний рост по популяции. Интересно дальше с мамой и с папой. Поскольку папа обычно выше мам, то один сантиметр роста папы меньше влияет на рост ребенка, чем один сантиметр роста мамы. Поэтому порядок важности такой, то есть важнее всего средний рост по популяции, затем важнее мамин рост и затем папин рост, если в сантиметрах. Это неочевидная вещь, но показывает на очень простом примере, что даже вот в таких вот простых штуках уже с важностью приходится напрягаться, чтобы понять что происходит. Если же мы залезем в какую-нибудь сложную модель, то вот эти вот рассуждения нам уже недоступны. В нейронной сети мы можем смотреть сколько угодно на веса и так и не поймем, почему она пришла к тому или иному решению. Поэтому вот такие вот рассуждения, что важнее глядя в веса модели, они работают для очень простых моделей, для сложных они уже не срабатывают. У любой промышленной модели, как я уже говорил, есть функция, которая возвращает важность модели. Вот это вот для градиентного бустинга показывает важность признаков. То есть общее энергопотребление, я не помню, что они тут предсказывают, но чем больше полосочка, тем важнее будет признак этот для ответа модели. Проблема с этой важностью в том, что во-первых в каждой библиотеке она считается по-разному, то есть они несравнимы между собой. Затем важность в моделях обычно показывает не то, насколько признак важен для того, чтобы сказать, давать кредит этому человеку или нет, а насколько модели было удобно пользоваться этим признаком для ответа. Это не совсем разные вещи. И почему они разные, а не совсем одинаковые вещи, почему они разные, видно, потому что ответ, важность она неустойчива. То есть если вы, например, взяли и добавили еще одну точку в данные, в принципе, интуитивно кажется, что было тысяча точек в данных, добавили тысячу, однако важность спокойно может измениться при переоблучении, вообще радикально, то есть какой-то признак был важен, стал не важен и наоборот. Это зачастую происходит из-за того, что модель может пользоваться любым из двух признаков. Например, есть два признака, длина левой ноги, длина правой ноги. Обычно они совпадают, модель может пользоваться тем, другим или любой их комбинацией. По живых данных всегда признаки связаны, то есть модель у нас страдает от созависимости признаков. Поэтому, когда мы ее переобучаем, она может взять этот набор признаков, может взять тот, и важность будет нам показывать не то, какой вообще признак характеризует результат, а то, насколько модели вот сегодня, как раз левая нога модели захотела им пользоваться. Затем вот эта вот важность, она не информативна, она не отвечает нам на очень простой вопрос, а насколько у нас изменится ответ модели, если, допустим, общее энергопотребление вырастет. То есть она говорит, что да, общее энергопотребление важно для ответа модели, но вот если мы его увеличим в два раза, совершенно непонятно, что будет. Затем вот эта важность, так называемая, она не локальна. Она говорит, насколько признак вообще был важен для решения модели, но она не говорит, в какую сторону, и вот конкретно для Пети, которому не дали кредит, или Васи, которому кредит дали, какой конкретно признак сработал, она не отвечает. Ну и тут лишний раз похвалить катбуст яндексовский. У него встроена так называемая объектная важность. То есть у него можно спросить, какая из строчек в данных научила его отвечать так. То есть вы как ребенка спрашиваете, а кто тебе этой гадости научил? Вот, дядя Коля. И вот тут катбусту тоже можно спросить, а какая строчка в обучающих данных была для тебя важна? Что привело тебя к этой мысли? Ну и почистить данные, выкинуть ее, например, чтобы модель лучше работала, или еще добавить подхожих. Вот. И еще вот эта важность, которой мы интерпретируем модель, она сама-то по себе не интерпретируемая. То есть что означает, что повер тотал в полтора раза выше, чем сейшн каунт? Ну, наверное, оно важнее. Что значит в полтора раза выше? Оно в полтора раза важнее. То есть в полтора раза чаще чем пользуется, в полтора раза его меньше надо увеличить, чтобы ответ модели изменился. То есть оно не несет никакого смысла прикладного для людей, которые пользуются моделью. Кроме того, что оно позволяет нам сказать, что вот этот признак, наверное, модель используется чаще, чем другой. С этим люди научились бороться. Например, библиотека LIME, она строит локальную суррогатную модель. Что такое суррогатная модель в принципе? Когда мы берем сложную модель, и для того, чтобы ее объяснить, строим очень простую модель, которая ведет себя примерно так же, но в некоторых диапазонах. Типа человек приходит получать кредит, ему кредит не дали. Говорит, а почему ему кредит не дали? Да, он, говорит, старикам вообще кредит не дает. То есть вот эта локальная суррогатная модель, она в принципе объясняет поведение модели вот в этой конкретной точке, то есть он старик, ему не дали. Был бы он помоложе, ему бы дали. Она может быть линейной. То есть, например, мы берем и говорим, что мы просуммировали твою зарплату с коэффициентом 1, твои накопления с коэффициентом 10 и пришли к выводу, что сумма больше, скажем, 30 тысяч долларов, значит мы можем дать тебе кредит. Или меньше 30 тысяч, значит мы тебе не дадим кредит. На самом деле эта модель врет. То есть для другого человека она выдаст другую линейную функцию, которая его объясняет. То есть она позволяет нам интерпретировать в точке. А как ее делают? То есть мы берем точку и чуть-чуть шатаем и смотрим, как изменяется ответ модели. То есть мы берем, допустим, человека, которому не дали кредит, чуть-чуть увеличиваем его значение от среднего дохода, смотрим, насколько изменилась вероятность, что ему дадут кредит. И говорим, ага, твой средний доход участвует в твоем кредитном скоминге с весом, допустим, таким и так далее. То есть мы можем построить простую интерпретируемую линейную модель, которая в одной точке будет прикидываться нашей сложной моделью. Она селективна, поскольку она нам показывает важные признаки, она информативна, то есть мы понимаем, что можно изменить до определенного предела. Она локальная, объясняет хорошо поведение модели в точке. LIME может объяснять не только для табличек, а, например, для текстов. То есть вот этот пример тоже из статьи про LIME. Люди классифицировали спам, не спам в комментариях к YouTube. И вот этот конкретный комментарий был помечен как спам, и LIME объясняет почему. Ну, потому что в нем есть слово channel. Люди, которые в комментариях к чужим видео пишут про какой-нибудь канал, они обычно спамеры. То есть все остальное не имеет признаков спамера, а channel спамер. Что интересно, с помощью LIME можно объяснять решение нейронок на картинках. Тут это делается интереснее. То есть мы берем и режем картинку на так называемые суперпикселы. То есть области примерно одинаково закрашены. Человечество умеет уже делать это лет 50, наверное, с 70-х годов. Алгоритмы для выявления суперпикселов известны. И потом мы суперпикселы по одному заменяем на фон и смотрим, как изменилось решение модели. И таким образом мы смотрим, как та или иная часть картинки повлияла на ее ответ. И вот тут есть человек с маской собаки, играющий на гитаре. И наша нейронная сеть говорит, что это немножко электрогитара, потому что гриф у нее такой длинный. Это немножко акустическая гитара, потому что у нее такая вот декая желтая. Ну и это еще немножко лабрадор. На самом деле это не лабрадор, это golden retriever. Но тем не менее общая идея, как мы можем объяснить, почему модель принимает на этой картинке такие решения, понятно. Но все это не имеет на самом деле никакого научного обоснования. Просто люди подумали, придумали, решили, что наверное можно построить линейную регрессию, которая будет объяснять проведение модели в точке почему линейным, почему она будет объяснять, почему на это можно полагаться. Ответа нет. Есть интересная модель в кооперативной теории игр Shape Your Values. То есть предположим, что три человека решили делить между собой выигрыш, например в лотерею или не в лотерею, пошли они на кегл, допустим. То есть три человека пошли на кегл, выиграли конкурс, им нужно разделить между собой выигрыш. И они начинают спорить. Один говорит, я старый опытный дата-сайентист, мне надо много денег. Другой говорит, нет, я молодой энергичный программист, я за вас код писал, пока вы тут чилились. А третий говорит, я вообще-то ученый, я один из вас понимаю, что тут происходит. Кому же отдать больше денег, кому меньше. Вопрос не разрешим, если бы у нас было множество параллельных вселенных, могли бы отправить их много раз на кегл, допустим, поодиночке, попарно, и посмотреть, сколько денег выиграют они в той или иной комбинации. И перебрав все возможные варианты, мы бы могли сказать, что мат ожидания выигрыша при добавлении игрока А увеличивается на 7000 долларов, при добавлении игрока Б увеличивается на 4000 долларов и так далее. И вот это мат ожидания увеличения выигрыша, то есть насколько мы больше добудем, если у нас будет этот игрок в команде в среднем, и есть шепьюэлиус. И собственно говоря, мы берем, считаем шепьюэлиус всех игроков и делим добычу пропорционально шепьюэлиус. Это научно обоснованный способ делить деньги, и насколько я знаю, однажды в американском суде он прокатил в качестве объяснения. Есть хорошая библиотека ШЭП, которая использует эту математику для объяснения решений модели машинного обучения. Только тут вместо людей, которые идут вместе и выигрывают конкурс на Кегл, используются признаки. То есть, например, мы возьмем комбинацию вот этих признаков вместе, и эта модель у нас настолько хорошо сможет работать. А если мы вот этот признак выкинем, ее качество работы скорее всего ухудшится. И затем мы можем, она достаточно быстро работает, она не делает полного перебора всех вариантов, там используется аппроксимация, быстрая оценка шепьюэлиуса. Но тем не менее, эта модель есть, и мы можем для любой модели, практически для любой модели машинного обучения, не влезая в ее потроха, посчитать, почему она приняла то или иное решение, то есть получить локальное обоснование. Вот это конкретно из медицинской тематики, то есть человек под наркозом, и модель постоянно собирает жизненные показатели и предсказывает, получит он повреждение мозга по сравнению со снабжением мозга кислородом или не получит. То есть считает такой балл, чем балл выше, тем лучше. И вот тут мы видим, что в каждый конкретный момент времени мы можем объяснить, почему этот балл получился такой, потому что возраст уменьшал его балл, а допустим жизненные показатели, снятые с монитора, то есть там пульс, частота дыхания и так далее и тому подобное, не улучшали его. То есть в принципе у больного все хорошо скорее. Дмитрий, вот вопрос про Шепли Уэллис. Означает ли это, что нужно каждый раз перетренировать модель, чтобы получить этот один сэмпл по парной игре, при добавлении игрока? Нет. Мы же можем на самом-то деле, вместо того, чтобы его... То есть предположим, давай вот сюда вот вернемся. Здесь как делается? То есть мы заменяем на средние, на то, что не влияет на модель. То есть у модели есть какой-то базовый ответ. Вот здесь вот он отмечен. Base value 22-34. То есть графичный на уровне предикта получается? То есть если мы выдадим что-то такое, средние признаки по больнице, то она выдаст 22-34. Мы смотрим только предикты. Модель перетренировать не нужно. То есть мы подаем ей разные признаки на вход и смотрим, что она ответила, чуть-чуть их качаем. То есть при объяснении с помощью ShapeValues модель переучивать не нужно, при объяснении нейронок модель переучивать приходится иногда. То есть я про это подробнее расскажу. Ответил ли я? Вот, ShapeValues можно считать не только как локальное, то есть объяснение модели в конкретной точке для конкретного сэмпла, но и в среднем посмотреть, насколько у нас возраст обычно влиял на ответ модели, насколько у нас насыщение крови кислородом влиял на ответ модели и так далее. То есть выбрать среднее абсолютное значение модели по всем точкам можно сказать, ну вот этот признак важнее, этот признак не важнее. Это будет похоже на карту важности, которую мы рассматривали несколько ранее. Но в отличие от вот этой, которая показывает, насколько просто данные были удобны для модели, вот это хорошая важность, это настоящая научно обоснованная важность, патентованная. В принципе, глядя вот в эту важность, можно отбирать признаки. То есть те, где важность маленькая, их выкидывайте с датасета, и модель все равно будет хорошо работать. Те, где важность большая, оставлять, модель будет работать с ними хорошо. В принципе, с помощью ШАП отбирать признаки можно, но есть более хорошие способы для отбора признаков, но работает. С помощью ШАП можно также объяснять не только таблички, но и картинки. Например, вот у нас есть куличок и сурикат. И мы спрашиваем у модели, что заставляет тебя думать, что это куличок? Ну и она говорит, ну нос у него длинный, вот я смотрю на нос, думаю, ну точно кулик. А что заставляет думать тебя, что это сурикат? Ну, видишь, глаза у него черные, круги такие, наверное, это сурикат. Ну да, то есть модель нам подсвечивает те части картинки, которые повлияли на... ШАПа нам подсвечивает те части картинки, которые модель использовала при принятии решения. И в принципе, это позволяет нам как-то проинтерпретировать поведение модели. Для картинок, впрочем, есть гораздо более хорошая технология для городка. Дело в том, что в... Дим, тут вопрос в чате. Что значит исключить признак в контексте картинки? Исключить признак в контексте картинки? Закрасить средним, например? Можно я немножко вмешаюсь? Это от меня вопрос. Я просто относительно недавно делал это и обычно это делается с помощью выбора какого-то фона. Но просто я глазами увидел, что эти ШЭП-велиус там, где они находятся, очень сильно зависят от того, какой именно фон вы выберете. Например, белый, черный, или это средняя картинка. И вот это очень сильно влияет. Я так и не понял. На самом деле я про это упомяну. Дело в том, что в принципе все эти... ШЭП-велиус это перестановочная важность. То есть есть такой класс методов по расчету важности, когда мы пытаемся перетусовывать данные и пытаемся понять, повлияло ли это как-нибудь. То есть, например, смотрите. Вот не на картинках, а на табличках рассмотрим. Предположим, что у нас есть табличка, в которой есть пол, возраст, месячный доход. И мы оцениваем кредитоспособность. И мы думаем, что месячный доход он влияет на кредитоспособность. Значит, если мы возьмем и столбец с месячным доходом случайно пересортируем, то у нас качество работы модели ухудшится. Правильно? Если он влиял. А если качество модели не ухудшится, значит она на него не опиралась. Ну и тут то же самое. То есть мы берем и переставляем, перекрываем какие-нибудь области в картинке с фоном стандартным, средним, нормальным для картинки. И смотрим, повлияло это или нет. Проблема тут на самом деле в том, что все эти перестановочные методы на картинках не работают. Они показывают нам не то, насколько этот кусочек был важен для ответа на нейронки, а насколько он был необычен для нейронки. Наверное, вот это объясняет вашу проблему. Я как раз просто хотел на предпоследнем слайде это все разобрать, потому что больно, что разговор длинный. Но если у вас необычность в датасете может совпадать с важностью, а может и не совпадать. То есть пример, когда необычность совпадает с важностью, например, что у вас на всех кадрах нет самолета летящего по небу, а на одной, допустим, есть. И вам, кажется, нужно самолет объективить, раз оно необычное с самолетом. Пример, когда необычность не совпадает с важностью. Например, у вас есть датасет, и в нем, везде он сделан на кухне, а один сделан в зоопарке. И вам нужно определить, есть ли в кадре, например, мобильный телефон. То есть зоопарк очень необычное место. Нейронная сеть будет обращать внимание на кучу мелких подробностей, но на самом деле они не повлияют на то, узнает она телефон или нет. Тут еще два вопроса в чате есть. Первый вопрос по поводу LIME. Зачем нужна дополнительная суррогатная модель, если можно смотреть, как реагируют на изменения для конкретного сэмпла исходная модель. Если подавать исходной модели на вход один и тот же сэмпл, меняя в нем значение какого-либо признака, и смотреть, как меняется выход, это не будет лучше. То мы получим LIME, вот и все. Это и есть LIME, только посчитанный за вас. То есть смотрите, вы берете, немножко шевелите признак, и смотрите, как он повлиял на ответ модели. Получаете производную, эту производную подставляете в параметры линейной функции. Это и есть LIME. То, что вы сказали, это не замена LIME, это LIME есть. Просто не оформленный в виде алгоритма, а руками сделан. Там еще один есть комментарий. На табличках-то с десятью фичами SHAP не дождаться, а уж про картинки, видимо, сомнение какое-то у человека, что это работает. На самом деле, я вот недавно гонял SHAP на датасете с, по-моему, десятью тысячами признаков, если я ничего не путаю. И он был достаточно живой. То есть, это вопрос мощного железа и сколько строк. Вообще, скорее всего, проблема тут не в количестве столбцов, а в количестве строк. То есть, когда у вас не хватает мощи посчитать объяснение, можно взять подвыборку небольшую и просто на ней посчитать. Но вообще, да, SHAP, как любая перестановочная сложность, считается долг. Это у него есть. Но SHAP считается гораздо быстрее, чем другие перестановочные сложности. И, опять же, для какой модели вы ее считали, если не секрет? Можно уточнить? Потому что для разных моделей SHAP считается по-разному. То есть, в моей практике он считался довольно-таки прилично быстро. Так, ответили для деревьев. Ну, вот я как раз для Random Forest, для Игжи Густаева считал. У меня такая же нога и не болит, как в том анекдоте про хирурга. Но медленно считается, надо другие способы смотреть. Если можно, я про нейронки еще дорасскажу. В большинстве случаев сейчас в промышленности для распознавания картинок используют сверточные сети. Сверточная сеть по сути своей состоит из ведра с матрицами, на которые картинка сложным образом переставляется. И двух- или трехслойной полносвязной нейронной сети, то есть классификатора, который потом смотрит, что у нас получилось. И тут ребята придумали красивое элегантное решение, поскольку у нас в нейронной сети, вот в ее первом сверточном слое, можно сказать для каждого конкретного выходного нейронно-сверточного слоя, какие пиксели картинки повлияли на него. И в зависимости от того, насколько этот пиксел повлиял на решение нашей модели, покрасить те или иные области исходной картинки. То есть мы тут фактически делаем две интерпретируемости. Сначала мы смотрим, насколько у нас важен был вход нашего классификатора, это то, что у нас FC layer activation на картинке. А затем мы для каждого входа пропорционально его активности красим те пикселы, которые на него повлияли. И получаем вот такую картинку, то есть куда нейронная сеть смотрела, когда она принимала решение. Скорее всего, с моих слов это не очень понятно, но поверьте, что с нейронками это самое быстрое, что можно сделать со сверточными. То есть все другие алгоритмы объяснения того, как работает нейронная сеть, они ужасающе медленны. А этот работает быстро, для него не надо переобучать сеть. И он позволяет нам сказать, куда смотрела нейронка. Опять же, тут есть тонкий момент, обязательно, что она смотрела на то, что повлияло на ее решение. Представьте себе, опять же, что вы сидите, разговариваете с человеком, он просит у вас денег взаимы, тут в кабинет забегает горилла, пробегает, убегает. Вы точно смотрели на гориллу, она вряд ли повлияла на решение, дали вам взаимы или нет. Но GradCAM обращает, подсвечивает те места, куда смотрела нейронка, когда принимала решение. Часто для отладки этого достаточно. Вот, например. Нейронка, глядя на картинку, говорит, что это немножко кошка, немножко собачка. Когда она думает, что это собака, она смотрит на лицо собаки, когда она думает, что это кошка, она смотрит на хвост и полосатые бока кошки. Это средняя сеть GradCAM. Что интересно, здесь есть вариант Е и К, это те же самые вещи, полученные с помощью карт перекрытия. Карты перекрытия очень трудоемкий способ, когда мы случайным образом перекрываем небольшой кусочек картинки и смотрим, как изменилось решение. Этого вы точно не дождетесь, пока оно посчитается. И, собственно, они приведены для того, чтобы показать, что карты перекрытия показывают примерно то же самое, что и GradCAM, но только, допустим, на 3 порядка медленнее. GradCAM очень быстрый алгоритм. У него есть эффективные реализации для PyTorch, например, и, скорее всего, для Keras тоже, если я просто PyTorch пользуюсь. Fast.ai, библиотеки, тоже очень популярны для картинок, для таких учебных проектов. Он просто встроен как основной способ объяснения, он там даже никак не называется GradCAM, он просто называется объяснением. Интересно, я могу скинуть ноутбук с тем, как на Fast.ai это все кошек от собачек отличать и интерпретировать. У меня с летней школы, с зимней школы остался. Ну и про картинки. Народ не первый год уже прорабатывает интерпретируемость нейронных сетей для картинок и впервые какой-то разумный результат был получен в 2013 году, так называемые карты значимости. Это, наверное, например, B&H, карты значимости. Что мы делаем? Мы берем нашу нейронную сеть. Обычно, когда мы учим нашу нейронную сеть, у нас есть фиксированные картинки, а мы подстраиваем веса в нейронной сети до тех пор, пока она не начнет правильно отвечать. А что если мы сделаем наоборот, зафиксируем веса в нашей нейронной сети и начнем подстраивать пикселы в картинке до тех пор, пока нейронная сеть не начнет отвечать нам тем или иным способом? Тут мы и получим те самые карты значимости. Тут я, наверное, хотел бы переключиться на расшаренный свой браузер. Сейчас, наверное, весь рабочий стол расшарю. Я хочу показать прямо. Кстати, видно мой браузер? Видно статью. Ага, вот, я просто картинки статьи хочу показать. Они брали картинку и шевелили в ней пикселы до тех пор, пока она не начинала отдавать правильный ответ. То есть, они брали просто зашумленную картинку и делали то же самое, что делают в ГАНах. Они обучали картинку, которая подойдет под этот класс. То есть, что нам нужно нарисовать на картинке, чтобы она определялась как кукуруза. И разными способами они ее генерировали. Видно, что она выделяет, показывает нам птичку, показывает нам кукурузку. И вроде бы даже лучше, чем просто детектор краев. То есть, карты значимости в 2013 году на самом деле произвели прорыв в объяснении нейронок. То есть, люди наконец поняли, куда нейронки смотрят. Но случилось страшное. В 2018 году хорошо проработали тему, что на самом деле карты значимости не работают. Почему они не работают? То есть, карта значимости, по идее, должна зависеть от весов сетки. Она же объясняет, как работает наша сетка. Но на самом деле эксперименты показали, что можно случайно переставить весов сетки, и карта значимости все равно будет выдавать примерно то же самое. Кроме всего прочего, карта значимости должна, по идее, зависеть от закономерности, которая есть в данных. То есть, если бы мы случайным образом переставили разметку, то есть, взяли бы, допустим, на птичек, повесили разметку кукурузы, а на кукурузу разметили разметка птичек, то у нас, по идее, должны были получиться другие карты значимости. Но на самом деле нет. И вот у нас, я не знаю, где она у меня тут, сейчас подтормаживает чуть-чуть у меня этот самый. Собственно, вот в этой статье как раз они показывают, что в принципе просто детектор краев показывает сопоставимо. Эта статья оригинальная не про карты значимости, это как раз критика карты значимости. То есть, они говорят, что мы сделали проверку, насколько хорошо работают карты, детектор краев, и мы переставили разметку, мы переставили веса сети и все равно получили очень похожие картинки. В принципе, вот тот метод городкам, кстати, он ломается. То есть, объяснение с помощью городкам ломается, если мы переставим веса или разметку, что как раз говорит о том, что он разумный. А просто карты значимости, они нам показывают не то, насколько это было важно для нейронки, а то, насколько этот пиксел на картинке необычен. То есть, карты значимости на самом деле, как было доказано в 2018 году, они просто показывают, насколько этот пиксел картинки необычен. А в чем разница необычности и важности? Необычности и важности в том, что если ты, допустим, распознаешь мобильные телефоны, и весь датасет был снят, как я уже говорил, например, на кухне, а потом ты пошел и сфотографировал мобильный телефон в зоопарке, у тебя Silencing Map подсветит решетки, подсветит горилл, подсветит зебр, но примет решение все равно на основании того, как выглядит мобильный телефон. У тебя, допустим, ты едешь по дороге, нейронка детектирует пешеходов, и в тот раз появился какой-то знак необычный. Она на него обратит внимание, но в расчет его не примет. Она не будет на основании этого знака решать, пешеход это или нет, но она на него будет смотреть. То есть, карты значимости показывают, куда нейронка смотрит. Вне зависимости от тренировки она будет это делать? Фактически, да. То есть, как раз эта работа, которая Scenic Check, она показывает, что зависимость от тренировки не очень большая, что Silencing Map сильнее зависит не от весов сети, а от самого датасета. То есть, это свойство датасета, а не свойство весов сети. В этом как раз и интерес этой работы, что они взяли и нижнюю шоколадку из пачки выдернули, все обрушилось. Вся идеология под картами значимости, которыми 5 лет люди пользовались, и ничего лучше вроде бы как не было. То есть, все говорили. То, что обычно говорят, карты градиента, вот это вот они и есть, карты значимости. Реально они не работают. Но они показывают вам необычные места в датасете, и нейронная сеть обычно учится на необычных местах в датасете, и эти вещи могут совпадать, а могут не совпадать, как повезет. Вот такая вот история. Дальше люди говорят, ну хорошо, давайте мы возьмем и посмотрим примерно тем же самым способом, как нам надо изменить исходную картинку, чтобы возбудился тот или иной нейрон. То есть была гипотеза, что в нейронной сети внизу есть нейрон, и каждый нейрон запоминает что-нибудь. Вроде бы как нейроны, которые в начале нейронной сети запоминают, выделяют признаки полосатой картинкой или не полосатой, и те, которые подальше, есть там кружочки или нет. Те, которые подальше, похожи они на человека, или нет. Чем дальше мы по нейронной сети, чем дальше от входа, тем более сложные концепции каждый нейрон выучивает. Такая была идея. И люди начали ее проверять, и в принципе так и вышло. То есть мы взяли какой-то конкретный нейрон в нейронной сети и начали менять исходную картинку, чтобы максимизировать активацию этого нейрона. И для разных нейронов у нас получились вот такие вот красивые картинки. В начале нейронной сети нейроны выучивают полоски. Дальше они начинают выучивать вот такие вот интересные текстурные штучечки. Перемещаемся еще правее и нейроны уже способны узнавать узоры, но пока эти узоры все еще не имеют особенного смысла для человеческого глаза. Здесь уже похоже, что она научилась узнавать какие-то глаза, цветочки, квадратики. А здесь уже ответ нейронной сети в принципе, то есть активация нейрона. То есть скорее всего этот нейрон отвечает за узнавание каких-нибудь зданий, этот за узнавание глаз, например. Этот, может быть, нейрон определяет пауков и насекомых. Вот этот, может быть, ловит шторты и руки. То есть, может быть, этот ловит еду нейрон. Этот ловит собачек. То есть, в принципе, мы можем понять, за что отвечает тот или иной нейрон, строя визуализацию. Есть целый сайт distil.pub, на котором несколько лет подряд выкладывали прекрасные совершенно материалы по визуализации нейронов. За что конкретный нейрон в сети отвечает. Это здорово продвинуло понимание того, как работают нейронные сети, но для конкретно взятой вашей промышленной нейронной сети, которая у вас конкретно здесь обучена на ваших данных и работает, это не очень много дает. Вот она не узнала пешехода на этом фото. Почему не узнала? Да черт бы его знал. Вот у вас несколько миллионов нейронов, посмотрите, каждый из них что выделяет. Может быть, догадаетесь. Однако же для самых распространенных архитектур, таких как ResNet-18, VGG-16 и так далее, LexNet, эти карты уже построены и вы, в принципе, можете походить по этим Activation Atlas и посмотреть, что вообще видит эта сеть, что она больше ориентируется на углы или больше ориентируется на текстуры. Ну и просто на самом деле с пивом позалипать, мне кажется, для датастиниста ничего лучше, чем карта активации нет. То есть они красивенькие. Но не очень практичные, правда. Дальше мысль не стояла на месте и в 2020 году как раз свежая работа Concept Activation Vector. Люди говорят, ну хорошо, а давайте мы научим нейронную сеть объяснять концепциями. То есть мы возьмем и нашу нейронную сеть, уже обученную, и отдельно обучим ее на примерах всего полосатого. Вопрос в чате. Первое, там спрашивали нейрон или сеть, уже не скажу к чему это относилось. И второе, карты активации выложены для сетей, обученных на каких-то конкретных датасетах? Ну обычно, поскольку вообще-то датасеты это большая проблема в машинном обучении и хороших, больших датасетов для картинок вообще-то мало. Обычно, когда говорят про сверточные сети, обычно имеется ввиду, что они обучены на имиджнете. И почти все предобученные сверточные сети на нем и обучены. А вот тут уточнили, шорты детектит нейрон или слой? Нейрон. Это именно для конкретного нейрона в слое. То есть, просто чем дальше от начала, тем более сложная концепция у нас внутри нейрона водится. Внутри слоя нейроны выучивают. То есть, слои, которые у нас... Так, блин, а как бы убрать эту панель сверху? Знает кто-нибудь, как убрать эту панельку сверху, зумовскую? Нет, она так и останется, как бы это интерфейс зума. Черт, значит надо свернуть просто интерфейс браузера, иначе они дерутся. Чем правее у нас, где у нас какая-нибудь картинка с нейронкой есть? Вот тут пока еще дополняют. То есть, если в своей задаче есть нейросет, то имеет смысл перестроить карты активации даже для известных архитектур, но это вопрос. А если у вас бесконечные патроны туда? Проблема тут в том, что вам надо научить столько картинок по этому способу, сколько у вас нейронов в сети. То есть, вы просто берете каждый нейрон и входную картинку для него шевелите до тех пор, пока этот нейрон не окажется максимально активирован. Что-то мне подсказывает, что если вы не Google и не Amazon, то вы не будете этим заниматься. Поэтому я и говорю, что они на практике не очень полезны. То есть, вы можете посмотреть, какие результаты получились у Google или у DeepBrain. Но вы для какого-то конкретного нейрона можете получить объяснение, что его активирует. Что вы с этим объяснением будете делать, когда нейронов у вас миллионы, а объяснение для каждого вы получаете, допустим, полчаса. Вперед, не очень понятно зачем. Так вот, идея была вот какая. Давайте мы научим нейронную сеть отвечать нам на примерах, чем эта картинка ей понравилась или не понравилась. То есть, в принципе, человеку мы можем спросить, на что, допустим, похож слон. Он говорит, ну знаете, это представьте себе такая корова с очень длинными толстыми ногами. У нее впереди такой шланг висит, сзади такой шланг. И такие уши большие, как лопухи. И рогов у нее нет. То есть, он описал вам на тех концептах, которые у вас уже есть. И, в принципе, нейронную сеть можно заставить делать то же самое. Например, есть такая штука вообще, как Zero-Shot Learning, когда вы можете обучить нейронную сеть узнавать предмет, которого не было в обучающей выборке. То есть, вы ей показали предметы полосатые, вы ей показали предметы лошадь, а потом сказали, знаешь, вот если встретишь полосатую лошадь, то это зебра. И примерно на этой же идее есть технология объяснения нейронных сетей с помощью концепт Activation Vectors. То есть, мы говорим, ну вот, давайте мы обучим нейронную сеть некоторым нашим концептам. То есть, покажем ей, что такое полосатость, покажем ей, что такое круглое, покажем ей, что такое квадратное. А потом мы ей что-нибудь покажем и проинтерпретируем с помощью обученных наших концептов. Нашла оно тут полосатое, нашла оно тут круглое. То есть, вот, например, смотрите, здесь, вот, мы ее обучили концепту полосатое, да, и потом, что они тут? Ага, покажи нам женщину, пожалуйста, наиболее похожую на концепт галстука. Покажи нам, пожалуйста, мужчину, наименее похожую на концепт галстука. Непонятно, почему здесь у нас Обама был по этому принципу дискриминирован. Вот. Все это достаточно хорошо работает, но для каждого концепта, концепт круглого, концепт зеленого, концепт мужчины, концепт женщины, вот, вам нужно учить нейронную сеть дополнительно выявлять вот эти концепты и потом она вам объяснит. Это похоже на то, как вы сначала для того, чтобы человек вам объяснил, что он видел, вы ему показали кучу примеров и спросили, на это похоже, на это похоже, на это похоже. В принципе, это работает, но, во-первых, это трудоемко, а во-вторых, если вашего концепта не было в обучающей выборке, то есть, если в вашей тестовой выборке не было, допустим, концепта круглого, а нейронная сеть решила, что это дорожный знак, потому что он круглый, вы об этом не узнаете. Ну и, кстати, вот тут эта интересная, известная находка, что сверточные сети часто определяют гантели на фотографии, потому что их держит рука, не потому что это гантеля, а потому что все, что фотографирует обычно такое продолговатое в руке, это обычно гантели. То есть, для того, чтобы понять, почему нейронная сеть узнает гантель, оно похоже на руку, на кисть руки, оно похоже на болло, это два шара, связанных вместе, которыми, например, страусов ловят. Ну и оно похоже на лампшейд, как это получается, фонарик для ламп, русский язык немножко разобрался у меня в голове. В общем, мы можем попросить нейронную сеть объяснить свое решение на концептах, если мы ее обучим этим концептам. Проблема тут в том, что нам ее нужно учить каждому из этих концептов отдельно, вручную, долго. Но в 2017 году еще была прекрасная статья на эту тему, Neutral Dissection, когда вместо того, чтобы сеть учить концептам, мы ей просто показываем примеры из датасета и говорим, на вот этот класс, допустим, лампа, какие картинки из датасета тебя больше возбуждают, какие меньше. И строим объяснения существующими классами. Тут именно такая проблема, что если какого-то нужного для объяснения картинки в датасете нет, то мы не узнаем. То есть у нас есть только положительные примеры, отрицательных мы тут не найдем. Но и с этим ученые справились. У нас же есть ганы, которые могут генерировать картинки. Давайте мы будем генерировать картинку такую, чтобы нейронная сеть сочла ее достаточно хорошим объяснением. То есть мы перед нейронной сетью, которую мы хотим объяснить, ставим ган. Ган генерирует картинки. А вместо дискриминатора мы смотрим активацию того или иного класса. Таким образом мы можем, это вот хорошо похоже на тот метод, который про Монтекарло спрашивали, про Монтекарлить. Вот это как раз про Монтекарлить. То есть мы случайным образом генерируем картинки на вход в сети и смотрим, на какие у нее душа откликнулась. Чрезвычайно трудоемкий способ, но он на самом деле позволяет вытащить из сети, на что она ориентируется, когда говорит свечка или банан или что-то еще. А также с его помощью можно находить закладки в нейронной сети. Или как-то нужно его приготовить? Приготовить он на самом деле проще, чем обычный ган. То есть ей не нужен такой полномасштабный, сложный, заведенный ган. Ну и что вот тут интересно на самом-то деле, что если посмотреть по годам, то пони бегают по кругу. Концепт активейшн вектора придумали буквально в апреле, а нитверг диссекшн, который ровно про это же, но без всяких сложностей и гораздо проще, придумали в 2017 году. А в 2016 году придумали вообще без примеров о генеритих ганах, хотя по смыслу, если бы концепт активейшн вектор придумали сегодня, то нитверг диссекшн должны были придумать завтра, а послезавтра придумать синтез примеров для объяснения. То есть получается, что ученые, во-первых, не считают работу друг друга, во-вторых, большая часть идей уже в том или ином виде есть, их просто можно пойти назад посмотреть, когда людям не хватило процессорной мощности или люди не умели какую-то оптимизацию, или люди не умели релю, например, а пользовались сигмойдой, поэтому ничего не взлетело. В общем, уже наработано много, просто бери чуть-чуть, оптимизируй и получишь новый метод интерпретации картинок. Кто-то еще спрашивает в чате. Первый вопрос. Там средний банан по всему датасету получается? Там получается не средний банан по всему датасету, получается, какие картинки сильнее всего похожи на концепцию банана в нейронке. То есть у нее есть какая-то концепция банана, мы ей показываем фотографии, вот на это откликнулось – ага, значит она больше похожа на концепцию банана, на это откликнулось – нет, значит меньше похожа на концепцию банана. И мы выбираем какую-нибудь картинку, которая сильнее всего возбудила нейронку на банан. А потом мы смотрим, допустим, ту же самую карту заметности, с которой мы начали разговор, и мы можем подсветить вот эту самую активированную картинку картой заметности и получим, какая часть картинки ее заинтересовала. И скорее всего это и будет объяснение банановости. То есть самая необычная картинка наиболее банановая, она скорее всего вот эта вот часть будет, самая суть банановости на этой картинке и будет. И следующий вопрос еще, возвращаясь к эмбеддингам, чем GRADCAM с ближайших соседей не концепт? В GRADCAM на самом-то деле он делает две вещи. Во-первых, он считает рецептивные поля классификатора. То есть у нас сверточная нейронная сеть состоит из классификатора и собственно сверток, классификатор справа, свертки слева. И к каждому выходному пикселу сверточного слоя на него пикселы входного слоя картинки оказывали разное влияние. Какие-то повлияли на него сильнее, какие-то слабее. То есть, грубо говоря, это такое расплывчатое пятно, похожее на двумерное гауссовое распределение. То есть такое пятно туманное, яркое в середине, туманное по краям. Это примерно рецептивные поля нейрона. Это первая техника. Вторая техника, они брали те же самые просто карты градиента на классификаторе. То есть насколько классификатор возбудился на ту или иную концепцию и подсвечивали через рецептивные поля исходную картинку. Как вообще, откуда уши растут? Первоначально для того, чтобы объяснить картинке, я про этот метод даже не рассказывал, потому что он ужасен, люди просто учили обратную нейронную сеть. Мы научим нейронную сеть задом наперед. Обычно мы учим нейронную сеть по картинкам выдавать классификацию, а давай мы научим нейронную сеть по классификации выдавать картинки. Это трудоемко, это требует переобучения сети, ну и качество получившихся картинок на самом деле так себе. Тут они говорят, давайте мы будем делать это только с последним полносвязанным слоем, для которого это имеет смысл. А для остальных слоев мы просто будем брать рецептивные поля и подсвечивать картинку в зависимости от того, насколько активизировался этот классификатор. Что ты называешь рецептивными полями? Вот смотри, у нас есть операция свертки. Про операцию свертки надо рассказывать, как она работает? Нет? Нет. У нас есть операция свертки, допустим, картинки. Она первый сверточный слой нам образовала. И каждому пикселу первого сверточного слоя соответствовало несколько пикселов исходной картинки. Не все подействовали на него, в разной степени на него повлияли. Затем мы переходим к второму сверточному слою. И тоже не весь первый сверточный слой повлиял на конкретный пиксел с второго сверточного слоя и т.д. Если мы пробросим эти зависимости назад, провернем их по сверточным слоям, мы увидим, какие пикселы картинки исходной в какой степени влияли на последний сверточный пиксел. Вот это рецептивные поля последнего сверточного пиксела. Этот термин, по-моему, отдельно где-то разбирается, я тоже ссылку на него скину, про рецептивные поля. Оказывается, что для сверточных сетей не обязательно тащить градиент через всю сверточную сеть, можно тащить его только до пикселов последних сверточных, а дальше просто рецептивными полями разбрасывать, как фонариком подсветить на нашу картинку. То есть, активация каждого нейрона, как фонарик, проходя через сверточную сеть, расширяется влияние нейрона и в конце концов на него влияла вся картинка, но разные ее пикселы в разных пропорциях. Что-нибудь еще рассказать? Просто очень трудно понять, надо еще говорить про это или не надо, когда не видишь. Слышно? У меня была другая мысль в голове, когда я об этом писал. У меня даже если взять VGG какую-нибудь и отрубить ее в голову классификатора, получим имбеддинги, правильно? Да. То есть, нам она выдала какой-то класс, мы имбеддинг забрали. И им можно пользоваться для целей КНН. Очень часто делают поиск по картинкам ровно таким способом, как вы сказали. То есть, считают имбеддинг до классифицирующей головы, складывают их, например, в какой-нибудь файс или анной и потом ищут картинки. И, в принципе, для целей найти картинку, похожую на эту, оно хорошо работает. Но оно не работает для целей объяснения, почему эта картинка была признана кошечкой или собачкой. А для поиска картинок, похожих на эту, это очень хорошо работает. И если вы хотите делать КНН на картинках, то есть у нас есть фотография какого-то чувака, одетого в черное, с торчащими за спиной мечами, он похож на фотографию ниндзейских кинофильмов. И поэтому вы его не пускаете на объект. А вот в городке это дополнительная архитектура где-то сбоку прикручивается? Нет, вы просто отрезаете веса, то есть он без модификации нейронки, вам главное надо иметь доступ к активациям сверточного условия. Я где-то видел статьи, где делали еще одну нейронку, которая объясняла веса другой, типа дистилляции что-то. Вот это как раз первые эксперименты с объяснением нейронных сетей, они очень трудоемкие, трудозатратные. И сейчас все идут по тому, чтобы еще одну нейронку не учить. К отладкам он тем и хорош, что он почти бесплатен. То есть вы его очень быстро получаете, поэтому он есть эффективный для пай-торча, для всего остального. И он, несмотря на то, что он не дает честного объяснения, почему нейронка приняла это решение, зато он очень хорошо показывает куда она смотрела, когда принимает решение. И поэтому лично я для отладки ровно им и пользуюсь. И почему это не считается очередной аномалией, как мы откинули с ленты МАПС? Смотри, вопрос вот такой, что когда тебе нужно отлаживать сетку, в принципе и карты заметности тоже работают. Потому что обычно аномальная картинка сама по себе интересна. Единственное, что там они получаются более размазанные, больше зависят от краев. То есть, грубо говоря, оно... Ну там, кстати, есть картинка, как она получена. Вот эти критики, кстати, в критике с LNCMAP, там по городкам тоже прошли. То есть, и городкам не подходит. Я вообще не понимаю, как вот Edge Detector тут получили? Они говорят, что если мы берем из OpenCV Edge Detector, который вообще без машинного обучения, то он нам тоже картинку нарисует достаточно приличную. Мы тоже можем его назвать интерпретацией. Как по Edge Detector понять, то есть, где края, это туда, где смотрит нейросеть? Понятно уже было в самом начале. Они то и говорят, что на самом деле ваши с LNCMAP и городкамы просто говорят то же самое, что и наш практически бесплатный Edge Detector на картинке OpenCV без всякой вашей нейронной сети. В этом критика и была. Тут вопрос уже висит, не стал пока прервать. Можно еще раз кратко подытожить, чем городкам всем угодил, а чем нет? Или это уже прошло? Городкам угодил мне тем, что он подсвечивает, на какую часть картинки смотрела нейронка, и он очень дешево и быстро считается. Всякий раз, когда мы интерпретируем нейронку, первый вопрос, насколько эта интерпретация дешева. Для того, чтобы нам посчитать с LNCMAP, нам нужен цикл оптимизации. Мы берем картинку нулевую, фоном закрашенную, и начинаем пробрасывать градиент на пикселы через сеть, чтобы посмотреть, какие из них возбудятся, какие нет. Это мы фактически не полный цикл обучения нейронки делаем, но все-таки мы должны запускать оптимизацию, тогда как для городкам этого не надо. И это прямо означает, что городкам вы можете использовать всякий раз, как ваша левая нога этого захотела, а с LNCMAP вы будете строить, когда у вас будет свободное время и ресурсы. Это поэтому они мне и угодили. Я интересовался тем, что LNCMAP не зависит от перестановки весов сетки, от перестановки, если я правильно помню, пищи. А городкам зависит, потому что у него ломается вот этот классификатор первый, он его честно использует, если вы его переставите, городкам перестанет работать. Я, к сожалению, тут эту картинку не вставил, но я могу тоже в материалах ссылки прислать потом в чате. А вообще у него есть какая-то критика? У городкама? Ну, есть, конечно. В принципе, он как все градиентные методы, он в основном показывает не объяснение, а показывает куда нейросетки смотрела. Я вот такую сексистскую шутку сделаю, к вам придет очень красивая девушка, и вам нужно будет оценить степень ее физической готовности. Вы будете смотреть не только на ее мышцы, я вас уверяю, просто вы так биологически устроены. Но принимать решение будете не на основе ее одежды, а на основе ее общей. То есть мы, люди, смотрим на много признаков, но не всегда то, на что мы смотрим, влияет или должно влиять на наше решение. Ну, понятно, спасибо. Ну и опять же, если так подытожить, для картинок я бы рекомендовал просто брать для сверточных сетей городкам и его использовать. Это дешево, сердито, почти всегда нам нужно просто какую-нибудь подсказку от нейронной сети, типа ну свистни ты для ориентировки, что тебе не понравилось в этой картинке. И городкам на этот вопрос отвечает. Для табличек на этот же вопрос обычно хорошо отвечает ШАП, который мы упоминали. Но есть куча вариантов. Я сейчас быстро пробегусь по инструментам, которые в принципе я часто использую сам. Чаще всего ШАП, конечно. Еще LIME мы про него говорили. Есть микрософтовская библиотека, по-моему, Три интерпретер, которая интерпретирует именно деревья. Есть ALIBI. ALIBI и ENCOR, две очень интересные библиотеки, у них логика другая, чем у ШАПа и LIME. То есть, например, ENCOR пытается выбрать минимальный набор признаков, который определил решение. То есть, например, я прихожу и мне не дают кредит, потому что, скажем, у меня нет недвижимости, у меня маленькая зарплата, например, у меня судимость, я состою на учете в наркодиспансерии. И все это как снежная комната. Я спрошу, почему мне не дали кредит? В принципе, достаточно того, что у меня маленький доход и все. Дальше можно не смотреть. Вот. И вот ENCOR, он выбирает вот такие как раз минимальные наборы признаков, которых достаточно было для принятия решения. То есть, необходимые и достаточные условия. В случае, когда у вас сложно сочиненный разбор полетов, когда вам нужно понять, почему такая странная ошибка случается, или ответить пользователю, который к вам возмущенно пришел, а почему это вы мне кредит не дали? Вот. ENCOR очень хорошее решение. Ну и алиби примерно похожий. Тут в презентации, которые я тоже расшарю, везде ссылки на них, имеет смысл просто посмотреть, пробежаться по документации библиотек. Алиби похожим образом, оно рассматривает контрпримеры и характерные признаки, характерные точки датасета. И иногда для того, чтобы понять, как думает модель, достаточно посмотреть на то, что она считает ключевыми примерами. То есть, какие примеры лучше всего характеризует датасет. И интерпрет – это, опять же, по-моему, микрософтовская библиотека, которая строит изначально объяснимые классификаторы. Ну, то есть, так в рекламе написано – изначально объяснимые классификаторы. То есть, вы его построили, вам сразу шепчу или сразу графики частичной зависимости. Ну, вот на мой практический вкус, если вы возьмете какой-нибудь Кодбуст и его же с помощью встроенных средств объяснения построите интерпретацию, вы получите не хуже, чем вот этот интерпрет, а качество будет лучше. Но я просто большой фанат Кодбуста. Что почитать и посмотреть? Если выбирать одну ссылку, я бы рекомендовал прочитать статью Дьяконова «Интерпретации черных ящиков». Дьяконов преподает в МГУ и все его статьи стоят того, чтобы их читать. Простым очень языком, очень хорошо, очень ярко и понятно написано про интерпретацию как раз моделей машинного обучения. Следующая ссылка – это курс Бекера на Кегле. На Кегле есть мини-курсы на разные темы. В частности, это курс Бекера из шести занятий «Как объяснять модели с помощью шапок». Прямо все на пальцах. Делай раз, делай два, становись здесь, бей сюда, получишь результат. Для тех, кто хочет по-настоящему упороться, есть книга Мольнара «Interpretable Machine Learning». Мольнар подошел к вопросу, честно, он просто собрал все способы, какими можно проинтерпретировать в основном таблички, разобрал их и приложил соответствующую математику. Это захватывающее чтение и если вы интерпретируемостью прямо серьезно интересуетесь, ее обязательно надо читать. У Гугла и Амазона есть свои системы машинного обучения, которые прямо им закинул датасет и получил результат. И, соответственно, есть средства объяснения для них, достаточно хорошие. Следующие две ссылки это гугловская объяснимая AI и про то, как объяснять модели в Azure, микрософтовская. Предпоследняя ссылка это фундаментальный труд, вышедший в апреле этого года, где вообще разбирается, почему и как мы можем доверять моделям, как нам сделать так, чтобы мы могли доверять и полагаться на модели машинного обучения. Там 80 страниц, набитые ссылками через одну и это лучший обзор на тему безопасности машинного обучения, интерпретации машинного обучения, fairness в том смысле, чтобы одноногих негров, гомосексуалистов ваша модель не дискриминировала и так далее. Хороший серьезный труд и там многие известные практики отрасли и известные организации принимали участие в разработке этого документа. И замечательный документ с критикой всего вышеперечисленного. Его я сейчас открою отдельно. Название статьи говорит само за себя. Перестаньте объяснять модели машинного обучения для важных применений и сразу просто используйте понятные модели. Статья вот в чем. Что мы конечно можем соорудить любое правдоподобное объяснение, но правда состоит в том, что оно будет не настоящее. Все эти наши суррогатные модели, которые как бы объясняют, как оно работает, на самом деле это неправда. На самом деле, когда мы объясняем очень сложную модель, очень простую, то есть деревянную модель линейной регрессии, мы не просто жульничаем, мы врем. Но то, что нас на этой лжи поймать трудно, потому что мы говорим, что да, в малой окрестности описываемой точки модель ведет себя примерно так, как нам ряды Тейлора учат, что совсем не сильно отдаляясь от точки, все можно линейной функцией описать. Но на самом-то деле модели будут вводить нас в заблуждение. И вместо того, чтобы строить правдоподобное объяснение моделей, надо просто говорить правду, делать модель, которая изначально понятна. И они говорят, ну да, конечно, вы говорите, что понятную модель построить трудно, но так старайтесь, говорят они, и у вас получится. Статья хорошая, короткая и тоже рекомендую к прочтению. Ну, вот примерно и все. Мне можно писать во все возможные разумные социальные сети, в LinkedIn, в Telegram, в Facebook, в ODS-овский Slack, во ВКонтакт даже. Слайды лежат в интернете, ну и еще я их, наверное, расшарю как-нибудь в Zoom. Все. Что еще сказать хорошего? А вопросы можно позадавать? Конечно, конечно. Да, нужно даже. Можно, как писал, врываться в эфир, задавать вопросы. У нас сейчас начинается такое уже неформальное общение. Все, кто два часа продержались, имеют право. Можно включать камеры, чтобы были, если это возможно, и задавать вопросы. Так, камера что-то не включилась тут на iPad, не хочет. Ну ладно, не суть. Хотел спросить, вот как раз изначально интерпретируемую модель с картинками, это случайно не U-Net какой-нибудь для сегментации? То есть, если можно не решать задачу классификации, почему бы не перейти к задаче сегментации сразу, например? Ну, вообще-то говоря, была такая работа интересная, Begov Patches, где люди нарезали картинку на кусочки на мелкие и обучили нейронку, не сверточную сеть, а именно на мешке. Ну, грубо говоря, смотрите, мы берем картинку, режем ее на маленькие кусочки, допустим 20 на 20 пикселов, и для каждого этого пиксела мы учим сверточную сеть, и потом на эмбеддингах этой сверточной сети мы строим back-of-words. И что интересно, эта сеть очень простой архитектуры, очень быстро учащаяся, показывала качество очень близкое к сложным сверточным архитектурам, и она абсолютно интерпретируемая, потому что она может прямо явно сказать, какой патч повлиял на ее решение на картинке. Ну, вот такие примеры есть, но правда состоит в том, что все эти сетки все равно работают хуже, чем предыдущие ResNet-50 из коробки. Поэтому, если вам нужно что-то практически быстро работающее за малые деньги, вы возьмете ResNet-50 и не будете этим заморачиваться. А так вообще, да, народ пытается построить такие вот сетки. Ну, так это опять задача классификации. Я просто предлагаю подменить задачи сегментации, там проще отлаживаться, мне так видится. Вот как раз деньги DARPA, по идее, должны были уйти, вот те, которые они много бабла выдали, на то, чтобы придумать архитектуры, которые будут понятны сами по себе. Вот они говорят, ну давайте мы не будем интерпретировать эти непонятные архитектуры, давайте мы придумаем такие модели, которые просто понятны. Вот как вы говорите, что мы заменим, допустим, классификацию сегментации и так далее и тому подобное. В принципе, вот как раз в рамках этой инициативы EI, они это именно и делают, примерно то, что вы говорите. Другое дело, что они пока недостаточно далеко тут продвинулись и это неспроста, если много денег, много людей недостаточно далеко продвинулись, наверное, там какие-то есть проблемы, я просто не в курсе. Я слежу за этой инициативой, потому что я лично жду, что оттуда выпадет волшебная кнопка и мы все заживем. Придется больше их интерпретировать. Они по графику должны эту волшебную кнопку в следующем году выпустить, потому что грант на три года давали. Тут еще вопросы есть в чате. Зачитываю. А как у CatBoost спросить, кто научил плохому и где почитать про расширение возможностей CatBoost? Вот тут, во-первых, 4 июня будет митап Яндексовский, на котором они будут рассказывать про свежие возможности CatBoost. Во-вторых, и как раз я думаю, что про эти тоже будут рассказывать. Во-вторых, вообще-то это в документации есть. В документации CatBoost есть Feature Importance и там есть Feature Importance and Object Importance. Object Importance это важность обучающих примеров, а Feature Importance это как раз важность столбцов. Важность по столбцам и важность по строкам. Опять же, если интересно, я могу в ссылке добавить на эту документацию. Она там ищется просто по CatBoost Object Importance. Там есть примеры, на Python хорошие. Можно выяснить, кто модель научил плохому и оторвать ему уши. Можно задавать другие вопросы, спрашивать, что было непонятно, уточнять. Может кто-то свое мнение имеет по этому поводу. Все можно высказывать. Подключайтесь со звуком и задаем вопросы. Либо в чатике, кому звук неудобно. Сразу-сразу спрошу, презентажку можно будет расшарить людям? Конечно, эта презентажка ее можно расшарить. Более того, она уже лежит на сайте по этому адресу. И с ней можно делать все, что хотите. Более того, если вы дадите потом видео, я его тоже туда же выложу к презентажке. Да, как раз думал сделать пост с итогами. Туда видео прикрепить и презентажку. Клево. А можно еще туда ссылку на материал по эмбеддингу и ноутбук с грэдкамом, которые были обещаны? Давайте я сделаю вот как. Сейчас у нас уже 2 часа это дело идет. У меня слегка язык во рту не поворачивается. Я все-таки паузу небольшую сделаю. А потом я Александру накидаю ссылок на эту тему, про которую я упоминал. И он в посте их все соберет. Да, да. Я думаю это будет хорошо. Вот можно будет сюда в чатик написать, что нужно, что обещали, чтобы все это в одном месте было. Ну и там запишем уже. Ну и можно меня в соцсетях, в телеграме в том же самом допустим спрашивать. Я отвечу ссылками поделюсь и если надо помогу. Мы кстати оказываем услуги Red Team. То есть грубо говоря, если у вас есть модель и вы хотели бы убедиться, что она не научилась какой-нибудь фигне, мы за долю малую берем вашу модель, проверяем ее, помогаем доучить, вылезти из тупиков и так далее. Вот такие вещи. То есть мы этим за деньги занимаемся, в числе прочего. Ну и добрые советы я даю за бесплатно всегда. У меня вопрос насчет 86-го года. Что делал ты на ассемблере? Я не на ассемблере, я на Fortran 4. Короче, это была программа, представь себе, она называлась Z1 мозг. Z1 это был наш код в исследовательской группе. Дело в том, что у нас это mainframe, поэтому две буквы твоего проекта, первые, должны были начинаться с кода твоей группы. И они определяли твой приоритет в вычислительных ресурсах. То есть понятно, какой у меня был приоритет, да? Примерно около Plintus. Мне было 14 лет, когда меня пустили изгаляться над mainframe 15, когда мне попался свежий сборник американских статей про искусственный интеллект, переводной. И там были экспертные системы, там была Eurisk экспертная система, было и Mission, они медицинские. Они на основе правил, данных делали вывод какой-то, я тоже пытался это делать, но реально на Fortran 4 делать это очень неудобно. Кроме того, сама по себе сложность была здорово ограничена сверху оперативной памятью. У нашего mainframe он был один из лучших, наверное, в том месте, где я мог работать. У него было 4 стойки оперативной памяти по 256 килобайт, и они все 4 никогда вместе не работали. Но это просто чтобы понять масштаб бедствия. То есть мы оперировали килобайтами и что-то успевали сделать, работали на перфокартах, выкручивались. Но это не очень продуктивно. Тогда же примерно на том же железе я делал систему, которая анализировала результаты анализа, делала вывод на результатах анализа углеводородов. То есть там была лаборатория нефтехимии, у которой были деньги и компьютеры. Я говорю, слушай, ты вроде компьютер умеешь, а вот те компьютеры, мы не знаем, что с ними делать. Сделай что-нибудь разумное. Это было интересно.