{"id":15249530,"url":"https://github.com/mrdimosthenis/gleam_synapses","last_synced_at":"2026-01-02T05:04:19.354Z","repository":{"id":53490632,"uuid":"348694503","full_name":"mrdimosthenis/gleam_synapses","owner":"mrdimosthenis","description":"A plug-and-play library for neural networks written in Gleam","archived":false,"fork":false,"pushed_at":"2024-09-26T17:02:19.000Z","size":1931,"stargazers_count":33,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-23T01:04:16.231Z","etag":null,"topics":["deep-learning","deep-neural-networks","deeplearning","functional-programming","gleam","gleam-lang","machine-learning","neural-network","neural-networks"],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/gleam_synapses/","language":"Gleam","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrdimosthenis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-17T12:05:15.000Z","updated_at":"2025-02-22T17:34:38.000Z","dependencies_parsed_at":"2022-08-19T11:21:15.118Z","dependency_job_id":null,"html_url":"https://github.com/mrdimosthenis/gleam_synapses","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrdimosthenis%2Fgleam_synapses","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrdimosthenis%2Fgleam_synapses/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrdimosthenis%2Fgleam_synapses/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrdimosthenis%2Fgleam_synapses/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrdimosthenis","download_url":"https://codeload.github.com/mrdimosthenis/gleam_synapses/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243538121,"owners_count":20307101,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deep-learning","deep-neural-networks","deeplearning","functional-programming","gleam","gleam-lang","machine-learning","neural-network","neural-networks"],"created_at":"2024-09-29T15:01:29.873Z","updated_at":"2026-01-02T05:04:19.295Z","avatar_url":"https://github.com/mrdimosthenis.png","language":"Gleam","funding_links":[],"categories":["Packages"],"sub_categories":["Machine Learning"],"readme":"# gleam_synapses\n\nA plug-and-play library for **neural networks** written in **Gleam**!\n\n## Basic usage\n\n### Install synapses\n\nRun `gleam add gleam_synapses` in the directory of your project.\n\n### Import the `Net` module\n\n```gleam\nimport gleam_synapses/net.{type Net}\n```\n\n### Create a random neural network by providing its layer sizes\n\n```gleam\nlet rand_net = net.new([2, 3, 1])\n```\n\n* Input layer: the first layer of the network has 2 nodes.\n* Hidden layer: the second layer has 3 neurons.\n* Output layer: the third layer has 1 neuron.\n\n### Get the json of the random neural network\n\n```gleam\nnet.to_json(rand_net)\n// \"[\n//   [{\\\"activationF\\\" : \\\"sigmoid\\\", \\\"weights\\\" : [-0.5,0.1,0.8]},\n//    {\\\"activationF\\\" : \\\"sigmoid\\\", \\\"weights\\\" : [0.7,0.6,-0.1]},\n//    {\\\"activationF\\\" : \\\"sigmoid\\\", \\\"weights\\\" : [-0.8,-0.1,-0.7]}],\n//   [{\\\"activationF\\\" : \\\"sigmoid\\\", \\\"weights\\\" : [0.5,-0.3,-0.4,-0.5]}]\n// ]\"\n```\n\n\n### Create a neural network by providing its json\n\n```gleam\nlet network = net.from_json(\"[\n   [{\\\"activationF\\\" : \\\"sigmoid\\\", \\\"weights\\\" : [-0.5,0.1,0.8]},\n    {\\\"activationF\\\" : \\\"sigmoid\\\", \\\"weights\\\" : [0.7,0.6,-0.1]},\n    {\\\"activationF\\\" : \\\"sigmoid\\\", \\\"weights\\\" : [-0.8,-0.1,-0.7]}],\n   [{\\\"activationF\\\" : \\\"sigmoid\\\", \\\"weights\\\" : [0.5,-0.3,-0.4,-0.5]}]\n ]\")\n```\n\n### Make a prediction\n\n```gleam\nnet.predict(network, [0.2, 0.6])\n// [0.49131100324012494]\n```\n\n### Train a neural network\n\n```gleam\nnet.fit(network, 0.1, [0.2, 0.6], [0.9])\n```\n\nThe `fit` method returns the neural network with its weights adjusted to a single observation.\n\n## Advanced usage\n\n### Fully train a neural network\n\nIn practice, for a neural network to be fully trained, it should be fitted with multiple observations, usually by folding over an iterator.\n\n```gleam\n[#([0.2, 0.6], [0.9]),\n #([0.1, 0.8], [0.2]),\n #([0.5, 0.4], [0.6])]\n|\u003e iterator.from_list\n|\u003e iterator.fold(network, fn(acc, t) {\n  let #(xs, ys) = t\n  net.fit(acc, 0.1, xs, ys)\n})\n```\n\n### Boost the performance\n\nEvery function is efficient because its implementation is based on lazy list\nand all information is obtained at a single pass.\n\nFor a neural network that has huge layers, the performance can be further improved\nby using the parallel counterparts of `predict` and `fit` (`par_predict` and `par_fit`).\n\n### Create a neural network for testing\n\n```gleam\nnet.new_with_seed([2, 3, 1], 1000)\n```\n\nWe can provide a `seed` to create a non-random neural network.\nThis way, we can use it for testing.\n\n### Define the activation functions and the weights\n\n```gleam\nimport gleam_synapses/fun.{type Fun}\nimport gleam/float\n\nlet activation_f = fn(layer_index: Int) -\u003e Fun {\n  case layer_index {\n    0 -\u003e fun.sigmoid()\n    1 -\u003e fun.identity()\n    2 -\u003e fun.leaky_re_lu()\n    3 -\u003e fun.tanh()\n  }\n}\n\nlet weight_init_f = fn(_: Int) -\u003e Float {\n  float.random(0.0, 1.0)\n}\n\nlet custom_net = net.new_custom([4, 6, 8, 5, 3], activation_f, weight_init_f)\n```\n\n* The `activation_f` function accepts the index of a layer and returns an activation function for its neurons.\n* The `weight_init_f` function accepts the index of a layer and returns a weight for the synapses of its neurons.\n\nIf we don't provide these functions, the activation function of all neurons is sigmoid,\nand the weight distribution of the synapses is normal between -1.0 and 1.0.\n\n### Draw a neural network\n\n```gleam\nnet.to_svg(custom_net)\n```\n\n![Network Drawing](https://github.com/mrdimosthenis/gleam_synapses/blob/master/readme_resources/network-drawing.png?raw=true)\n\nWith its svg drawing, we can see what a neural network looks like.\nThe color of each neuron depends on its activation function\nwhile the transparency of the synapses depends on their weight.\n\n### Measure the difference between the expected and predicted values\n\n```gleam\nimport gleam_synapses/stats\n\nfn exp_and_pred_vals() -\u003e Iterator(#(List(Float), List(Float))) {\n  [\n    #([0.0, 0.0, 1.0], [0.0, 0.1, 0.9]),\n    #([0.0, 1.0, 0.0], [0.8, 0.2, 0.0]),\n    #([1.0, 0.0, 0.0], [0.7, 0.1, 0.2]),\n    #([1.0, 0.0, 0.0], [0.3, 0.3, 0.4]),\n    #([0.0, 0.0, 1.0], [0.2, 0.2, 0.6])\n  ]\n  |\u003e iterator.from_list\n}\n```\n\n* Root-mean-square error\n\n```gleam\nstats.rmse(exp_and_pred_vals())\n// 0.6957010852370435\n```\n\n* Classification accuracy score\n\n```gleam\nstats.score(exp_and_pred_vals())\n// 0.6\n```\n\n### Import the `Codec` module\n\n```gleam\nimport gleam_synapses/codec.{type Codec}\n```\n\n* One hot encoding is a process that turns discrete attributes into a list of 0.0 and 1.0.\n* Minmax normalization scales continuous attributes into values between 0.0 and 1.0.\n\n```gleam\nfn setosa() -\u003e Dict(String, String) {\n  [\n    #(\"petal_length\", \"1.5\"),\n    #(\"petal_width\", \"0.1\"),\n    #(\"sepal_length\", \"4.9\"),\n    #(\"sepal_width\", \"3.1\"),\n    #(\"species\", \"setosa\")\n  ]\n  |\u003e dict.from_list\n}\n\nfn versicolor() -\u003e Dict(String, String) {\n  [\n    #(\"petal_length\", \"3.8\"),\n    #(\"petal_width\", \"1.1\"),\n    #(\"sepal_length\", \"5.5\"),\n    #(\"sepal_width\", \"2.4\"),\n    #(\"species\", \"versicolor\")\n  ]\n  |\u003e dict.from_list\n}\n\nfn virginica() -\u003e Dict(String, String) {\n  [\n    #(\"petal_length\", \"6.0\"),\n    #(\"petal_width\", \"2.2\"),\n    #(\"sepal_length\", \"5.0\"),\n    #(\"sepal_width\", \"1.5\"),\n    #(\"species\", \"virginica\")\n  ]\n  |\u003e dict.from_list\n}\n\nfn dataset() -\u003e Iterator(Dict(String, String)) {\n  iterator.from_list([setosa(), versicolor(), virginica()])\n}\n```\n\nYou can use a `Codec` to encode and decode a data point.\n\n### Create a `Codec` by providing the attributes and the data points\n\n```gleam\nlet cdc = codec.new([\n      #(\"petal_length\", False),\n      #(\"petal_width\", False),\n      #(\"sepal_length\", False),\n      #(\"sepal_width\", False),\n      #(\"species\", True))\n    ],\n    dataset()\n)\n```\n\n* The first parameter is a list of pairs that define the name and the type (discrete or not) of each attribute.\n* The second parameter is an iterator that contains the data points.\n\n### Get the json of the codec\n\n```gleam\nlet codec_json = codec.to_json(cdc)\n// \"[\n//   {\\\"Case\\\" : \\\"SerializableContinuous\\\",\n//    \\\"Fields\\\" : [{\\\"key\\\" : \\\"petal_length\\\",\\\"min\\\" : 1.5,\\\"max\\\" : 6.0}]},\n//   {\\\"Case\\\" : \\\"SerializableContinuous\\\",\n//    \\\"Fields\\\" : [{\\\"key\\\" : \\\"petal_width\\\",\\\"min\\\" : 0.1,\\\"max\\\" : 2.2}]},\n//   {\\\"Case\\\" : \\\"SerializableContinuous\\\",\n//    \\\"Fields\\\" : [{\\\"key\\\" : \\\"sepal_length\\\",\\\"min\\\" : 4.9,\\\"max\\\" : 5.5}]},\n//   {\\\"Case\\\" : \\\"SerializableContinuous\\\",\n//    \\\"Fields\\\" : [{\\\"key\\\" : \\\"sepal_width\\\",\\\"min\\\" : 1.5,\\\"max\\\" : 3.1}]},\n//   {\\\"Case\\\" : \\\"SerializableDiscrete\\\",\n//    \\\"Fields\\\" : [{\\\"key\\\" : \\\"species\\\",\\\"values\\\" : [\\\"virginica\\\",\\\"versicolor\\\",\\\"setosa\\\"]}]}\n// ]\"\n```\n\n\n### Create a codec by providing its json\n\n```gleam\ncodec.from_json(codec_json)\n```\n\n### Encode a data point\n\n```gleam\nlet encoded_setosa = codec.encode(cdc, setosa())\n// [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0]\n```\n\n### Decode a data point\n\n```gleam\ncodec.decode(cdc, encoded_setosa)\n|\u003e dict.to_list\n// [\n//   #(\"species\", \"setosa\"),\n//   #(\"sepal_width\", \"3.1\"),\n//   #(\"petal_width\", \"0.1\"),\n//   #(\"petal_length\", \"1.5\"),\n//   #(\"sepal_length\", \"4.9\")\n// ]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrdimosthenis%2Fgleam_synapses","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrdimosthenis%2Fgleam_synapses","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrdimosthenis%2Fgleam_synapses/lists"}