Actually already wrote this but when I tried attching a file via drag&drop(over the ad file button instead of the text entry) so my browser made the tab a download tab for my local file and everything got deleted for my convenience I suppose.
Anyways I got this neural network algorithm to work in lua due to me being to dumb to compile a mainstream-nn-framework for love. No actually it took me months to understand it by myself and youtube while I wanted to do my own. And after months of lazy(when I had time and interest) youtube research and 3 attempts at this I finally got it working and reviewing my own code also grew my understanding of this.
Here are some videos that helped me:
https://www.youtube.com/watch?v=q555kfIFUCM --Si
https://www.youtube.com/watch?v=GlcnxUlrtek
https://www.youtube.com/watch?v=Ilg3gGewQ5U
This actually made me understand it but it's German: https://youtu.be/EAtQCut6Qno?t=4m49s
The main problem I had was the chainrule. Most videos presented me the chainrule as concept thats built into the network. And while I thought I got to implement the chainrule it was already included in the formula.
And that the backpropagation is basically the same as the forwardpropagation but reusing the values of the forward pass in the derivative function(here we got the chainrule).
After I built it I broke it again by applying random jitters to all kinds of updates to see what kind of effect it has and just playing around with it.
And here's the .love for you to play around with: https://github.com/SirRanjid/lua-nn
PRESS SPACE to pause/unpause.
So the dots on the bottom are vertically one batch of errorvalues for different inputs. They ideally reach the bottom of the screen. Or do nothing when a local minimum is reached. (they are randomly initiated so sometimes they get it, sometimes not for this XOR-datasetlet)
Functionality:
Code: Select all
local nn = require("nn")
local x = 3 --amount of layers
local y = 5 --default amount of neurons per layer
local y_inputs = 2 --nodes of input layer (the original 5 of y become 2 for the first layer, *not* a new layer with 2 as input)
local y_outputs = 1 --nodes of output layer
local activation_func = nn.func.sig
local act_f_drv = nn.func.asig
local lear_rate = 0.02
new_net = nn(x,y,y_inputs,y_outputs,activation_func, act_f_drv, lear_rate) --generate a new_net
new_net:addlayer(y) --becomes new output layer
new_net:build() --make weights for all connections
local train_pairs = {
{{0,0},{0}},
{{1,0},{1}},
{{0,1},{1}},
{{1,1},{0}},
--{{<inputs>},{<expected_outputs>}},
}
local batches = 10
local batchsize = 10
for I = 1, batches
for J = 1, batchsize do
new_net:smart_train(train_pairs,0.6) --0.6 60% chance of picking a random pair, 40% picking the one that gives least error
--smart_train is experimental and picks a random pair from train_pairs and keeps track of the error
end
new_net:applybatch() --apply weight updates
end
And here some motivational nerdgasm videoson that topic: