Создайте приложение для создания фотореалистичных граней с помощью TensorFlow и Streamlit |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Нейронные сети начинающим Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2020-04-07 04:25 В статье показано, как сделать приложение для создания фотореалистичных лиц, используя TensorFlow и Streamlit. Мы покажем вам, как быстро построить приложение Streamlit для синтеза лиц знаменитостей с помощью GANs, Tensorflow и st. cache. Модели машинного обучения - это черные ящики. Да, вы можете запускать их на тестовых наборах и строить причудливые кривые производительности, но все равно часто бывает трудно ответить на основные вопросы о том, как они работают. Удивительно мощный источник озарения-это просто играть с вашими моделями! Настройка входов. Следите за выходами. Пусть ваши коллеги и менеджеры тоже играют с ними. Такой интерактивный подход - это не только мощный способ обрести интуицию, но и отличный способ заставить людей восхищаться вашей работой. Создание интерактивных моделей - это один из вариантов использования, который вдохновил Streamlit, фреймворк Python, который делает написание приложений таким же простым, как написание скриптов Python. Этот обзор поможет вам создать приложение Streamlit, чтобы играть с одной из самых волосатых и черных коробок-iest моделей там: глубокая генеративная состязательная сеть (GAN). В этом случае мы визуализируем PG-GAN Nvidia [1], используя TensorFlow для синтеза фотореалистичных человеческих лиц из тонкого воздуха. Затем, используя удивительную модель TL-GAN Shaobo Guan [2], мы создадим приложение, которое даст нам возможность настроить синтезированные GAN лица знаменитостей по таким признакам, как возраст, улыбчивость, мужское сходство и цвет волос. К концу урока вы получите полностью параметрическую модель человека! (Обратите внимание, что мы не создавали атрибуты. Они пришли из набора данных CelebA [3], и некоторые из них могут быть немного странными…) Начало работы с Streamlit Если вы еще не установили Streamlit, вы можете сделать это, запустив: pip install streamlit streamlit hello И если вы опытный Streamlit-Эр, вам нужно будет быть на 0.57.1 или более поздней версии, так что не забудьте обновить! pip install --upgrade streamlit Настройка вашей среды Прежде чем мы начнем, используйте команды ниже, чтобы проверить РЕПО проекта GitHub и запустить демо-версию Face GAN для себя. Эта демонстрация зависит от Tensorflow 1, который не поддерживает Python 3.7 или 3.8, поэтому вам понадобится Python 3.6. На Mac и Linux мы рекомендуем использовать pyenv для установки Python 3.6 вместе с текущей версией, а затем настроить новую виртуальную среду с помощью venv или virtualenv. В Windows навигатор Anaconda Navigator позволяет выбрать версию Python с помощью интерфейса point-and-click. Когда все будет готово, откройте окно терминала и введите: git clone https://github.com/streamlit/demo-face-gan.git Дайте ему минуту, чтобы закончить загрузку обученного GAN, а затем попробуйте поиграть с ползунками, чтобы исследовать различные грани, которые GAN может синтезировать. Довольно круто, правда? Полный код приложения - это файл, содержащий ~190 строк кода, из которых только 13 являются потоковыми вызовами. Это верно, весь пользовательский интерфейс выше нарисован только из этих 13 строк! Давайте взглянем на то, как структурировано приложение: def main():
st.image(image_out, use_column_width=True) Теперь, когда у вас есть представление о том, как она структурирована, давайте погрузимся в каждый из 5 шагов выше, чтобы увидеть, как они работают. Этот шаг загружает необходимые нам файлы: предварительно подготовленную модель PG-GAN и модель TL-GAN, предварительно приспособленную к ней (мы погрузимся в них немного позже!). Служебная функция download_file немного умнее, чем чистый загрузчик: Он проверяет, есть ли файл уже в локальном каталоге, поэтому загружает его только в случае необходимости. Он также проверяет, соответствует ли размер загруженного файла тому, что мы ожидали, поэтому он может исправить прерванные загрузки. Это отличный образец для подражания! # If the file exists and has the expected size, return.
return Он использует st. progress () и st.warning (), Чтобы показать хороший пользовательский интерфейс пользователю во время загрузки файла. А потом он звонит .пустой () на этих элементах пользовательского интерфейса, чтобы скрыть их, когда это будет сделано. # Draw UI elements.
progress_bar.empty() Шаг 2. Загрузка моделей в память Следующим шагом является загрузка этих моделей в память. Вот код для загрузки модели PG-GAN: @st.cache(allow_output_mutation=True, hash_funcs=TL_GAN_HASH_FUNCS)
return session, G Обратите внимание на декоратор @ st.cache в начале load_pg_gan_model (). Обычно в Python вы можете просто запустить load_pg_gan_model () и повторно использовать эту переменную снова и снова. Однако модель выполнения Streamlit уникальна тем, что каждый раз, когда пользователь взаимодействует с виджетом пользовательского интерфейса, ваш сценарий снова выполняется полностью, сверху донизу. Добавляя @st. cache к дорогостоящим функциям загрузки модели, мы говорим Streamlit, чтобы он запускал эти функции только при первом выполнении скрипта — и просто повторно использовал выходные данные кэша для каждого последующего выполнения. Это одна из самых фундаментальных функций Streamlit, поскольку она позволяет эффективно запускать сценарии, кэшируя результаты вызовов функций. Таким образом, большие подогнанные модели GAN будут загружены в память ровно один раз; и точно так же наш сеанс TensorFlow будет создан также точно один раз. (См. нашу статью запустить для повышения квалификации по модели исполнения Streamlit по.) [Figure 1. How caching works in Streamlit’s execution model] Однако есть одна загвоздка: объект сеанса TensorFlow может изменяться внутренне, когда мы используем его для выполнения различных вычислений. Обычно мы не хотим, чтобы кэшированные объекты мутировали, так как это может привести к неожиданным результатам. Поэтому, когда Streamlit обнаруживает такие мутации, он выдает предупреждение пользователю. Однако в этом случае мы случайно узнаем, что это нормально, если объект сеанса TensorFlow мутирует, поэтому мы обходим предупреждение, устанавливая allow_output_mutation=True. Шаг 3. Нарисуйте пользовательский интерфейс боковой панели Если это первый раз, когда вы видите API Streamlit для рисования виджетов, вот 30-секундный аварийный курс: Вы добавляете виджеты, вызывая API-методы, такие как st.slider() и st.checkbox(). Поэтому, чтобы добавить слайдер в боковую панель, например-слайдер, позволяющий пользователю настроить параметр brown_hair, вы просто добавите: brown_hair = st.sidebar.slider("Brown Hair", 0, 100, 50, step=5)
# Then set the default value to 50. В нашем приложении мы хотим немного пофантазировать, чтобы показать, насколько легко сделать сам пользовательский интерфейс модифицируемым в Streamlit! Мы хотим, чтобы пользователи могли сначала использовать виджет multiselect для выбора набора функций, которыми они хотят управлять в созданном изображении, а это означает, что наш пользовательский интерфейс должен быть нарисован программно: С Streamlit код для этого на самом деле довольно прост: st.sidebar.title('Features')
features[feature] = st.sidebar.slider(feature, 0, 100, 50, 5) Шаг 4. Синтезировать изображение Теперь, когда у нас есть набор признаков, говорящих нам, какое лицо синтезировать, нам нужно сделать тяжелую работу по синтезированию лица. Мы сделаем это, передав объекты в TL-GAN, чтобы создать вектор в латентном пространстве PG-GAN, а затем передать этот вектор в PG-GAN. Если это предложение не имеет для вас никакого смысла, давайте сделаем крюк и поговорим о том, как работают наши две нейронные сети. Чтобы понять, как вышеприведенное приложение генерирует грани из значений слайдера, вам сначала нужно понять кое-что о том, как работают PG-GAN и TL — GAN-но не волнуйтесь, вы можете пропустить этот раздел и все равно понять, как приложение работает на более высоком уровне! PG-GAN, как и любой GAN, по сути своей представляет собой пару нейронных сетей, одну генеративную и одну различительную, которые натренированы друг против друга, навсегда сцепившись в смертельной схватке. Генеративная сеть отвечает за синтез изображений, которые, по ее мнению, выглядят как лица, а дискриминирующая сеть отвечает за принятие решения о том, действительно ли эти изображения являются лицами. Эти две сети итеративно обучаются против выходных данных друг друга, поэтому каждая из них делает все возможное, чтобы научиться обманывать другую сеть. Конечным результатом является то, что конечная генеративная сеть способна синтезировать реалистичные лица, даже если в начале обучения все, что она могла синтезировать, было случайным шумом. Это действительно очень удивительно! В этом случае GAN, генерирующий лицо, который мы используем, был обучен на лицах знаменитостей Каррасом и др., Используя их прогрессивный алгоритм роста GANs (PG-GAN), который обучает GANs, используя изображения с прогрессивно более высоким разрешением. [1] Входным сигналом для PG-GAN является высокомерный вектор, принадлежащий его так называемому латентному пространству. Латентное пространство-это в основном пространство всех возможных граней, которые может генерировать сеть, поэтому каждый случайный вектор в этом пространстве соответствует уникальной грани (или, по крайней мере, должен! Иногда вы получаете странные результаты...) обычно вы используете GAN, чтобы дать ему случайный вектор, а затем проверить, какое лицо синтезируется (Рис. 2.ля). Однако это звучит немного скучно, и мы предпочли бы иметь немного больше контроля над выходом. Мы хотели бы сказать PG-GAN “создать образ мужчины с бородой “или”создать образ женщины с каштановыми волосами". Вот тут-то и появляется ТЛ-Ган. TL-GAN - это еще одна нейронная сеть, которая обучается путем ввода случайных векторов в PG-GAN, взятия сгенерированных лиц и прогона их через классификаторы для таких атрибутов, как “молодо выглядит”, “бородат”, “шатен” и т. д. На этапе обучения TL-GAN помечает тысячи граней из PG-GAN с помощью этих классификаторов и определяет направления в скрытом пространстве, соответствующие изменениям в метках, о которых мы заботимся. В результате TL-GAN учится сопоставлять эти классы (т. е. “молодой на вид”, “бородатый”, "шатен") в соответствующий вектор случайного вида, который должен быть введен в PG-GAN для создания лица с этими характеристиками (Рис.2.б). Возвращаясь к нашему приложению, на данный момент мы уже загрузили предварительно обученные модели GAN и загрузили их в память,а также захватили вектор функций из пользовательского интерфейса. Так что теперь нам просто нужно ввести эти функции в TL-GAN, а затем PG-GAN, чтобы получить изображение: @st.cache(show_spinner=False, hash_funcs={tf.Session: id})
return images[0] Оптимизация производительности Приведенная выше функция generate_image () может занять некоторое время для выполнения, особенно при работе на центральном процессоре. Чтобы улучшить производительность нашего приложения, было бы здорово, если бы мы могли кэшировать выходные данные этой функции, поэтому нам не нужно повторно синтезировать лица, которые мы уже видели, перемещая ползунок вперед и назад. Ну, как вы уже могли заметить в приведенном выше фрагменте, решение здесь заключается в том, чтобы еще раз использовать декоратор @st.cache. Но обратите внимание на два аргумента, которые мы передали в @st. cache в этом случае: show_spinner=False и hash_funcs={tf.Идентификатор сеанса}. А для чего они здесь? Первый из них легко объяснить: по умолчанию @st.cache показывает поле состояния в пользовательском интерфейсе, сообщая вам, что в данный момент выполняется медленно работающая функция. Мы называем это "вертушкой". Однако в этом случае мы хотели бы избежать его показа, чтобы пользовательский интерфейс не прыгал неожиданно. Поэтому мы установили show_spinner в False. Следующий вариант решает более сложную проблему: объект сеанса TensorFlow, который передается в качестве аргумента в generate_image (), обычно мутирует внутренними функциями TensorFlow в промежутках между запусками этой кэшированной функции. Это означает, что входные аргументы для generate_image () всегда будут отличаться, и мы никогда не получим попадание в кэш. Другими словами, декоратор @st.cache на самом деле ничего не будет делать! Как мы можем решить эту проблему? Hash_funcs к спасению Опция hash_funcs позволяет нам указать пользовательские хэш-функции, которые говорят @st. cache, как он должен интерпретировать различные объекты при проверке, является ли это попадание в кэш или промах в кэше. В этом случае мы будем использовать эту опцию, чтобы сказать Streamlit хэшировать сеанс TensorFlow, вызывая функцию Python id (), а не изучая ее содержимое: @st.cache(..., hash_funcs={tf.Session: id}) def generate_image(session, ...): Это работает для нас, потому что объект сеанса в нашем случае фактически является синглетным во всех исполнениях базового кода, так как он исходит из функции @st.cache load_pg_gan_model (). Для получения дополнительной информации о hash_funcs ознакомьтесь с нашей документацией о передовых методах кэширования. Шаг 5. Нарисуйте собирательный образ Теперь, когда у нас есть выходное изображение, нарисовать его-это просто кусок пирога! Просто вызовите функцию St.image Streamlit: st.image(image_out, use_column_width=True) И мы закончили! Сворачивание дела Итак, у вас есть это: интерактивный синтез лица с TensorFlow в 190-линейном приложении Streamlit и только 13 вызовов функций Streamlit! Получайте удовольствие, исследуя пространство лиц, которые эти два Гана могут нарисовать, и большое спасибо Nvidia и Shaobo Guan за то, что они позволили нам построить свои супер крутые демо-версии. Мы надеемся, что вам будет так же весело создавать приложения и играть с моделями, как и нам. Источник: towardsdatascience.com Комментарии: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||