{"id":51294454,"url":"https://github.com/xylambda/toydiff","last_synced_at":"2026-06-30T13:02:33.510Z","repository":{"id":37661617,"uuid":"264269959","full_name":"Xylambda/toydiff","owner":"Xylambda","description":"Yet another tensor automatic differentiation framework","archived":false,"fork":false,"pushed_at":"2023-10-29T22:04:18.000Z","size":793,"stargazers_count":1,"open_issues_count":4,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-10-29T23:25:19.199Z","etag":null,"topics":["autodiff","autodifferentiation","backpropagation","computational-graphs","gradient","numpy","python","tensor"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Xylambda.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-05-15T18:31:48.000Z","updated_at":"2023-10-29T23:25:20.717Z","dependencies_parsed_at":"2022-09-08T00:40:39.305Z","dependency_job_id":"1a6f2b4c-725d-434f-b86c-c2961895bdf1","html_url":"https://github.com/Xylambda/toydiff","commit_stats":null,"previous_names":[],"tags_count":4,"template":null,"template_full_name":null,"purl":"pkg:github/Xylambda/toydiff","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xylambda%2Ftoydiff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xylambda%2Ftoydiff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xylambda%2Ftoydiff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xylambda%2Ftoydiff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Xylambda","download_url":"https://codeload.github.com/Xylambda/toydiff/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xylambda%2Ftoydiff/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34967640,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["autodiff","autodifferentiation","backpropagation","computational-graphs","gradient","numpy","python","tensor"],"created_at":"2026-06-30T13:02:32.389Z","updated_at":"2026-06-30T13:02:33.500Z","avatar_url":"https://github.com/Xylambda.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Toydiff\n\n`toydiff` is a simple automatic differentiation library that I created to wrap\nmy head around how autodiff works. It is built using NumPy and SciPy and it has\nbeen tested using PyTorch as a reference.\n\nThe libray is very versatile, and can be used to create and train neural\nnetworks (WIP, only linear layers for now).\n\n## Installation\nNormal user:\n```bash\ngit clone https://github.com/Xylambda/toydiff.git\npip install toydiff/.\n```\n\nDeveloper:\n```bash\ngit clone https://github.com/Xylambda/toydiff.git\npip install -e toydiff/. -r toydiff/requirements-dev.txt\n```\n\n## Tests\nTo run test, you must install the library as a `developer`.\n\n```bash\ncd toydiff/\npytest -v tests/\n```\n\n## Differentiable operations\nThe use is almost the same as the one you would expect from PyTorch:\n\n```python\n\u003e\u003e\u003e import toydiff as tdf\n\u003e\u003e\u003e # use `track_gradient=True` to allow backward to fill the gradients\n\u003e\u003e\u003e a = tdf.random.rand((3,3), track_gradient=True)\n\u003e\u003e\u003e b = tdf.random.rand((3,3), track_gradient=True)\n\u003e\u003e\u003e c = tdf.matmul(a, b)\n\u003e\u003e\u003e d = tdf.log(c)\n\u003e\u003e\u003e e = tdf.sum(d)\n```\n\nVariable `e` is a Tensor that allows to backpropagate:\n```python\n\u003e\u003e\u003e e\nTensor(0.22356361, dtype=float32, backward_fn=\u003cSum(ReduceOp).Backward\u003e)\n\u003e\u003e\u003e e.backward()  # can pass a gradient tensor too if needed\n\u003e\u003e\u003e a.gradient\nTensor([[0.7647713, 2.643686 , 3.2196524],\n       [0.4147661, 1.494362 , 1.8254415],\n       [0.5436615, 1.9049336, 2.524307 ]], dtype=float32, track_gradient=False)\n```\n\nThe library tracks intermediate gradients by default, without needing to\nperform extra steps to do so:\n\n```python\n\u003e\u003e\u003e c.gradient\nTensor([[1.1955129 , 1.6154591 , 1.1438175 ],\n       [0.7210128 , 0.91004455, 0.60389584],\n       [0.83467734, 1.4432425 , 0.75835925]], dtype=float32, track_gradient=False)\n```\n\n## Neural networks (WIP)\n\nThe module `nn` contains all necessary functionality to create and optimize\nbasic neural networks:\n\n```python\nimport numpy as np\nimport toydiff as tdf\nfrom toydiff.nn.blocks import Linear\nfrom toydiff.nn.optim import SGD\nfrom toydiff.nn.functional import mse_loss\n\n# generate data\nx = np.arange(-1, 1, 0.01).reshape(-1,1)\ny = 2 * x + np.random.normal(size=(len(x), 1), scale=0.3)\n\n# create model\nmodel = Linear(1, 1, bias=False)\n\n# wrap your data in Tensors with `track_gradient=True`\nfeat = tdf.Tensor(X, track_gradient=True)\nlabels = tdf.Tensor(y, track_gradient=True)\n\n# pass model to optimizer\noptimizer = SGD(model)\n\n# build train loop\nlosses = []\nn_epochs = 15_000\nfor i in range(n_epochs):\n    # zero grads if you do not want to accumulate gradients\n    optimizer.zero_grad()\n\n    # forward pass, loss and backward pass\n    out = model(feat)\n    loss = mse_loss(out, labels)  # minimize sum of square differences\n    loss.backward()\n\n    # use gradients to update parameters\n    optimizer.step()\n    \n    losses.append(loss.value)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxylambda%2Ftoydiff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxylambda%2Ftoydiff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxylambda%2Ftoydiff/lists"}