All pastes #440774 Raw Edit

Anonymous

public lua v1 · immutable
·published 2007-04-15 08:49 UTC
rendered paste body
-- Neural Network Layer.NNLayer = {};-- Init.function NNLayer:init( parent, child )    -- Variables.    self.values = {};    self.desired = {};    self.errors = {};    -- Save parent/child layer.    self.parent = parent;    self.child = child;    -- If we have a child, init weights.    if( child ) then        -- Init weights tables.        self.weights = {};        for i = 1, self.nodes do            self.weights[i] = {};        end        -- Init bias values.        self.bias_weights = {};    end    -- Init information    for i = 1, self.nodes do        -- Zero out values, errors, desired values.        self.values[i] = 0;        self.desired[i] = 0;        self.errors[i] = 0;        -- Seed the generator.        math.randomseed( _CurTime() );        -- If we have a child, init it too.        if( child ) then            for j = 1, child.nodes do                -- Randommize weights.                self.weights[i][j] = math.random() * 2 - 1;                self.bias_weights[j] = math.random() * 2 - 1;            end        end    endend-- New layer.function NNLayer:new( nodes )    -- Init object.    local obj = {};    setmetatable( obj, self );    self.__index = self;    -- Nodes.    obj.nodes = nodes;    -- Return object.    return obj;end-- Calculate neuron values.function NNLayer:calcValues( )    if( self.parent ) then        for j = 1, self.nodes do            -- Activation.            local x = 0;            for i = 1, self.parent.nodes do                x = x + self.parent.values[i] * self.parent.weights[i][j];            end            x = x + 1 * self.parent.bias_weights[j];            -- Run sigmoid filter.            self.values[j] = 1 / ( 1 + math.exp( -x ) );        end    endend-- Calculate errors.function NNLayer:calcErrors( )    if( not self.child ) then        -- Output layer.        for i = 1, self.nodes do            self.errors[i] = ( self.desired[i] - self.values[i] ) * self.values[i] * ( 1 - self.values[i] );        end    elseif( not self.parent ) then        -- No errors, input layer.        for i = 1, self.nodes do            self.errors[i] = 0;        end    else        -- Hidden layer.        for i = 1, self.nodes do            local sum = 0;            for j = 1, self.child.nodes do                sum = sum + self.child.errors[j] * self.weights[i][j];            end            self.errors[i] = sum * self.values[i] * ( 1 - self.values[i] );        end    endend-- Adjust weights.function NNLayer:adjustWeights( )    local t = 0;    if( self.child ) then        for i = 1, self.nodes do            for j = 1, self.child.nodes do                t = 0.33 * self.child.errors[j] * self.values[i];                self.weights[i][j] = self.weights[i][j] + t;            end        end        for i = 1, self.child.nodes do            self.bias_weights[i] = self.bias_weights[i] + 0.33 * self.child.errors[i] * 1;        end    endend-- Neural Network.NNetwork = {};-- New.function NNetwork:new( input, hidden, layers, output )    -- Create object.    local obj = {};    setmetatable( obj, self );    self.__index = self;    -- Need at least 1 hidden layer.    if( layers < 1 ) then        layers = 1;    end    -- Create the layers.    local inLayer = NNLayer:new( input );    -- Create the hidden layers.    local hiddenLayers = {};    for i = 1, layers do        hiddenLayers[i] = NNLayer:new( hidden );    end    local outLayer = NNLayer:new( output );    -- Init the layers.    inLayer:init( nil, hiddenLayers[1] );    -- Attach hidden layers.    if( table.getn( hiddenLayers ) == 1 ) then        -- Just link directly with the output layer.        hiddenLayers[1]:init( inLayer, outLayer );        -- Setup output.        outLayer:init( hiddenLayers[1], nil );    else        -- Link with the next hidden layer.        hiddenLayers[1]:init( inLayer, hiddenLayers[2] );        -- Loop through rest.        for i = 2, table.getn( hiddenLayers ) - 1 do            hiddenLayers[i]:init( hiddenLayers[ i - 1 ], hiddenLayers[ i + 1 ] );        end        -- Link last hidden layer to output layer.        hiddenLayers[ table.getn( hiddenLayers ) ]:init( hiddenLayers[ table.getn( hiddenLayers ) - 1 ], outLayer );        -- Setup output.        outLayer:init( hiddenLayers[ table.getn( hiddenLayers ) ], nil );    end    -- Save layers.    obj.inLayer = inLayer;    obj.hiddenLayers = hiddenLayers;    obj.outLayer = outLayer;    -- Return object.    return obj;end-- Set input.function NNetwork:setInput( node, val )    self.inLayer.values[node] = val;end-- Get output.function NNetwork:getOutput( node )    return self.outLayer.values[node];end-- Set desired output.function NNetwork:setDesiredOutput( node, val )    self.outLayer.desired[node] = val;end-- Feed forward.function NNetwork:feedForward( )    -- Input.    self.inLayer:calcValues();    -- Run hidden layers.    for i = 1, table.getn( self.hiddenLayers ) do        self.hiddenLayers[i]:calcValues();    end    -- Output.    self.outLayer:calcValues();end-- Back propagate.function NNetwork:backPropagate( )    -- Output.    self.outLayer:calcErrors();    -- Hidden.    local i = table.getn( self.hiddenLayers );    while( i >= 1 ) do        self.hiddenLayers[i]:calcErrors();        i = i - 1;    end    -- Hidden Adjust    i = table.getn( self.hiddenLayers );    while( i >= 1 ) do        self.hiddenLayers[i]:adjustWeights();        i = i - 1;    end    -- Input adjust.    self.inLayer:adjustWeights();end-- Calculate error.function NNetwork:calculateError( )    local err = 0;    for i = 1, self.outLayer.nodes do        err = err + math.pow( self.outLayer.values[i] - self.outLayer.desired[i], 2 );    end    err = err / self.outLayer.nodes;    return err;end-- Save network.function NNetwork:saveNetwork( filename )    local data = "";    -- Create the weight tables.    data = data .. "InputWeights    =   {};\r\n";    data = data .. "HiddenWeights   =   {};\r\n";    -- Create the bias tables.    data = data .. "InputBiasWeights    =   {};\r\n";    data = data .. "HiddenBiasWeights   =   {};\r\n\r\n";    -- Save input weights.    for i = 1, self.inLayer.nodes do        data = data .. "InputWeights[" .. i .. "]   =   {};\r\n";        for j = 1, self.inLayer.child.nodes do            data = data .. "InputWeights[" .. i .. "][" .. j .. "] = " .. self.inLayer.weights[i][j] .. ";\r\n";        end    end    -- Empty line.    data = data .. "\r\n";    -- Save hidden weights.    for i = 1, table.getn( self.hiddenLayers ) do        data = data .. "HiddenWeights[" .. i .. "]  =   {};\r\n";        for j = 1, self.hiddenLayers[i].nodes do            data = data .. "HiddenWeights[" .. i .. "][" .. j .. "]   =   {};\r\n";            for k = 1, self.hiddenLayers[i].child.nodes do                data = data .. "HiddenWeights[" .. i .. "][" .. j .. "][" .. k .. "] = " .. self.hiddenLayers[i].weights[j][k] .. ";\r\n";            end        end    end    -- Empty line.    data = data .. "\r\n";    -- Save input bias weights.    for j = 1, self.inLayer.child.nodes do        data = data .. "InputBiasWeights[" .. j .. "] = " .. self.inLayer.bias_weights[j] .. ";\r\n";    end    -- Empty line.    data = data .. "\r\n";    -- Save hidden bias weights.    for i = 1, table.getn( self.hiddenLayers ) do        data = data .. "HiddenBiasWeights[" .. i .. "]  =   {};\r\n";        for k = 1, self.hiddenLayers[i].child.nodes do            data = data .. "HiddenBiasWeights[" .. i .. "][" .. k .. "] = " .. self.hiddenLayers[i].bias_weights[k] .. ";\r\n";        end    end    -- Write to file    _file.Write( filename, data );end-- Load network.function NNetwork:loadNetwork( filename )    _RunString( _file.Read( filename ) );    -- Restore input weights.    self.inLayer.weights = InputWeights;    self.inLayer.bias_weights = InputBiasWeights;    -- Restore hidden weights.    for i = 1, table.getn( HiddenWeights ) do        self.hiddenLayers[i].weights = HiddenWeights[i];        self.hiddenLayers[i].bias_weights = HiddenBiasWeights[i];    endend