Generate simple Mondrian Tableaux


View the Project on GitHub ignacioarnaldo/generateMondrianTableaux

Have you ever seen one of Mondrian's Tableaux and thought: "mmmm I could paint that". Well, this tutorial explores an AI method to generate many!

Let's start by examining these handcrafted examples:

Example 1
Example 2
Example 3
Example 4
hc1
hc2
hc3
hc4

We can generate a large number of Tableaux like these ones following simple 4 steps:

  1. Split the tableau in two rows such that one of the rows occupies one third of the tableau and the other occupies the remaining two thirds.
  2. Split the first row into two (also with a one-third vs two third split) or into three equal columns.
  3. Split the second row into two (also with a one-third vs two third split) or into three equal columns.
  4. Assign a color (white, red, blue, or yellow) to each of the resulting cells.

There will be at least 4 cells and at most 6 cells (in the case where the two rows are split into three columns). This means that we can code these tableaux with 9 variables where 3 variables (X1, X2, X3) determine the structure of the tableau, and 6 variables (X4, X5, X6, X7, X8, X9) code for the cell colors:

Variable
X1
X2
X3
X4 ... X9
Action
Split tableau into 2 rows
Split 1st row into 2 or 3 columns
Split 2nd row into 2 or 3 columns
Assign one color per cell
Choices
(1/3,2/3) or (2/3,1/3)
(1/3,2/3) or (2/3,1/3) or (1/3,1/3,1/3)
(1/3,2/3) or (2/3,1/3) or (1/3,1/3,1/3)
white, red, blue, yellow, dummy
Possible values
{1,2}
{1,2,3}
{1,2,3}
{1,2,3,4,5}

Generating all possible Tableaux

This program exhaustively generates all feasible configurations in this notation (X1...X9). From the terminal:

$ java -jar allPaintings.jar all_paintings.csv

Even with this simplification of Mondrian's tableaux, 18433 tableaux are created! Unfortunately, most of them (like the examples below) do not look great:

Bad example 1
Bad example 2
Bad example 3
Bad example 4
Bad example 5
b1
b2
b3
b4
b4

Discarding Tableaux

After examination of the tableaux, we create a set of arbitrary rules that will help us discard "bad-looking" tableaux (note that this step is completely subjective). We discard the tableaux that satisfy one of the following conditions:

  1. The tableau has 4 cells and 0 white cells.
  2. The tableau has 5 or 6 cells and 0-1 white cells.
  3. There are only two colors, out of which white is one of them.
  4. The tableau has 5 or 6 cells and there are only three colors, out of which white is one of them.
  5. Two consecutive cells in the same row have the same color.
  6. Cells on top of each other have the same color.

To discard the bad-looking paintings according to this set of rules, please download this other executable and run:

$ java -jar discardPaintings.jar all_paintings.csv good_paintings.csv bad_paintings.csv

After filtering the tableaux, we are left with 648 great tableaux! Below we show 4 nice paintings:

Good example 1
Good example 2
Good example 3
Good example 4
Good example 5
g1
g2
g3
g4
g4

Modeling the tableaux with Bayesian networks

Let's say that we do not want to store all 648 tableaux. Instead, we want to learn the patterns that characterize these "good" tableaux, and generate new aesthetic tableaux on the fly. We can learn the structure and parameters of a Bayesian network from which we can sample as many tableaux as we want! For this part we use the Bayes Net Toolbox for Matlab by Kevin Murphy. You can download the Matlab code for the following steps from here.


Step 1: Learning the dependencies between variables

Dependencies between variables can be represented graphically with Directed Acyclic Graphs (DAG) where:

  • nodes correspond to the variables of the problem (X1,...,X9),
  • an edge between two nodes indicates that the two variables are conditionally dependent.
  • The goal of this step is to learn a DAG that captures the conditional dependencies between the variables X1,...,X9. We help the process by entering manually the number of discrete emissions (called choices above) and order of the variables X1,...,X9, and run the K2 algorithm to learn the structure of the DAG with the 648 "good" paintings:

    node_sizes = [2 3 3 5 5 5 5 5 5];
    order = [X1 X2 X3 X4 X5 X6 X7 X8 X9];
    dag_k2 = learn_struct_K2(cases, node_sizes, order, 'max_fan_in', 8);
    

    The obtained Directed Acyclic Graph (DAG) captures well the hierarchy of our representation. In fact, X8 and X9 (Nodes 8 and 9) both depend on X2 and X3 (nodes 2 and 3). This is exactly what we should expect since X2 and X3 determine the number of cells of the painting, and if the final number of cells is 4 (or 5) then the color assigned to X8 (and X9) will be the dummy value 5.
    dag_k2

    Step 2: Initializing a Bayesian Network

    We can now create a Bayesian network with the generated DAG:

    bnet_k2 = mk_bnet(dag_k2, node_sizes, 'names', {'X1','X2','X3','X4','X5','X6','X7','X8','X9'}, 'discrete', 1:9);
    

    Step 3: Learning the parameters of the network

    We now compute the maximum likelihood parameters of the Bayesian network with the 648 "good" paintings:

    bnet_k2 = learn_params(bnet_k2, cases);
    

    Step 4: sample paintings from the learned model

    Once the parameters of the model are learned, we can generate as many samples as we want with:

    sample = sample_bnet(bnet_k2);
    

    We sample 10000 paintings with replacement and select the 30 most frequent ones.

    Step 5: generate the htmls

    To generate the html version of the generated paintings, download this executable and run:

    $ mkdir generated_htmls
    java -jar execs/generateHTMLs.jar generated_paintings.csv generated_htmls
    

    We show the 30 paintings below. We did it!

    Top 1
    Top 2
    Top 3
    Top 4
    Top 5
    Top 6
    Top 7
    Top 8
    Top 9
    Top 10
    top1
    top2
    top3
    top4
    top5
    top6
    top7
    top8
    top9
    top10

    Top 11
    Top 12
    Top 13
    Top 14
    Top 15
    Top 16
    Top 17
    Top 18
    Top 19
    Top 20
    top11
    top12
    top13
    top14
    top15
    top16
    top17
    top18
    top19
    top20

    Top 21
    Top 22
    Top 23
    Top 24
    Top 25
    Top 26
    Top 27
    Top 28
    Top 29
    Top 30
    top21
    top22
    top23
    top24
    top25
    top26
    top27
    top28
    top29
    top30

    Authors and Contributors

    This project was developed by Ignacio Arnaldo (@ignacioarnaldo)