Hello,
So, I am building an AI that you know can do stuff. Like chatgpt but smaller bla bla bla.
Anyways, I don’t know what went wrong but I didn’t change the code but I did get different results. With huge differences.
code:
-- Script to train a neural network based on provided training data
local memory = require(game.Workspace.Memory)
local M = memory.Memory
local HttpService = game:GetService("HttpService")
local DataStoreService = game:GetService("DataStoreService")
local networkDataStore = DataStoreService:GetDataStore("NeuralNetworkStore")
-- Function to save the neural network state
local function saveNetwork(category, NG_N, neuronCounts, layers)
local data = {
neuronCounts = neuronCounts,
layers = {}
}
for l = 1, #neuronCounts do
data.layers["Layer_" .. l] = {}
for n = 1, neuronCounts[l] do
data.layers["Layer_" .. l]["Neuron_" .. n] = {
weights = layers["Layer_" .. l]["Neuron_" .. n].weights,
biases = layers["Layer_" .. l]["Neuron_" .. n].biases,
activationFunction = layers["Layer_" .. l]["Neuron_" .. n].activationFunction
}
end
end
local success, errorMessage = pcall(function()
networkDataStore:SetAsync(category .. "_" .. NG_N, HttpService:JSONEncode(data))
end)
if success then
print("Network saved successfully.")
else
warn("Failed to save network: " .. errorMessage)
end
end
-- Function to load the neural network state
local function loadNetwork(category, NG_N)
local data
local success, errorMessage = pcall(function()
data = networkDataStore:GetAsync(category .. "_" .. NG_N)
end)
if success and data then
data = HttpService:JSONDecode(data)
local neuronCounts = data.neuronCounts
local layers = {}
for l = 1, #neuronCounts do
layers["Layer_" .. l] = {}
for n = 1, neuronCounts[l] do
layers["Layer_" .. l]["Neuron_" .. n] = {
weights = data.layers["Layer_" .. l]["Neuron_" .. n].weights,
biases = data.layers["Layer_" .. l]["Neuron_" .. n].biases,
activationFunction = data.layers["Layer_" .. l]["Neuron_" .. n].activationFunction
}
end
end
print("Network loaded successfully.")
return neuronCounts, layers
else
warn("Failed to load network: " .. (errorMessage or "No data found"))
return nil, nil
end
end
-- Function to initialize the neural network with He initialization
local function initializeNetwork(neuronCounts)
local weights = {}
local biases = {}
local activationFunctions = {}
for l = 1, #neuronCounts do
weights[l] = {}
biases[l] = {}
activationFunctions[l] = "leaky_relu" -- Using Leaky ReLU for all layers
local numInputs = neuronCounts[l - 1] or neuronCounts[1]
for n = 1, neuronCounts[l] do
weights[l][n] = {}
for i = 1, numInputs do
weights[l][n][i] = math.random() * 2 - 1 -- Improved He initialization
end
biases[l][n] = 0.01 -- Small positive bias
end
end
return weights, biases, activationFunctions
end
-- Function to apply the activation function
local function activate(z, activationFunction)
if activationFunction == "leaky_relu" then
return z > 0 and z or 0.01 * z
else
return math.max(0, z) -- Default to ReLU
end
end
-- Function to perform a forward pass
local function forwardPass(inputs, neuronCounts, layers)
local outputs = {}
for l = 1, #neuronCounts do
outputs[l] = {}
for n = 1, neuronCounts[l] do
local neuron = layers["Layer_" .. l]["Neuron_" .. n]
local z = neuron.biases
for i = 1, #inputs do
z = z + neuron.weights[i] * inputs[i]
end
outputs[l][n] = activate(z, neuron.activationFunction) -- Use activation function
end
inputs = outputs[l]
end
return outputs
end
-- Function to compute the loss (mean squared error)
local function computeLoss(outputs, expectedOutput)
local loss = 0
for i = 1, #outputs do
loss = loss + (outputs[i] - expectedOutput[i])^2
end
return loss / #outputs
end
-- Function to clip gradients to avoid exploding gradients
local function clipGradient(value, threshold)
if value > threshold then
return threshold
elseif value < -threshold then
return -threshold
else
return value
end
end
-- Function to perform Adam optimizer update
local function adamUpdate(params, grads, learningRate, beta1, beta2, epsilon, m, v, t)
for i = 1, #params do
m[i] = beta1 * m[i] + (1 - beta1) * grads[i]
v[i] = beta2 * v[i] + (1 - beta2) * grads[i]^2
local m_hat = m[i] / (1 - beta1^t)
local v_hat = v[i] / (1 - beta2^t)
params[i] = params[i] - learningRate * m_hat / (math.sqrt(v_hat) + epsilon)
end
end
-- Function to adjust the learning rate dynamically
local function adjustLearningRate(learningRate, loss)
if loss > 1 then
learningRate = learningRate * 0.7
elseif loss < 0.01 then
learningRate = learningRate * 1.03
end
return learningRate
end
-- Function to train the neural network
local function trainNetwork(category, NG_N, neuronCounts, trainingData, epochs, initialLearningRate, minNeurons, maxNeurons)
local neuronGroup = M[category][NG_N]
local layers = neuronGroup.layers
local gradientThreshold = 1 -- Adjusted gradient clipping threshold
-- Adam optimizer parameters
local beta1, beta2, epsilon = 0.9, 0.999, 1e-8
local m, v = {}, {}
for l = 1, #neuronCounts do
m[l], v[l] = {}, {}
for n = 1, neuronCounts[l] do
m[l][n], v[l][n] = {}, {}
for i = 1, (neuronCounts[l - 1] or neuronCounts[1]) + 1 do -- +1 for bias term
m[l][n][i], v[l][n][i] = 0, 0
end
end
end
local learningRate = initialLearningRate
for epoch = 1, epochs do
print("Epoch:", epoch)
local totalLoss = 0
local allCorrect = true -- Flag to check if all predictions are correct
for _, data in ipairs(trainingData) do
local inputs = data.input
local expectedOutput = data.output
-- Forward pass: Calculate the network's output
local outputs = forwardPass(inputs, neuronCounts, layers)
local prediction = outputs[#outputs][1]
-- Compute loss
local loss = computeLoss(outputs[#outputs], expectedOutput)
totalLoss = totalLoss + loss
-- Print network's prediction for current data
print(string.format("Inputs: %s | Expected Output: %.2f | Predicted Output: %.2f | Loss: %.6f",
table.concat(inputs, ", "), expectedOutput[1], prediction, loss))
if loss ~= 0 then
allCorrect = false
end
-- If the loss is not zero, perform backpropagation and update
if loss ~= 0 then
-- Backward pass: Calculate the error and update weights and biases
local errors = {}
for l = #neuronCounts, 1, -1 do
errors[l] = {}
for n = 1, neuronCounts[l] do
if l == #neuronCounts then
errors[l][n] = outputs[l][n] - expectedOutput[n]
else
local sum = 0
for pn = 1, neuronCounts[l + 1] do
sum = sum + errors[l + 1][pn] * layers["Layer_" .. (l + 1)]["Neuron_" .. pn].weights[n]
end
errors[l][n] = sum * (outputs[l][n] > 0 and 1 or 0.01) -- Derivative of Leaky ReLU
end
-- Gradient clipping
errors[l][n] = clipGradient(errors[l][n], gradientThreshold)
-- Update weights and biases with Adam optimizer
local input = (l == 1) and data.input or outputs[l - 1]
local numInputs = neuronCounts[l - 1] or neuronCounts[1]
local grads = {}
for i = 1, numInputs do
grads[i] = errors[l][n] * input[i]
end
grads[numInputs + 1] = errors[l][n] -- For bias
-- Perform Adam update
local params = {}
for i = 1, numInputs do
params[i] = layers["Layer_" .. l]["Neuron_" .. n].weights[i]
end
params[numInputs + 1] = layers["Layer_" .. l]["Neuron_" .. n].biases
adamUpdate(params, grads, learningRate, beta1, beta2, epsilon, m[l][n], v[l][n], epoch)
-- Assign updated params back
for i = 1, numInputs do
layers["Layer_" .. l]["Neuron_" .. n].weights[i] = params[i]
end
layers["Layer_" .. l]["Neuron_" .. n].biases = params[numInputs + 1]
-- Debugging prints for weights and biases
if l == #neuronCounts and epoch % 10 == 0 then -- Print every 10 epochs
print(string.format("Layer %d Neuron %d Weights: %s", l, n, HttpService:JSONEncode(layers["Layer_" .. l]["Neuron_" .. n].weights)))
print(string.format("Layer %d Neuron %d Biases: %.4f", l, n, layers["Layer_" .. l]["Neuron_" .. n].biases))
end
end
end
end
end
-- Print the average loss after each epoch
print(string.format("Average Loss after Epoch %d: %.6f", epoch, totalLoss / #trainingData))
-- Adjust the learning rate based on loss
learningRate = adjustLearningRate(learningRate, totalLoss / #trainingData)
-- If all predictions are correct, exit the training loop
if allCorrect then
print("All predictions are correct. Exiting training.")
break
end
wait(0.05)
end
-- Save the trained neural network
saveNetwork(category, NG_N, neuronCounts, layers)
-- Print final results
print("Final Results:")
for _, data in ipairs(trainingData) do
local inputs = data.input
local expectedOutput = data.output
local outputs = forwardPass(inputs, neuronCounts, layers)
local prediction = outputs[#outputs][1]
print(string.format("Inputs: %s | Expected Output: %.2f | Predicted Output: %.2f",
table.concat(inputs, ", "), expectedOutput[1], prediction))
end
-- Print the network's weights, biases, and activation functions
for l = 1, #neuronCounts do
for n = 1, neuronCounts[l] do
print(string.format("Layer %d Neuron %d Weights: %s", l, n, HttpService:JSONEncode(layers["Layer_" .. l]["Neuron_" .. n].weights)))
print(string.format("Layer %d Neuron %d Biases: %.4f", l, n, layers["Layer_" .. l]["Neuron_" .. n].biases))
print(string.format("Layer %d Neuron %d Activation Function: %s", l, n, layers["Layer_" .. l]["Neuron_" .. n].activationFunction))
end
end
end
-- Example usage
local category = "ExampleCategory"
local NG_N = "ExampleNeuronGroup"
local neuronCounts = {2, 8, 8, 8, 1} -- Example structure: 2 input neurons, 3 hidden layers with 8 neurons each, 1 output neuron
local trainingData = {
{input = {0.1, 0.2}, output = {0.3}},
{input = {0.4, 0.5}, output = {0.9}},
{input = {0.7, 0.3}, output = {1.0}},
{input = {0.6, 0.4}, output = {1.0}},
{input = {0.8, 0.2}, output = {1.0}},
{input = {89, 18}, output = {107}},
{input = {6, 7}, output = {13}},
{input = {426, 180}, output = {606}},
{input = {12, 18}, output = {30}},
{input = {-17, 18}, output = {1}},
{input = {-893, 18}, output = {-875}},
{input = {2, 4}, output = {6}},
{input = {11, 14}, output = {25}},
{input = {7, 15}, output = {22}},
{input = {50, 15}, output = {65}},
{input = {129, 2}, output = {131}},
{input = {-9, 15}, output = {6}},
{input = {-2, -89}, output = {-91}},
{input = {-112, 15}, output = {-97}}
}
local epochs = 1000
local initialLearningRate = 0.01
local minNeurons = 2
local maxNeurons = 32
-- Initialize and store the neural network
local weights, biases, activationFunctions = initializeNetwork(neuronCounts)
memory.AddNeuronGroup(category, NG_N, {})
memory.InitializeLayers(M[category][NG_N], neuronCounts, weights, biases, activationFunctions)
-- Check if a previously saved network exists and load it
local savedNeuronCounts, savedLayers = loadNetwork(category, NG_N)
if savedNeuronCounts and savedLayers then
neuronCounts = savedNeuronCounts
M[category][NG_N].layers = savedLayers
print("Using saved network values.")
end
-- Train the neural network
trainNetwork(category, NG_N, neuronCounts, trainingData, epochs, initialLearningRate, minNeurons, maxNeurons)
output:
10:49:40.258 Epoch: 67 - Server - Learning:184
10:49:40.258 Inputs: 0.1, 0.2 | Expected Output: 0.30 | Predicted Output: 63553058446415219725232508447206116355218373449097623061397504.00 | Loss: 4038991237893468909209056607037075954023852182080316854826666959618463789445938484397694040095012475867375429931665798987776.000000 - Server - Learning:201
10:49:40.258 Inputs: 0.4, 0.5 | Expected Output: 0.90 | Predicted Output: 68790924304853437319661193797004382119333528703934149607555072.00 | Loss: 4732191266716075164866795683606134712481463241746677796606880770833342736281226827316982033237508521188841317766004333346816.000000 - Server - Learning:201
10:49:40.258 Inputs: 0.7, 0.3 | Expected Output: 1.00 | Predicted Output: 61694389343673492502279529058975145963325270814272954185023488.00 | Loss: 3806197676488773376692214824010979915717082717963119795311305787223928810255662235394736275345408544061287665973072674947072.000000 - Server - Learning:201
10:49:40.258 Inputs: 0.6, 0.4 | Expected Output: 1.00 | Predicted Output: 64882194385374680368334823985101772090154482082075431032324096.00 | Loss: 4209699148261545820811905179300701729275466523940641480089280707553609877557806611367472978154747870855811223514880795475968.000000 - Server - Learning:201
10:49:40.258 Inputs: 0.8, 0.2 | Expected Output: 1.00 | Predicted Output: 58506584301972281800261150837490422903920548354548295213776896.00 | Loss: 3423020406683789300234152107377703183792548788617159391177554183171706970593611239416619427100522234825389470028108228722688.000000 - Server - Learning:201
10:49:40.259 Inputs: 89, 18 | Expected Output: 107.00 | Predicted Output: -1382444887193586155981323891933543820082718475156347244511232.00 | Loss: 1911153866127687125209223891114151123515378588373917850885176909592547752969490246153607390050915922887160181818736508928.000000 - Server - Learning:201
10:49:40.259 Inputs: 6, 7 | Expected Output: 13.00 | Predicted Output: 188766341804346285051037258662296377262598166341192824720982016.00 | Loss: 35632731798195289597537126018167324128856030361210191200326479533846434479508795242957238363746361415187071790470087674167296.000000 - Server - Learning:201
10:49:40.259 Inputs: 426, 180 | Expected Output: 606.00 | Predicted Output: 1428584538726479188208071637490960630999510675952743343535947776.00 | Loss: 2040853784288347325611904431504817050111049035168505963741938444070813772904749130530307510736056114024324092359841833373663232.000000 - Server - Learning:201
10:49:40.259 Inputs: 12, 18 | Expected Output: 30.00 | Predicted Output: 416867667169292489417345299490117681071890514802122396570484736.00 | Loss: 173778651931168025972213569323873366751414270931792029034610870638297621921298044784198557599141646848156206328726255443116032.000000 - Server - Learning:201
10:49:40.259 Inputs: -17, 18 | Expected Output: 1.00 | Predicted Output: 625935881724784875174239354103613768574583469215459371292557312.00 | Loss: 391795728030583854158395991187827920991258260723081202737825372444929280140511589783025073242189710201611192373705362192203776.000000 - Server - Learning:201
10:49:40.259 Inputs: -893, 18 | Expected Output: -875.00 | Predicted Output: 6941237811056213972719861813368053773817537879263426070974562304.00 | Loss: 48180782349636464870467367628741664973713700613031338923589243159254331806573066807967017087191771313309675184979386640743006208.000000 - Server - Learning:201
10:49:40.260 Inputs: 2, 4 | Expected Output: 6.00 | Predicted Output: 143596931997739662943682654249924977049491900181856883795034112.00 | Loss: 20620078879163468463463179164271683796529653867257854015231141407513167925589869920044801412441553815105366536400292710187008.000000 - Server - Learning:201
10:49:40.260 Inputs: 11, 14 | Expected Output: 25.00 | Predicted Output: 325401709390122698287868581282392729273797473651325581108707328.00 | Loss: 105886272474013862622702585762083257928731938691265851156744462033058268994420447364522197741264978115702144887078386613092352.000000 - Server - Learning:201
10:49:40.260 Inputs: 7, 15 | Expected Output: 22.00 | Predicted Output: 378907506140461466818849110754073732151980557415660144428056576.00 | Loss: 143570898209583835300207728025666361512889890180324067779663131187707326552506981045023691752948382591718392670088511417745408.000000 - Server - Learning:201
10:49:40.260 Inputs: 50, 15 | Expected Output: 65.00 | Predicted Output: 68909808696110368234454070536979969488482123495180977001463808.00 | Loss: 4748561734534527879278027717169691509576326611283978276881019727847393405178864532605865538439376039784229330962214587203584.000000 - Server - Learning:201
10:49:40.260 Inputs: 129, 2 | Expected Output: 131.00 | Predicted Output: -8213152660581643090804411322614294977504513750470011811528704.00 | Loss: 67455876626019326366129882797577423558944457035053445010601697012176915220504166895655694054020867718675074764417108279296.000000 - Server - Learning:201
10:49:40.260 Inputs: -9, 15 | Expected Output: 6.00 | Predicted Output: 494255486584871058960583761575312952843121497781639164964372480.00 | Loss: 244288486019247657576123601770148145172250332053438440105728367060781335409516453910938776901879335330056932114799601083482112.000000 - Server - Learning:201
10:49:40.260 Inputs: -2, -89 | Expected Output: -91.00 | Predicted Output: -21217646253400673314428572888190554686043747327457288167358464.00 | Loss: 450188512534447648061332586583676872036161463261553841264861816890309336075857011892157358020455287300993829996597295972352.000000 - Server - Learning:201
10:49:40.261 Inputs: -112, 15 | Expected Output: -97.00 | Predicted Output: 1236808110695758356436114575325634762424153569993761480641609728.00 | Loss: 1529694302682811148869555208232464000017876126463280099586397765302404176772115003923933261716722453075002071918185442783002624.000000 - Server - Learning:201
10:49:40.261 Average Loss after Epoch 67: 2783809552682272106176829247651559407082222351397947264105385703439571675022344829936867912328429174758697357027430473448554496.000000 - Server - Learning:262
I really have no idea what happened, even restoring to previous versions didn’t fix it where it did worked.