May 21, 2019     8min read

StyleGAN Pokemon Card Generator


StyleGANs have sort of become a little hobby for me as of late. Specifically I find myself drawn into the idea of re-purposing existing work into a packaged solution for people to enjoy. So when I found an implementation of StyleGAN trained on images of Pokemon, I got excited at the possibilities of generating entirely random cards.

Overview

This post is going to cover all the bits of pieces required to generate your very own Pokemon cards using a mixture of StyleGANs and RNNs.

Images [StyleGAN] - Text [RNN]
Images [StyleGAN] - Text [RNN]

There are five parts to creating these cards:

  • StyleGAN Generate Image of a Pokemon
  • RNN Generate Pokemon

    • Names
    • Moves
    • Move Descriptions
  • Generate a card image using all this information

In this post we'll go over how to achieve each of these steps and create some of your own cards.

Preparation

In order to get started you will need a couple dependencies on your local computer. One of these is the repository that contains all the code we'll use. You can pull this down using the following command, or simply download a copy from t04glovern/stylegan-pokemon.

git clone https://github.com/t04glovern/stylegan-pokemon.git

Dependencies

I've encapsulated all the dependencies you'll need for this project within an Anaconda environment.

conda env create -f environment.yml
conda activate stylegan-pokemon
cd stylegan

Download Data & Models

Downloading the data (in this case, images of pokemon) is a crucial step if you are looking to build a model from scratch using some image data. In this tutorial I'll be making use of this data and an existing pre-trained model by ahsenk to demonstrate how you can build on top of his work using data. Run the following commands from within the repository you just cloned to download all the files from S3

aws s3 cp s3://devopstar/resources/stylegan-pokemon/network-snapshot-007961.pkl network-snapshot-007961.pkl
aws s3 sync s3://devopstar/resources/stylegan-pokemon/kaggle-one-shot-pokemon kaggle-one-shot-pokemon

If you don't have the AWS CLI installed you can get the kaggle-one-shot-pokemon dataset from the kaggle page and download the network snapshot from ahsenk's original post available at the following

# Note: updated link to s3 bucket due to dropbox link going down
wget --no-check-certificate --no-proxy 'https://devopstar.s3.amazonaws.com/resources/stylegan-pokemon/network-snapshot-007961.pkl'

There is also a bonus model provided by MichaelFriese10 that you can preemptively download also if you'd like to generate some Pokemon with a more pixel vibe.

# AWS CLI
aws s3 cp s3://devopstar/resources/stylegan-pokemon/MichaelFriese10_pokemon.pkl MichaelFriese10_pokemon.pkl

# Other link
wget https://s3.amazonaws.com/devopstar/resources/stylegan-pokemon/MichaelFriese10_pokemon.pkl

StyleGAN

There are three avenues you can go down here.

  • Train your own model
  • Run the pre-trained model
  • Run Michael's pre-trained model

Train Model

Training a model requires some data to be prepared. to do this simple run the following from within the stylegan directory

mkdir pokemon
python prepare.py
python dataset_tool.py create_from_images datasets/smalls/ ./pokemon/

The process will resize all the images within the pokemon-a dataset and prepare them for training.

Here's where you have to make your first decision, do you want to train from scratch, or just build on-top of the existing network?

Train from Scratch

To train from scratch you will need to edit

Run Training

Execute the process of training by running the following from the stylegan directory

python train.py

The process is going to take a while if you do decide to train from scratch. Which ever method you used will output entries in the results directory of the project. Within each of these resulting folders will be a network-final.pkl file that is the model that can be invoked against in the coming steps.

Invoking Model

As with training there are three possible ways you can approach the invocation of the model. If you trained your own model, you will need to point the --model_file parameter in the following command to the location of the model you'd like to build a Pokemon with

python invoke.py \
    --model_file './results/00000-sgan-custom-1gpu/network-final.pkl'

By default the output image will be placed into ../img/pokemon.png in the root of the repository however this can be overridden using the --output_file param. The example below will invoke the network using the originally downloaded pre-trained model and puts it into the stylegan folder under the name test.png

python invoke.py \
    --model_file './network-snapshot-007961.pkl' \
    --output_file './test.png'

The final invocation you can perform is against MichaelFriese10's pre-trained model that he based off Pokemon Pixel art instead.

python invoke.py \
    --model_file './MichaelFriese10_pokemon.pkl'

Below is an example of the three outputs

Pokemon StyleGAN test
Pokemon StyleGAN test

Excellent we know we're able to generate Pokemon images so we can move onto text generation for the Name, Move and Descriptions.

RNN Text Generator

For text generation I made use of a Multi-layer Recurrent Neural Networks (LSTM, RNN) for character-level language models in Python using Tensorflow. This implementation is heavily based on the work done in karpathy/char-rnn. To get started move into the rnn folder.

cd rnn

I've already compiled a dataset for you in three places

RNN Training

Running training over the tree different inputs is the next step. This can be accomplished by running the following three commands. They will output a model for each to a subsequent folder under save.

# Pokemon
python train.py \
    --data_dir=./data/pokemon \
    --save_dir=./save/pokemon \
    --seq_length=12

# Moves
python train.py \
    --data_dir=./data/moves \
    --save_dir=./save/moves \
    --rnn_size=300 \
    --seq_length=12

# Description
python train.py \
    --data_dir=./data/desc \
    --save_dir=./save/desc \
    --seq_length=25

Feel free to play around with the values in seq_length, though note that the ones above I found to work the best.

RNN Invoking

To generate image from the model, run the following commands. Note that the output should place a text file in the samples directory of the project

# Pokemon
python sample.py \
    --save_dir=./save/pokemon \
    --output_dir=../samples/pokemon.txt

# Moves
python sample.py \
    --save_dir=./save/moves \
    --output_dir=../samples/moves.txt

# Description
python sample.py \
    --save_dir=./save/desc \
    --output_dir=../samples/desc.txt \
    -n=1500

Card Creation

The final piece of the puzzle is the actual card creation. This process is handled by a super complex ImageMagick cropping script along with some wonderful card templates by user levelinfinitum. From the root directory of the project one one of the two methods to create a card.

# Define all fields adhoc
./cropper.sh \
    "Pokemon Name" \
    "Pokemon Attack 1" \
    "Pokemon Attack Description 1" \
    "Pokemon Attack 2" \
    "Pokemon Attack Description 2" \
    "img/pokemon1.png"

# Random
./cropper-shuffle.sh \
    "samples/pokemon.txt" \
    "samples/moves.txt" \
    "samples/desc.txt" \
    "img/pokemon1.png"

Below are some example cards I generated with the randomised shuffle

Pokemon StyleGAN final test
Pokemon StyleGAN final test

Attribution

devopstar

DevOpStar by Nathan Glover | 2020