Week 10: The Artificial Pokémon (Trainer)
June 17, 2024
We’re finally here! I’ve spent so long theorizing how to make this project work, but now it’s so close. All the research, all the trying and failing, all the slowly building experience has led me to this week. So let’s get into it!
Layer Selecting
The first step in the neural network construction is figuring out how I want to actually structure it. I have to use a series of Layers, basically matrix functions that transform the data successively until outputting desired results. A large amount of these layers are learnable, meaning that the way that they transform the data changes depending on how good of a job they did. This process of learning is done through gradient descent. This uses calculus to find the fastest way towards a minimum amount of “loss”. Loss is a numeric measure of how far-off from a desired result the network is. The whole idea of training a network is to minimize this loss.
LinearLayer[]
Linear layers are learnable layers that perform simple mx+b
operations on the data (just in matrix form instead of single-number form). This way, they can both change the numbers of the data, and change the matrix size of the data (reshaping).
FunctionLayer[]
Function layers map apply a function over its inputs. For example, a FunctionLayer[Plus]
with 3 different input ports of maybe {1}
, {3}
, and {5.3}
would output {9.3}
as a result. Function layers can also be written in pure function form, basically a way of constructing custom mathematical functions without naming them. These typically require you to specify the amount of inputs a function will intake — after all, if you were plugging in 4
and 3
into the function 2x+1
, it’s unclear which one to use. I used FunctionLayer[]
specifically to join data on a higher dimension instead of simply catenating it (think like stacking sheets of paper to give the stack height instead of taping them together on the sides to make them wider).
ConvolutionLayer[]
Convolution layers are a more recent breakthrough in machine learning, but they’re incredibly resourceful. Instead of transforming data the same way every time, like a LinearLayer[]
, convolution layers learn how to change it in a way where every aspect of the input affects the input as a whole. Everything is interconnected, and allows for much more complexity in the program’s understanding of patterns on higher levels. I used convolution layers for the bulk of the data processing. I felt they captured the intricacy of the factors a player takes in when making decisions.
RandomArrayLayer[]
Random arrays are simply just matrices of random numbers that I hooked up to some ports in the network to give it a little kick. Adding randomness has been proven to greatly improve network productivity. On top of that idea of stimulating the program, I also wanted to use this to emulate how Pokémon battles have randomness intrinsic to them. Randomized damage multipliers are threaded over every attack, sometimes moves can miss, sometimes a move will be a critical hit, sometimes secondary effects will proc, etc.
SoftmaxLayer[]
Softmax layers are the final piece of a neural network, as they simply turn the resulting matrices of numbers into probability values for a decoder to then translate out into a class. It’s just a simple operation of totaling the matrix and dividing each element by the sum.
NetGraph
In order to link all these layers together, I need to manually hook up the ports together during NetGraph construction. Every layer has to have a specified port, be it input or output, or else the program won’t know how to arrange it. Not only do I have to link all the layers together in a cohesive path, but I also have to link the association inputs/outputs into their respective encoders/decoders and then link those into the starting/ending layers. After doing all that, the NetGraph is done!
Next week, I’ll finally mesh together the network and the training data to complete my project. I’m so excited!
-Alex R.
Leave a Reply
You must be logged in to post a comment.