0.1.1 • Published 6 months ago

rescript-perceptron-ml v0.1.1

Weekly downloads
-
License
MIT
Repository
-
Last release
6 months ago

rescript-perceptron-ml

Perceptron realization on rescript

Example of usage

open MlErrorMetricFunction
open MlActivationFunction
open MlPerceptronLayer
open MlPerceptron
open MlPerceptronRunner
open Belt

module L1Count: LayerCount = {
  let layerCount = 10
}
module L2Count: LayerCount = {
  let layerCount = 4
}
module L3Count: LayerCount = {
  let layerCount = 1
}

//It's layers built from array of k-th count with assertion - easiest way to create a layer
module L1 = MakePerceptronLayerLimitedArr(L1Count)
module L2 = MakePerceptronLayerLimitedArr(L2Count)
module L3 = MakePerceptronLayerLimitedArr(L3Count)

module RecognizerPerceptron = MakePerceptron3(L1, L2, L3, ActivFuncSigmoid, ErrorMetricEuclidean)
module RecognizerPerceptronRunner = MakePerceptronRunner(RecognizerPerceptron)

//This 3-layers perceptron will start with random weights it will get on input array kind
//of [0, ... 0, 1, 0, ... 0] where [n]th elements is 1, all other is 0.
//It will studed to recognize arrays with 3th and 7th elem is = 1
let weightsStart = RecognizerPerceptron.init((_, _, _) => Js.Math.random() *. 3.0 -. 1.5)
let datarowBuilder = () => {
  let emptyInp = Array.range(0, 9)
  let dig = Js.Math.floor_int(Js.Math.random() *. 10.0)
  let inp =
    emptyInp->Array.mapWithIndex((i, _) => i == dig ? 1.0 : 0.0)->L1.arrToLayer->Result.getExn
  {
    i: inp,
    o: [dig == 3 || dig == 7 ? 1.0 : 0.0]->L3.arrToLayer->Result.getExn,
  }
}
let weightsFinal = //correct recognizing arrays perceptron's weights
  RecognizerPerceptronRunner.studeMass(datarowBuilder, weightsStart, 0.01, 100000)->Result.getExn
//Test that asserts same perceptron studes correctly placed in module MlPerceptronRunnerTest

API

MlActivationFunction.resi

Modules provides activation functions for neurons

module type ActivFunc = {
  let solve: float => float
  let derivative: float => float
}

//Sigmoid AF
module ActivFuncSigmoid: ActivFunc

//ReLU AF
module ActivFuncReLU: ActivFunc

//Hyperbolic tangens AF
module ActivFuncTh: ActivFunc

MlErrorMetricFunction

Module provides error-metric functions for perceptron's output

module type ErrorMetric = {
  type errVal //its a float, but essense into special type for user not confused it with input or solution

  let errToFloat: errVal => float
  let floatToErr: float => errVal
  let errMetricDerivative: (float, float) => errVal
}

module ErrorMetricEuclidean: ErrorMetric

MlPerceptronLayer.resi

module provides perceptron layers and layers-cross descriptions

open MlActivationFunction
open MlErrorMetricFunction

type activFuncValue = {
  solve: float,
  derivative: float,
}

module type PerceptronLayer = {
  type layer<'a>

  let layerToArr: layer<'a> => array<'a>
  let arrToLayer: array<'a> => result<layer<'a>, exn>
  let init: (int => 'a) => layer<'a>
}

module type LayerCount = {
  let layerCount: int
}

module type PerceptronLayersCross = {
  type layer1<'a>
  type layer2<'a>
  type weights = layer1<layer2<float>>
  type errVal

  let input: layer1<float> => result<layer1<activFuncValue>, exn>
  let solve: (layer1<activFuncValue>, weights) => result<layer2<activFuncValue>, exn>
  let findError: (layer2<activFuncValue>, layer2<float>) => result<layer2<errVal>, exn>
  let backpropagadeError: (
    layer1<activFuncValue>,
    layer2<errVal>,
    weights,
  ) => result<layer1<errVal>, exn>
  let weightCorrection: (
    layer1<activFuncValue>,
    layer2<errVal>,
    weights,
    float,
  ) => result<weights, exn>
  let init: ((int, int) => float) => weights
}

module type MakePerceptronLayerLimitedArr = (LayerCount: LayerCount) => PerceptronLayer

exception InvalidCountOfLayerElements

module MakePerceptronLayerLimitedArr: MakePerceptronLayerLimitedArr

module type MakePerceptronLayersCross = (
  Layer1: PerceptronLayer,
  Layer2: PerceptronLayer,
  F: ActivFunc,
  Err: ErrorMetric,
) =>
(
  PerceptronLayersCross
    with type layer1<'a> = Layer1.layer<'a>
    and type layer2<'a> = Layer2.layer<'a>
    and type errVal = Err.errVal
)

exception WeightsLayerHasNoZeroElement

module MakePerceptronLayersCross: MakePerceptronLayersCross

MlPerceptron.resi

Module provides perceptron interface and 3-layers and 4-layers ready perceptron realizations

open MlPerceptronLayer
open MlActivationFunction
open MlErrorMetricFunction

module type Perceptron = {
  type input<'a>
  type output<'a>
  type weights

  let solve: (input<float>, weights) => result<output<float>, exn>
  let stude: (input<float>, output<float>, weights, float) => result<weights, exn>
  let init: ((int, int, int) => float) => weights
}

type w2<'a, 'b> = W('a, 'b)

module type MakePerceptron3 = (
  L1: PerceptronLayer,
  L2: PerceptronLayer,
  L3: PerceptronLayer,
  AF: ActivFunc,
  EM: ErrorMetric,
) =>
(
  Perceptron
    with type input<'a> = L1.layer<'a>
    and type output<'a> = L3.layer<'a>
    and type weights = w2<L1.layer<L2.layer<float>>, L2.layer<L3.layer<float>>>
)

module MakePerceptron3: MakePerceptron3

type w3<'a, 'b, 'c> = W('a, 'b, 'c)

module type MakePerceptron4 = (
  L1: PerceptronLayer,
  L2: PerceptronLayer,
  L3: PerceptronLayer,
  L4: PerceptronLayer,
  AF: ActivFunc,
  EM: ErrorMetric,
) =>
(
  Perceptron
    with type input<'a> = L1.layer<'a>
    and type output<'a> = L4.layer<'a>
    and type weights = w3<
      L1.layer<L2.layer<float>>,
      L2.layer<L3.layer<float>>,
      L3.layer<L4.layer<float>>,
    >
)

module MakePerceptron4: MakePerceptron4

MlPerceptronRunner.resi

Runs bulk stude of checking for perceptron

open MlPerceptron

type datarow<'i, 'o> = {i: 'i, o: 'o}
type datacompars<'o, 'n> = {o: 'o, n: 'n}

module type PerceptronRunner = {
  type input<'a>
  type output<'a>
  type weights

  let checkMass: (
    unit => datarow<input<float>, output<float>>,
    weights,
    int,
  ) => result<array<datacompars<output<float>, output<float>>>, exn>

  let studeMass: (
    unit => datarow<input<float>, output<float>>,
    weights,
    float,
    int,
  ) => result<weights, exn>
}

module type MakePerceptronRunner = (P: Perceptron) =>
(
  PerceptronRunner
    with type input<'a> = P.input<'a>
    and type output<'a> = P.output<'a>
    and type weights = P.weights
)

exception CountShouldBeGreaterThenZero

module MakePerceptronRunner: MakePerceptronRunner

Author

Anatoly Starodubtsev tostar74@mail.ru

License

MIT

0.1.1

6 months ago

0.0.1

7 months ago