0 people like it.

Basic Feed-Forward Neural network (without training code)

Basic Feed-Forward Neural network build, compute result & error functions. Tested with crude random search training to generalize XOR. (https://gist.github.com/ideaflare/c0b2cb2d96e76b72ca7937cc188f579b)

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
//------------------------------- Create Network ------------------------------- 
type Neuron  = { Weights : float  list ; Bias : float }
type Layer   = { Neurons : Neuron list }
type Network = { Layers  : Layer  list }

let rnd = System.Random()

let randomWeight _ = (2.0 * rnd.NextDouble()) - 1.0

let buildNeuron inputs =
    { Neuron.Weights = List.init inputs randomWeight ; Bias = randomWeight ()}

let buildLayer inputs neurons =
    { Layer.Neurons = List.init neurons (fun i -> buildNeuron inputs) }

let buildNetwork inputs layerSizes =
    let rec createLayers acc inputs layers =
        match layers with
        | [] -> acc
        | neurons :: nextSizes ->
            let newLayer = buildLayer inputs neurons
            createLayers (newLayer :: acc) neurons nextSizes
    { Network.Layers = List.rev (createLayers [] inputs layerSizes) }

//------------------------------- Compute Result ------------------------------- 
let activation x = System.Math.Tanh(x)

let neuronOutput neuron inputs =
    let weightedSum = 
        List.zip neuron.Weights inputs 
        |> List.sumBy (fun (w, i) -> w * i)
    activation (weightedSum + neuron.Bias)

let layerOutput layer inputs =
    layer.Neurons 
    |> List.map (fun neuron -> neuronOutput neuron inputs)

let feedForwardResult network inputs =
    let rec ff activationResult layers =
        match layers with
        | [] -> activationResult
        | layer :: remainingLayers -> 
            let nextLayerInput = layerOutput layer activationResult
            ff nextLayerInput remainingLayers 
    ff inputs network.Layers

//------------------------------- Compute Errors ------------------------------- 
type TrainingCase = { Inputs : float list; Outputs : float list }

let neuronError (expected, computed) =
    let error = expected - computed
    error * error

let layerError (expectedLastLayer, actualLastLayer) =
    List.zip actualLastLayer expectedLastLayer
    |> List.sumBy neuronError

let networkError network trainingCases =
    let expectedResults = trainingCases |> List.map (fun case -> case.Outputs)
    let networkResults  = trainingCases |> List.map (fun case -> feedForwardResult network case.Inputs)
    List.zip expectedResults networkResults
    |> List.sumBy layerError
Neuron.Weights: float list
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = System.Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
Neuron.Bias: float
type Layer =
  {Neurons: Neuron list;}

Full name: Script.Layer
Layer.Neurons: Neuron list
type Neuron =
  {Weights: float list;
   Bias: float;}

Full name: Script.Neuron
type Network =
  {Layers: Layer list;}

Full name: Script.Network
Network.Layers: Layer list
val rnd : System.Random

Full name: Script.rnd
namespace System
Multiple items
type Random =
  new : unit -> Random + 1 overload
  member Next : unit -> int + 2 overloads
  member NextBytes : buffer:byte[] -> unit
  member NextDouble : unit -> float

Full name: System.Random

--------------------
System.Random() : unit
System.Random(Seed: int) : unit
val randomWeight : 'a -> float

Full name: Script.randomWeight
System.Random.NextDouble() : float
val buildNeuron : inputs:int -> Neuron

Full name: Script.buildNeuron
val inputs : int
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member GetSlice : startIndex:int option * endIndex:int option -> 'T list
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val init : length:int -> initializer:(int -> 'T) -> 'T list

Full name: Microsoft.FSharp.Collections.List.init
val buildLayer : inputs:int -> neurons:int -> Layer

Full name: Script.buildLayer
val neurons : int
val i : int
val buildNetwork : inputs:int -> layerSizes:int list -> Network

Full name: Script.buildNetwork
val layerSizes : int list
val createLayers : (Layer list -> int -> int list -> Layer list)
val acc : Layer list
val layers : int list
val nextSizes : int list
val newLayer : Layer
val rev : list:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.rev
val activation : x:float -> float

Full name: Script.activation
val x : float
type Math =
  static val PI : float
  static val E : float
  static member Abs : value:sbyte -> sbyte + 6 overloads
  static member Acos : d:float -> float
  static member Asin : d:float -> float
  static member Atan : d:float -> float
  static member Atan2 : y:float * x:float -> float
  static member BigMul : a:int * b:int -> int64
  static member Ceiling : d:decimal -> decimal + 1 overload
  static member Cos : d:float -> float
  ...

Full name: System.Math
System.Math.Tanh(value: float) : float
val neuronOutput : neuron:Neuron -> inputs:float list -> float

Full name: Script.neuronOutput
val neuron : Neuron
val inputs : float list
val weightedSum : float
val zip : list1:'T1 list -> list2:'T2 list -> ('T1 * 'T2) list

Full name: Microsoft.FSharp.Collections.List.zip
val sumBy : projection:('T -> 'U) -> list:'T list -> 'U (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.List.sumBy
val w : float
val i : float
val layerOutput : layer:Layer -> inputs:float list -> float list

Full name: Script.layerOutput
val layer : Layer
val map : mapping:('T -> 'U) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
val feedForwardResult : network:Network -> inputs:float list -> float list

Full name: Script.feedForwardResult
val network : Network
val ff : (float list -> Layer list -> float list)
val activationResult : float list
val layers : Layer list
val remainingLayers : Layer list
val nextLayerInput : float list
type TrainingCase =
  {Inputs: float list;
   Outputs: float list;}

Full name: Script.TrainingCase
TrainingCase.Inputs: float list
TrainingCase.Outputs: float list
val neuronError : expected:float * computed:float -> float

Full name: Script.neuronError
val expected : float
val computed : float
val error : float
val layerError : expectedLastLayer:float list * actualLastLayer:float list -> float

Full name: Script.layerError
val expectedLastLayer : float list
val actualLastLayer : float list
val networkError : network:Network -> trainingCases:TrainingCase list -> float

Full name: Script.networkError
val trainingCases : TrainingCase list
val expectedResults : float list list
val case : TrainingCase
val networkResults : float list list

More information

Link:http://fssnip.net/7PF
Posted:3 years ago
Author:Christoph Alrich
Tags: machine learning , neural network