anchor.diff:      {layers = Array.init (l.Length - 1) (fun i ->
           {W = Mat.init l.[i + 1] l.[i] (fun _ _ -> -0.5 + rnd.NextDouble())
            b = Vec.init l.[i + 1] (fun _ -> -0.5 + rnd.NextDouble())
  -         a = sigmoid})}
  +         a = (fun t -> t.sigmoid())})}
   (**
   
   This gives us an easily scalable feedforward network architecture capable of expressing any number of inputs, outputs, and hidden layers. The network is fully connected, meaning that each neuron in a layer receives the output of all the neurons in the previous layer.
  
positive.code: let net2 = createNetwork [|2; 1|]
  
  // Train
  let train2 = backprop net2 0.9 1000 ORx ORy
  
  // Plot the error during training
  Chart.Line train2
  
  (**
  
  
negative.code: // x: training input vectors
  // y: training target vectors
  let backprop (n:Network) eta epochs (x:Vec[]) (y:Vec[]) =
      dsharp.nest()
      let i = dsharp.nestLevel()
      seq {for j in 0 .. epochs do
              for l in n.layers do
                  l.W <- l.W.reverseDiff i
                  l.b <- l.b.reverseDiff i
  
              let L = Array.map2 (fun x y -> Vec.l2normSq (y - runNetwork x n)) x y |> Array.sum
              L |> dsharp.reversePush (v 1.) // Propagate adjoint value 1 backward
  
              for l in n.layers do
                  l.W <- dsharp.primal (l.W.primal - eta * l.W.derivative)
                  l.b <- dsharp.primal (l.b.primal - eta * l.b.derivative)
  
              printfn "Iteration %i, loss %f" j (float L)
              yield float L}
  