[P] A little gadget that plays rock-paper-scissors slightly better than random using a small quantized RNN running on an 8-bit microcontroller
I was looking for some kind of project that let me combine my love for building small electronics/3d-printing projects and machine learning, and this is what I came up with.
The machine learning side of this isn’t too interesting, just a small 3 layer vanilla RNN (all layers with 10-d state, trained in tensorflow/keras) that takes as input the moves of the two players and outputs a prediction for the opponents next move. The data comes from human games played on roshambo.me via this blog article. I added some simulated data of periodic sequences, because that seems like the sort of thing people might try out when playing against an “AI”.
Without the simulated data (which is easy to predict) the model gets something like 38% accuracy on the test set (compared to 33% playing randomly). One nice thing about rock-paper-scissors is that you can’t do much better than random, so there isn’t much pressure 😉
I had some problems getting training with larger batches to work (either with just padding or padding and masking the gradients) so I just trained it with batch_size=1, which wasn’t too bad for such a small network.
The probably more interesting part of this project is running that network on a small microcontroller. I quantized the network weights (to 8-bit integers) to save some space (it only has 2kiB RAM and 16kiB flash, although the network I ended up using would actually fit without that). The calculations are done using software floats, as performance isn’t really an issue. The C-code running on the microcontroller is all custom, not that it’s particularly complicated.
The finished device is about the size of a coin (but thicker). It uses a custom pcb (ordered from dirtyPCBs), is powered by a coin cell battery, and has a nice 3d-printed case. The form-factor is pretty close to my electronic dice so that wasn’t too much work.