[Python, Машинное обучение] Эволюция OLEG AI. Нейросеть, утечки памяти, нагрузка
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Прошло чуть больше месяца с релиза OLEG AI - моего бота, который рекомендует посты из пабликов Телеграма.Вот предыдущий пост, в котором я подробно описал сабж: Аналог фейсбучной ленты для Телеграма. Тупенький ИИ OLEGПосле релиза и последовавшего хабраэффекта (так еще говорят?), Олег получил несколько сотен новых юзеров, нагрузку и датасет реальных оценок.А я получил понимание того, что модель рекомендаций надо немного докрутить, и побороться с утечками памяти.Модель рекомендацийВ предыдущей статье я писал, что решил отказаться от нейросети в модели, тк модель на основе произведения векторов эмбеддингов обучается быстрее и менее склонна к переобучению. Поюзав немного старую модель и собрав фидбек с первых юзеров, мне стало понятно, что модель все-таки нужно немного усложнить. Поисследовав немного, я пришел к тому, что нужно поработать над следующими вещами:Научить модель отличать каналыСтарая модель не знала ничего про каналы, для нее каждый пост был уникальным. Я думал, что в результате разметки постов голосами пользователей посты с одного канала получат похожие эмбеддинги. Но внимательно присмотревшись к этому вопросу, я понял, что так не будет, потому что постов всегда будет гораздо больше чем юзеров, а это значит, что пространство постов будет размечено разреженными оценками. Далеко не всем постам достанется хотя бы одна оценка, а ведь чтобы считать пост хорошо размеченным, ему нужно 10-100 оценок. Как быть? Количество каналов гораздо меньше количества постов и меньше количества юзеров. В канале все посты имеют примерно одинаковый flavour (извините), поэтому есть смысл ввести в модель эмбеддинги каналов и сделать их основным источником предсказательности. Посты тоже имеют свои эмбеддинги, но теперь 80% эмбеддингов несет канал и 20% - пост.Окей, если мы вводим эмбеддинги каналов, простая модель DotProduct перестает работать, потому что перемножить три вектора для получения скаляра мы уже не можем. На помощь приходит нейросеть!
Нейросеть с одним скрытым слоемБерем эмбеддинги юзера, канала и поста, конкатенируем их в один длинный тензор, и подаем этот тензор на входы нейросети. В моем случае эмбеддинг юзера имеет размерность 100, канала - 80, юзера - 20. Соответственно, у нейросети должно быть столько входов, сколько элементов у конкатенированного тензора. На иллюстрации я изобразил в 10 раз меньше нейронов (10-8-2) просто для удобства иллюстрации. Почему я выбрал такие размерности (100-80-20) - см. ниже.Нейросеть имеет один скрытый слой из 70 нейронов и 1 нейрон на выходном слое, степень активации которого означает предсказанную оценку.Предполагается, что нейроны скрытого слоя обучаются признакам более высокого порядка, и сигнал от слоя эмбеддингов, проходя через них, формирует в итоге скаляр, предсказывающий оценку поста юзером.Подобрать размерности эмбеддинговВ прошлой статье я писал, что не нашел какого-то четкого правила выбора размерностей эмбеддингов, и выбрал размерность 13 для юзера и для поста.На этой итерации я поисследовал этот момент самостоятельно и провел пару дней в экспериментах.Я пробовал разные размерности эмбеддингов и соотношение размерностей скрытого слоя и эмбеддингов, а также константы learning rate. Я смотрел, как быстро обучается модель, следил, чтобы скорость обучения (хорошо) не перерастала в быстрое скатывание в переобучение (плохо). Пытался найти баланс между точностью предсказания и генерализацией.Поскольку у меня на руках был реальный датасет из нескольких десятков тысяч оценок, я мог себе позволить отрезать от него кусок для валидации, и сделать всё как надо: тренировать сетку на обучающем подсете, и валидировать ее работу, находя момент, когда начинается переобучение.Попробовав различные комбинации размерностей, я подобрал такие значения:
- Эмбеддинг юзера - 100,
- Канала - 80,
- Поста - 20
Соотношение между каналом и постом я выбрал самостоятельно, мне показалось, что смыслы которые несет собой канал превалируют над смыслами, которые несет собой отдельный пост. Также я чисто эмпирически предположил, что общая размерность канал+пост должна быть равна размерности эмбеддинга юзера. Остальные соотношения я подбирал экспериментально. Так, у меня получилось, что размерность скрытого слоя = 70. Такой результат получился, когда я пытался сделать обучение гладким, быстрым, но не очень быстрым, чтобы не проскакивать момент начала переобучения.Утечки памятиОлежка работал на самом простом инстансе DigitalOcean с 1ГБ ОЗУ, но так было лишь до тех пор, пока я не получил первую сотню юзеров. Он начал жрать память, пришлось разбираться. Сначала я конечно тупо увеличил ОЗУ дроплета, но оказалось, что это помогает лишь на время :)Оказалось, что при массовой рассылке свежих постов, Олег каждый раз запрашивает из базы пул свежих постов (10-50к записей). Это тупо и медленно. По моим прикидкам это не должно было жрать память, ведь объект хранящий посты теряет ссылки на себя, как только метод рассылки заканчивает свою работу. Но у питонячего сборщика мусора, видимо, свой взгляд на этот вопрос. Кроме того, это просто некультурно - много раз подряд в цикле забирать из базы одну и ту же инфу. Я написал простой кеш пула свежих постов, это в общем помогло.Память все еще течет, но гораздо медленнее. На докер-контейнере стоит restart: on-failure, и когда контейнер вылетает по out-of-memory, он рестартит, происходит это раз в несколько суток.Как полностью это побороть, я пока не понял. Много раз исследовал свой код на предмет утечек, есть пара методов - кандидатов на создание утечки. Это, например, метод, который добавляет в тензор эмбеддингов новую строку при добавлении нового юзера. PyTorch не поддерживает append строки к тензору, приходится пересоздавать тензор, и в этом месте возможна утечка. Но метод реализован по рекомендациям разработчиков PyTorch, и лучше его не сделать (вроде).Теперь Олежке достаточно 4 ГБ и Shared CPU. Если кто вам скажет, что для ML нужна стойка с 8 dedicated GPU's - плюньте ему в лицо. Об этом, кстати, часто говорит Jeremy Howard, создатель курса fast.ai.
===========
Источник:
habr.com
===========
Похожие новости:
- [Python, Алгоритмы, Big Data, Машинное обучение, Искусственный интеллект] Data Phoenix Digest — 01.07.2021
- [Python, Алгоритмы, Big Data, Машинное обучение, Искусственный интеллект] Data Phoenix Digest — 01.07.2021
- [Мессенджеры, Поисковые технологии, Управление медиа, Социальные сети и сообщества] Закон о «приземлении» иностранных интернет-порталов
- [Обработка изображений, Машинное обучение, Транспорт, Урбанизм] Независимые испытания показали, что автопилот Tesla на машинном зрении не хуже радарного
- [Python, PDF] Tesseract OCR, выделение распознанного текста на изображении
- [Машинное обучение] Mediated ASI — будущее искусственного интеллекта, которое пришло незаметно
- [Алгоритмы, Машинное обучение, Искусственный интеллект, Будущее здесь, Natural Language Processing] 30 миллиардов параметров: реально ли обучить русский GPT-3 в «домашних» условиях?
- [Big Data, Машинное обучение, Искусственный интеллект] На All Cups открыта регистрация на IT-чемпионат в рамках конкурса «Цифровой прорыв»
- [Python, Машинное обучение, Искусственный интеллект, TensorFlow] TensorFlow vs PyTorch в 2021: сравнение фреймворков глубокого обучения
- [Python, 1С] Хранилище внешних обработок 1С на python
Теги для поиска: #_python, #_mashinnoe_obuchenie (Машинное обучение), #_python, #_pytorch, #_machinelearning, #_telegram, #_bot, #_python, #_mashinnoe_obuchenie (
Машинное обучение
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:12
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Прошло чуть больше месяца с релиза OLEG AI - моего бота, который рекомендует посты из пабликов Телеграма.Вот предыдущий пост, в котором я подробно описал сабж: Аналог фейсбучной ленты для Телеграма. Тупенький ИИ OLEGПосле релиза и последовавшего хабраэффекта (так еще говорят?), Олег получил несколько сотен новых юзеров, нагрузку и датасет реальных оценок.А я получил понимание того, что модель рекомендаций надо немного докрутить, и побороться с утечками памяти.Модель рекомендацийВ предыдущей статье я писал, что решил отказаться от нейросети в модели, тк модель на основе произведения векторов эмбеддингов обучается быстрее и менее склонна к переобучению. Поюзав немного старую модель и собрав фидбек с первых юзеров, мне стало понятно, что модель все-таки нужно немного усложнить. Поисследовав немного, я пришел к тому, что нужно поработать над следующими вещами:Научить модель отличать каналыСтарая модель не знала ничего про каналы, для нее каждый пост был уникальным. Я думал, что в результате разметки постов голосами пользователей посты с одного канала получат похожие эмбеддинги. Но внимательно присмотревшись к этому вопросу, я понял, что так не будет, потому что постов всегда будет гораздо больше чем юзеров, а это значит, что пространство постов будет размечено разреженными оценками. Далеко не всем постам достанется хотя бы одна оценка, а ведь чтобы считать пост хорошо размеченным, ему нужно 10-100 оценок. Как быть? Количество каналов гораздо меньше количества постов и меньше количества юзеров. В канале все посты имеют примерно одинаковый flavour (извините), поэтому есть смысл ввести в модель эмбеддинги каналов и сделать их основным источником предсказательности. Посты тоже имеют свои эмбеддинги, но теперь 80% эмбеддингов несет канал и 20% - пост.Окей, если мы вводим эмбеддинги каналов, простая модель DotProduct перестает работать, потому что перемножить три вектора для получения скаляра мы уже не можем. На помощь приходит нейросеть! Нейросеть с одним скрытым слоемБерем эмбеддинги юзера, канала и поста, конкатенируем их в один длинный тензор, и подаем этот тензор на входы нейросети. В моем случае эмбеддинг юзера имеет размерность 100, канала - 80, юзера - 20. Соответственно, у нейросети должно быть столько входов, сколько элементов у конкатенированного тензора. На иллюстрации я изобразил в 10 раз меньше нейронов (10-8-2) просто для удобства иллюстрации. Почему я выбрал такие размерности (100-80-20) - см. ниже.Нейросеть имеет один скрытый слой из 70 нейронов и 1 нейрон на выходном слое, степень активации которого означает предсказанную оценку.Предполагается, что нейроны скрытого слоя обучаются признакам более высокого порядка, и сигнал от слоя эмбеддингов, проходя через них, формирует в итоге скаляр, предсказывающий оценку поста юзером.Подобрать размерности эмбеддинговВ прошлой статье я писал, что не нашел какого-то четкого правила выбора размерностей эмбеддингов, и выбрал размерность 13 для юзера и для поста.На этой итерации я поисследовал этот момент самостоятельно и провел пару дней в экспериментах.Я пробовал разные размерности эмбеддингов и соотношение размерностей скрытого слоя и эмбеддингов, а также константы learning rate. Я смотрел, как быстро обучается модель, следил, чтобы скорость обучения (хорошо) не перерастала в быстрое скатывание в переобучение (плохо). Пытался найти баланс между точностью предсказания и генерализацией.Поскольку у меня на руках был реальный датасет из нескольких десятков тысяч оценок, я мог себе позволить отрезать от него кусок для валидации, и сделать всё как надо: тренировать сетку на обучающем подсете, и валидировать ее работу, находя момент, когда начинается переобучение.Попробовав различные комбинации размерностей, я подобрал такие значения:
=========== Источник: habr.com =========== Похожие новости:
Машинное обучение ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:12
Часовой пояс: UTC + 5