Intro
Recently, in an effort to find new & MCU-suitable training-algorithms (for a NN-library I'm developing), I came up with a trick (which I doubt I'm the first one). A HillClimb-algorithm utilizing a PRNG for traning the weights, keeping track of the seed, and therefore eliminating completly the need for memory allocation related to changes in weights [...]
Context
Here's a simplified c++ code of what exactly I'm talking about:
void NeuralNetwork::climb(int8_t direction)
{
// deterministic Psudo-random(-1,2) changes between {-1,0,1}
for (unsigned int l = 0; l < numberOflayers; l++){
for (unsigned int i = 0; i < layers[l]._numberOfOutputs; i++){
for (unsigned int j = 0; j < layers[l]._numberOfInputs; j++){
layers[l].weights[i][j] += (LearningRateOfWeights * random(-1,2) * direction);
}
bool NeuralNetwork::HillClimb(DFLOAT error, DFLOAT tolerance)
{
// Break the training-while-loop if tolerance is achieved
if (error <= tolerance)
return false;
// If the new error > old_error revert changes
if (error > old_error){
// -- revert-seed & climb-back\revert-changes
// ++ to skip the bad seed later on at climb(1)
--nn_seed; // -1
randomSeed(nn_seed++);
climb(-1);
}else{
// if we revert we keep the same old_error, else:
old_error = error;
}
// climb-up\retry & increment the seed for the next time
randomSeed(nn_seed++); // +1
climb(1);
return true;
}
(and here's the full implementation, tested and working)
Questions
- Is this approach practical beyond just for simple xor-problems? Could it really work for fine-tuning or other use cases?
- And are there alternative algorithms that could (or already) benefit from this trick?