Всем привет.
Сделал нейронку на LUA. Может кому пригодится:
Пример:
Сделал нейронку на LUA. Может кому пригодится:
Код |
---|
NeuralNetwork = {} NeuralNetwork.__index = NeuralNetwork function NeuralNetwork.new(inputs, layers, neyrons) -- Инициализация local self = setmetatable({}, NeuralNetwork) self.layers=layers -- слоев self.inputs=inputs -- входов self.neyrons=neyrons --нейронов в слое self.k=0.5 self.e=0.01 -- Скорость обучения self.im=0.01 -- импульс self.traininig_count=0 --Будем считать обучения self.w={} self.nout={} self.dw={} self.delta={} self.w[1]={} self.nout[1]={} self.dw[1]={} self.delta[1]={} local i local l for i = 1, self.neyrons, 1 do self.w[1][i]={} self.dw[1][i]={} self.delta[1][i]={} self.nout[1][i]={} for ii = 1, self.inputs+1, 1 do self.w[1][i][ii]=math.random() self.dw[1][i][ii]=0 end end for l = 2, self.layers, 1 do --перебор остальных слоев self.w[l]={} self.dw[l]={} self.delta[l]={} self.nout[l]={} for i = 1, self.neyrons, 1 do self.w[l][i]={} self.dw[l][i]={} self.delta[l][i]={} self.nout[l][i]={} for ii = 1, self.neyrons+1, 1 do self.w[l][i][ii]=1*math.random() self.dw[l][i][ii]=0 end end end --Выходной нейрон self.w[self.layers+1]={} self.dw[self.layers+1]={} self.w[self.layers+1][1]={} self.dw[self.layers+1][1]={} self.delta[self.layers+1]={} self.delta[self.layers+1][1]={} for ii = 1, self.neyrons+1, 1 do -- +w0 self.w[self.layers+1][1][ii]=1*math.random() self.dw[self.layers+1][1][ii]=0 end return self end function NeuralNetwork.Save(self, filename) local f,err = io.open(filename,"w") if not f then return false end f:write(table.tostring(self)) f:close() return true end function NeuralNetwork.Load(self, filename) local f,err = io.open(filename,"r") if not f then return false end local tbl = assert(load("return " .. f:read("*a"))) f:close() for k,v in pairs(tbl()) do if (type(v)=="table") then self[k]=table_copy(v) else self[k] = v end end return true end function NeuralNetwork.Training(self, data, res) --Одно обучение self.traininig_count=self.traininig_count+1 -- счетчик обучений local nres=self:Play(data) --Свой результат self.delta[self.layers+1][1]=(res-nres) --Начинаем с выходного слоя for tmpi = 1, self.neyrons, 1 do -- последний перед выходом слой self.delta[self.layers][tmpi] = self.w[self.layers + 1][1][tmpi] * self.delta[self.layers + 1][1]*dsigmoda(self.nout[self.layers][tmpi], self.k) end for tmpl =self.layers-1, 1, -1 do -- слои for tmpn = 1, self.neyrons, 1 do-- нейроны в слое self.delta[tmpl][tmpn] = 0 for tmpi = 1, self.neyrons, 1 do self.delta[tmpl][tmpn] = self.delta[tmpl][tmpn] + (self.w[tmpl + 1][tmpi][tmpn] * self.delta[tmpl + 1][tmpi]) end self.delta[tmpl][tmpn] = self.delta[tmpl][tmpn] * dsigmoda(self.nout[tmpl][tmpn],self.k) end end --Теперь правим веса --Правим в первом/входном слое *************************** первый(0) ************************************* for tmpn = 1, self.neyrons, 1 do -- нейроны в слое self.dw[1][tmpn][self.inputs + 1] = (self.e * self.delta[1][tmpn] * (1 - self.im)) + (self.im * self.dw[1][tmpn][self.inputs + 1]) self.w[1][tmpn][self.inputs + 1] = self.w[1][tmpn][self.inputs + 1] + self.dw[1][tmpn][self.inputs + 1] for tmpi = 1, self.inputs, 1 do -- нейроны в слое self.dw[1][tmpn][tmpi] = (data[tmpi] * self.e * self.delta[1][tmpn] * (1 - self.im)) + (self.im * self.dw[1][tmpn][tmpi]) self.w[1][tmpn][tmpi] = self.w[1][tmpn][tmpi] + self.dw[1][tmpn][tmpi] end end --Остальные слои for tmpl = 2, self.layers, 1 do for tmpn = 1, self.neyrons, 1 do self.dw[tmpl][tmpn][self.neyrons + 1] = (self.e * self.delta[tmpl][tmpn] * (1 - self.im)) + (self.im * self.dw[tmpl][tmpn][self.neyrons + 1]) self.w[tmpl][tmpn][self.neyrons + 1] = self.w[tmpl][tmpn][self.neyrons + 1] + self.dw[tmpl][tmpn][self.neyrons + 1] for tmpi = 1, self.neyrons, 1 do --нейроны в слое self.dw[tmpl][tmpn][tmpi] = (self.nout[tmpl-1][tmpi] * self.e * self.delta[tmpl][tmpn] * (1 - self.im)) + (self.im * self.dw[tmpl][tmpn][tmpi]) self.w[tmpl][tmpn][tmpi] = self.w[tmpl][tmpn][tmpi] + self.dw[tmpl][tmpn][tmpi] end end end -- Выходной слой из одного нейрона self.dw[self.layers+1][1][self.neyrons + 1] = (self.e * self.delta[self.layers + 1][1] * (1 - self.im)) + (self.im * self.dw[self.layers + 1][1][self.neyrons + 1]) self.w[self.layers+1][1][self.neyrons + 1] = self.w[self.layers + 1][1][self.neyrons + 1] + self.dw[self.layers + 1][1][self.neyrons + 1] for tmpi = 1, self.neyrons, 1 do -- нейроны в слое self.dw[self.layers + 1][ 1][tmpi] = (self.nout[self.layers][tmpi] * self.e * self.delta[self.layers + 1][1] * (1 - self.im)) + (self.im * self.dw[self.layers + 1][1][tmpi]) self.w[self.layers + 1][1][tmpi] = self.w[self.layers + 1][1][tmpi] + self.dw[self.layers + 1][1][tmpi] end end function NeuralNetwork.Play(self, tick_data) -- Принятие решения local l local n local i for l = 1, self.layers, 1 do -- проход по всем слоям, 1 - входной слой for n = 1, self.neyrons, 1 do local mmax if (l==1) then --входной слой self.nout[l][n]=1*self.w[l][n][self.inputs+1] --W0 последний mmax=self.inputs else self.nout[l][n]=1*self.w[l][n][self.neyrons+1] --W0 последний mmax=self.neyrons end for i = 1, mmax, 1 do if (l==1) then --входной слой self.nout[l][n]=self.nout[l][n]+(tick_data[i]*self.w[l][n][i]) --W0 последний else self.nout[l][n]=self.nout[l][n]+(self.nout[l-1][i]*self.w[l][n][i]) --W0 последний end end self.nout[l][n]=sigmoda(self.nout[l][n], self.k) end end --Выходной нейрон self.nout[self.layers+1]=self.w[self.layers+1][1][self.neyrons+1] --W0 for i = 1, self.neyrons, 1 do self.nout[self.layers+1]=self.nout[self.layers+1]+(self.nout[self.layers][i]*self.w[self.layers+1][1][i]) end return sigmoda(self.nout[self.layers+1], self.k) end function dsigmoda(x, k) local r r = k * x * (1 - x) return r end function sigmoda(x, k) local r r = 1 / (1 + math.exp(-x * k)) return r end function table_copy(originalTable) local copyTable = {} for k,v in pairs(originalTable) do if (type(v)=="table") then copyTable[k]=table_copy(v) else copyTable[k] = v end end return copyTable end |
Пример:
Код |
---|
--Обучающие данные local TrainingData={} for i=1, 100, 1 do local d1=math.random() -- Обучающие данные local d2=math.random() -- Обучающие данные local result=0 -- Правильный ответ if (d1>d2) then result=1 end local td={d1, d2, result} TrainingData[#TrainingData+1]=td end --Обучение local nn=NeuralNetwork.new(2, 3, 3) for age=1, 100, 1 do -- Эпохи for i=1, #TrainingData, 1 do local td=TrainingData[i] nn:Training(td, td[#td]) end end --Проверка local d1=math.random() local d2=math.random() td={d1, d2} local result=nn:Play(td) PrintDbgStr(d1.." "..d2.." "..result) --Сохраним обученную нейронку fn=getScriptPath().."\\test.nn" nn:Save(fn) |