Update 1.6.0: Recurrent Neural Network added. Go ahead and try it out!
Update 1.8.0:
-
LSTM model added!
-
Adjustable input, hidden, output layers for both RNN and LSTM
-
Made some changes to OnlineLearning so that it accepts both sequential and non-sequential inputs/outputs.
Note: You many need to update your Matrix Library.
Woah woah, you are telling me with this I can make those AI’s that pathfind and become better each time they train?
If this is stable, performant and good might actually use it to make a pathfinding NPC, Ive heard you can use raycasts and shapecasts to create a view for it, and the AI can learn every simulation more.
Absolutely! What’s even better about this library, you can:
-
Use Online Learning to do real-time training if you were to collect data real-time and train the model when you are not around.
-
Retrieve and store the model parameters values into datastores.
It’s about to reach the final development stage. I’m thinking whether or not to add feature that enables the models avoid exhausting script execution time. Not only that, I’m trying to add some more kernels to support vector machine right now.
I have no idea about machine learning AI, so if I decide to dive into it ill deffinetely use this, it just sounds too hard for me atm. but good job on this
Update 1.9.0:
-
Added new kernels for support vector machine.
-
Added internal model wait component to avoid exhaustion time.
-
RNN and LSTM can take in multiple token sequences.
-
Changed the parameters for online learning.
-
Some fixes.
Update 1.10.0:
-
You can now change any of neural network’s layers’s properties using setLayer() function.
-
Some calculation fixes. This leads to training improvement to certain models.
-
And some more other stuff.
PS: I recommend you to update both the Machine Learning Library and Matrix Library.
Release Version 1.0 (Beta Version 1.11.0) is here! Get the ModuleScript from the original post now!
-
Fixed a couple of stuff.
-
Added new optimizers.
-
Many more!
Greetings. I read the full version of the documentation, but I couldn’t find anywhere to save the model.
Every model is inherited from a BaseModel class. The BaseModel class contains functions getModelParameters() and setModelParameters(). You can call those functions from any models that inherits it.
Then you can save the model parameters to Roblox’s DataStore or print out the values.
Oh, I understand you, thank you very much!
Alright guys, it seems like I will not updating this for a long time. Let m know if there are any issues with the codes or any feature requests you want me to add to this library.
I’m really interested in this and it seems incredible, i would only like to see some tutorial of this being applied in a NPC
I’ll probably make a tutorial video next month once I am done with my work contract.
You can give me some suggestions and I’ll see if I can fit any of the models for those suggestions.
Suggestion : make a pathfinding ai in the tutorial
Alright! Enemy NPCs(Follow and Attack the player) but for that i would like to see if these kind of Enemy NPCs could be trained to dodge projectiles, block attacks, maybe even using objects around him to his advantage like to avoid being hit by a projectile, hope this made sense!
Hello, I am grateful for this library, however, I am still confused on how to intergrate it into gameplay. Suppose I have an NPC, I want it to train with players, so I have this pseudo-code:
local NPC = workspace.NPC
local function moveRight()
end
local function moveLeft()
end
local function moveFoward()
end
local function moveBackward()
end
local function moveJump()
end
local function attack()
end
local function getInputFromEyeWithRays()
end
How would I implement your module with this pseudo-code?
Sure! Something like this with an additional functions added. Unfortunately, I am not good at pseudo code, so I’ll give the partially-completed Lua code instead (not tested).
NPC trained using player data and online learning.
local NPC = workspace.NPC
local NeuralNetwork = DataPredict.Models.NeuralNetwork
local OnlineLearning = DataPredict.Others.OnlineLearning
local function moveRight()
end
local function moveLeft()
end
local function moveFoward()
end
local function moveBackward()
end
local function moveJump()
end
local function attack()
end
local function checkIfIsCharacter(HittedPart)
local ParentPart = HittedPart.ParentPart
local Humanoid = ParentPart:FindFirstChild("Humanoid")
if Humanoid then
return 1
else
return 0
end
end
local function performAction(actionNumber)
if (actionNumber == 1) then
attack()
if (actionNumber == 2) then
jump()
else -- You can add more actions here.
end
end
local function getInputFromEyeWithRays()
local inputVector
local materialEnumValue
local distance
local isPlayer
local ForwardRaycast = workspace:Raycast()
if ForwardRaycast then
materialEnumValue = ForwardRaycast.Material
distance = ForwardRaycast.Distance
isCharacter = checkIfIsCharacter(ForwardRaycast.Instance)
else
materialEnumValue = 0
distance = inf
isCharacter = 0
end
inputVector = {{1, materialEnumValue, distance, isCharacter}} -- 1 is added for bias
return inputVector
end
local function convertControlToActionNumber(ReceivedControls)
-- Assign each integer number to each control here
local actionNumber = 0
if (ReceivedControls == "Control1") then
actionNumber = 1
end
return actionNumber
end
local function startTrainingFromPlayer(Player)
local inputVector
local NeuralNetworkForThisPlayer = NeuralNetwork.new()
NeuralNetworkForThisPlayer:addLayer(3, true) -- First input layer. Add bias too.
NeuralNetworkForThisPlayer:addLayer(5, true) -- Second input layer. Add bias too.
NeuralNetworkForThisPlayer:addLayer(6, false) -- Final output layer. Value is six because of 6 actions.
NeuralNetworkForThisPlayer:setClassesList({1, 2, 3, 4, 5, 6}) -- 6 different actions, so six classes.
local OnlineLearningForThisPlayer = OnlineLearning.new(NeuralNetworkForThisPlayer)
local DataHarvestRemoteEvent
DataHarvestRemoteEvent.OnServerEvent:Connect(function(ReceivedPlayer, ReceivedControls)
if (ReceivedPlayer == Player) then
inputVector = getInputFromEyeWithRays()
actionNumber = convertControlToActionNumber(ReceivedControls)
OnlineLearningForThisPlayer:addInputToOnlineLearningQueue(inputVector)
OnlineLearningForThisPlayer:addOutputToOnlineLearningQueue(actionNumber)
end
end)
OnlineLearningForThisPlayer:startOnlineLearning()
end
local function runTrainedNPC()
local inputVector
local predictedActionNumber
local NeuralNetworkForThisNPC = NeuralNetwork.new()
-- The layers are the same to our previous neural network
NeuralNetworkForThisNPC:addLayer(3, true) -- First input layer. Add bias too.
NeuralNetworkForThisNPC:addLayer(5, true) -- Second input layer. Add bias too.
NeuralNetworkForThisNPC:addLayer(6, false) -- Final output layer. Value is six because of 6 actions.
NeuralNetworkForThisNPC:setClassesList({1, 2, 3, 4, 5, 6}) -- 6 different actions, so six classes.
while true do
inputVector = getInputFromEyeWithRays()
predictedActionNumber = NeuralNetworkForThisNPC:predict(inputVector)
performAction(actionNumber)
end
end
NPC trained using reinforcement (accidentally misread the question, but I’ll just leave it here).
local NPC = workspace.NPC
local NeuralNetwork = DataPredict.Models.NeuralNetwork.new()
NeuralNetwork:addLayer(3, true) -- First input layer. Add bias too.
NeuralNetwork:addLayer(5, true) -- Second input layer. Add bias too.
NeuralNetwork:addLayer(6, false) -- Final output layer. Value is six because of 6 actions.
NeuralNetwork:setClassesList({1, 2, 3, 4, 5, 6}) -- 6 different actions, so six classes.
local function moveRight()
end
local function moveLeft()
end
local function moveFoward()
end
local function moveBackward()
end
local function moveJump()
end
local function attack()
end
local function checkIfIsCharacter(HittedPart)
local ParentPart = HittedPart.ParentPart
local Humanoid = ParentPart:FindFirstChild("Humanoid")
if Humanoid then
return 1
else
return 0
end
end
local function getInputFromEyeWithRays()
local inputVector
local materialEnumValue
local distance
local isPlayer
local ForwardRaycast = workspace:Raycast()
if ForwardRaycast then
materialEnumValue = ForwardRaycast.Material
distance = ForwardRaycast.Distance
isCharacter = checkIfIsCharacter(ForwardRaycast.Instance)
else
materialEnumValue = 0
distance = inf
isCharacter = 0
end
inputVector = {{1, materialEnumValue, distance, isCharacter}} -- 1 is added for bias
return inputVector
end
local function performAction(actionNumber)
if (actionNumber == 1) then
attack()
if (actionNumber == 2) then
jump()
else -- You can add more actions here.
end
end
local function evaluateRealActionNumber(predictedActionNumber)
local realActionNumber = 0
--[[
Put your own conditions if certain conditions are met.
For example, if the NPC takes a hit while fighting, then move back.
Another one is that if the NPC doesnt move forward because of something blocking it, then it needs to jump.
--]]
return realActionNumber
end
local function run()
local realActionNumber = 0
local inputVector
local predictedActionNumber
local rewardValue = 0.3
local punishValue = 0.5
while true do
inputVector = getInputFromEyeWithRays()
predictedActionNumber = NeuralNetwork:reinforce(inputVector, realActionNumber, rewardValue, punishValue)
performAction(actionNumber)
realActionNumber = evaluateRealActionNumber()
end
end
Alternatively, you can use the QueuedReinforcementNeuralNetwork in AqwamCustomModels. However, you need the while loop.
Look’s very interesting i’m gonna check it out.
Don’t forget to leave a like on the first post if you find this useful! I’d appreciate it.