Глубокие мечты

Продолжим расширять границы привычного, смешивая различные области искусства. На этот раз мы соединим живопись и …программирование.

DeepDream

Некоторое время назад я стал увлекаться искусственным интеллектом и нейронными сетями. Среди них есть и так называемые «мечтающие сети». Одна из реализаций носит название «DeepDream» . Принцип работы примерно следующий: Имеется нейронная сеть, натренированная на наборе ImageNet, включающий в себя около 14 миллионов изображений, разделенных по 21 тысяче категорий. Сети предоставляется какая-то картинка, DeepDream отыскиевает в ней знакомые элементы и «дорисовывает» их, согласно своим представлениям. Получаются своеобразные психоделические картинки. Из побочных эффектов можно отметить большое количество глаз и носов животных в сгенерированных изображениях, что объясняется большим количеством животных в обучающей выборке.

Результаты

А теперь о результатах экспериментов. Я передал на вход DeepDream картины из своих предыдущих постов и немного покрутил настройки визуализации. Смотрим, что вышло:

Завораживающе

neuro1

Завораживающе-2

neuro2

Завораживающе-3

neuro3

Завораживающе-4

neuro4

И несколько изображений «вне конкурса«neuro5

neuro7

Исходный код

И напоследок, прикладываю листинг программы на Python для самостоятельных экспериментов. В её основе пример, представленный в книге Ф.Шолле «Глубокое обучение на Python»

from keras.applications import inception_v3
from keras import backend as K
import scipy
import imageio
from keras.preprocessing import image
import numpy as np

def resize_img(img, size):
    img = np.copy(img)
    factors = (1,
               float(size[0]) / img.shape[1],
               float(size[1]) / img.shape[2],
               1)
    return scipy.ndimage.zoom(img, factors, order=1)

def save_img(img, fname):
    pil_img = deprocess_image(np.copy(img))
    imageio.imwrite(fname, pil_img)

def preprocess_image(image_path):
    img = image.load_img(image_path)
    img = image.img_to_array(img)
    img = np.expand_dims(img, axis=0)
    img = inception_v3.preprocess_input(img)
    return img

def deprocess_image(x):
    if K.image_data_format() == 'channels_first':
        x = x.reshape((3, x.shape[2], x.shape[3]))
        x = x.transpose((1, 2, 0))
    else:
        x = x.reshape(x.shape[1], x.shape[2], 3)
    x /= 2.
    x += 0.5
    x *=255
    x = np.clip(x, 0, 255).astype('uint8')
    return x

K.set_learning_phase(0)

model = inception_v3.InceptionV3(weights='imagenet', include_top=False)

layer_contributions = {'mixed2':0.2, 'mixed3':3., 'mixed4':2., 'mixed5':1.5,}

layer_dict = dict([(layer.name, layer) for layer in model.layers])

loss = K.variable(0.)
for layer_name in layer_contributions:
    coeff = layer_contributions[layer_name]
    activation = layer_dict[layer_name].output

    scaling = K.prod(K.cast(K.shape(activation), 'float32'))
    loss += coeff * K.sum(K.square(activation[:, 2: -2, 2: -2, :])) / scaling

dream = model.input

grads = K.gradients(loss, dream)[0]

grads /= K.maximum(K.mean(K.abs(grads)), 1e-7)

outputs = [loss, grads]
fetch_loss_and_grads = K.function([dream], outputs)

def eval_loss_and_grads(x):
    outs = fetch_loss_and_grads([x])
    loss_value = outs[0]
    grad_values = outs[1]
    return loss_value, grad_values

def gradient_ascent(x, iterations, step, max_loss=None):
    for i in range(iterations):
        loss_value, grad_values = eval_loss_and_grads(x)
        if max_loss is not None and loss_value > max_loss:
            break
        print('...Loss value at', i, ':', loss_value)
        x += step * grad_values
    return x

step = 0.05
num_octave = 4
octave_scale = 1.6
iterations = 300

max_loss = 5.

base_image_path = 'D:\\temp\\Gen.jpg'

img = preprocess_image(base_image_path)

original_shape = img.shape[1:3]
successive_shapes = [original_shape]
for i in range(1, num_octave):
    shape = tuple([int(dim / (octave_scale ** i))
        for dim in original_shape])
    successive_shapes.append(shape)

successive_shapes = successive_shapes[::-1]

original_img = np.copy(img)
shrunk_original_img = resize_img(img, successive_shapes[0])

for shape in successive_shapes:
    print('Processing image shape', shape)
    img = resize_img(img, shape)
    img = gradient_ascent(img, iterations=iterations, step=step, max_loss=max_loss)
    upscaled_shrunk_original_img = resize_img(shrunk_original_img, shape)
    same_size_original = resize_img(original_img, shape)
    lost_detail = same_size_original - upscaled_shrunk_original_img

    img += lost_detail
    shrunk_original_img = resize_img(original_img, shape)
    save_img(img, fname ='dream_at_scale'+str(shape)+'.png')

save_img(img, fname ='final_dream.png')



 

3 комментария на «“Глубокие мечты”»

  1. […] тяжёлые математические вычисления. Например, нейронную сеть на 1С написать можно, но производительность такого […]

  2. […] эстафету Сопряжения искусств. Скрестить литературу с программированием? Легко! […]

  3. […] игры в BlackJack. «Мозгами» боту служит искусственная нейронная сеть, привязанная к каждому из виртуальных картёжников. На […]

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *