Compositional pattern-producing networks (CPPNs)

This example shows and implementation of Compositional Pattern-Producing Networks in Flux.

Load the necessary packages.


using Images
using Flux
using Parameters: @with_kw


Set parameters

@with_kw mutable struct Args
    z_dim::Int = 2		# Dim of Latent Vector
    x_dim::Int = 512	# X-Dimension of Image
    y_dim::Int = 512	# Y-Dimension of Image
    N::Int = 14			#
    hidden::Int = 9		# Number of hidden layers in the image
    batch_size::Int = 1024	# Batch Size for prediction
end


Cast 0:x-1 to -0.5:0.5.

cast(x) = [range(-0.5, stop=0.5, step=1/(x - 1))...]


Obtain data.

function getdata(args)
    xs, ys = cast(args.x_dim), cast(args.y_dim)
    xs = repeat(xs, inner=(args.y_dim))
    ys = repeat(ys, outer=(args.x_dim))
	# Radius term for each point of input
    rs = sqrt.(xs.^2 + ys.^2)
    return xs,ys,rs
end


Definition for each individual layer sample weigths from a gaussian distribution.

unit(args, in=args.N, out=args.N, f=tanh) = Dense(in, out, f, initW=randn)


Build the model.

function build_model(args)
    # input -> [x, y, r, z...]
    layers = Any[unit(args, 3 + args.z_dim)]
    for i=1:args.hidden
        push!(layers, unit(args))
    end
    push!(layers, unit(args,args.N, 1, σ))
    model = Chain(layers...)
    return model
end


function batch(arr, s)
    batches = []
    l = size(arr, 2)
    for i=1:s:l
        push!(batches, arr[:, i:min(i+s-1, l)])
    end
    batches
end


function get_image(z, model, args) 
    n = args.x_dim * args.y_dim   
    z = repeat(reshape(z, 1, args.z_dim), outer=(n, 1))
    xs, ys, rs = getdata(args)
    coords = hcat(xs, ys, rs, z)'
    
    coords = batch(coords, args.batch_size)
    
    # Pixel value at a position x is defined as output of model at that point 
    getColorAt(x) = model(x)

    pixels = [Gray.(hcat(getColorAt.(coords)...))...]
    reshape(pixels, args.y_dim, args.x_dim)
end

Save the image.

function save_img(z, model, args, image_path=joinpath(dirname(@__FILE__),"sample.png"))
    imgg = get_image(z, model, args)
    save(image_path, imgg)
    imgg
end


Generate the image.

function generate_img(; kws...)
    args = Args(; kws...)
	
    model = build_model(args)
	
    #Saving image as "sample.png"
    save_img(rand(args.z_dim), model, args)
end

cd(@__DIR__)
generate_img()

– Adarsh Kumar, Neethu Mariya Joy, Sudhanshu Agrawal