Mark Gritter (markgritter) wrote,
Mark Gritter

NNMF project

Some notes on a procedural generation project, just for fun.

Non-Negative Matrix Factorization is a dimensionality reduction technique. It reduces a set of samples (say, books consisting of words or images consisting of pixels) to a set of lower-dimensional "components". Then we can do fun things like interpolate between two of the samples by interpolating their component representation. One of the ProcJam 2016 speakers used this for blending Zelda levels; his talk can be found here:

I wanted to play around with this but lacked an appropriate data set that was easy to use. So I decided to try the flower pixel art from the ProcJam Garden Pack found here:

The first attempt was disastrous. Even with the number of components == the number of samples (which permits a trivial matrix factorization) I couldn't convince the NNMF implementation to learn the shapes. What I did here was build the matrix out of RGBA values.

So, my first thought was that we could make it simpler by using a matrix where there was one row per pixel per color in the palette (since the pictures are reduced-palette anyway.) This is actually a dimensional increase, but it means every training value is either zero or one. This produced somewhat more interesting results, not only successfully learning the shapes, but also managing to represent them with a little bit of dimensional reduction. Of course, subtleties between the similar shapes are lost quite quickly.

20 components:

16 components:

12 components:

In order to convert back from a vector of palette color indicator values (c0, c1, c2, c3, c4, c5) to RGBA, I first normalized (so the sum is 1) and then do a weighted average of the indicated colors. This is probably too linear to produce non-"muddy" results as you can see in the last image above and in the mixed images below.

So here's the first attempt at doing a 50% mixture between every sample, using the full dimension. Some of them are arguably a good mixture, but most just come out sort of grey or confusing.

The code for this iteration can be found in the Gist here:

Probably the next thing to try is to switch the vector to RGB conversion to be nonlinear; perhaps just take the highest-ranked palette color. This would mean every output pixel uses the palette, which is a more faithful interpolation. But overall this doesn't look like a good data set for NNMF.
Tags: geek, programming
  • Post a new comment


    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.