Advertisement
eea

modules

eea
Mar 8th, 2022 (edited)
802
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.16 KB | None | 0 0
  1. local Matrix = {}
  2.  
  3. function random(min, max)
  4.     min = min or 0
  5.     max = max or 1
  6.     return min + math.random() * (max - min)
  7. end
  8.  
  9. local matrixmeta = {
  10.     __add = function(self, M2)
  11.         local NewMatrix = Matrix.new(self.rows, self.cols, self.comment..M2.comment)
  12.         for x = 1, NewMatrix.rows do
  13.             for y = 1, NewMatrix.cols do
  14.                 NewMatrix.Matrix[x][y] = self.Matrix[x][y] + M2.Matrix[x][y]
  15.             end
  16.         end
  17.         return NewMatrix
  18.     end;
  19.  
  20.     __sub = function(self, M2)
  21.         local NewMatrix = Matrix.new(self.rows, self.cols, self.comment..M2.comment)
  22.         for x = 1, NewMatrix.rows do
  23.             for y = 1, NewMatrix.cols do
  24.                 NewMatrix.Matrix[x][y] = self.Matrix[x][y] - M2.Matrix[x][y]
  25.             end
  26.         end
  27.         return NewMatrix
  28.     end;
  29.  
  30.     __div = function(self, M2)
  31.         local NewMatrix = Matrix.new(self.rows, self.cols, self.comment..M2.comment)
  32.         for x = 1, NewMatrix.rows do
  33.             for y = 1, NewMatrix.cols do
  34.                 NewMatrix.Matrix[x][y] = self.Matrix[x][y] / M2.Matrix[x][y]
  35.             end
  36.         end
  37.         return NewMatrix
  38.     end;
  39.  
  40.     __mul = function(self, M2)
  41.         if type(M2) == "number" and type(self) == "table" then
  42.             local newMatrix = Matrix.new(self.rows, self.cols, self.comment)
  43.             for x = 1, newMatrix.rows do
  44.                 for y = 1, newMatrix.cols do
  45.                     newMatrix.Matrix[x][y] = self.Matrix[x][y] * M2
  46.                 end
  47.             end
  48.             return newMatrix
  49.         elseif type(self) == "number" and type(M2) == "table" then
  50.             local newMatrix = Matrix.new(M2.rows, M2.cols, M2.comment)
  51.             for x = 1, newMatrix.rows do
  52.                 for y = 1, newMatrix.cols do
  53.                     newMatrix.Matrix[x][y] = M2.Matrix[x][y] * self
  54.                 end
  55.             end
  56.             return newMatrix
  57.         end
  58.  
  59.         if type(self) == "table" and type(M2) == "table" then
  60.             local newMatrix = Matrix.new(self.rows, M2.cols, self.comment..M2.comment)
  61.             for x = 1, newMatrix.rows do
  62.                 for y = 1, newMatrix.cols do
  63.                     local sum = 0
  64.                     for z = 1, self.cols do
  65.                         sum = sum + self.Matrix[x][z] * M2.Matrix[z][y]
  66.                     end
  67.                     newMatrix.Matrix[x][y] = sum
  68.                 end
  69.             end
  70.             return newMatrix
  71.         end
  72.     end;
  73. }
  74.  
  75. function Matrix.new(rows, cols, comment)
  76.     -- Creates a new Matrix with x rows and y coloums
  77.     local Table = {}
  78.  
  79.     Table.rows = rows
  80.     Table.cols = cols
  81.     Table.comment = comment or ""
  82.     Table.Matrix = {}
  83.     for x = 1, rows do
  84.         Table.Matrix[x] = {}
  85.         for y = 1, cols do
  86.             Table.Matrix[x][y] = 0
  87.         end
  88.     end
  89.     Table.set = function(p)
  90.         if p["Matrix"] ~= nil then
  91.             Table.Matrix = p.Matrix
  92.         else
  93.             Table.Matrix = p
  94.         end
  95.     end
  96.  
  97.     setmetatable(Table, matrixmeta)
  98.     return Table
  99. end
  100.  
  101. function Matrix:randomizeMatrix(M, min, max)
  102.     for x = 1, M.rows do
  103.         for y = 1, M.cols do
  104.             M.Matrix[x][y] = random(min, max)
  105.         end
  106.     end
  107. end
  108.  
  109. function Matrix:toMatrix(array, i, comment)
  110.     local isMATRIX
  111.     for i, v in pairs(array) do
  112.         if i == "Matrix" then
  113.             isMATRIX = true
  114.         end
  115.     end
  116.     if isMATRIX then return array end
  117.     if i then
  118.         arrayToMatrix = Matrix.new(1, #array, comment)
  119.         for y = 1, #array do
  120.             arrayToMatrix.Matrix[1][y] = array[y]
  121.         end
  122.     else
  123.         arrayToMatrix = Matrix.new(#array, 1, comment)
  124.         for x = 1, #array do
  125.             arrayToMatrix.Matrix[x][1] = array[x]
  126.         end
  127.     end
  128.  
  129.     return arrayToMatrix
  130. end
  131.  
  132. function Matrix:toArray(M)
  133.     local array = {}
  134.     for x = 1, M.rows do
  135.         for y = 1, M.cols do
  136.             array[#array + 1] = M.Matrix[x][y]
  137.         end
  138.     end
  139.     return array
  140. end
  141.  
  142. function Matrix:transposeMatrix(M)
  143.     local newMatrix = Matrix.new(M.cols, M.rows, M.comment)
  144.     for x = 1, M.rows do
  145.         for y = 1, M.cols do
  146.             newMatrix.Matrix[y][x] = M.Matrix[x][y]
  147.         end
  148.     end
  149.     return newMatrix
  150. end
  151.  
  152. function Matrix:multMatrices(M1, M2)
  153.     local newMatrix = Matrix.new(M1.rows, M1.cols, M1.comment)
  154.     for x = 1, newMatrix.rows do
  155.         for y = 1, newMatrix.cols do
  156.             newMatrix.Matrix[x][y] = M1.Matrix[x][y] * M2.Matrix[x][y]
  157.         end
  158.     end
  159.     return newMatrix
  160. end
  161.  
  162. function Matrix:mapMatrix(M, functio, s)
  163.     local newMatrix = Matrix.new(M.rows, M.cols, M.comment)
  164.     for x = 1, newMatrix.rows do
  165.         for y = 1, newMatrix.cols do
  166.             newMatrix.Matrix[x][y] = functio(M.Matrix[x][y], s)
  167.         end
  168.     end
  169.     return newMatrix
  170. end
  171.  
  172.  
  173.  
  174.  
  175. local module = {}
  176.  
  177. function he(_,h)
  178.     return random(h[1], h[2])*math.sqrt(2/h[3])
  179. end
  180. local ActivationFuncs = {}
  181.  
  182. ActivationFuncs.Sigmoid = function(x, d)
  183.     if d then
  184.         return x*(1-x)
  185.     end
  186.     return 1/(1+math.exp(-x))
  187. end
  188.  
  189. ActivationFuncs.Tanh = function(x, d)
  190.     if d then
  191.         return 1/math.cosh(x)^2
  192.     end
  193.     return math.tanh(x)
  194. end
  195.  
  196. ActivationFuncs.Identity = function(x, d)
  197.     if d then
  198.         return 1
  199.     end
  200.     return x
  201. end
  202.  
  203. ActivationFuncs.ArcTanh = function(x, d)
  204.     if d then
  205.         return 1/(x^2+1)
  206.     end
  207.     return math.atan(x)
  208. end
  209.  
  210. ActivationFuncs.Sign = function(x, d)
  211.     if d then
  212.         return 0
  213.     end
  214.     return math.sign(x)
  215. end
  216.  
  217. ActivationFuncs.LeakyReLU = function(x, d)
  218.     if d then
  219.         if x >= 0 then
  220.             return 1
  221.         end
  222.         return 0.1
  223.     end
  224.     return math.max(0.1*x, x)
  225. end
  226.  
  227. ActivationFuncs.Sin = function(x, d)
  228.     if d then
  229.         return math.cos(x)
  230.     end
  231.     return math.sin(x)
  232. end
  233.  
  234. ActivationFuncs.V = function(x, d)
  235.     if d then
  236.         return math.abs(x)/x
  237.     end
  238.     return math.abs(x)
  239. end
  240.  
  241. function module:MAp(tabl, functio, d)
  242.     for i, v in pairs(tabl) do
  243.         if type(v) == "table" then
  244.             module:MAp(tabl[i], functio)
  245.         elseif type(v) == "number" then
  246.             tabl[i] = functio(tabl[i], d)
  247.         end
  248.     end
  249. end
  250.  
  251. function module:CopyTable(s)
  252.     local f = {}
  253.     for i, v in pairs(s) do
  254.         if type(v) == "table" then
  255.             f[i] = module:CopyTable(v)
  256.         else
  257.             f[i] = v
  258.         end
  259.     end
  260.     return f
  261. end
  262.  
  263. function module:LayerM(net, input, layer, f, d, s)
  264.     local minput = Matrix:toMatrix(input)
  265.     if f then
  266.         local n = net.__Weights[layer] * minput
  267.         local nplusb = n + net.__Bias[layer]
  268.         local nplusb_a = Matrix:mapMatrix(nplusb, ActivationFuncs[net.__AF[layer]], d)
  269.         return nplusb_a
  270.     else
  271.         if s then
  272.             return Matrix:transposeMatrix(net.__Weights[layer-1]) * minput
  273.         end
  274.         local n = Matrix:transposeMatrix(net.__Weights[layer-1]) * minput
  275.         local nplusb = n + net.__Bias[layer-1]
  276.         local nplusb_a = Matrix:mapMatrix(nplusb, ActivationFuncs[(net.__AF[layer-2] or "Identity")], d)
  277.         return nplusb_a
  278.     end
  279. end
  280.  
  281. function module:CreateNN(NumberInputs, NumberHidden, NumberHLayers, NumberOutputs, LearningRate, ActivationFunction)
  282.     local NewNN = {}
  283.    
  284.     NewNN.__NumberInputs = NumberInputs
  285.     NewNN.__NumberHidden = NumberHidden
  286.     NewNN.__NumberHLayers = NumberHLayers
  287.     NewNN.__NumberOut = NumberOutputs
  288.     NewNN.__LR = LearningRate
  289.     NewNN.__AF = {}
  290.     NewNN.__Weights = {}
  291.     NewNN.__Layers = {}
  292.     NewNN.__Bias = {}
  293.     NewNN.__Hidden = {}
  294.    
  295.     if type(ActivationFunction) == "string" then
  296.         for i = 1, NumberHLayers+1, 1 do
  297.             NewNN.__AF[i] = ActivationFunction
  298.         end
  299.     elseif type(ActivationFunction) == "table" then
  300.         for i = 1, NumberHLayers+1, 1 do
  301.             NewNN.__AF[i] = ActivationFunction[i]
  302.         end
  303.     end
  304.    
  305.     NewNN.__Layers[1] = NumberInputs
  306.    
  307.     for layer = 1,NumberHLayers,1 do
  308.         NewNN.__Bias[layer] = Matrix.new(NumberHidden, 1)
  309.         NewNN.__Layers[#NewNN.__Layers+1] = NumberHidden
  310.     end
  311.  
  312.     NewNN.__Bias[NumberHLayers+1] = Matrix.new(NumberOutputs, 1)
  313.    
  314.     NewNN.__Layers[#NewNN.__Layers+1] = NumberOutputs
  315.    
  316.     local iw = Matrix.new(NumberHidden, NumberInputs)
  317.     iw = Matrix:mapMatrix(iw, he, {-1, 1, NumberHidden})
  318.     NewNN.__Weights[1] = iw
  319.    
  320.     for i=1,NumberHLayers-1 do
  321.         local hw = Matrix.new(NumberHidden, NumberHidden)
  322.         hw = Matrix:mapMatrix(hw, he, {-1, 1, NumberHidden})
  323.         NewNN.__Weights[#NewNN.__Weights+1] = hw
  324.     end
  325.    
  326.     local ow = Matrix.new(NumberOutputs, NumberHidden)
  327.     ow = Matrix:mapMatrix(ow, he, {-1, 1, NumberOutputs})
  328.    
  329.     NewNN.__Weights[#NewNN.__Weights+1] = ow
  330.    
  331.     function NewNN:Forward(Inputs, giveotherstuff, d)
  332.         local output = {}
  333.         local otherstuff = {}
  334.         otherstuff[1] = Inputs
  335.         local oh = module:LayerM(self, Inputs, 1, true)
  336.         if giveotherstuff then
  337.             otherstuff[#otherstuff+1] = Matrix:toArray(oh)
  338.         end
  339.         local inpu = oh
  340.        
  341.         for l = 1,self.__NumberHLayers,1 do
  342.             inpu = module:LayerM(self, inpu, l+1, true)
  343.             if giveotherstuff then
  344.                 otherstuff[#otherstuff+1] = Matrix:toArray(inpu)
  345.             end
  346.         end
  347.         output = inpu
  348.    
  349.        
  350.         if giveotherstuff then
  351.             return Matrix:toArray(output), otherstuff
  352.         end
  353.         return Matrix:toArray(output)
  354.     end
  355.    
  356.     function NewNN:BackProp(Inputs, Targets)
  357.         local mTargets = Matrix:toMatrix(Targets)
  358.         local Output, stuff = self:Forward(Inputs, true)
  359.         local mOutput = Matrix:toMatrix(Output)
  360.         local l_error = mTargets - mOutput
  361.         for layer = self.__NumberHLayers+2, 2, -1 do
  362.             local vinlayer = Matrix:toMatrix(stuff[layer])
  363.             local lvinlayer = Matrix:toMatrix(stuff[layer-1])
  364.             local t_lvinlayer = Matrix:transposeMatrix(lvinlayer)
  365.             local g = Matrix:mapMatrix(vinlayer, ActivationFuncs[self.__AF[layer-1]], true)
  366.             g = Matrix:multMatrices(g, l_error)
  367.             g = g * self.__LR
  368.             self.__Weights[layer-1] = self.__Weights[layer-1] + g * t_lvinlayer
  369.             self.__Bias[layer-1] = self.__Bias[layer-1] + g
  370.             l_error = module:LayerM(self, l_error, layer, false, false, true)
  371.         end
  372.        
  373.     end
  374.    
  375.     function NewNN:CopyNet()
  376.         return module:CreateNN(self.__NumberInputs, self.__NumberHidden, self.__NumberHLayers, self.__NumberOut, self.__LR, self.__AF)
  377.     end
  378.    
  379.     function NewNN:CopyNet2()
  380.         local copied = module:CopyTable(self)
  381.         --local copied = module:CreateNN(self.__NumberInputs, self.__NumberHidden, self.__NumberHLayers, self.__NumberOut, self.__LR, self.__AF)
  382.         --copied.__Weights = module:CopyTable(self.__Weights)
  383.         --copied.__Bias = module:CopyTable(self.__Bias)
  384.         --copied.__Layers = module:CopyTable(self.__Layers)
  385.         --copied.__Hidden = module:CopyTable(self.__Hidden)
  386.         return copied
  387.     end
  388.    
  389.     function NewNN:Randomize()
  390.         for i = 1,#self.__Weights do
  391.             for ii = 1,#self.__Weights[i].Matrix do
  392.                 for iii = 1,#self.__Weights[i].Matrix[ii] do
  393.                     self.__Weights[i].Matrix[ii][iii] = random(-1, 1)
  394.                 end
  395.             end
  396.         end
  397.         for i = 1,#self.__Bias do
  398.             for ii = 1,#self.__Bias[i].Matrix do
  399.                 for iii = 1,#self.__Bias[i].Matrix[ii] do
  400.                     local c_biasr = self.__Bias[i].Matrix[ii]
  401.                     local rando = random(-1,1)
  402.                     c_biasr[iii] = rando
  403.                 end
  404.             end
  405.         end
  406.     end
  407.     function NewNN:Mutate(c, chance, rate)
  408.         chance = chance or 50
  409.         for i = 1,#self.__Weights do
  410.             for ii = 1,#self.__Weights[i].Matrix do
  411.                 for iii = 1,#self.__Weights[i].Matrix[ii] do
  412.                     local c_weightr = self.__Weights[i].Matrix[ii]
  413.                     local rando = random(-rate,rate)
  414.                     if c then
  415.                         if rando > (chance/100-.5) then
  416.                             c_weightr[iii] += rando
  417.                         end
  418.                     else
  419.                         c_weightr[iii] += rando
  420.                     end
  421.                 end
  422.             end
  423.         end
  424.  
  425.         for i = 1,#self.__Bias do
  426.             for ii = 1,#self.__Bias[i].Matrix do
  427.                 for iii = 1,#self.__Bias[i].Matrix[ii] do
  428.                     local c_biasr = self.__Bias[i].Matrix[ii]
  429.                     local rando = random(-rate,rate)
  430.                     if c then
  431.                         if rando > (chance/100-.5) then
  432.                             c_biasr[iii] += rando
  433.                         end
  434.                     else
  435.                         c_biasr[iii] += rando
  436.                     end
  437.                 end
  438.             end
  439.         end
  440.     end
  441.     return NewNN
  442. end
  443.  
  444. function module:CopyNet(net)
  445.     local cnet = {}
  446.     for i, v in pairs(net) do
  447.         cnet[i] = v
  448.     end
  449.     return cnet
  450. end
  451.  
  452. function module:CreateGA(t, b)
  453.     local ga = {}
  454.     for i = 1, b, 1 do
  455.         ga[i] = module:CopyNet(t):RandomizeWeights()
  456.     end
  457.     return ga
  458. end
  459.  
  460. local GA = {}
  461.  
  462. function GA:CopyTable(t)
  463.     local f = {}
  464.     for i, v in pairs(t) do
  465.         f[i]=v
  466.     end
  467.     return f
  468. end
  469.  
  470. function random(min, max)
  471.     min = min or 0
  472.     max = max or 1
  473.     return (max - min)*math.random() + min
  474. end
  475.  
  476. function GA:MutateNet(net, c, chance, rate)
  477.     chance = chance or 50
  478.     for i = 1,#net.__Weights do
  479.         for ii = 1,#net.__Weights[i].Matrix do
  480.             for iii = 1,#net.__Weights[i].Matrix[ii] do
  481.                 local c_weightr = net.__Weights[i].Matrix[ii]
  482.                 local rando = random(-rate,rate)
  483.                 if c then
  484.                     if rando > (chance/100-.5) then
  485.                         c_weightr[iii] += rando
  486.                     end
  487.                 else
  488.                     c_weightr[iii] += rando
  489.                 end
  490.             end
  491.         end
  492.     end
  493.  
  494.     for i = 1,#net.__Bias do
  495.         for ii = 1,#net.__Bias[i].Matrix do
  496.             for iii = 1,#net.__Bias[i].Matrix[ii] do
  497.                 local c_biasr = net.__Bias[i].Matrix[ii]
  498.                 local rando = random(-rate,rate)
  499.                 if c then
  500.                     if rando > (chance/100-.5) then
  501.                         c_biasr[iii] += rando
  502.                     end
  503.                 else
  504.                     c_biasr[iii] += rando
  505.                 end
  506.             end
  507.         end
  508.     end
  509. end
  510.  
  511. function GA:MutateNet2(snet, c, chance, rate)
  512.     chance = chance or 50
  513.     local net = snet:CopyNet2()
  514.     for i = 1,#net.__Weights do
  515.         for ii = 1,#net.__Weights[i].Matrix do
  516.             for iii = 1,#net.__Weights[i].Matrix[ii] do
  517.                 local c_weightr = net.__Weights[i].Matrix[ii]
  518.                 local rando = random(-rate,rate)
  519.                 if c then
  520.                     if rando > (chance/100-.5) then
  521.                         c_weightr[iii] += rando
  522.                     end
  523.                 else
  524.                     c_weightr[iii] += rando
  525.                 end
  526.             end
  527.         end
  528.     end
  529.  
  530.     for i = 1,#net.__Bias do
  531.         for ii = 1,#net.__Bias[i].Matrix do
  532.             for iii = 1,#net.__Bias[i].Matrix[ii] do
  533.                 local c_biasr = net.__Bias[i].Matrix[ii]
  534.                 local rando = random(-rate,rate)
  535.                 if c then
  536.                     if rando > (chance/100-.5) then
  537.                         c_biasr[iii] += rando
  538.                     end
  539.                 else
  540.                     c_biasr[iii] += rando
  541.                 end
  542.             end
  543.         end
  544.     end
  545.     return net
  546. end
  547.  
  548. function GA:CrossNets(net1, net2, m, rate)
  549.     local child = net1:CopyNet()
  550.     for i, v in pairs(net1.__Weights) do
  551.         for ii, vv in pairs(v) do
  552.             local p1w = net1.__Weights[i][ii]
  553.             local p2w = net2.__Weights[i][ii]
  554.             if m then
  555.                 local rando = random(-1, 1)*(rate or 1)
  556.                 child.__Weights[i][ii] = ((p1w + p2w)/2) + rando
  557.             else
  558.                 child.__Weights[i][ii] = (p1w + p2w)/2
  559.             end
  560.         end
  561.     end
  562.  
  563.     for i, v in pairs(net1.__Bias) do
  564.         for ii, vv in pairs(v) do
  565.             local p1w = net1.__Bias[i][ii]
  566.             local p2w = net2.__Bias[i][ii]
  567.             if m then
  568.                 local rando = random(-1, 1)*(rate or 1)
  569.                 child.__Bias[i][ii] = ((p1w + p2w)/2) + rando
  570.             else
  571.                 child.__Bias[i][ii] = (p1w + p2w)/2
  572.             end
  573.         end
  574.     end
  575.     return child
  576. end
  577.  
  578. function GA:CreateGA(n, q)
  579.     local ns = {}
  580.     ns.ns = {}
  581.     ns.q = q
  582.     function ns:RunGA(scores, mt)
  583.         local mut = {}
  584.         local bnet = self.ns[table.find(scores,math.max(table.unpack(scores)))]
  585.         for i = 1,self.q do
  586.             ns.ns[i] = bnet:CopyNet2()
  587.             ns.ns[i]:Mutate(false, 0, mt)
  588.         end
  589.     end
  590.     for i = 1,q do
  591.         table.insert(ns.ns, n:CopyNet())
  592.     end
  593.     return ns
  594. end
  595.  
  596.  
  597. function random(min, max)
  598.     min = min or 0
  599.     max = max or 1
  600.     return min + math.random() * (max-min)
  601. end
  602.  
  603.  
  604. return module, Matrix, GA
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement