Create your own project with rebar3.
$ rebar3 new app yourapp
Then in your project path find rebar.config file and add nnet as dependency under the deps key:
{deps,
[
{nnet, {git, "https://github.com/BorjaEst/nnet.git", {tag, "<version>"}}}
]}.
Then using compile command, rebar3 will fetch the defined dependencies and compile them as well for your application.
$ rebar3 compile
At the end for making a release you first need to create your release structure and then making a release with following commands.
$ rebar3 new release yourrel
$ rebar3 release
You can find more information about dependencies in rebar3 - dependencies.
Load the app using your prefered method. For example in the project folder executing rebar3 shell:
$ rebar3 shell
===> Booted nnet
All user functions are defined inside the module src/nnet, however here is an example:
As library without OTP supervision tree, the best way to start is to ensure the tables are created.
1> nnet:start_tables().
ok
The function will not fail if the tables are already created and correct.
To create a network from a model it is very easy. Just create a map where each layer is a key (inputs & outputs are mandatory) and the values are:
- "connections": Type of connection and density between layers.
- "units": The amount of neurons on each layer.
- "data": The information on each node on each layer.
2> M = #{inputs => #{connections => #{
2> layer1 => sequential,
2> layer2 => {sequential,0.5}},
2> units => 2, data=>#{}},
2> layer1 => #{connections => #{
2> layer2 => sequential,
2> outputs => {sequential,0.5}},
2> units => 4, data=>#{}},
2> layer2 => #{connections => #{
2> layer2 => recurrent,
2> outputs => sequential},
2> units => 4, data=>#{}},
2> outputs => #{connections => #{
2> inputs => {recurrent, 0.5},
2> layer2 => recurrent},
2> units => 2, data=>#{}}}.
...
3> {atomic,Id} = mnesia:transaction(fun() -> nnet:from_model(M) end)
{atomic,{network,#Ref<0.1530882211.2808086529.180929>}}
Using the function nnet:to_map/1
you can retrieve the network data.
4> mnesia:transaction(fun() -> nnet:to_map(Id) end).
{atomic,#{{network,#Ref<0.1530882211.2808086529.180929>} =>
[{{network,#Ref<0.1530882211.2808086529.180929>},
{nnode,#Ref<0.1530882211.2808086529.180893>}},
{{network,#Ref<0.1530882211.2808086529.180929>},
{nnode,#Ref<0.1530882211.2808086529.180896>}}],
{nnode,#Ref<0.1530882211.2808086529.180893>} =>
[{{nnode,#Ref<0.1530882211.2808086529.180893>},
{nnode,#Ref<0.1530882211.2808086529.180899>}},
{{nnode,#Ref<0.1530882211.2808086529.180893>},
{nnode,#Ref<0.1530882211.2808086529.180902>}},
{{nnode,#Ref<0.1530882211.2808086529.180893>},
{nnode,#Ref<0.1530882211.2808086529.180905>}},
{{nnode,#Ref<0.1530882211.2808086529.180893>},
{nnode,#Ref<0.1530882211.2808086529.180908>}},
{{nnode,#Ref<0.1530882211.2808086529.180893>},
{nnode,#Ref<0.1530882211.2808086529.180911>}},
{{nnode,#Ref<0.1530882211.2808086529.180893>},
{nnode,#Ref<0.1530882211.2808086529.180914>}}],
...
{nnode,#Ref<0.1530882211.2808086529.180926>} =>
[{{nnode,#Ref<0.1530882211.2808086529.180926>},
{network,#Ref<0.1530882211.2808086529.180929>}}]}}
Note the network inputs are out(Network): Network -> NNode
Note the network outputs are in(Network): NNode -> Network
After a network is create, you can modify it using the functions:
%% NNode operations (run inside 'fun edit/1')
-export([rnode/1, wnode/2, rlink/1, wlink/2]).
-export([out/1, out_seq/1, out_rcc/1, in/1, lx/1]).
%% Connections operations (run inside 'fun edit/1')
-export([connect/1, connect_seq/1, connect_rcc/1, disconnect/1]).
-export([move/2, reset/1]).
%% Network operations (run inside 'fun edit/1')
-export([copy/2, clone/2, divide/2, split/2, delete/2, join/2]).
There is a secret (not so secret) module "umlnn" which prints/formats the neural network in UML format (components diagram). You can use the results of that function together with plantUML to display your nerwork.
To display the sequential connections use the output from: umlnn:print_seq(Network_id)
To display the recurrent connections use the output from: umlnn:print_rcc(Network_id)
Inside the module ./src/nnet.erl you will find the spec and comments for each function. Note that most of the functions are mnesia transactions therefore should run inside a mnesia:transaction/1
context.
For examples of usage you can take a look on the test suite ./test/nnet_SUITE.erl.
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
All ideas and sugestions are welcome:
This software is under GPL-3.0 license.