Нейросеть на LUA

Страницы: 1
RSS
Нейросеть на LUA, Нейронная сеть на 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)


 
Цитата
Сергей написал:
Всем привет.
Сделал нейронку на LUA. Может кому пригодится:
что-то не вижу обратного распространения ошибки.
Ткните в строку, плиз.
 
Цитата
Сергей написал:
Ткните в строку, плиз.
В NeuralNetwork.Training первые строки до коммента "--Теперь правим веса": ошибки(delta) собираются в обратной порядке: выходной слой, далее остальные(for tmpl =self.layers-1, 1, -1 do -- слои) до первого.
 
Цитата
Сергей написал:
Цитата
Сергей написал:
Ткните в строку, плиз.
В NeuralNetwork.Training первые строки до коммента "--Теперь правим веса": ошибки(delta) собираются в обратной порядке: выходной слой, далее остальные(for tmpl =self.layers-1, 1, -1 do -- слои) до первого.
Можете привести оценку скорости обучения для каких либо примеров и сравнение скорости например с факелом.
--------------------------
Я сделал обертку для Lua библиотеки  fastNet на СИ, но  для акций ее так и не применил,
так как использую бинарную сеть, для которой не нашел алгоритма оптимизации.
 
 
Спасибо за код.
Будет время попробую.
 
Цитата
nikolz написал:
Можете привести оценку скорости обучения для каких либо примеров и сравнение скорости например с факелом.
Я пока сравнивал только с такой же нейронкой на C#. На шарпе сильно медленней работает. Скорость и качество обучения зависит от параметра "e". Сейчас эксперементирую с изменением "е" во время обучения в зависимосит от средней квадратической ошибки.
Страницы: 1
Читают тему
Наверх