В мире искусственного интеллекта есть много всего интересного и многие начинающие разработчики не могут определиться с тем, с чего начать погружение в этот мир. В этой статье мы познакомим читателя с одним из направлений работы с графикой – нейросетевом переносе стиля.
Представьте: вы фотографируете своего кота, а нейросеть перерисовывает его в стиле Ван Гога или Пикассо. Еще недавно это казалось чудом, доступным лишь ученым, а сегодня это называется нейронный перенос стиля (Neural Style Transfer, NST). Это не просто модный фильтр, а один из самых красивых и понятных способов прикоснуться к миру искусственного интеллекта.

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

Впервые этот алгоритм был представлен в 2015 году в работе Леона Гатиса «A Neural Algorithm of Artistic Style» . С тех пор технология шагнула далеко вперед и сейчас любой желающий может ее использовать в своих проектах.
Как это работает
Для того, чтобы по-простому объяснить, как это работает, давайте представим себе художника-реставратора с идеальным зрением и фотографической памятью. Художник сначала должен извлечь содержание. Для этого он смотрит на вашу фотографию и запоминает, какие объекты где находятся, а также запоминает так называемые высокоуровневые концепции: очертания людей и животных, формы зданий и сооружений и т. д. Затем он изучает картину-стиль, то есть, его интересуют уже не объекты, а текстуры, мазки кисти, цветовые пятна.
После этого, начинается самое интересное. Художник берет чистый холст (белый шум) и начинает итеративно менять его, минимизируя две ошибки:
Потеря контента: Холст должен быть похож на вашу фотографию
Потеря стиля: Холст должен быть похож на картину.
Именно таким художником и является наша нейросеть. Изучая исходную фотографию, нейросеть извлекает из глубоких слоев сети, которые понимают те самые высокоуровневые концепции (очертания людей и формы).
Затем нейросеть изучает картину-стиль. Эту информацию он черпает из ранних слоев сети, а также с помощью специального математического приема — матрицы Грама, которая позволяет отделить стиль от содержания.

Этот процесс называется оптимизацией, когда нейросеть не обучается, а именно подгоняет пиксели изображения под нужные критерии.
Готовые инструменты
Получив общее представление о принципах работы нейронного переноса, поговорим немного о готовых инструментах, которые позволяют обрабатывать изображения без написания собственного кода.
Существует большое количество различных сервисов для обработки изображений с помощью ИИ. Не все из них доступны из России без специальных средств, поэтому в качестве примера приведем решение от Яндекса.
Алиса на базе модели YandexART 2.5 умеет не просто накладывать фильтры, а понимать сложные запросы вроде «нарисуй в стиле «Ходячего замка»». Например, вот так:

Вы можете загрузить фото в приложении «Алиса» или на сайте и выбрать стиль из меню (аниме, киберпанк и др.) или описать его словами.
Это удобно для тех, кто хочет быстро получить результат. Но тем, кто хочет написать собственное приложение для нейронного переноса мы рекомендуем продолжить читать статью дальше, чтобы узнать, как можно реализовать свой Style Transfer на Python.
Пишем свой код
А теперь давайте напишем собственный генератор новых картин. Мы будем использовать библиотеки TensorFlow и Keras.
Для начала установите необходимые пакеты, если вы этого еще не сделали:
pip install tensorflow tensorflow-hub matplotlib pillow numpy
Теперь импортируем их в наш скрипт или Jupyter Notebook.
import os import numpy as np import PIL.Image import matplotlib.pyplot as plt import tensorflow as tf # Загружаем сжатые модели из TF Hub для быстрой версии os.environ['TFHUB_MODEL_LOAD_FORMAT'] = 'COMPRESSED' # Настройка отображения графиков plt.rcParams['figure.figsize'] = (10, 10) plt.rcParams['axes.grid'] = False print("Версия TensorFlow:", tf.__version__)
Далее, напишем функции для загрузки, обработки и отображения картинок. Нейросети любят пакетную обработку, поэтому мы будем добавлять изображениям дополнительное измерение (batch dimension).
def load_img(path_to_img): # Загружает изображение, изменяет размер до 512px по большей стороне и нормализует пиксели # к [0,1]. max_dim = 512 img = tf.io.read_file(path_to_img) img = tf.image.decode_image(img, channels=3) img = tf.image.convert_image_dtype(img, tf.float32) shape = tf.cast(tf.shape(img)[:-1], tf.float32) long_dim = max(shape) scale = max_dim / long_dim new_shape = tf.cast(shape * scale, tf.int32) img = tf.image.resize(img, new_shape) # Добавляем batch dimension: (1, height, width, channels) img = img[tf.newaxis, :] return img def tensor_to_image(tensor): # Превращает тензор обратно в изображение, которое можно сохранить. tensor = tensor * 255 tensor = np.array(tensor, dtype=np.uint8) if np.ndim(tensor) > 3: assert tensor.shape[0] == 1 tensor = tensor[0] return PIL.Image.fromarray(tensor) def imshow(image, title=None): # Отображает изображение. if len(image.shape) > 3: image = tf.squeeze(image, axis=0) plt.imshow(image) if title: plt.title(title) plt.axis('off')
Теперь давайте загрузим два изображения. Вы можете использовать свои или скачать примеры с сайта TensorFlow.
# Укажите пути к вашим изображениям или используйте примеры от TensorFlow content_path = tf.keras.utils.get_file('content.jpg', 'https://storage.googleapis.com/download.tensorflow.org/example_images/YellowLabradorLooking_new.jpg') style_path = tf.keras.utils.get_file('style.jpg', 'https://storage.googleapis.com/download.tensorflow.org/example_images/Vassily_Kandinsky%2C_1913_-_Composition_7.jpg') content_image = load_img(content_path) style_image = load_img(style_path) # Отобразим исходные картинки plt.subplot(1, 2, 1) imshow(content_image) plt.subplot(1, 2, 2) imshow(style_image) plt.show()
В рамках данной статьи мы не будем углубляться в дебри работы алгоритма, а вместо этого воспользуемся готовой моделью для произвольной стилизации.
import tensorflow_hub as hub # Загружаем модель, которая умеет переносить любой стиль на любое изображение hub_model = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2') # Применяем модель stylized_image = hub_model(tf.constant(content_image), tf.constant(style_image))[0] # Отображаем и сохраняем результат imshow(stylized_image) plt.show() tensor_to_image(stylized_image).save('fast_stylized_output.png')
В итоге мы с помощью нескольких строк кода смогли получить стилизованное изображение. Этот метод называется Fast Style Transfer, потому что нейросеть уже обучена это делать, и результат получается мгновенно.
Заключение
В рамках этой небольшой статьи мы прошли путь от понимания теории до практической реализации. Нейронный перенос стиля — это довольно интересный сплав технологий и искусства. Для начинающих это идеальная тема, так как она дает быстрый, красивый результат и наглядно демонстрирует работу сверточных нейросетей.

Если хочется двигаться дальше и разбирать ML глубже, на курсе Machine Learning. Basic последовательно соберёте базу: Python, матстат и классические модели. Будет много практики на реальных данных, тренажёры с автопроверкой, pandas/sklearn и итоговый проект в портфолио — чтобы уверенно стартовать на junior-задачах. А до уровня Middle ML-инженера (Data Scientist) с нуля можно прокачаться на специализации.
Больше практических курсов по нейросетям от экспертов — в каталоге. Подберите трек под свою роль: от базовой подготовки до продакшен-задач.
