Neural Network Library (Obsolete)

I’ve only taken classes on Machine Learning and Deep Learning but they were mainly conceptual, so its interesting how you applied it. The problem is a few inputs aren’t enough to train an optimal AI. I remember having to run hundreds of computer simulations when it comes to training AI.

2 Likes

They are not, but it seems like this method is a real thing. By using 2 AIs, you can achieve much more efficient training for circumstances where writing a cost function is hard or impossible.

Edit: Realised windows had an inbuilt recorder.
Edit2: Here is the file for people who are interested:
Flappy bird neural network.rbxl (41.5 KB)

Im not good at creating UI based games but I have attempted to to do it anyways. So far my other attempts with forward feed propagation has been in vain. There are two inputs fed into the “forwardNet function” from the module.

  1. Distance to the next pipe
    image
  2. Height from the bird to the midpoint of pipe pairs
    image

as Kironte mentioned I had to scale these values. I decided to use LeakyReLU which accepts values between 0 and 1 (I could also use tanh which takes values from the interval [-1,1]).
I would achieve scaled values by dividing my distances by the screensize.

The output would give me a value between 0 and 1. If the value was >0.5 then i would flap.
I got some inspiration from this video about flappy birds “Machine Learning for Flappy Bird using Neural Network & Genetic Algorithm - YouTube”.

I do have some questions though. What would multiple outputs mean? In this case the output >0.5 tells the bird to jump. If I had 2 outputs would the second one be defined by what I choose to score in my fitness function. As of right now I only let it jump with a set power but would the values in the output be holding information of how much power i would need to use?

5 Likes

Multiple outputs is just giving the network more options to choose. If you add another output but don’t use it, the network will learn that the output doesn’t matter and will ignore it. If you add a function to the output that significantly affects gameplay, it will use it in the most effective manner. If it turns out that this new output is actually superficial, the network may realize that and start ignoring it.
If you want to add extra outputs so the network can give more information on what to do, go for it. Just be sure to add more nodes into the layers if you have too many outputs.

By the way, is that an example using this library?

2 Likes

Why such a small resolution???

1 Like

Because 30x30 is already 900 inputs. Not only does this increase the size of the network a LOT, it becomes nearly impossible to train the network if you have too many inputs.

Wait… You need 1 input per pixel?

1 Like

Yup. This is why artificial NNs are generally not used for image recognition. You use convolutional networks, which use completely different methods and work very differently.

1 Like

Why not have a huge number as an input that would look a little something like so: 1100101011100011010, and make it so each digit describes weather or not a pixel is lit up?

1 Like

Yes i used the module you provided but somehow felt unnatural by how fast it was learning (Already learning by second generation jumping through multiple pipes). I checked if it was falsely learning, but im just feeding it inputs and the jumping is purely based on the work inside the module.

1 Like

2 reasons.

  1. NNs cannot work with such absurdly large numbers effectively
  2. To us, the difference between 10001001 and 10001000 is that one digit flipped, right? Well, all the NN can tell is that the second number is 99.99990009999% the size of the first one. That’s it. And there is a 100% chance that this ridiculously precise number will get rounded somewhere in the process. This is why you have to chop each digit up into a 0-1 input, which is basically making every pixel an input.

This is common for very simple AIs. If the goal is is simple and there are not many inputs/outputs, its common for the AI to figure it out by the 3rd or 5th generation as there isn’t much to fine tune.

1 Like

Also, will this work if I access the neural network in a localscript?

1 Like

Absolutely. As it is a module, it will work server-side or client-side.

1 Like

For people who are interested here is the studio file for the flappy bird. Just press run.
Flappy bird neural network.rbxl

2 Likes

Ok, so I think I finished the number recognition system, but I would like to know if I am doing everything correctly. So here is the place: Number Neural Network.rbxl (41.7 KB)

Here is the main code:

local parent = script.Parent
local players = game:GetService("Players")
local player = players.LocalPlayer
local mouse = player:GetMouse()
local mouseDown = nil -- The very first line of code that was ever written and this is what I feel when I think about the first line of code that was ever written: https://www.youtube.com/watch?v=6eb_zYknomY
local camera = workspace:WaitForChild("Camera")
local viewPortSize = camera.ViewportSize
local pix3lFrame = parent:WaitForChild("DrawFrame")
local pix3ls = {}
local clearButton = parent:WaitForChild("Clear")
local numberLabels = {parent:WaitForChild("A"), parent:WaitForChild("B"), parent:WaitForChild("C"), parent:WaitForChild("D"), parent:WaitForChild("E"), parent:WaitForChild("F"), parent:WaitForChild("G"), parent:WaitForChild("H"), parent:WaitForChild("I")}
local numberLablesPercents = {parent:WaitForChild("0"), parent:WaitForChild("1"), parent:WaitForChild("2"), parent:WaitForChild("3"), parent:WaitForChild("4"), parent:WaitForChild("5"), parent:WaitForChild("6"), parent:WaitForChild("7"), parent:WaitForChild("8"), parent:WaitForChild("9")}
local trainingNumber = parent:WaitForChild("TrainingNumber")
local clearButton = parent:WaitForChild("Clear")
local trainButton = parent:WaitForChild("Train")
local calculate = parent:WaitForChild("Calculate")
local replicatedStorage = game:GetService("ReplicatedStorage")
local modulesFolder = replicatedStorage:WaitForChild("Modules")
local neuralNetworkModule = require(modulesFolder:WaitForChild("KNNLibrary"))
local neuralNetwork = neuralNetworkModule.createNet(616, 2, 16, 10, "LeakyReLU")

for i, v in pairs(pix3lFrame:GetChildren()) do
	if v:IsA("Frame") then
		if v.Name == "Pixel" then
			table.insert(pix3ls, v)
		end
	end
end

function draw()
	while mouseDown do
		game:GetService("RunService").Stepped:Wait()
		local mouseX = mouse.X
		local mouseY = mouse.Y
			
		for i, v in ipairs(pix3ls) do
			--print(1) --if I print here, the program grinds to a halt, because printing (or most things, really) 20000 times per second is very intensive
			if (mouseX > v.AbsolutePosition.X and --mouse is beyond the left wall
				mouseX < v.AbsolutePosition.X + v.AbsoluteSize.X and --but not past the right wall
				mouseY > v.AbsolutePosition.Y and --and below the top wall
				mouseY < v.AbsolutePosition.Y + v.AbsoluteSize.Y) then --aboove the bottom wall
				v.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
			end 
		end
	end
end

mouse.Button1Down:Connect(function()
	mouseDown = true
	draw()	
end)

calculate.MouseButton1Click:Connect(function()
	local litPixels = {}
	for i, v in ipairs(pix3ls) do
		if v.BackgroundColor3 == Color3.fromRGB(255, 255, 255) then
			table.insert(litPixels, 1)
		else
			table.insert(litPixels, 0)
		end
	end
	local answer = neuralNetworkModule.forwardNet(neuralNetwork, litPixels)
	
	for i, v in pairs(answer) do
		numberLablesPercents[i].Text = math.floor(v + 0.5).." %"
	end
end)

trainButton.MouseButton1Click:Connect(function()
	local litPixels = {}
	for i, v in ipairs(pix3ls) do
		if v.BackgroundColor3 == Color3.fromRGB(255, 255, 255) then
			table.insert(litPixels, 1)
		else
			table.insert(litPixels, 0)
		end
	end
	local correctAnswer = {}
	for i, v in ipairs(numberLablesPercents) do
		if v.Name == trainingNumber.Text then
			table.insert(correctAnswer, 100)
		else
			table.insert(correctAnswer, 0)
		end
	end
	--[[
	for i, v in pairs(correctAnswer) do
		print((i - 1 ).. " "..v)
	end]]--
	neuralNetworkModule.backwardNet(neuralNetwork, 0.1, litPixels, correctAnswer)
end)

clearButton.MouseButton1Click:Connect(function()
	for i, v in pairs(pix3ls) do
		v.BackgroundColor3 = Color3.fromRGB(0, 0, 0)	
	end
end)

mouse.Button1Up:Connect(function()
	mouseDown = false
end)

My brain is pretty much burned up rn, and I don’t know what I am doing anymore. And thats why I want to make sure I am doing everything correctly.

2 Likes

Looks good other than for the training. I don’t think anyone is going to be drawing odd digits thousands of times to train it.

1 Like

(If I am not clearly out of my mind) I know that there are images of numbers on MNIST, but how would I put them into my draw pad? (This question probably does not belong here tbh)

1 Like

That’s the reason why CNNs aren’t useful on Roblox. There isn’t a way (from what I know at least). Roblox doesn’t offer a way of analyzing images pixel by pixel like that.

1 Like

Is it possible to make a script which trains the neural network what a one handwritten zero looks like… a thousand times (or use a(n) auto clicker :stuck_out_tongue: ), then see if it will guess that specific zero more properly?

1 Like