{"id":16701830,"url":"https://github.com/mrdimosthenis/scala-synapses","last_synced_at":"2025-04-10T04:21:11.554Z","repository":{"id":57721628,"uuid":"389320214","full_name":"mrdimosthenis/scala-synapses","owner":"mrdimosthenis","description":"A plug-and play library for neural networks written in Scala 3","archived":false,"fork":false,"pushed_at":"2024-08-16T11:50:06.000Z","size":9692,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-24T05:35:41.510Z","etag":null,"topics":["deep-learning","dotty","functional-programming","machine-learning","neural-network","scala"],"latest_commit_sha":null,"homepage":"https://mrdimosthenis.github.io/scala-synapses/target/scala-3.0.1/api/api/synapses/Documentation$.html","language":"Scala","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":"docs/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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-25T10:28:49.000Z","updated_at":"2024-08-16T11:50:09.000Z","dependencies_parsed_at":"2025-02-16T14:37:55.613Z","dependency_job_id":"95d157e4-e4af-41d5-82c5-f8883fe31702","html_url":"https://github.com/mrdimosthenis/scala-synapses","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrdimosthenis%2Fscala-synapses","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrdimosthenis%2Fscala-synapses/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrdimosthenis%2Fscala-synapses/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrdimosthenis%2Fscala-synapses/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrdimosthenis","download_url":"https://codeload.github.com/mrdimosthenis/scala-synapses/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248155433,"owners_count":21056638,"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","dotty","functional-programming","machine-learning","neural-network","scala"],"created_at":"2024-10-12T18:45:52.035Z","updated_at":"2025-04-10T04:21:11.544Z","avatar_url":"https://github.com/mrdimosthenis.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# scala-synapses\n\nA plug-and-play library for **neural networks** written in **Scala 3**!\n\n## Basic usage\n\n### Install synapses\n\n```scala\nlibraryDependencies += \"com.github.mrdimosthenis\" %% \"synapses\" % \"8.0.0\"\n```\n\n### Import the `Net` object\n\n```scala mdoc:silent\nimport synapses.lib.Net\n```\n\n### Create a random neural network by providing its layer sizes\n\n```scala mdoc:silent\nval randNet = Net(List(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```scala mdoc:silent\nrandNet.json()\n// res0: String = \"\"\"[\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### Create a neural network by providing its json\n\n```scala mdoc:silent\nval net = Net(\"\"\"[\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```scala mdoc\nnet.predict(List(0.2, 0.6))\n```\n\n### Train a neural network\n\n```scala mdoc:silent\nnet.fit(\n    learningRate = 0.1,\n    inputValues = List(0.2, 0.6),\n    expectedOutput = List(0.9)\n)\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,\nusually by folding over an iterator.\n\n```scala mdoc:silent\nIterator(\n    (List(0.2, 0.6), List(0.9)),\n    (List(0.1, 0.8), List(0.2)),\n    (List(0.5, 0.4), List(0.6))\n).foldLeft(net){ case (acc, (xs, ys)) =\u003e\n    acc.fit(learningRate = 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` (`parPredict` and `parFit`).\n\n### Create a neural network for testing\n\n```scala mdoc:silent\nNet(layerSizes = List(2, 3, 1), seed = 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```scala mdoc:silent\nimport scala.util.Random\nimport synapses.lib.Fun\n\ndef activationF(layerIndex: Int): Fun =\n    layerIndex match\n      case 0 =\u003e Fun.sigmoid\n      case 1 =\u003e Fun.identity\n      case 2 =\u003e Fun.leakyReLU\n      case 3 =\u003e Fun.tanh\n\ndef weightInitF(layerIndex: Int): Double =\n    (layerIndex + 1) * (1.0 - 2.0 * Random().nextDouble())\n\nval customNet = Net(layerSizes = List(4, 6, 8, 5, 3), activationF, weightInitF)\n```\n\n* The `activationF` function accepts the index of a layer and returns an activation function for its neurons.\n* The `weightInitF` 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```scala mdoc:silent\ncustomNet.svg()\n```\n\n![Network Drawing](https://github.com/mrdimosthenis/scala-synapses/blob/master/neural_network.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```scala mdoc:silent\nimport synapses.lib.Stats\ndef expAndPredVals() =\n    Iterator(\n      (List(0.0, 0.0, 1.0), List(0.0, 0.1, 0.9)),\n      (List(0.0, 1.0, 0.0), List(0.8, 0.2, 0.0)),\n      (List(1.0, 0.0, 0.0), List(0.7, 0.1, 0.2)),\n      (List(1.0, 0.0, 0.0), List(0.3, 0.3, 0.4)),\n      (List(0.0, 0.0, 1.0), List(0.2, 0.2, 0.6))\n    )\n```\n\n* Root-mean-square error\n\n```scala mdoc\nStats.rmse(expAndPredVals())\n```\n\n* Classification accuracy score\n\n```scala mdoc\nStats.score(expAndPredVals())\n```\n\n### Import the `Codec` object\n\n```scala mdoc:silent\nimport synapses.lib.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```scala mdoc:silent\nval setosa = Map(\n  \"petal_length\" -\u003e \"1.5\",\n  \"petal_width\" -\u003e \"0.1\",\n  \"sepal_length\" -\u003e \"4.9\",\n  \"sepal_width\" -\u003e \"3.1\",\n  \"species\" -\u003e \"setosa\"\n)\n\nval versicolor = Map(\n  \"petal_length\" -\u003e \"3.8\",\n  \"petal_width\" -\u003e \"1.1\",\n  \"sepal_length\" -\u003e \"5.5\",\n  \"sepal_width\" -\u003e \"2.4\",\n  \"species\" -\u003e \"versicolor\"\n)\n\nval virginica = Map(\n  \"petal_length\" -\u003e \"6.0\",\n  \"petal_width\" -\u003e \"2.2\",\n  \"sepal_length\" -\u003e \"5.0\",\n  \"sepal_width\" -\u003e \"1.5\",\n  \"species\" -\u003e \"virginica\"\n)\n\ndef dataset() = Iterator(setosa,versicolor,virginica)\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```scala mdoc:silent\nval codec = Codec(\n    List((\"petal_length\", false),\n         (\"petal_width\", false),\n         (\"sepal_length\", false),\n         (\"sepal_width\", false),\n         (\"species\", true)),\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```scala mdoc:silent\nval codecJson = codec.json()\n// codecJson: String = \"\"\"[\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### Create a codec by providing its json\n\n```scala mdoc:silent\nCodec(codecJson)\n```\n\n### Encode a data point\n\n```scala mdoc\nval encodedSetosa = codec.encode(setosa)\n```\n\n### Decode a data point\n\n```scala mdoc\ncodec.decode(encodedSetosa)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrdimosthenis%2Fscala-synapses","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrdimosthenis%2Fscala-synapses","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrdimosthenis%2Fscala-synapses/lists"}