0 | module NN.Architectures.MLP
  1 |
  2 | import Data.Tensor
  3 | import Data.Para
  4 |
  5 | import NN.Architectures.Affine
  6 | import NN.Architectures.Activations
  7 |
  8 |
  9 | ||| N-layer multi-layer perceptron with a specified activation function,
 10 | ||| and flag for whether the last layer should have it
 11 | public export
 12 | multiLayerPerceptron : {a : Type} -> Num a =>
 13 |   {ieva : Axis} ->
 14 |   (allAlg : AllAlgebra [ieva] a) =>
 15 |   TensorMonoid ieva.cont =>
 16 |   (numLayers : Nat) ->
 17 |   (activation : Tensor [ieva] a -\-> Tensor [ieva] a) ->
 18 |   {default False lastLayerActivation : Bool} ->
 19 |   Tensor [ieva] a -\-> Tensor [ieva] a
 20 | multiLayerPerceptron 0 _ = id
 21 | multiLayerPerceptron 1 activation {lastLayerActivation = False}
 22 |   = affinePara
 23 | multiLayerPerceptron 1 activation {lastLayerActivation = True}
 24 |   = composePara affinePara activation
 25 | multiLayerPerceptron (S (S k)) activation
 26 |   = composePara (composePara affinePara activation) (multiLayerPerceptron (S k) activation {lastLayerActivation = lastLayerActivation})
 27 |
 28 |
 29 | -- public export
 30 | -- threeLayerPerceptron : {inputSize, outputSize : Nat} ->
 31 | --   AllConsistent [inName, outName] [Vect outputSize, Vect inputSize] =>
 32 | --   Tensor [inputSize] [inName] Double -\-> Tensor [outputSize] [outName] Double
 33 | -- threeLayerPerceptron =
 34 | --   let hiddenDimension1 = inputSize * 10
 35 | --       hiddenDimension2 = inputSize * 10
 36 | --   in     affinePara
 37 | --      \>> trivialParam Tensor.sigmoid
 38 | --      \>> affinePara {x=Vect hiddenDimension1}
 39 | --      \>> trivialParam Tensor.sigmoid
 40 | --      \>> affinePara {x=Vect hiddenDimension2}
 41 |
 42 |
 43 |
 44 |
 45 |
 46 | -- public export
 47 | -- inputTensor : Tensor [3] Double
 48 | -- inputTensor = ># [1, 2, 3]
 49 | -- 
 50 | -- 
 51 | -- public export
 52 | -- outputTensor : IO (Tensor [2] Double)
 53 | -- outputTensor = do
 54 | --   let pr = randomRIO {io=IO} {a=(Param (trivialParam Tensor.sigmoid) inputTensor)}
 55 | --   ?asdfasdf
 56 |
 57 |   {-
 58 | public export
 59 | mlpNonDependentPara : {a : Type} -> Num a =>
 60 |   {ieva : Cont} ->
 61 |   (allAlg : AllAlgebra [ieva] a) =>
 62 |   (allAppl : All TensorMonoid [ieva]) =>
 63 |   (numLayers : Nat) ->
 64 |   (activation : CTensor [ieva] a -> CTensor [ieva] a) ->
 65 |   {default False lastLayerActivation : Bool} ->
 66 |   IsNotDependent (multiLayerPerceptron numLayers (trivialParam activation) {lastLayerActivation = lastLayerActivation})
 67 | mlpNonDependentPara 0 activation = ?oqwi -- MkNonDep () (\t, _ => t)
 68 | mlpNonDependentPara 1 activation {lastLayerActivation = False}
 69 |   = MkNonDep (AffineLayerParams ieva ieva a)
 70 |     (\x, p => (Run (multiLayerPerceptron 1 (trivialParam activation) {lastLayerActivation = False})) x p)
 71 | mlpNonDependentPara 1 activation {lastLayerActivation = True} = ?wiii_1 -- MkNonDep ?ppp ?fff
 72 | mlpNonDependentPara (S k) activation = ?wiii_11 -- MkNonDep ?ppp ?fff
 73 |   -- = MkNonDep ?ppp ?fff
 74 |
 75 |
 76 |
 77 | public export
 78 | simpleNLayerNet : {features : Nat} -> (n : Nat) ->
 79 |   Tensor [features] Double -\-> Tensor [features] Double
 80 | simpleNLayerNet n = multiLayerPerceptron n (trivialParam sigmoid)
 81 |
 82 |
 83 | public export
 84 | exampleInput : Tensor [2] Double
 85 | exampleInput = ># [1, 5]
 86 |
 87 | public export
 88 | exampleParam : Tensor [2, 2] Double
 89 | exampleParam = ># [ [0.4, 0.2]
 90 |                   , [0.7, -3]]
 91 |
 92 | public export
 93 | exampleBias : Tensor [2] Double
 94 | exampleBias = ># [0, 0]
 95 |
 96 | public export
 97 | layerParam : AffineLayerParams (Vect 2) (Vect 2) Double
 98 | layerParam = MkParams exampleParam exampleBias
 99 |
100 | public export
101 | exampleOutput : Tensor [2] Double
102 | exampleOutput = Run (simpleNLayerNet 2) exampleInput
103 |   ((layerParam ** ()) ** layerParam)
104 |