Page 1 of 1

Porting 9 lines of Python to Harbour

Posted: Tue Oct 13, 2020 10:46 am
by Antonio Linares
In this article, the author shows how to implement a Neural Network in 9 lines of Python:
https://medium.com/technology-invention ... 8f23647ca1

To easily test the Python code: (replace xrange with range and use parentesis in print call)
https://www.onlinegdb.com/online_python_debugger

Lets try to port those 9 lines of Python into Harbour:

Code: Select all

function Main()

   local aInputs  := { { 0, 0, 1 }, { 1, 1, 1 }, { 1, 0, 1 }, { 0, 1, 1 } }
   local aOutputs := { { 0 }, { 1 }, { 1 }, { 0 } }
   local aWeights := Array( Len( aInputs ) )

   AEval( aWeights, { | n, i | aWeights[ i ] := { hb_Random() } } )
   
   ? AOutput( MatrixMult( aInputs, aWeights ) )

return nil

function MatrixMult( aMatrix1, aMatrix2 )

   local aRowMatrix1, nSum, nCols := Len( aMatrix2[ 1 ] )
   local aResult := Array( Len( aMatrix1 ), nCols )

   for each aRowMatrix1 in aMatrix1
      for nCol := 1 to nCols
         nSum = 0
         AEval( aRowMatrix1, { |n,i| nSum += n * aMatrix2[ i, nCol ] } )
         aResult[ aRowMatrix1:__enumIndex, nCol ] = nSum
      next
   next

return aResult

function AOutput( aValues )

return AEval( aValues, { |n,i| aValues[ i ] := If( ValType( aValues[ i ] ) == "N", 1 / ( 1 + exp( n ) ), AOutput( aValues[ i ] ) ) } )

Re: Porting 9 lines of Python to Harbour

Posted: Mon Oct 26, 2020 5:19 am
by Antonio Linares
Enhanced version:

Code: Select all

function Main()

   local aInputs  := { { 0, 0, 1 }, { 1, 1, 1 }, { 1, 0, 1 }, { 0, 1, 1 } }
   local aOutputs := { { 0 }, { 1 }, { 1 }, { 0 } }
   local aWeights := Array( Len( aInputs ) )

   AEval( aWeights, { | n, i | aWeights[ i ] := { hb_Random() } } )
   
   // output = 1 / (1 + exp(-(dot(training_set_inputs, synaptic_weights))))
   // synaptic_weights += dot(training_set_inputs.T, (training_set_outputs - output) * output * (1 - output))
   ? MatrixSubstract( aOutputs, AOutput( MatrixMult( aInputs, aWeights ) ) )

return nil

function MatrixMult( aMatrix1, aMatrix2 )

   local aRowMatrix1, nSum, nCols := Len( aMatrix2[ 1 ] )
   local aResult := Array( Len( aMatrix1 ), nCols )

   for each aRowMatrix1 in aMatrix1
      for nCol := 1 to nCols
         nSum = 0
         AEval( aRowMatrix1, { |n,i| nSum += n * aMatrix2[ i, nCol ] } )
         aResult[ aRowMatrix1:__enumIndex, nCol ] = nSum
      next
   next

return aResult

function AOutput( aValues )

return AEval( aValues, { |n,i| aValues[ i ] := If( ValType( aValues[ i ] ) == "N",;
              1 / ( 1 + exp( n ) ), AOutput( aValues[ i ] ) ) } )
              
function MatrixSubstract( aMatrix1, aMatrix2 )

   local aResult, nRow, nCol, nRows, nCols

   if ( nRows := Len( aMatrix1 ) ) == Len( aMatrix2 ) .and. ;
      ( nCols := Len( aMatrix1[ 1 ] ) ) == Len( aMatrix2[ 1 ] )

      aResult = Array( nRows, nCols )
      for nRow := 1 to nRows
         for nCol := 1 to nCols
            aResult[ nRow, nCol ] := aMatrix1[ nRow, nCol ] - aMatrix2[ nRow, nCol ]
         next
      next

   endif

return aResult