Convolutional neural networks for artistic style transfer

This iPython notebook is an implementation of a popular paper (Gatys et al., 2015) that demonstrates how to use neural networks to transfer artistic style from one image onto another. It is meant to go along with a related blog post that provides more context, and explains a lot of the theory behind the steps that follow.

There will be a companion blog post and project coming soon in the future that implements a much faster version of this algorithm (Johnson et al., 2016) and wraps it in a webapp, a la Prisma.

In [13]:
from __future__ import print_function

import time
from PIL import Image
import numpy as np

from keras import backend
from keras.models import Model
from keras.applications.vgg16 import VGG16

from scipy.optimize import fmin_l_bfgs_b
from scipy.misc import imsave,imresize

from copy import deepcopy

Load and preprocess the content and style images

Our first task is to load the content and style images. Note that the content image we're working with is not particularly high quality, but the output we'll arrive at the end of this process still looks really good.

The crux of the paper we're trying to reproduce is that the style transfer problem can be posed as an optimisation problem, where the loss function we want to minimise can be decomposed into three distinct parts: the content loss, the style loss and the total variation loss.

The relative importance of these terms are determined by a set of scalar weights. These are arbitrary, but the following set have been chosen after quite a bit of experimentation to find a set that generates output that's aesthetically pleasing to me.

In [14]:
# These represent some easily changable numbers: weights, number of iterations, and I/O
content_weight = 0.025
style_weight = 20
total_variation_weight = 3
iterations = 500
# Orginal 0.025, 20, 3

# Beginning of filename to save the output. We later append the style, content, and total 
# weights to the end of the filename.
filename_orig = 'Filis_square_as_DaVinci_square_iter500_style'
#"FilisMonetsGardenflipped_as_leonardodavinci5_crop_iter41_style"
content_image_path = 'images/FilisMonetsGarden_.jpg'
style_image_path = 'images/leonardodavinci5_crop_left.jpg'

filename_from_routine = filename_orig
filename_from_routine += (str(style_weight) + "_total" + str(total_variation_weight) + 
                          "_content" + str(content_weight) + "origSize")
filename_content_size = filename_orig
filename_content_size += (str(style_weight) + "_total" + str(total_variation_weight) + 
                          "_content" + str(content_weight))

# Content definition:
content_layers = 'block2_conv2'

# Style definition: Sum of Gram matrix of the following layers
feature_layers = ['block1_conv2', 'block2_conv2',
                  'block3_conv3', 'block4_conv3',
                  'block5_conv3']
In [15]:
height = 512
width = 512

#content_image_path = 'images/hugo.jpg'
content_image = Image.open(content_image_path)
content_image = content_image.resize((height, width))
content_image
Out[15]:
In [16]:
#style_image_path = 'images/styles/wave.jpg'
style_image = Image.open(style_image_path)
style_image = style_image.resize((height, width))
style_image
Out[16]:

Then, we convert these images into a form suitable for numerical processing. In particular, we add another dimension (beyond the classic height x width x 3 dimensions) so that we can later concatenate the representations of these two images into a common data structure.

Before we proceed much further, we need to massage this input data to match what was done in Simonyan and Zisserman (2015), the paper that introduces the VGG Network model that we're going to use shortly.

For this, we need to perform two transformations:

  1. Subtract the mean RGB value (computed previously on the ImageNet training set and easily obtainable from Google searches) from each pixel.
  2. Flip the ordering of the multi-dimensional array from RGB to BGR (the ordering used in the paper).
In [17]:
content_array = np.asarray(content_image, dtype='float32')
content_array = np.expand_dims(content_array, axis=0)
print(content_array.shape)

style_array = np.asarray(style_image, dtype='float32')
style_array = np.expand_dims(style_array, axis=0)
print(style_array.shape)

content_array[:, :, :, 0] -= 103.939
content_array[:, :, :, 1] -= 116.779
content_array[:, :, :, 2] -= 123.68
content_array = content_array[:, :, :, ::-1]

style_array[:, :, :, 0] -= 103.939
style_array[:, :, :, 1] -= 116.779
style_array[:, :, :, 2] -= 123.68
style_array = style_array[:, :, :, ::-1]
(1, 512, 512, 3)
(1, 512, 512, 3)
In [18]:
# Now we're ready to use these arrays to define variables in Keras' backend (the TensorFlow graph).
# We also introduce a placeholder variable to store the combination image that retains the content 
# of the content image while incorporating the style of the style image.
content_image = backend.variable(content_array)
style_image = backend.variable(style_array)
combination_image = backend.placeholder((1, height, width, 3)) ## Original -- random starting image
# New (3/25/2018) -- starting image = content image
#combination_image = backend.variable(deepcopy(content_array)) # It didn't work . . .

# Finally, we concatenate all this image data into a single tensor that's suitable for processing by Keras' VGG16 model.
input_tensor = backend.concatenate([content_image,
                                    style_image,
                                    combination_image], axis=0)

Reuse a model pre-trained for image classification to define loss functions

The core idea introduced by Gatys et al. (2015) is that convolutional neural networks (CNNs) pre-trained for image classification already know how to encode perceptual and semantic information about images. We're going to follow their idea, and use the feature spaces provided by one such model to independently work with content and style of images.

The original paper uses the 19 layer VGG network model from Simonyan and Zisserman (2015), but we're going to instead follow Johnson et al. (2016) and use the 16 layer model (VGG16). There is no noticeable qualitative difference in making this choice, and we gain a tiny bit in speed.

Also, since we're not interested in the classification problem, we don't need the fully connected layers or the final softmax classifier. We only need the part of the model marked in green in the table below.

VGG Network Architectures

It is trivial for us to get access to this truncated model because Keras comes with a set of pretrained models, including the VGG16 model we're interested in. Note that by setting include_top=False in the code below, we don't include any of the fully connected layers.

In [19]:
model = VGG16(input_tensor=input_tensor, weights='imagenet',
              include_top=False)
layers = dict([(layer.name, layer.output) for layer in model.layers])
layers.keys()
Out[19]:
dict_keys(['input_1', 'block1_conv1', 'block1_conv2', 'block1_pool', 'block2_conv1', 'block2_conv2', 'block2_pool', 'block3_conv1', 'block3_conv2', 'block3_conv3', 'block3_pool', 'block4_conv1', 'block4_conv2', 'block4_conv3', 'block4_pool', 'block5_conv1', 'block5_conv2', 'block5_conv3', 'block5_pool'])

As is clear from the table above, the model we're working with has a lot of layers. Keras has its own names for these layers. Let's make a list of these names so that we can easily refer to individual layers later.

If you stare at the list above, you'll convince yourself that we covered all items we wanted in the table (the cells marked in green). Notice also that because we provided Keras with a concrete input tensor, the various TensorFlow tensors get well-defined shapes.


The crux of the paper we're trying to reproduce is that the style transfer problem can be posed as an optimisation problem, where the loss function we want to minimise can be decomposed into three distinct parts: the content loss, the style loss and the total variation loss.

The relative importance of these terms are determined by a set of scalar weights. These are arbitrary, but the following set have been chosen after quite a bit of experimentation to find a set that generates output that's aesthetically pleasing to me.

We'll now use the feature spaces provided by specific layers of our model to define these three loss functions. We begin by initialising the total loss to 0 and adding to it in stages.

The content loss

For the content loss, we follow Johnson et al. (2016) and draw the content feature from block2_conv2, because the original choice in Gatys et al. (2015) (block4_conv2) loses too much structural detail. And at least for faces, I find it more aesthetically pleasing to closely retain the structure of the original content image.

This variation across layers is shown for a couple of examples in the images below (just mentally replace reluX_Y with our Keras notation blockX_convY).

Content feature reconstruction

The content loss is the (scaled, squared) Euclidean distance between feature representations of the content and combination images.

The style loss

This is where things start to get a bit intricate.

For the style loss, we first define something called a Gram matrix. The terms of this matrix are proportional to the covariances of corresponding sets of features, and thus captures information about which features tend to activate together. By only capturing these aggregate statistics across the image, they are blind to the specific arrangement of objects inside the image. This is what allows them to capture information about style independent of content. (This is not trivial at all, and I refer you to a paper that attempts to explain the idea.)

The style loss is then the (scaled, squared) Frobenius norm of the difference between the Gram matrices of the style and combination images.

Again, in the following code, I've chosen to go with the style features from layers defined in Johnson et al. (2016) rather than Gatys et al. (2015) because I find the end results more aesthetically pleasing. I encourage you to experiment with these choices to see varying results.

The total variation loss

Now we're back on simpler ground.

If you were to solve the optimisation problem with only the two loss terms we've introduced so far (style and content), you'll find that the output is quite noisy. We thus add another term, called the total variation loss (a regularisation term) that encourages spatial smoothness.

You can experiment with reducing the total_variation_weight and play with the noise-level of the generated image.

Define needed gradients and solve the optimisation problem

The goal of this journey was to setup an optimisation problem that aims to solve for a combination image that contains the content of the content image, while having the style of the style image. Now that we have our input images massaged and our loss function calculators in place, all we have left to do is define gradients of the total loss relative to the combination image, and use these gradients to iteratively improve upon our combination image to minimise the loss.

We start by defining the gradients.

We then introduce an Evaluator class that computes loss and gradients in one pass while retrieving them via two separate functions, loss and grads. This is done because scipy.optimize requires separate functions for loss and gradients, but computing them separately would be inefficient.

In [20]:
# initiazlie the loss variable
loss = backend.variable(0.)

# Content loss
# block2_conv2
def content_loss(content, combination):
    return backend.sum(backend.square(np.sqrt(content_weight)*combination - np.sqrt(content_weight)*content))

# layer_features defines the "content" 
# original: layer_features = layers['block2_conv2']
layer_features = layers[content_layers]
content_image_features = layer_features[0, :, :, :]
combination_features = layer_features[2, :, :, :]
loss += content_loss(content_image_features, combination_features)

# Style loss
# Combine:
# block1_conv2, block2_conv2, block3_conv3, block4_conv3, block5_conv3
# The Gram matrix can be computed efficiently by reshaping the feature spaces suitably and taking an outer product.
def gram_matrix(x):
    features = backend.batch_flatten(backend.permute_dimensions(x, (2, 0, 1)))
    gram = backend.dot(features, backend.transpose(features))
    return gram

def style_loss(style, combination):
    S = gram_matrix(style)
    C = gram_matrix(combination)
    channels = 3
    size = height * width
    return backend.sum(backend.square(np.sqrt(style_weight)*S - np.sqrt(style_weight)*C)) / (4. * (channels ** 2) * (size ** 2))

# feature_layers defines the "style" of an image
# original:

for layer_name in feature_layers:
    layer_features = layers[layer_name]
    style_features = layer_features[1, :, :, :]
    combination_features = layer_features[2, :, :, :]
    sl = style_loss(style_features, combination_features)
    loss += (1. / len(feature_layers)) * sl
    
def total_variation_loss(x):
    a = backend.square(x[:, :height-1, :width-1, :] - x[:, 1:, :width-1, :])
    b = backend.square(x[:, :height-1, :width-1, :] - x[:, :height-1, 1:, :])
    return backend.sum(backend.pow(a + b, 1.25))

loss += total_variation_weight * total_variation_loss(combination_image)


grads = backend.gradients(loss, combination_image)

outputs = [loss]
outputs += grads
f_outputs = backend.function([combination_image], outputs)

def eval_loss_and_grads(x):
    x = x.reshape((1, height, width, 3))
    outs = f_outputs([x])
    loss_value = outs[0]
    grad_values = outs[1].flatten().astype('float64')
    return loss_value, grad_values

class Evaluator(object):

    def __init__(self):
        self.loss_value = None
        self.grads_values = None

    def loss(self, x):
        assert self.loss_value is None
        loss_value, grad_values = eval_loss_and_grads(x)
        self.loss_value = loss_value
        self.grad_values = grad_values
        return self.loss_value

    def grads(self, x):
        assert self.loss_value is not None
        grad_values = np.copy(self.grad_values)
        self.loss_value = None
        self.grad_values = None
        return grad_values

evaluator = Evaluator()

Now we're finally ready to solve our optimisation problem. This combination image begins its life as a random collection of (valid) pixels, and we use the L-BFGS algorithm (a quasi-Newton algorithm that's significantly quicker to converge than standard gradient descent) to iteratively improve upon it.

We stop after 10 iterations because the output looks good to me and the loss stops reducing significantly.

In [21]:
def save_image(im,name=None,iteration=0):
    dat = deepcopy(im)
    dat = dat.reshape((height, width, 3))
    dat = dat[:, :, ::-1]
    dat[:, :, 0] += 103.939
    dat[:, :, 1] += 116.779
    dat[:, :, 2] += 123.68
    dat = np.clip(dat, 0, 255).astype('uint8')

    A = Image.fromarray(dat)
    if (name == None):
        name = "Image_" + str(iteration) + ".jpg"
        
    A.save(name)

x = np.random.uniform(0, 255, (1, height, width, 3)) - 128.

for i in range(iterations):
    print('Start of iteration', i)
    start_time = time.time()
    x, min_val, info = fmin_l_bfgs_b(evaluator.loss, x.flatten(),
                                     fprime=evaluator.grads, maxfun=20)
    print('Current loss value:', min_val)
    end_time = time.time()
    print('Iteration %d completed in %ds' % (i, end_time - start_time))
    filename = filename_from_routine + "it" + str(i) + ".jpg"
    save_image(x,name=filename, iteration=i)
    
    
x = x.reshape((height, width, 3))
x = x[:, :, ::-1]
x[:, :, 0] += 103.939
x[:, :, 1] += 116.779
x[:, :, 2] += 123.68
x = np.clip(x, 0, 255).astype('uint8')

A = Image.fromarray(x)
A.save(filename_from_routine + ".jpg")
#Image.fromarray(x)

#from skimage.transform import resize
orig_im = np.array(Image.open(content_image_path))
x = imresize(x, orig_im.shape)
B = Image.fromarray(x)
B.save(filename_content_size + ".jpg")

Image.fromarray(x)
Start of iteration 0
Current loss value: 1.54985e+11
Iteration 0 completed in 36s
Start of iteration 1
Current loss value: 8.13659e+10
Iteration 1 completed in 29s
Start of iteration 2
Current loss value: 4.67024e+10
Iteration 2 completed in 30s
Start of iteration 3
Current loss value: 4.00476e+10
Iteration 3 completed in 30s
Start of iteration 4
Current loss value: 3.75801e+10
Iteration 4 completed in 30s
Start of iteration 5
Current loss value: 3.55564e+10
Iteration 5 completed in 30s
Start of iteration 6
Current loss value: 3.3875e+10
Iteration 6 completed in 30s
Start of iteration 7
Current loss value: 3.24224e+10
Iteration 7 completed in 30s
Start of iteration 8
Current loss value: 3.14208e+10
Iteration 8 completed in 31s
Start of iteration 9
Current loss value: 3.08254e+10
Iteration 9 completed in 30s
Start of iteration 10
Current loss value: 3.02801e+10
Iteration 10 completed in 30s
Start of iteration 11
Current loss value: 2.99124e+10
Iteration 11 completed in 30s
Start of iteration 12
Current loss value: 2.96048e+10
Iteration 12 completed in 30s
Start of iteration 13
Current loss value: 2.93954e+10
Iteration 13 completed in 30s
Start of iteration 14
Current loss value: 2.92228e+10
Iteration 14 completed in 30s
Start of iteration 15
Current loss value: 2.90942e+10
Iteration 15 completed in 31s
Start of iteration 16
Current loss value: 2.89976e+10
Iteration 16 completed in 31s
Start of iteration 17
Current loss value: 2.89131e+10
Iteration 17 completed in 30s
Start of iteration 18
Current loss value: 2.88461e+10
Iteration 18 completed in 31s
Start of iteration 19
Current loss value: 2.87905e+10
Iteration 19 completed in 31s
Start of iteration 20
Current loss value: 2.87417e+10
Iteration 20 completed in 31s
Start of iteration 21
Current loss value: 2.86973e+10
Iteration 21 completed in 31s
Start of iteration 22
Current loss value: 2.86628e+10
Iteration 22 completed in 31s
Start of iteration 23
Current loss value: 2.86317e+10
Iteration 23 completed in 31s
Start of iteration 24
Current loss value: 2.8606e+10
Iteration 24 completed in 31s
Start of iteration 25
Current loss value: 2.85809e+10
Iteration 25 completed in 31s
Start of iteration 26
Current loss value: 2.856e+10
Iteration 26 completed in 31s
Start of iteration 27
Current loss value: 2.85407e+10
Iteration 27 completed in 31s
Start of iteration 28
Current loss value: 2.85234e+10
Iteration 28 completed in 31s
Start of iteration 29
Current loss value: 2.85072e+10
Iteration 29 completed in 31s
Start of iteration 30
Current loss value: 2.84927e+10
Iteration 30 completed in 31s
Start of iteration 31
Current loss value: 2.84795e+10
Iteration 31 completed in 31s
Start of iteration 32
Current loss value: 2.84673e+10
Iteration 32 completed in 31s
Start of iteration 33
Current loss value: 2.84548e+10
Iteration 33 completed in 31s
Start of iteration 34
Current loss value: 2.84432e+10
Iteration 34 completed in 31s
Start of iteration 35
Current loss value: 2.84318e+10
Iteration 35 completed in 31s
Start of iteration 36
Current loss value: 2.84211e+10
Iteration 36 completed in 31s
Start of iteration 37
Current loss value: 2.8411e+10
Iteration 37 completed in 31s
Start of iteration 38
Current loss value: 2.84008e+10
Iteration 38 completed in 31s
Start of iteration 39
Current loss value: 2.83909e+10
Iteration 39 completed in 31s
Start of iteration 40
Current loss value: 2.8381e+10
Iteration 40 completed in 31s
Start of iteration 41
Current loss value: 2.83709e+10
Iteration 41 completed in 31s
Start of iteration 42
Current loss value: 2.83606e+10
Iteration 42 completed in 31s
Start of iteration 43
Current loss value: 2.83502e+10
Iteration 43 completed in 31s
Start of iteration 44
Current loss value: 2.83399e+10
Iteration 44 completed in 31s
Start of iteration 45
Current loss value: 2.833e+10
Iteration 45 completed in 31s
Start of iteration 46
Current loss value: 2.83211e+10
Iteration 46 completed in 31s
Start of iteration 47
Current loss value: 2.8313e+10
Iteration 47 completed in 31s
Start of iteration 48
Current loss value: 2.83056e+10
Iteration 48 completed in 31s
Start of iteration 49
Current loss value: 2.82987e+10
Iteration 49 completed in 31s
Start of iteration 50
Current loss value: 2.82922e+10
Iteration 50 completed in 30s
Start of iteration 51
Current loss value: 2.8286e+10
Iteration 51 completed in 31s
Start of iteration 52
Current loss value: 2.82802e+10
Iteration 52 completed in 31s
Start of iteration 53
Current loss value: 2.82746e+10
Iteration 53 completed in 31s
Start of iteration 54
Current loss value: 2.82693e+10
Iteration 54 completed in 31s
Start of iteration 55
Current loss value: 2.82643e+10
Iteration 55 completed in 31s
Start of iteration 56
Current loss value: 2.82596e+10
Iteration 56 completed in 31s
Start of iteration 57
Current loss value: 2.82552e+10
Iteration 57 completed in 31s
Start of iteration 58
Current loss value: 2.82508e+10
Iteration 58 completed in 31s
Start of iteration 59
Current loss value: 2.82468e+10
Iteration 59 completed in 31s
Start of iteration 60
Current loss value: 2.82431e+10
Iteration 60 completed in 31s
Start of iteration 61
Current loss value: 2.82396e+10
Iteration 61 completed in 31s
Start of iteration 62
Current loss value: 2.82363e+10
Iteration 62 completed in 31s
Start of iteration 63
Current loss value: 2.82331e+10
Iteration 63 completed in 31s
Start of iteration 64
Current loss value: 2.823e+10
Iteration 64 completed in 31s
Start of iteration 65
Current loss value: 2.82272e+10
Iteration 65 completed in 31s
Start of iteration 66
Current loss value: 2.82245e+10
Iteration 66 completed in 31s
Start of iteration 67
Current loss value: 2.8222e+10
Iteration 67 completed in 31s
Start of iteration 68
Current loss value: 2.82196e+10
Iteration 68 completed in 31s
Start of iteration 69
Current loss value: 2.82173e+10
Iteration 69 completed in 31s
Start of iteration 70
Current loss value: 2.8215e+10
Iteration 70 completed in 31s
Start of iteration 71
Current loss value: 2.82129e+10
Iteration 71 completed in 31s
Start of iteration 72
Current loss value: 2.82107e+10
Iteration 72 completed in 31s
Start of iteration 73
Current loss value: 2.82086e+10
Iteration 73 completed in 31s
Start of iteration 74
Current loss value: 2.82066e+10
Iteration 74 completed in 31s
Start of iteration 75
Current loss value: 2.82047e+10
Iteration 75 completed in 31s
Start of iteration 76
Current loss value: 2.82028e+10
Iteration 76 completed in 31s
Start of iteration 77
Current loss value: 2.8201e+10
Iteration 77 completed in 31s
Start of iteration 78
Current loss value: 2.81993e+10
Iteration 78 completed in 31s
Start of iteration 79
Current loss value: 2.81976e+10
Iteration 79 completed in 31s
Start of iteration 80
Current loss value: 2.81961e+10
Iteration 80 completed in 31s
Start of iteration 81
Current loss value: 2.81946e+10
Iteration 81 completed in 31s
Start of iteration 82
Current loss value: 2.81931e+10
Iteration 82 completed in 31s
Start of iteration 83
Current loss value: 2.81916e+10
Iteration 83 completed in 31s
Start of iteration 84
Current loss value: 2.819e+10
Iteration 84 completed in 31s
Start of iteration 85
Current loss value: 2.81885e+10
Iteration 85 completed in 31s
Start of iteration 86
Current loss value: 2.81871e+10
Iteration 86 completed in 31s
Start of iteration 87
Current loss value: 2.81858e+10
Iteration 87 completed in 31s
Start of iteration 88
Current loss value: 2.81845e+10
Iteration 88 completed in 31s
Start of iteration 89
Current loss value: 2.81833e+10
Iteration 89 completed in 31s
Start of iteration 90
Current loss value: 2.81822e+10
Iteration 90 completed in 31s
Start of iteration 91
Current loss value: 2.81811e+10
Iteration 91 completed in 31s
Start of iteration 92
Current loss value: 2.818e+10
Iteration 92 completed in 31s
Start of iteration 93
Current loss value: 2.8179e+10
Iteration 93 completed in 31s
Start of iteration 94
Current loss value: 2.8178e+10
Iteration 94 completed in 31s
Start of iteration 95
Current loss value: 2.81771e+10
Iteration 95 completed in 31s
Start of iteration 96
Current loss value: 2.81761e+10
Iteration 96 completed in 31s
Start of iteration 97
Current loss value: 2.81752e+10
Iteration 97 completed in 31s
Start of iteration 98
Current loss value: 2.81743e+10
Iteration 98 completed in 31s
Start of iteration 99
Current loss value: 2.81735e+10
Iteration 99 completed in 31s
Start of iteration 100
Current loss value: 2.81727e+10
Iteration 100 completed in 30s
Start of iteration 101
Current loss value: 2.81719e+10
Iteration 101 completed in 30s
Start of iteration 102
Current loss value: 2.81711e+10
Iteration 102 completed in 30s
Start of iteration 103
Current loss value: 2.81703e+10
Iteration 103 completed in 30s
Start of iteration 104
Current loss value: 2.81695e+10
Iteration 104 completed in 31s
Start of iteration 105
Current loss value: 2.81688e+10
Iteration 105 completed in 31s
Start of iteration 106
Current loss value: 2.8168e+10
Iteration 106 completed in 30s
Start of iteration 107
Current loss value: 2.81673e+10
Iteration 107 completed in 31s
Start of iteration 108
Current loss value: 2.81666e+10
Iteration 108 completed in 31s
Start of iteration 109
Current loss value: 2.81658e+10
Iteration 109 completed in 30s
Start of iteration 110
Current loss value: 2.81651e+10
Iteration 110 completed in 31s
Start of iteration 111
Current loss value: 2.81644e+10
Iteration 111 completed in 30s
Start of iteration 112
Current loss value: 2.81637e+10
Iteration 112 completed in 30s
Start of iteration 113
Current loss value: 2.8163e+10
Iteration 113 completed in 31s
Start of iteration 114
Current loss value: 2.81623e+10
Iteration 114 completed in 31s
Start of iteration 115
Current loss value: 2.81616e+10
Iteration 115 completed in 31s
Start of iteration 116
Current loss value: 2.8161e+10
Iteration 116 completed in 30s
Start of iteration 117
Current loss value: 2.81603e+10
Iteration 117 completed in 30s
Start of iteration 118
Current loss value: 2.81597e+10
Iteration 118 completed in 30s
Start of iteration 119
Current loss value: 2.81591e+10
Iteration 119 completed in 30s
Start of iteration 120
Current loss value: 2.81585e+10
Iteration 120 completed in 30s
Start of iteration 121
Current loss value: 2.81579e+10
Iteration 121 completed in 31s
Start of iteration 122
Current loss value: 2.81574e+10
Iteration 122 completed in 30s
Start of iteration 123
Current loss value: 2.81568e+10
Iteration 123 completed in 31s
Start of iteration 124
Current loss value: 2.81563e+10
Iteration 124 completed in 30s
Start of iteration 125
Current loss value: 2.81558e+10
Iteration 125 completed in 31s
Start of iteration 126
Current loss value: 2.81552e+10
Iteration 126 completed in 30s
Start of iteration 127
Current loss value: 2.81547e+10
Iteration 127 completed in 30s
Start of iteration 128
Current loss value: 2.81542e+10
Iteration 128 completed in 30s
Start of iteration 129
Current loss value: 2.81538e+10
Iteration 129 completed in 31s
Start of iteration 130
Current loss value: 2.81533e+10
Iteration 130 completed in 30s
Start of iteration 131
Current loss value: 2.81528e+10
Iteration 131 completed in 31s
Start of iteration 132
Current loss value: 2.81523e+10
Iteration 132 completed in 30s
Start of iteration 133
Current loss value: 2.81518e+10
Iteration 133 completed in 30s
Start of iteration 134
Current loss value: 2.81513e+10
Iteration 134 completed in 30s
Start of iteration 135
Current loss value: 2.81508e+10
Iteration 135 completed in 30s
Start of iteration 136
Current loss value: 2.81503e+10
Iteration 136 completed in 31s
Start of iteration 137
Current loss value: 2.81498e+10
Iteration 137 completed in 31s
Start of iteration 138
Current loss value: 2.81493e+10
Iteration 138 completed in 30s
Start of iteration 139
Current loss value: 2.81489e+10
Iteration 139 completed in 31s
Start of iteration 140
Current loss value: 2.81485e+10
Iteration 140 completed in 30s
Start of iteration 141
Current loss value: 2.8148e+10
Iteration 141 completed in 31s
Start of iteration 142
Current loss value: 2.81476e+10
Iteration 142 completed in 31s
Start of iteration 143
Current loss value: 2.81472e+10
Iteration 143 completed in 31s
Start of iteration 144
Current loss value: 2.81468e+10
Iteration 144 completed in 30s
Start of iteration 145
Current loss value: 2.81464e+10
Iteration 145 completed in 31s
Start of iteration 146
Current loss value: 2.8146e+10
Iteration 146 completed in 30s
Start of iteration 147
Current loss value: 2.81456e+10
Iteration 147 completed in 30s
Start of iteration 148
Current loss value: 2.81453e+10
Iteration 148 completed in 31s
Start of iteration 149
Current loss value: 2.81449e+10
Iteration 149 completed in 31s
Start of iteration 150
Current loss value: 2.81445e+10
Iteration 150 completed in 30s
Start of iteration 151
Current loss value: 2.81442e+10
Iteration 151 completed in 31s
Start of iteration 152
Current loss value: 2.81438e+10
Iteration 152 completed in 31s
Start of iteration 153
Current loss value: 2.81434e+10
Iteration 153 completed in 31s
Start of iteration 154
Current loss value: 2.81431e+10
Iteration 154 completed in 31s
Start of iteration 155
Current loss value: 2.81428e+10
Iteration 155 completed in 31s
Start of iteration 156
Current loss value: 2.81424e+10
Iteration 156 completed in 31s
Start of iteration 157
Current loss value: 2.81421e+10
Iteration 157 completed in 31s
Start of iteration 158
Current loss value: 2.81418e+10
Iteration 158 completed in 31s
Start of iteration 159
Current loss value: 2.81414e+10
Iteration 159 completed in 31s
Start of iteration 160
Current loss value: 2.81411e+10
Iteration 160 completed in 31s
Start of iteration 161
Current loss value: 2.81408e+10
Iteration 161 completed in 31s
Start of iteration 162
Current loss value: 2.81405e+10
Iteration 162 completed in 31s
Start of iteration 163
Current loss value: 2.81402e+10
Iteration 163 completed in 31s
Start of iteration 164
Current loss value: 2.81399e+10
Iteration 164 completed in 31s
Start of iteration 165
Current loss value: 2.81396e+10
Iteration 165 completed in 31s
Start of iteration 166
Current loss value: 2.81392e+10
Iteration 166 completed in 32s
Start of iteration 167
Current loss value: 2.81389e+10
Iteration 167 completed in 31s
Start of iteration 168
Current loss value: 2.81386e+10
Iteration 168 completed in 31s
Start of iteration 169
Current loss value: 2.81383e+10
Iteration 169 completed in 31s
Start of iteration 170
Current loss value: 2.8138e+10
Iteration 170 completed in 31s
Start of iteration 171
Current loss value: 2.81376e+10
Iteration 171 completed in 31s
Start of iteration 172
Current loss value: 2.81373e+10
Iteration 172 completed in 31s
Start of iteration 173
Current loss value: 2.81371e+10
Iteration 173 completed in 31s
Start of iteration 174
Current loss value: 2.81368e+10
Iteration 174 completed in 31s
Start of iteration 175
Current loss value: 2.81366e+10
Iteration 175 completed in 31s
Start of iteration 176
Current loss value: 2.81364e+10
Iteration 176 completed in 31s
Start of iteration 177
Current loss value: 2.81362e+10
Iteration 177 completed in 31s
Start of iteration 178
Current loss value: 2.81361e+10
Iteration 178 completed in 31s
Start of iteration 179
Current loss value: 2.81359e+10
Iteration 179 completed in 31s
Start of iteration 180
Current loss value: 2.81358e+10
Iteration 180 completed in 30s
Start of iteration 181
Current loss value: 2.81357e+10
Iteration 181 completed in 28s
Start of iteration 182
Current loss value: 2.81357e+10
Iteration 182 completed in 26s
Start of iteration 183
Current loss value: 2.81357e+10
Iteration 183 completed in 26s
Start of iteration 184
Current loss value: 2.81357e+10
Iteration 184 completed in 26s
Start of iteration 185
Current loss value: 2.81357e+10
Iteration 185 completed in 24s
Start of iteration 186
Current loss value: 2.81357e+10
Iteration 186 completed in 24s
Start of iteration 187
Current loss value: 2.81357e+10
Iteration 187 completed in 24s
Start of iteration 188
Current loss value: 2.81357e+10
Iteration 188 completed in 25s
Start of iteration 189
Current loss value: 2.81357e+10
Iteration 189 completed in 26s
Start of iteration 190
Current loss value: 2.81357e+10
Iteration 190 completed in 23s
Start of iteration 191
Current loss value: 2.81357e+10
Iteration 191 completed in 24s
Start of iteration 192
Current loss value: 2.81357e+10
Iteration 192 completed in 24s
Start of iteration 193
Current loss value: 2.81357e+10
Iteration 193 completed in 26s
Start of iteration 194
Current loss value: 2.81357e+10
Iteration 194 completed in 24s
Start of iteration 195
Current loss value: 2.81357e+10
Iteration 195 completed in 26s
Start of iteration 196
Current loss value: 2.81357e+10
Iteration 196 completed in 24s
Start of iteration 197
Current loss value: 2.81357e+10
Iteration 197 completed in 24s
Start of iteration 198
Current loss value: 2.81357e+10
Iteration 198 completed in 22s
Start of iteration 199
Current loss value: 2.81357e+10
Iteration 199 completed in 24s
Start of iteration 200
Current loss value: 2.81357e+10
Iteration 200 completed in 26s
Start of iteration 201
Current loss value: 2.81357e+10
Iteration 201 completed in 26s
Start of iteration 202
Current loss value: 2.81357e+10
Iteration 202 completed in 24s
Start of iteration 203
Current loss value: 2.81357e+10
Iteration 203 completed in 29s
Start of iteration 204
Current loss value: 2.81357e+10
Iteration 204 completed in 29s
Start of iteration 205
Current loss value: 2.81357e+10
Iteration 205 completed in 29s
Start of iteration 206
Current loss value: 2.81357e+10
Iteration 206 completed in 29s
Start of iteration 207
Current loss value: 2.81357e+10
Iteration 207 completed in 29s
Start of iteration 208
Current loss value: 2.81357e+10
Iteration 208 completed in 29s
Start of iteration 209
Current loss value: 2.81357e+10
Iteration 209 completed in 29s
Start of iteration 210
Current loss value: 2.81357e+10
Iteration 210 completed in 29s
Start of iteration 211
Current loss value: 2.81357e+10
Iteration 211 completed in 29s
Start of iteration 212
Current loss value: 2.81357e+10
Iteration 212 completed in 29s
Start of iteration 213
Current loss value: 2.81357e+10
Iteration 213 completed in 29s
Start of iteration 214
Current loss value: 2.81357e+10
Iteration 214 completed in 29s
Start of iteration 215
Current loss value: 2.81357e+10
Iteration 215 completed in 29s
Start of iteration 216
Current loss value: 2.81357e+10
Iteration 216 completed in 29s
Start of iteration 217
Current loss value: 2.81357e+10
Iteration 217 completed in 29s
Start of iteration 218
Current loss value: 2.81357e+10
Iteration 218 completed in 29s
Start of iteration 219
Current loss value: 2.81357e+10
Iteration 219 completed in 29s
Start of iteration 220
Current loss value: 2.81357e+10
Iteration 220 completed in 29s
Start of iteration 221
Current loss value: 2.81357e+10
Iteration 221 completed in 29s
Start of iteration 222
Current loss value: 2.81357e+10
Iteration 222 completed in 29s
Start of iteration 223
Current loss value: 2.81357e+10
Iteration 223 completed in 29s
Start of iteration 224
Current loss value: 2.81357e+10
Iteration 224 completed in 29s
Start of iteration 225
Current loss value: 2.81357e+10
Iteration 225 completed in 29s
Start of iteration 226
Current loss value: 2.81357e+10
Iteration 226 completed in 29s
Start of iteration 227
Current loss value: 2.81357e+10
Iteration 227 completed in 29s
Start of iteration 228
Current loss value: 2.81357e+10
Iteration 228 completed in 29s
Start of iteration 229
Current loss value: 2.81357e+10
Iteration 229 completed in 29s
Start of iteration 230
Current loss value: 2.81357e+10
Iteration 230 completed in 29s
Start of iteration 231
Current loss value: 2.81357e+10
Iteration 231 completed in 29s
Start of iteration 232
Current loss value: 2.81357e+10
Iteration 232 completed in 29s
Start of iteration 233
Current loss value: 2.81357e+10
Iteration 233 completed in 29s
Start of iteration 234
Current loss value: 2.81357e+10
Iteration 234 completed in 29s
Start of iteration 235
Current loss value: 2.81357e+10
Iteration 235 completed in 29s
Start of iteration 236
Current loss value: 2.81357e+10
Iteration 236 completed in 29s
Start of iteration 237
Current loss value: 2.81357e+10
Iteration 237 completed in 29s
Start of iteration 238
Current loss value: 2.81357e+10
Iteration 238 completed in 29s
Start of iteration 239
Current loss value: 2.81357e+10
Iteration 239 completed in 29s
Start of iteration 240
Current loss value: 2.81357e+10
Iteration 240 completed in 29s
Start of iteration 241
Current loss value: 2.81357e+10
Iteration 241 completed in 29s
Start of iteration 242
Current loss value: 2.81357e+10
Iteration 242 completed in 29s
Start of iteration 243
Current loss value: 2.81357e+10
Iteration 243 completed in 29s
Start of iteration 244
Current loss value: 2.81357e+10
Iteration 244 completed in 29s
Start of iteration 245
Current loss value: 2.81357e+10
Iteration 245 completed in 29s
Start of iteration 246
Current loss value: 2.81357e+10
Iteration 246 completed in 29s
Start of iteration 247
Current loss value: 2.81357e+10
Iteration 247 completed in 29s
Start of iteration 248
Current loss value: 2.81357e+10
Iteration 248 completed in 29s
Start of iteration 249
Current loss value: 2.81357e+10
Iteration 249 completed in 29s
Start of iteration 250
Current loss value: 2.81357e+10
Iteration 250 completed in 29s
Start of iteration 251
Current loss value: 2.81357e+10
Iteration 251 completed in 29s
Start of iteration 252
Current loss value: 2.81357e+10
Iteration 252 completed in 29s
Start of iteration 253
Current loss value: 2.81357e+10
Iteration 253 completed in 29s
Start of iteration 254
Current loss value: 2.81357e+10
Iteration 254 completed in 29s
Start of iteration 255
Current loss value: 2.81357e+10
Iteration 255 completed in 29s
Start of iteration 256
Current loss value: 2.81357e+10
Iteration 256 completed in 29s
Start of iteration 257
Current loss value: 2.81357e+10
Iteration 257 completed in 29s
Start of iteration 258
Current loss value: 2.81357e+10
Iteration 258 completed in 29s
Start of iteration 259
Current loss value: 2.81357e+10
Iteration 259 completed in 29s
Start of iteration 260
Current loss value: 2.81357e+10
Iteration 260 completed in 29s
Start of iteration 261
Current loss value: 2.81357e+10
Iteration 261 completed in 29s
Start of iteration 262
Current loss value: 2.81357e+10
Iteration 262 completed in 29s
Start of iteration 263
Current loss value: 2.81357e+10
Iteration 263 completed in 29s
Start of iteration 264
Current loss value: 2.81357e+10
Iteration 264 completed in 29s
Start of iteration 265
Current loss value: 2.81357e+10
Iteration 265 completed in 29s
Start of iteration 266
Current loss value: 2.81357e+10
Iteration 266 completed in 29s
Start of iteration 267
Current loss value: 2.81357e+10
Iteration 267 completed in 29s
Start of iteration 268
Current loss value: 2.81357e+10
Iteration 268 completed in 29s
Start of iteration 269
Current loss value: 2.81357e+10
Iteration 269 completed in 29s
Start of iteration 270
Current loss value: 2.81357e+10
Iteration 270 completed in 29s
Start of iteration 271
Current loss value: 2.81357e+10
Iteration 271 completed in 29s
Start of iteration 272
Current loss value: 2.81357e+10
Iteration 272 completed in 29s
Start of iteration 273
Current loss value: 2.81357e+10
Iteration 273 completed in 29s
Start of iteration 274
Current loss value: 2.81357e+10
Iteration 274 completed in 29s
Start of iteration 275
Current loss value: 2.81357e+10
Iteration 275 completed in 29s
Start of iteration 276
Current loss value: 2.81357e+10
Iteration 276 completed in 29s
Start of iteration 277
Current loss value: 2.81357e+10
Iteration 277 completed in 29s
Start of iteration 278
Current loss value: 2.81357e+10
Iteration 278 completed in 29s
Start of iteration 279
Current loss value: 2.81357e+10
Iteration 279 completed in 29s
Start of iteration 280
Current loss value: 2.81357e+10
Iteration 280 completed in 29s
Start of iteration 281
Current loss value: 2.81357e+10
Iteration 281 completed in 29s
Start of iteration 282
Current loss value: 2.81357e+10
Iteration 282 completed in 29s
Start of iteration 283
Current loss value: 2.81357e+10
Iteration 283 completed in 29s
Start of iteration 284
Current loss value: 2.81357e+10
Iteration 284 completed in 29s
Start of iteration 285
Current loss value: 2.81357e+10
Iteration 285 completed in 29s
Start of iteration 286
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-21-043573beb46d> in <module>()
     20     start_time = time.time()
     21     x, min_val, info = fmin_l_bfgs_b(evaluator.loss, x.flatten(),
---> 22                                      fprime=evaluator.grads, maxfun=20)
     23     print('Current loss value:', min_val)
     24     end_time = time.time()

C:\Users\837040\AppData\Local\Continuum\Anaconda3\lib\site-packages\scipy\optimize\lbfgsb.py in fmin_l_bfgs_b(func, x0, fprime, args, approx_grad, bounds, m, factr, pgtol, epsilon, iprint, maxfun, maxiter, disp, callback, maxls)
    191 
    192     res = _minimize_lbfgsb(fun, x0, args=args, jac=jac, bounds=bounds,
--> 193                            **opts)
    194     d = {'grad': res['jac'],
    195          'task': res['message'],

C:\Users\837040\AppData\Local\Continuum\Anaconda3\lib\site-packages\scipy\optimize\lbfgsb.py in _minimize_lbfgsb(fun, x0, args, jac, bounds, disp, maxcor, ftol, gtol, eps, maxfun, maxiter, iprint, callback, maxls, **unknown_options)
    326             # until the completion of the current minimization iteration.
    327             # Overwrite f and g:
--> 328             f, g = func_and_grad(x)
    329         elif task_str.startswith(b'NEW_X'):
    330             # new iteration

C:\Users\837040\AppData\Local\Continuum\Anaconda3\lib\site-packages\scipy\optimize\lbfgsb.py in func_and_grad(x)
    276     else:
    277         def func_and_grad(x):
--> 278             f = fun(x, *args)
    279             g = jac(x, *args)
    280             return f, g

C:\Users\837040\AppData\Local\Continuum\Anaconda3\lib\site-packages\scipy\optimize\optimize.py in function_wrapper(*wrapper_args)
    290     def function_wrapper(*wrapper_args):
    291         ncalls[0] += 1
--> 292         return function(*(wrapper_args + args))
    293 
    294     return ncalls, function_wrapper

<ipython-input-20-094ad4716be4> in loss(self, x)
     69     def loss(self, x):
     70         assert self.loss_value is None
---> 71         loss_value, grad_values = eval_loss_and_grads(x)
     72         self.loss_value = loss_value
     73         self.grad_values = grad_values

<ipython-input-20-094ad4716be4> in eval_loss_and_grads(x)
     56 def eval_loss_and_grads(x):
     57     x = x.reshape((1, height, width, 3))
---> 58     outs = f_outputs([x])
     59     loss_value = outs[0]
     60     grad_values = outs[1].flatten().astype('float64')

C:\Users\837040\AppData\Local\Continuum\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py in __call__(self, inputs)
   2355         session = get_session()
   2356         updated = session.run(fetches=fetches, feed_dict=feed_dict,
-> 2357                               **self.session_kwargs)
   2358         return updated[:len(self.outputs)]
   2359 

C:\Users\837040\AppData\Local\Continuum\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in run(self, fetches, feed_dict, options, run_metadata)
    887     try:
    888       result = self._run(None, fetches, feed_dict, options_ptr,
--> 889                          run_metadata_ptr)
    890       if run_metadata:
    891         proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)

C:\Users\837040\AppData\Local\Continuum\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in _run(self, handle, fetches, feed_dict, options, run_metadata)
   1118     if final_fetches or final_targets or (handle and feed_dict_tensor):
   1119       results = self._do_run(handle, final_targets, final_fetches,
-> 1120                              feed_dict_tensor, options, run_metadata)
   1121     else:
   1122       results = []

C:\Users\837040\AppData\Local\Continuum\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in _do_run(self, handle, target_list, fetch_list, feed_dict, options, run_metadata)
   1315     if handle is None:
   1316       return self._do_call(_run_fn, self._session, feeds, fetches, targets,
-> 1317                            options, run_metadata)
   1318     else:
   1319       return self._do_call(_prun_fn, self._session, handle, feeds, fetches)

C:\Users\837040\AppData\Local\Continuum\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in _do_call(self, fn, *args)
   1321   def _do_call(self, fn, *args):
   1322     try:
-> 1323       return fn(*args)
   1324     except errors.OpError as e:
   1325       message = compat.as_text(e.message)

C:\Users\837040\AppData\Local\Continuum\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in _run_fn(session, feed_dict, fetch_list, target_list, options, run_metadata)
   1300           return tf_session.TF_Run(session, options,
   1301                                    feed_dict, fetch_list, target_list,
-> 1302                                    status, run_metadata)
   1303 
   1304     def _prun_fn(session, handle, feed_dict, fetch_list):

KeyboardInterrupt: