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.
Files changed (105) hide show
  1. {neuralfabric-0.1.0.dev2/src/neuralfabric.egg-info → neuralfabric-0.1.0.dev3}/PKG-INFO +3 -3
  2. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/README.md +2 -2
  3. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/pyproject.toml +1 -1
  4. neuralfabric-0.1.0.dev3/src/neuralfabric/base.py +58 -0
  5. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/config.py +1 -0
  6. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/tensor.py +24 -0
  7. neuralfabric-0.1.0.dev3/src/neuralfabric/exceptions.py +0 -0
  8. neuralfabric-0.1.0.dev3/src/neuralfabric/linear_model/__init__.py +7 -0
  9. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/linear_model/linear_regression.py +28 -38
  10. neuralfabric-0.1.0.dev3/src/neuralfabric/linear_model/logistic_regression.py +102 -0
  11. neuralfabric-0.1.0.dev3/src/neuralfabric/metrics/__init__.py +7 -0
  12. neuralfabric-0.1.0.dev3/src/neuralfabric/metrics/classification.py +12 -0
  13. neuralfabric-0.1.0.dev3/src/neuralfabric/metrics/regression.py +19 -0
  14. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/__init__.py +1 -1
  15. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/train_test_split.py +11 -4
  16. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3/src/neuralfabric.egg-info}/PKG-INFO +3 -3
  17. neuralfabric-0.1.0.dev2/src/neuralfabric/base.py +0 -43
  18. neuralfabric-0.1.0.dev2/src/neuralfabric/exceptions.py +0 -13
  19. neuralfabric-0.1.0.dev2/src/neuralfabric/linear_model/__init__.py +0 -3
  20. neuralfabric-0.1.0.dev2/src/neuralfabric/linear_model/logistic_regression.py +0 -1
  21. neuralfabric-0.1.0.dev2/src/neuralfabric/metrics/__init__.py +0 -1
  22. neuralfabric-0.1.0.dev2/src/neuralfabric/metrics/classification.py +0 -1
  23. neuralfabric-0.1.0.dev2/src/neuralfabric/metrics/regression.py +0 -1
  24. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/CHANGELOG.md +0 -0
  25. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/LICENSE +0 -0
  26. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/MANIFEST.in +0 -0
  27. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/setup.cfg +0 -0
  28. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/__init__.py +0 -0
  29. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/__version__.py +0 -0
  30. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/cluster/__init__.py +0 -0
  31. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/cluster/dbscan.py +0 -0
  32. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/cluster/hierarchical.py +0 -0
  33. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/cluster/kmeans.py +0 -0
  34. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/__init__.py +0 -0
  35. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/autograd.py +0 -0
  36. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/device.py +0 -0
  37. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/dtype.py +0 -0
  38. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/core/ops.py +0 -0
  39. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/datasets/__init__.py +0 -0
  40. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/datasets/data/.gitkeep +0 -0
  41. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/datasets/loaders.py +0 -0
  42. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/decomposition/__init__.py +0 -0
  43. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/decomposition/pca.py +0 -0
  44. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/decomposition/svd.py +0 -0
  45. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/__init__.py +0 -0
  46. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/adaboost.py +0 -0
  47. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/bagging.py +0 -0
  48. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/gradient_boosting.py +0 -0
  49. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/ensemble/random_forest.py +0 -0
  50. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/linear_model/elastic_net.py +0 -0
  51. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/linear_model/lasso.py +0 -0
  52. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/linear_model/ridge.py +0 -0
  53. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/metrics/clustering.py +0 -0
  54. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/cross_validation.py +0 -0
  55. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/grid_search.py +0 -0
  56. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/model_selection/split.py +0 -0
  57. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/naive_bayes/__init__.py +0 -0
  58. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/naive_bayes/gaussian_nb.py +0 -0
  59. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/naive_bayes/multinomial_nb.py +0 -0
  60. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/__init__.py +0 -0
  61. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/activations.py +0 -0
  62. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/functional.py +0 -0
  63. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/__init__.py +0 -0
  64. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/conv.py +0 -0
  65. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/dropout.py +0 -0
  66. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/embedding.py +0 -0
  67. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/linear.py +0 -0
  68. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/normalization.py +0 -0
  69. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/pooling.py +0 -0
  70. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/layers/recurrent.py +0 -0
  71. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/losses.py +0 -0
  72. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/module.py +0 -0
  73. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/nn/parameter.py +0 -0
  74. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/optim/__init__.py +0 -0
  75. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/optim/adam.py +0 -0
  76. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/optim/lr_scheduler.py +0 -0
  77. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/optim/rmsprop.py +0 -0
  78. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/optim/sgd.py +0 -0
  79. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/pipeline.py +0 -0
  80. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/__init__.py +0 -0
  81. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/encoders.py +0 -0
  82. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/imputers.py +0 -0
  83. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/preprocessing/scalers.py +0 -0
  84. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/svm/__init__.py +0 -0
  85. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/svm/kernels.py +0 -0
  86. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/svm/svc.py +0 -0
  87. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/svm/svr.py +0 -0
  88. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/__init__.py +0 -0
  89. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/attention.py +0 -0
  90. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/decoder.py +0 -0
  91. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/encoder.py +0 -0
  92. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/model.py +0 -0
  93. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/positional_encoding.py +0 -0
  94. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/transformer/transformer_block.py +0 -0
  95. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/tree/__init__.py +0 -0
  96. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/tree/criterion.py +0 -0
  97. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/tree/decision_tree.py +0 -0
  98. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/tree/splitter.py +0 -0
  99. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/utils/__init__.py +0 -0
  100. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/utils/math_utils.py +0 -0
  101. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric/utils/validation.py +0 -0
  102. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric.egg-info/SOURCES.txt +0 -0
  103. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric.egg-info/dependency_links.txt +0 -0
  104. {neuralfabric-0.1.0.dev2 → neuralfabric-0.1.0.dev3}/src/neuralfabric.egg-info/requires.txt +0 -0
  105. {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.dev2
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 linear regression to transformers.
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 linear regression to transformers.
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.dev2"
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)
@@ -10,4 +10,5 @@ def set_seed(seed: int) -> None:
10
10
  global RANDOM_SEED
11
11
  RANDOM_SEED = seed
12
12
  import numpy as np
13
+
13
14
  np.random.seed(seed)
@@ -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
@@ -0,0 +1,7 @@
1
+ from .linear_regression import LinearRegression
2
+ from .logistic_regression import LogisticRegression
3
+
4
+ __all__ = [
5
+ "LinearRegression",
6
+ "LogisticRegression",
7
+ ]
@@ -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
- ) -> "LinearRegression":
33
+ ) -> Self:
28
34
  n_features = X.shape[1]
29
35
 
30
36
  self.weight = Tensor(
31
- [[0.0]] * n_features,
37
+ [[0.0] for _ in range(n_features)],
32
38
  requires_grad=True,
33
39
  )
34
40
 
35
41
  self.bias = Tensor(
36
- [0.0],
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.data -= (
51
- self.lr * self.weight.grad
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
- return self
59
+ assert weight_grad is not None
60
+ assert bias_grad is not None
59
61
 
60
- def predict(self, X: Tensor) -> Tensor:
61
- if self.weight is None or self.bias is None:
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 X @ self.weight + self.bias
65
+ return self
67
66
 
68
- def score(
67
+ def predict(
69
68
  self,
70
69
  X: Tensor,
71
- y: Tensor,
72
- ) -> float:
73
- predictions = self.predict(X)
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 1.0 - (ss_res / ss_tot)
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 [self.weight, self.bias]
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,7 @@
1
+ from .classification import accuracy_score
2
+ from .regression import r2_score
3
+
4
+ __all__ = [
5
+ "accuracy_score",
6
+ "r2_score",
7
+ ]
@@ -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))
@@ -1,3 +1,3 @@
1
1
  from .train_test_split import train_test_split
2
2
 
3
- __all__ = ["train_test_split"]
3
+ __all__ = ["train_test_split"]
@@ -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 X_train, X_test, y_train, y_test
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.dev2
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 linear regression to transformers.
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,3 +0,0 @@
1
- from .linear_regression import LinearRegression
2
-
3
- __all__ = ["LinearRegression"]
@@ -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."""