Creating Fake Maps with GANs

From the moment I learned of ML models that could create new, artistic images, I wanted to try it. As somewhat of a creative endeavor, I wanted to see if GANs could help me create fake maps… and consequently help inspire perspective about maps and my world.

My expectation was that I would be able to create clear, detailed maps just like Google Maps or Open Street Maps… but with made up street names and novel street patterns. And if I was lucky, there would be some shortcuts! The results (at this point in time)… NOT EVEN F*CKING CLOSE. While I was able to create a working model that produces map-like images… they are a million miles away from my original expectation. But, IMHO this is still a smashing success. It’s really cool to see the iterations and even get to “map-like” images. I would love recommendations on next steps. Here’s the abbrevated journey and lessons learned (so far)…

Iterations of Fake Maps

For starters, I knew I needed a lot of images as training data. I have a personality that allows me to do really mundane shit for long periods of time to meet a goal, so I considered taking hundreds of snapshots of Google Maps to create the dataset. I quickly realized this was futile particularly because all the images should be the same size. Then I found the incredible python package — TileMapBase, that allowed me to create hundreds of uniform, random Open Street Map images (see below, these needed to be 32x32 pixels).

(Augmented) 32x32 pixel tile images from great Minneapolis/St.Paul area.

The model I developed as part of Udacity’s Deep Learning Nanodegree required that the images be 32x32 pixels. So I created ~20 32x32 map images from the greater Minneapolis/St.Paul area and ran the model for 10 epochs (I ran it locally on my laptop since I just wanted to see if it would work without error). It worked and the results, as expected, looked like this…

1st attempt at generating 32x32 pixel map images with DCGAN.

I knew it ran, so that was good. I immediately create ~100 map tiles and ran the model for 100 epochs. Better, but still crappy.

2nd, slightly better, attempt at generating 32x32 pixel map images with DCGAN.

Several issues…

  • 100 images likely isn’t a sufficiently large dataset.
  • What good is a 32x32 pixel map?!?! I instantly knew I needed a model that could produce larger images.
  • Training was slow… I needed a GPU.

Next, I created ~850 images size 256x256 pixels (samples below). Not the ideal map size, but way better than 32x32. Additionally, I found and started testing this code that uses a DCGAN to create 256x256 images. Biggest change for me here was that it used keras and tensorflow… and I had gotten used to working with pytorch. Didn’t seem to slow me down much since the repo was really clean and beatifully documented! Finally, I spun up a Google Cloud compute instance to harness the power of GPUs.

256x256 pixel tile images from great Minneapolis/St.Paul area.

Instead of running epochs, it looked like in keras we were exectuing steps. Since the DCGAN256 authors let their algorithm run for 500,000 steps when generating images of women’s blouses and shoes… I figured I would start with 20% of that and see if it was worth doing more. Toward the end of training, here’s what some of the generated images looked like:

256x256 pixel tile images generated from the DCGAN256.

Pretty neat. We can also look at how the model improved over the course of training. It was especially exciting to see this improvement from step 0 to step 25! Note that the sample generated images below are a concoction of 48 individual images (scaled down a little bit).

Sample generated image after 1,000 steps:

Sample generated image after 25,000 steps:

Sample generated image after 50,000 steps:

Sample generated image after 75,000 steps:

Sample generated image after 99,000 steps:

Hell yes. It’s not exactly what I pictured when I first imagined this. However, the algorithm did “learn” about parks and lakes, the highway system (we don’t see highways running through lakes :), and the urban/suburban grid pattern found across the majority of the Minneapolis/St.Paul metro.

As for next steps, I didn’t see vast improvement between 75k and 99k. I could run for longer, but I’m not convinced I know the value of that yet. It would be good to mention that it took me roughly 5 hours to run the full 99k steps and cost me in the $4-$5 range.

I’m starting to see more problems as image problems which is a fundamentally different way of thinking about them. Shane Parrish always reminds us that the map is not the territory. This exercise takes that a step further and reminds me that a map is simply a way to think about relationships rather than a thing that determines reality.

Here is my GitHub repo that contains both the tile map generation and the DCGAN. I would absolutely love to hear thoughts and feedback either via comments or hit me up on LinkedIn.