Оглавление

  1. Прием данных
  2. Рекуррентная нейронная сеть
  3. ГПТ-2
  4. Автоматическая публикация
  5. Веб-приложение

Прием данных

Я начал этот проект с расплывчатой ​​целью — попытаться создать программу на Python для имитации активности пользователя в моей личной учетной записи Instagram, с первоначальной целью программно размещать изображения с подписями. Раньше я работал с моделью Open AI GPT-2, которая работает по методу «обезьяна-видит-обезьяна-делает» для генерации текста (для подписи) на основе обучающих данных. Имея это в виду, я знал, что первым шагом будет получение обучающего набора данных приличного размера из Instagram. Я понятия не имел, как сделать так, чтобы подпись GPT-2 действительно соответствовала фотографии в посте.

К сожалению для моего проекта, функции API Instagram сильно ограничены. Решение состояло в том, чтобы использовать веб-скребок на основе Selenium для очистки реальных постов в Instagram с вкладки «Исследовать». Эти обучающие данные использовались для обучения части бота, генерирующей подписи, поэтому он имеет тенденцию быть смещенным в сторону этих данных. Я бы предположил, что Instagram имеет тенденцию адаптировать вкладку «Обзор» каждого пользователя в зависимости от их поведения в Интернете, однако, поскольку я не использую Instagram, я считаю, что моя вкладка «Обзор» близка к стандартной. По какой-то причине это включает в себя много микологии и Гарри Стайлса. Я не знаю почему. В результате окончательные подписи, как правило, предрасположены к их показу.

Первоначальный план здесь состоял в том, чтобы загрузить очищенные данные в мою личную корзину S3, однако я обнаружил, что после 10 000 очищенных сообщений фактические фотографии были переведены примерно в 1,3 ГБ данных и связанных с ними метаданных (заголовки, временные метки, имена пользователей, подборка комментариев, д.) примерно до 25 Мб. С этим легко справился мой локальный компьютер.

Рекуррентная нейронная сеть

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

Эта сеть обучается на наборе данных Flickr 8K, который состоит из 8000 фотографий, каждая из которых имеет пять подписей, описывающих, что на фотографии. К сожалению, этот набор данных больше не хранится в Университете Иллинойса, однако его несложно найти в Google в другом месте. Я обучил эту модель на своем собственном ПК (очень весело получить правильную версию Tensorflow и связанных библиотек, выстроенных и правильно установленных) с графическим процессором Nvidia RTX2070 Super, запуск которого занял менее получаса.

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

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

ГПТ-2

Open AI GPT-2 удивительно хорошо генерирует текст, настроенный на корпус, на который вы его настроили. В этом случае я обучил его 10 000 реальных подписей в Instagram, которые я извлек из вкладки «Исследование» в Instagram. Как я уже упоминал, это сильно перекошено в сторону Гарри Стайлса и микологии.

Эта часть проекта была бы невозможна без работы Max Woolf, чью библиотеку gpt-2-simple я широко использовал. Vanilla GPT-2 может принимать ключевое слово в качестве отправной точки для генерации текста, однако оно буквально используется в качестве первого слова в сгенерированном тексте и на основе ключевых слов RNN сильно ограничило бы возвращаемый заголовок.

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

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

Автоматическая публикация

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

GPT-2 достаточно хорош тем, что включает смайлики в свой сгенерированный вывод. Я высоко оценил это, поскольку смайлики являются ключевой функцией подписей в Instagram, однако метод send_keys драйверов Chrome поддерживает только буквальные клавиши на вашей клавиатуре и поэтому не может отправлять смайлики. Я пробовал много вещей здесь. Я попытался использовать Javascript для ввода текста в поле ввода. Я пробовал имитировать Firefox (не могу имитировать мобильные устройства). Последнее, дерганое решение, которое я использую, — буквально копировать и вставлять текст (через python), имитируя CTRL-C, CTRL-V. Для тех, кто следит дома, это означает, что если я нажму на что-то еще, пока я запускаю эту часть программы, она сломается. Но если нет, то работает. Так что я не знаю.

Веб-приложение

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

Шаг первый заключался в том, чтобы обернуть модель в приложение Flask, которое я мог запускать локально вместе с внешним интерфейсом. Любой, кто его использует, вероятно, сможет сказать, что я работаю над интерфейсом впервые. Там много скопированных функций HTML, CSS, Javascript и т. д., и мне пришлось узнать о проверке на стороне клиента и на стороне сервера, очистке ввода и т. д. Это запутанно, но это работает.

Шаг второй заключался в том, чтобы обернуть его в более пригодное для производства приложение Gunicorn, а затем обернуть их и их зависимости в контейнер Docker. Урок, извлеченный здесь, о том, как забыть использовать виртуальную среду Python.

Шаг второй (или третий, или четвертый, или что-то еще) заключался в создании другого контейнера докеров, работающего с NGINX в качестве обратного прокси-сервера, а затем в докере, составляющего оба контейнера для совместной работы, опять же локально. Сделав это с нуля, я развернул весь пакет на EC2, работающем под моей учетной записью AWS. Изначально я планировал развертывание в кластере ECS с механизмом балансировки нагрузки, но мне стало лень, и я также хотел снизить свои расходы (избегая одновременного запуска нескольких платных экземпляров EC2). В сочетании с доменным именем, которое я купил, и вуаля, версия веб-приложения, которую может попробовать каждый.

Я все еще могу получить какое-то шифрование SSL для приложения или Google Ad Sense, поэтому я надеюсь, что смогу окупить затраты на запуск сервера, но idk.

Вы можете следить за сообщениями аккаунта на @notdavidyu. Веб-приложение доступно, пока я все еще хочу заплатить за него на www.thegram9000.com.