Neural network abstract art with Keras

Published 10-04-2018

I really like the abstract renderings by otoro.net. I decided to recreate the example in Keras, and use as few lines as possible, to make it easier to grasp the full concept. The article in the link is very understandable, so I recommend you read it if you want to learn more.

In [9]:
import numpy as np
import keras
import matplotlib.pyplot as plt
%matplotlib inline
In [7]:
c_dim = 3 # 3 color channels (RGB)
latent_size = 8

input_size = latent_size + 3

def layer(size, activation='tanh'):
    return keras.layers.Dense(size, activation=activation, use_bias=False)

input_layer = keras.layers.Input((input_size,))
layer1 = layer(32)(input_layer)
layer2 = layer(32)(layer1)
layer3 = layer(32)(layer2)
output_layer = layer(c_dim, activation='sigmoid')(layer3)
model = keras.Model(input_layer, output_layer)

def initialize_weights():
    for layer in model.layers[1:]:
        weights = layer.get_weights()
        new_weights = [ np.random.normal(0.0, 1.2, size=weights[0].shape) ]
        layer.set_weights(new_weights)
initialize_weights()
In [8]:
scale = 10.0
x_dim = 1200
y_dim = 1200

latent = np.random.uniform(-scale, scale, size=(latent_size,))

def image(model):
    inp = np.zeros((x_dim*y_dim, input_size))
    
    xs = scale * ( ( np.arange(x_dim) - (x_dim-1)/2.0 ) / (x_dim-1) / 0.5 )
    ys = scale * ( ( np.arange(y_dim) - (y_dim-1)/2.0 ) / (y_dim-1) / 0.5 )
    rs = np.sqrt( (xs*xs)[:, np.newaxis].dot((ys*ys)[np.newaxis]) )
    inp[:, 0] = np.repeat(xs, y_dim)
    inp[:, 1] = np.tile(ys, x_dim)
    inp[:, 2] = np.sqrt( inp[:, 0]**2 + inp[:, 1]**2 )
    inp[:, 3:] = np.tile(latent, x_dim*y_dim).reshape((x_dim*y_dim, 8))
    
    data = model.predict(inp, batch_size=inp.shape[0])
    return data.reshape((x_dim, y_dim, c_dim))

data = image(model)

plt.figure(figsize=(10, 10))
if c_dim > 1:
    plt.imshow(data)
else:
    plt.imshow(data.reshape(x_dim, y_dim), cmap='Greys')
print(data.shape)
(1200, 1200, 3)