Skip to main content

Command Palette

Search for a command to run...

ML Experiment Log - Differentiable graph environment

Published
2 min read

I'm interested in generative design, especially geometric deep learning.

For a simple environment I'd like to have an environment where given some sizes of boxes, the network will pack the boxes as compactly as possible by outputting a set of positions for those boxes. This output should also prefer to be square overall.

For scoring there will be 2 components to the score:

  • a penalty for boxes that are taking up the same space
  • a smaller penalty for the amount of space the outputs as a whole take up

Several qualities we want in our score function

  • The different loss components should scale similarly for different numbers of boxes.
  • The loss for conflict should be roughly the right amount to exactly move outside the box if lr=1.
    • The reasoning for this is sgd directly on our loss function would hopefully have a less
  • Due to the previous 2 statements, our loss functions should both scale roughly with average height/width of all boxes.

On another note, our score function should be differentiable. I'm hoping this will help reduce the amount of compute needed to train a network on the environment, but that'll be for future experiments.

Conflict

Conflict penalty is the length of the smallest dimension's overlap.

Pseudocode

for each rect i
  for each rect j
    dx = abs(i.pos_x - j.pos_x)
    x_conf = maximum(0, (i.w + j.w)/2 - dx) # Only conflicts if inner term was > 0

    dy = abs(i.pos_y - j.pos_y)
    y_conf = maximum(0, (i.y + j.y)/2 - dy) # Only conflicts if inner term was > 0

Footprint area

For footprint area, this is calculated by taxing the max and min of each dimension (x/y). This is basically calculating the smallest rectangle that fits around all our boxes.

Pseudo code for calculating foot print area.

max_x, min_x, max_y, min_y = get_min_max(box_sizes, box_positions)

box_areas = (max_x - min_x) * (max_y - min_y) 
box_area_sum = reduce_sum(box_areas)

batch_max_x, batch_min_x = reduce_max(max_x), reduce_min(min_x)
batch_max_y, batch_min_y = reduce_max(max_y), reduce_min(min_y)
total_footprint = (batch_max_x - batch_min_x) * (batch_max_y - batch_min_y)

# A perfect score would result in an exactly square footprint, with total footprint area
# equal to the sum of areas of individual boxes.  We multiply by rectangle count and 
# average height/width to keep this scoring roughly the same as the other score functions.
footprint_penalty = (1 - sqrt(box_area_sum) / sqrt(total_footprint)) * rect_count * sqrt(box_area_sum)

Important notes

The way it's implemented, our minimum will actually be with a small amount of box conflict. I think this is fine for the moment, but can be fixed.

More from this blog

Jimmie's Mostly Tech Blog

16 posts

Developer with around 10 years experience. Full stack developer, with experience in dev-ops, and interest in machine learning.

Available for work.