0 people like it.
Like the snippet!
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