Curves (2015)

neural network generative art javascript demo.

higher resolution w/ png export demo here (slower).

Recently, google’s work on generating art from convolutional neural networks has drawn a lot of attention.  It’s amazing to be able to dig deep into what a deep convolutional network is actually seeing, and contrast that to human perception.  That got me thinking about the flexibility and generativeness of deep neural networks.  In the spirit of generative neural network art, I hacked together a quick and dirty script that attempts to generate random art pieces by randomly assigning weights to a not-so-shallow neural network using p5.js and recurrent.js libraries, just to see what can get drawn randomly without any training of the network.

// actual size of generated image

var sizeh = 320;
var sizew = 320;

// settings of nnet:

var networkSize = 16; // 16 neurons in each layer

var nHidden = 8; // depth of 8 layers

var nOut = 3; // r, g, b layers


// support variables:

var img; // this is where we hold the image

var G = new R.Graph(false); // graph object from recurrent.js


var initModel = function() {
  var model = [];
  // define the model below:

  model.w_in = R.RandMat(networkSize, 3); // x, y, and bias

  for (var i = 0; i < nHidden; i++) {
    model['w_'+i] = R.RandMat(networkSize, networkSize);
  }
  model.w_out = R.RandMat(nOut, networkSize); // output layer

  return model;
};

var model = initModel();

var forwardNetwork = function(G, model, x_, y_) {
  var x = new R.Mat(3, 1); // input

  var i;
  x.set(0, 0, x_);
  x.set(1, 0, y_);
  x.set(2, 0, 1.0); // bias.

  var out;
  out = G.tanh(G.mul(model.w_in, x));
  for (i = 0; i < nHidden; i++) {
    out = G.tanh(G.mul(model['w_'+i], out));
  }
  out = G.sigmoid(G.mul(model.w_out, out));
  return out;
};

function getColorAt(x, y) {
  // function that returns a color given coord (x, y)

  var r, g, b;
  var out = forwardNetwork(G, model, x, y);

  r = out.w[0]*255.0;
  g = out.w[1]*255.0;
  b = out.w[2]*255.0;

  return color(r, g, b);
}

// ... rest of the code populates img using getColorAt(x, y)

You can try to run the code in your browser here to generate a random image.

If you like this style of generated art, here is a higher resolution demo that exports the image to a png after it displays.  It will take around 30 seconds to generate on a macbook air for the higher resolution version.

The cool thing is that while I am generating 320×320 images, I can use the same neural network to generate much larger images that are more refined but loo the same, or much smaller images.  In that sense it is sort of like generating fractals, and as the image information is stored in the weights that can generate the same image of infinite dimension.

The next step can be to try to use indirect encodings to populate the weight space to see if we can get more interesting patterns.  Going to use this as base for more advanced generative works.

Below are some more images generated from the code.

genart07

genart01 genart03 genart04 genart05

Other pieces from playing around with number of levels and neurons.

small_genart1 small_genart2 small_genart3