neuralfabric 0.1.0.dev2__tar.gz → 0.1.0.dev3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {neuralfabric-0.1.0.dev2/src/neuralfabric.egg-info → neuralfabric-0.1.0.dev3}/PKG-INFO +3 -3
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/README.md +2 -2
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/pyproject.toml +1 -1
- neuralfabric-0.1.0.dev3/src/neuralfabric/base.py +58 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/config.py +1 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/tensor.py +24 -0
- neuralfabric-0.1.0.dev3/src/neuralfabric/exceptions.py +0 -0
- neuralfabric-0.1.0.dev3/src/neuralfabric/linear_model/__init__.py +7 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/linear_model/linear_regression.py +28 -38
- neuralfabric-0.1.0.dev3/src/neuralfabric/linear_model/logistic_regression.py +102 -0
- neuralfabric-0.1.0.dev3/src/neuralfabric/metrics/__init__.py +7 -0
- neuralfabric-0.1.0.dev3/src/neuralfabric/metrics/classification.py +12 -0
- neuralfabric-0.1.0.dev3/src/neuralfabric/metrics/regression.py +19 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/__init__.py +1 -1
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/train_test_split.py +11 -4
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3/src/neuralfabric.egg-info}/PKG-INFO +3 -3
- neuralfabric-0.1.0.dev2/src/neuralfabric/base.py +0 -43
- neuralfabric-0.1.0.dev2/src/neuralfabric/exceptions.py +0 -13
- neuralfabric-0.1.0.dev2/src/neuralfabric/linear_model/__init__.py +0 -3
- neuralfabric-0.1.0.dev2/src/neuralfabric/linear_model/logistic_regression.py +0 -1
- neuralfabric-0.1.0.dev2/src/neuralfabric/metrics/__init__.py +0 -1
- neuralfabric-0.1.0.dev2/src/neuralfabric/metrics/classification.py +0 -1
- neuralfabric-0.1.0.dev2/src/neuralfabric/metrics/regression.py +0 -1
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/CHANGELOG.md +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/LICENSE +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/MANIFEST.in +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/setup.cfg +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/__version__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/cluster/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/cluster/dbscan.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/cluster/hierarchical.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/cluster/kmeans.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/autograd.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/device.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/dtype.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/ops.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/datasets/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/datasets/data/.gitkeep +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/datasets/loaders.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/decomposition/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/decomposition/pca.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/decomposition/svd.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/adaboost.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/bagging.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/gradient_boosting.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/random_forest.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/linear_model/elastic_net.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/linear_model/lasso.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/linear_model/ridge.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/metrics/clustering.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/cross_validation.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/grid_search.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/split.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/naive_bayes/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/naive_bayes/gaussian_nb.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/naive_bayes/multinomial_nb.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/activations.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/functional.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/conv.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/dropout.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/embedding.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/linear.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/normalization.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/pooling.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/recurrent.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/losses.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/module.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/parameter.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/optim/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/optim/adam.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/optim/lr_scheduler.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/optim/rmsprop.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/optim/sgd.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/pipeline.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/encoders.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/imputers.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/scalers.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/svm/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/svm/kernels.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/svm/svc.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/svm/svr.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/attention.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/decoder.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/encoder.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/model.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/positional_encoding.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/transformer_block.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/tree/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/tree/criterion.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/tree/decision_tree.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/tree/splitter.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/utils/__init__.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/utils/math_utils.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/utils/validation.py +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric.egg-info/SOURCES.txt +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric.egg-info/dependency_links.txt +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric.egg-info/requires.txt +0 -0
- {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neuralfabric
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev3
|
|
4
4
|
Summary: A from-scratch machine learning and deep learning framework, from linear regression to transformers.
|
|
5
5
|
Author-email: Aryan Patel <aryanpatel2906.ap@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -61,12 +61,12 @@ Dynamic: license-file
|
|
|
61
61
|
|
|
62
62
|
# NeuralFabric
|
|
63
63
|
|
|
64
|
-
A from-scratch machine learning and deep learning framework, from
|
|
64
|
+
A from-scratch machine learning and deep learning framework, from tensors to transformers.
|
|
65
65
|
|
|
66
66
|
## Installation
|
|
67
67
|
|
|
68
68
|
```bash
|
|
69
|
-
pip install neuralfabric
|
|
69
|
+
pip install -U neuralfabric
|
|
70
70
|
# or, for local development:
|
|
71
71
|
pip install -e ".[dev]"
|
|
72
72
|
```
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# NeuralFabric
|
|
2
2
|
|
|
3
|
-
A from-scratch machine learning and deep learning framework, from
|
|
3
|
+
A from-scratch machine learning and deep learning framework, from tensors to transformers.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pip install neuralfabric
|
|
8
|
+
pip install -U neuralfabric
|
|
9
9
|
# or, for local development:
|
|
10
10
|
pip install -e ".[dev]"
|
|
11
11
|
```
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "neuralfabric"
|
|
7
|
-
version = "0.1.0.
|
|
7
|
+
version = "0.1.0.dev3"
|
|
8
8
|
description = "A from-scratch machine learning and deep learning framework, from linear regression to transformers."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import abstractmethod
|
|
4
|
+
from typing import Any, Self
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BaseEstimator:
|
|
8
|
+
def get_params(self) -> dict[str, Any]:
|
|
9
|
+
return {
|
|
10
|
+
key: value for key, value in self.__dict__.items() if not key.endswith("_")
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
def set_params(self, **params: Any) -> Self:
|
|
14
|
+
for key, value in params.items():
|
|
15
|
+
setattr(self, key, value)
|
|
16
|
+
|
|
17
|
+
return self
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class RegressorMixin:
|
|
21
|
+
@abstractmethod
|
|
22
|
+
def predict(self, X):
|
|
23
|
+
raise NotImplementedError
|
|
24
|
+
|
|
25
|
+
def score(self, X, y) -> float:
|
|
26
|
+
from neuralfabric.metrics.regression import r2_score
|
|
27
|
+
|
|
28
|
+
return r2_score(
|
|
29
|
+
y,
|
|
30
|
+
self.predict(X),
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ClassifierMixin:
|
|
35
|
+
@abstractmethod
|
|
36
|
+
def predict(self, X):
|
|
37
|
+
raise NotImplementedError
|
|
38
|
+
|
|
39
|
+
def score(self, X, y) -> float:
|
|
40
|
+
from neuralfabric.metrics.classification import accuracy_score
|
|
41
|
+
|
|
42
|
+
return accuracy_score(
|
|
43
|
+
y,
|
|
44
|
+
self.predict(X),
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class TransformerMixin:
|
|
49
|
+
@abstractmethod
|
|
50
|
+
def fit(self, X, y=None):
|
|
51
|
+
raise NotImplementedError
|
|
52
|
+
|
|
53
|
+
@abstractmethod
|
|
54
|
+
def transform(self, X):
|
|
55
|
+
raise NotImplementedError
|
|
56
|
+
|
|
57
|
+
def fit_transform(self, X, y=None):
|
|
58
|
+
return self.fit(X, y).transform(X)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import numpy as np
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
class Tensor:
|
|
5
6
|
__slots__ = ("data", "grad", "requires_grad", "_prev", "_op", "_backward")
|
|
6
7
|
|
|
@@ -229,6 +230,29 @@ class Tensor:
|
|
|
229
230
|
out._backward = _backward
|
|
230
231
|
return out
|
|
231
232
|
|
|
233
|
+
def clip(
|
|
234
|
+
self,
|
|
235
|
+
min_value: float,
|
|
236
|
+
max_value: float,
|
|
237
|
+
) -> Tensor:
|
|
238
|
+
out = Tensor(
|
|
239
|
+
np.clip(self.data, min_value, max_value),
|
|
240
|
+
requires_grad=self.requires_grad,
|
|
241
|
+
_children=(self,),
|
|
242
|
+
_op="clip",
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
def _backward() -> None:
|
|
246
|
+
if self.requires_grad:
|
|
247
|
+
mask = ((self.data >= min_value) & (self.data <= max_value)).astype(
|
|
248
|
+
self.data.dtype
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
self._accumulate(out.grad * mask)
|
|
252
|
+
|
|
253
|
+
out._backward = _backward
|
|
254
|
+
return out
|
|
255
|
+
|
|
232
256
|
def relu(self):
|
|
233
257
|
out = Tensor(
|
|
234
258
|
np.maximum(self.data, 0),
|
|
File without changes
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from typing import Self
|
|
4
|
+
|
|
5
|
+
from neuralfabric.base import BaseEstimator, RegressorMixin
|
|
3
6
|
from neuralfabric.core.tensor import Tensor
|
|
4
7
|
|
|
5
8
|
|
|
6
|
-
class LinearRegression
|
|
9
|
+
class LinearRegression(
|
|
10
|
+
BaseEstimator,
|
|
11
|
+
RegressorMixin,
|
|
12
|
+
):
|
|
7
13
|
"""
|
|
8
|
-
Ordinary Least Squares Linear Regression
|
|
14
|
+
Ordinary Least Squares (OLS) Linear Regression
|
|
9
15
|
optimized using Gradient Descent.
|
|
10
16
|
"""
|
|
11
17
|
|
|
@@ -24,16 +30,16 @@ class LinearRegression:
|
|
|
24
30
|
self,
|
|
25
31
|
X: Tensor,
|
|
26
32
|
y: Tensor,
|
|
27
|
-
) ->
|
|
33
|
+
) -> Self:
|
|
28
34
|
n_features = X.shape[1]
|
|
29
35
|
|
|
30
36
|
self.weight = Tensor(
|
|
31
|
-
[[0.0]
|
|
37
|
+
[[0.0] for _ in range(n_features)],
|
|
32
38
|
requires_grad=True,
|
|
33
39
|
)
|
|
34
40
|
|
|
35
41
|
self.bias = Tensor(
|
|
36
|
-
|
|
42
|
+
0.0,
|
|
37
43
|
requires_grad=True,
|
|
38
44
|
)
|
|
39
45
|
|
|
@@ -47,50 +53,34 @@ class LinearRegression:
|
|
|
47
53
|
|
|
48
54
|
loss.backward()
|
|
49
55
|
|
|
50
|
-
self.weight.
|
|
51
|
-
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
self.bias.data -= (
|
|
55
|
-
self.lr * self.bias.grad
|
|
56
|
-
)
|
|
56
|
+
weight_grad = self.weight.grad
|
|
57
|
+
bias_grad = self.bias.grad
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
assert weight_grad is not None
|
|
60
|
+
assert bias_grad is not None
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
raise RuntimeError(
|
|
63
|
-
"LinearRegression must be fitted before prediction."
|
|
64
|
-
)
|
|
62
|
+
self.weight.data -= self.lr * weight_grad
|
|
63
|
+
self.bias.data -= self.lr * bias_grad
|
|
65
64
|
|
|
66
|
-
return
|
|
65
|
+
return self
|
|
67
66
|
|
|
68
|
-
def
|
|
67
|
+
def predict(
|
|
69
68
|
self,
|
|
70
69
|
X: Tensor,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
ss_res = ((y - predictions) ** 2).sum().item()
|
|
76
|
-
|
|
77
|
-
ss_tot = (
|
|
78
|
-
((y - y.mean()) ** 2)
|
|
79
|
-
.sum()
|
|
80
|
-
.item()
|
|
81
|
-
)
|
|
70
|
+
) -> Tensor:
|
|
71
|
+
if self.weight is None or self.bias is None:
|
|
72
|
+
raise RuntimeError("LinearRegression must be fitted before prediction.")
|
|
82
73
|
|
|
83
|
-
return
|
|
74
|
+
return X @ self.weight + self.bias
|
|
84
75
|
|
|
85
76
|
def parameters(self) -> list[Tensor]:
|
|
86
77
|
if self.weight is None or self.bias is None:
|
|
87
78
|
return []
|
|
88
79
|
|
|
89
|
-
return [
|
|
80
|
+
return [
|
|
81
|
+
self.weight,
|
|
82
|
+
self.bias,
|
|
83
|
+
]
|
|
90
84
|
|
|
91
85
|
def __repr__(self) -> str:
|
|
92
|
-
return (
|
|
93
|
-
f"LinearRegression("
|
|
94
|
-
f"lr={self.lr}, "
|
|
95
|
-
f"epochs={self.epochs})"
|
|
96
|
-
)
|
|
86
|
+
return f"LinearRegression(" f"lr={self.lr}, " f"epochs={self.epochs})"
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Self
|
|
4
|
+
|
|
5
|
+
from neuralfabric.base import BaseEstimator, ClassifierMixin
|
|
6
|
+
from neuralfabric.core.tensor import Tensor
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class LogisticRegression(
|
|
10
|
+
BaseEstimator,
|
|
11
|
+
ClassifierMixin,
|
|
12
|
+
):
|
|
13
|
+
"""
|
|
14
|
+
Binary Logistic Regression
|
|
15
|
+
optimized using Gradient Descent.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
lr: float = 0.01,
|
|
21
|
+
epochs: int = 1000,
|
|
22
|
+
) -> None:
|
|
23
|
+
self.lr = lr
|
|
24
|
+
self.epochs = epochs
|
|
25
|
+
|
|
26
|
+
self.weight: Tensor | None = None
|
|
27
|
+
self.bias: Tensor | None = None
|
|
28
|
+
|
|
29
|
+
def fit(
|
|
30
|
+
self,
|
|
31
|
+
X: Tensor,
|
|
32
|
+
y: Tensor,
|
|
33
|
+
) -> Self:
|
|
34
|
+
n_features = X.shape[1]
|
|
35
|
+
|
|
36
|
+
self.weight = Tensor(
|
|
37
|
+
[[0.0] for _ in range(n_features)],
|
|
38
|
+
requires_grad=True,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
self.bias = Tensor(
|
|
42
|
+
0.0,
|
|
43
|
+
requires_grad=True,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
for _ in range(self.epochs):
|
|
47
|
+
logits = X @ self.weight + self.bias
|
|
48
|
+
|
|
49
|
+
predictions = logits.sigmoid().clip(
|
|
50
|
+
1e-7,
|
|
51
|
+
1 - 1e-7,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
loss = -(y * predictions.log() + (1 - y) * (1 - predictions).log()).mean()
|
|
55
|
+
|
|
56
|
+
self.weight.zero_grad()
|
|
57
|
+
self.bias.zero_grad()
|
|
58
|
+
|
|
59
|
+
loss.backward()
|
|
60
|
+
|
|
61
|
+
weight_grad = self.weight.grad
|
|
62
|
+
bias_grad = self.bias.grad
|
|
63
|
+
|
|
64
|
+
assert weight_grad is not None
|
|
65
|
+
assert bias_grad is not None
|
|
66
|
+
|
|
67
|
+
self.weight.data -= self.lr * weight_grad
|
|
68
|
+
self.bias.data -= self.lr * bias_grad
|
|
69
|
+
|
|
70
|
+
return self
|
|
71
|
+
|
|
72
|
+
def predict_proba(
|
|
73
|
+
self,
|
|
74
|
+
X: Tensor,
|
|
75
|
+
) -> Tensor:
|
|
76
|
+
if self.weight is None or self.bias is None:
|
|
77
|
+
raise RuntimeError("LogisticRegression must be fitted before prediction.")
|
|
78
|
+
|
|
79
|
+
logits = X @ self.weight + self.bias
|
|
80
|
+
|
|
81
|
+
return logits.sigmoid()
|
|
82
|
+
|
|
83
|
+
def predict(
|
|
84
|
+
self,
|
|
85
|
+
X: Tensor,
|
|
86
|
+
threshold: float = 0.5,
|
|
87
|
+
) -> Tensor:
|
|
88
|
+
probabilities = self.predict_proba(X)
|
|
89
|
+
|
|
90
|
+
return Tensor((probabilities.data >= threshold).astype(float))
|
|
91
|
+
|
|
92
|
+
def parameters(self) -> list[Tensor]:
|
|
93
|
+
if self.weight is None or self.bias is None:
|
|
94
|
+
return []
|
|
95
|
+
|
|
96
|
+
return [
|
|
97
|
+
self.weight,
|
|
98
|
+
self.bias,
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
def __repr__(self) -> str:
|
|
102
|
+
return f"LogisticRegression(" f"lr={self.lr}, " f"epochs={self.epochs})"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from neuralfabric.core.tensor import Tensor
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def accuracy_score(
|
|
7
|
+
y_true: Tensor,
|
|
8
|
+
y_pred: Tensor,
|
|
9
|
+
) -> float:
|
|
10
|
+
correct = (y_true.data == y_pred.data).sum()
|
|
11
|
+
|
|
12
|
+
return float(correct / y_true.data.shape[0])
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from neuralfabric.core.tensor import Tensor
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def r2_score(
|
|
7
|
+
y_true: Tensor,
|
|
8
|
+
y_pred: Tensor,
|
|
9
|
+
) -> float:
|
|
10
|
+
y_true_data = y_true.data
|
|
11
|
+
y_pred_data = y_pred.data
|
|
12
|
+
|
|
13
|
+
ss_res = ((y_true_data - y_pred_data) ** 2).sum()
|
|
14
|
+
ss_tot = ((y_true_data - y_true_data.mean()) ** 2).sum()
|
|
15
|
+
|
|
16
|
+
if ss_tot == 0:
|
|
17
|
+
return 0.0
|
|
18
|
+
|
|
19
|
+
return float(1.0 - (ss_res / ss_tot))
|
|
@@ -12,15 +12,17 @@ def train_test_split(
|
|
|
12
12
|
shuffle: bool = True,
|
|
13
13
|
random_state: int | None = None,
|
|
14
14
|
) -> tuple[Tensor, Tensor, Tensor, Tensor]:
|
|
15
|
+
"""
|
|
16
|
+
Split arrays or tensors into random train and test subsets.
|
|
17
|
+
"""
|
|
18
|
+
|
|
15
19
|
if not 0 < test_size < 1:
|
|
16
20
|
raise ValueError("test_size must be between 0 and 1.")
|
|
17
21
|
|
|
18
22
|
n_samples = X.shape[0]
|
|
19
23
|
|
|
20
24
|
if y.shape[0] != n_samples:
|
|
21
|
-
raise ValueError(
|
|
22
|
-
"X and y must contain the same number of samples."
|
|
23
|
-
)
|
|
25
|
+
raise ValueError("X and y must contain the same number of samples.")
|
|
24
26
|
|
|
25
27
|
indices = np.arange(n_samples)
|
|
26
28
|
|
|
@@ -39,4 +41,9 @@ def train_test_split(
|
|
|
39
41
|
y_train = Tensor(y.data[train_idx])
|
|
40
42
|
y_test = Tensor(y.data[test_idx])
|
|
41
43
|
|
|
42
|
-
return
|
|
44
|
+
return (
|
|
45
|
+
X_train,
|
|
46
|
+
X_test,
|
|
47
|
+
y_train,
|
|
48
|
+
y_test,
|
|
49
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neuralfabric
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev3
|
|
4
4
|
Summary: A from-scratch machine learning and deep learning framework, from linear regression to transformers.
|
|
5
5
|
Author-email: Aryan Patel <aryanpatel2906.ap@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -61,12 +61,12 @@ Dynamic: license-file
|
|
|
61
61
|
|
|
62
62
|
# NeuralFabric
|
|
63
63
|
|
|
64
|
-
A from-scratch machine learning and deep learning framework, from
|
|
64
|
+
A from-scratch machine learning and deep learning framework, from tensors to transformers.
|
|
65
65
|
|
|
66
66
|
## Installation
|
|
67
67
|
|
|
68
68
|
```bash
|
|
69
|
-
pip install neuralfabric
|
|
69
|
+
pip install -U neuralfabric
|
|
70
70
|
# or, for local development:
|
|
71
71
|
pip install -e ".[dev]"
|
|
72
72
|
```
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"""BaseEstimator and Mixins (RegressorMixin, ClassifierMixin, TransformerMixin)
|
|
2
|
-
shared by every classical estimator in LevelGraphs.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class BaseEstimator:
|
|
7
|
-
"""Base class for all estimators.
|
|
8
|
-
|
|
9
|
-
Provides ``get_params`` / ``set_params`` (sklearn-style) so every model
|
|
10
|
-
is introspectable and plugs into model_selection utilities (e.g. grid
|
|
11
|
-
search) without extra boilerplate.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
def get_params(self) -> dict:
|
|
15
|
-
return {k: v for k, v in self.__dict__.items() if not k.endswith("_")}
|
|
16
|
-
|
|
17
|
-
def set_params(self, **params):
|
|
18
|
-
for key, value in params.items():
|
|
19
|
-
setattr(self, key, value)
|
|
20
|
-
return self
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class RegressorMixin:
|
|
24
|
-
"""Marks an estimator as a regressor; adds a default R^2 `score`."""
|
|
25
|
-
|
|
26
|
-
def score(self, X, y):
|
|
27
|
-
from .metrics.regression import r2_score
|
|
28
|
-
return r2_score(y, self.predict(X))
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class ClassifierMixin:
|
|
32
|
-
"""Marks an estimator as a classifier; adds a default accuracy `score`."""
|
|
33
|
-
|
|
34
|
-
def score(self, X, y):
|
|
35
|
-
from .metrics.classification import accuracy_score
|
|
36
|
-
return accuracy_score(y, self.predict(X))
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class TransformerMixin:
|
|
40
|
-
"""Adds `fit_transform` for free, given `fit` and `transform`."""
|
|
41
|
-
|
|
42
|
-
def fit_transform(self, X, y=None):
|
|
43
|
-
return self.fit(X, y).transform(X)
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"""Library-specific exception types."""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class LevelGraphsError(Exception):
|
|
5
|
-
"""Base class for all NeuralFabric exceptions."""
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class NotFittedError(LevelGraphsError):
|
|
9
|
-
"""Raised when a method needs a fitted estimator that hasn't been fit yet."""
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ShapeMismatchError(LevelGraphsError):
|
|
13
|
-
"""Raised when input shapes are incompatible with the requested operation."""
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""Binary/multiclass logistic regression classifier. TODO: implement."""
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""Evaluation metrics for regression, classification, and clustering."""
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""Accuracy, precision, recall, F1, ROC-AUC, confusion matrix. TODO: implement."""
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""MSE, RMSE, MAE, R^2 and other regression metrics. TODO: implement."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/cluster/hierarchical.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/decomposition/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/gradient_boosting.py
RENAMED
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/random_forest.py
RENAMED
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/linear_model/elastic_net.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/grid_search.py
RENAMED
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/split.py
RENAMED
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/naive_bayes/__init__.py
RENAMED
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/naive_bayes/gaussian_nb.py
RENAMED
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/naive_bayes/multinomial_nb.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/normalization.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/__init__.py
RENAMED
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/encoders.py
RENAMED
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/imputers.py
RENAMED
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/scalers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/__init__.py
RENAMED
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/attention.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|