Vishtorch 0.1.0__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.
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: Vishtorch
3
+ Version: 0.1.0
4
+ Summary: A deep learning framework built completely from scratch.
5
+ Author-email: Vish <your_email@example.com>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: numpy>=1.20.0
@@ -0,0 +1,3 @@
1
+ from .tensor import Tensor
2
+ from .nn import Module, Parameter, Linear, Sequential, ReLU, Sigmoid, MSELoss, BCELoss, SimpleDataset, DataLoader
3
+ from .optim import SGD
@@ -0,0 +1,131 @@
1
+ import numpy as np
2
+ from Vishtorch.tensor import Tensor
3
+
4
+ class Parameter(Tensor):
5
+ """ A wrapper designating a Tensor as a trainable layer weight or bias """
6
+ def __init__(self, data):
7
+ super().__init__(data, requires_grad=True)
8
+
9
+
10
+ class Module:
11
+ """ Base structural Module matching PyTorch tracking layout """
12
+ def __init__(self):
13
+ self._modules = {}
14
+ self._parameters = {}
15
+
16
+ def __setattr__(self, name, value):
17
+ if isinstance(value, Parameter):
18
+ self._parameters[name] = value
19
+ elif isinstance(value, Module):
20
+ self._modules[name] = value
21
+ super().__setattr__(name, value)
22
+
23
+ def parameters(self):
24
+ params = list(self._parameters.values())
25
+ for module in self._modules.values():
26
+ params.extend(module.parameters())
27
+ return params
28
+
29
+ def __call__(self, *args, **kwargs):
30
+ if hasattr(self, 'forward'):
31
+ return self.forward(*args, **kwargs)
32
+ raise NotImplementedError
33
+
34
+
35
+ class Linear(Module):
36
+ """ Fully connected deep learning dense network layer """
37
+ def __init__(self, in_features, out_features):
38
+ super().__init__()
39
+ # Standard Xavier/He initial weight variance scaling
40
+ bound = 1.0 / np.sqrt(in_features)
41
+ self.weight = Parameter(np.random.uniform(-bound, bound, (in_features, out_features)))
42
+ self.bias = Parameter(np.zeros((1, out_features)))
43
+
44
+ def forward(self, x):
45
+ return x @ self.weight + self.bias
46
+
47
+
48
+ class Sequential(Module):
49
+ """ Structural module pipe container that runs layers consecutively """
50
+ def __init__(self, *layers):
51
+ super().__init__()
52
+ self.layers = list(layers)
53
+ for i, layer in enumerate(self.layers):
54
+ setattr(self, f"layer_{i}", layer)
55
+
56
+ def forward(self, x):
57
+ out = x
58
+ for layer in self.layers:
59
+ out = layer(out)
60
+ return out
61
+
62
+
63
+ class ReLU(Module):
64
+ def forward(self, x): return x.relu()
65
+
66
+
67
+ class Sigmoid(Module):
68
+ def forward(self, x): return x.sigmoid()
69
+
70
+
71
+ class MSELoss(Module):
72
+ def __call__(self, predictions, targets):
73
+ diff = predictions + (targets.data * -1.0)
74
+ sq_diff = Tensor(diff.data ** 2, requires_grad=predictions.requires_grad, _children=(predictions,))
75
+
76
+ def _backward():
77
+ if predictions.requires_grad:
78
+ N = predictions.data.size
79
+ predictions.grad += out.grad * (2.0 / N) * diff.data
80
+
81
+ out = sq_diff.sum()
82
+ out._backward = _backward
83
+ return out
84
+
85
+
86
+ class BCELoss(Module):
87
+ def __call__(self, predictions, targets):
88
+ p = np.clip(predictions.data, 1e-7, 1.0 - 1e-7)
89
+ t = targets.data
90
+ loss_val = -np.mean(t * np.log(p) + (1.0 - t) * np.log(1.0 - p))
91
+ out = Tensor(loss_val, requires_grad=predictions.requires_grad, _children=(predictions,))
92
+
93
+ def _backward():
94
+ if predictions.requires_grad:
95
+ N = predictions.data.size
96
+ predictions.grad += out.grad * (1.0 / N) * (p - t) / (p * (1.0 - p))
97
+
98
+ out._backward = _backward
99
+ return out
100
+
101
+
102
+ class SimpleDataset:
103
+ def __init__(self, X, y):
104
+ self.X = np.array(X, dtype=np.float32)
105
+ self.y = np.array(y, dtype=np.float32)
106
+
107
+ def __len__(self): return len(self.X)
108
+ def __getitem__(self, idx): return self.X[idx], self.y[idx]
109
+
110
+
111
+ class DataLoader:
112
+ def __init__(self, dataset, batch_size=2, shuffle=True):
113
+ self.dataset = dataset
114
+ self.batch_size = batch_size
115
+ self.shuffle = shuffle
116
+
117
+ def __iter__(self):
118
+ self.indices = np.arange(len(self.dataset))
119
+ if self.shuffle:
120
+ np.random.shuffle(self.indices)
121
+ self.idx = 0
122
+ return self
123
+
124
+ def __next__(self):
125
+ if self.idx >= len(self.dataset):
126
+ raise StopIteration
127
+ batch_idx = self.indices[self.idx : self.idx + self.batch_size]
128
+ self.idx += self.batch_size
129
+ X_batch = [self.dataset[i][0] for i in batch_idx]
130
+ y_batch = [self.dataset[i][1] for i in batch_idx]
131
+ return Tensor(X_batch), Tensor(y_batch)
@@ -0,0 +1,14 @@
1
+ class SGD:
2
+ """ Stochastic Gradient Descent parameter weights manager """
3
+ def __init__(self, parameters, lr=0.01):
4
+ self.parameters = list(parameters)
5
+ self.lr = lr
6
+
7
+ def zero_grad(self):
8
+ for p in self.parameters:
9
+ if p.grad is not None:
10
+ p.grad.fill(0.0)
11
+
12
+ def step(self):
13
+ for p in self.parameters:
14
+ p.data -= self.lr * p.grad
@@ -0,0 +1,115 @@
1
+ import numpy as np
2
+
3
+ class Tensor:
4
+ """ Core Autograd Tensor engine with multidimensional broadcasting support """
5
+ def __init__(self, data, requires_grad=False, _children=()):
6
+ self.data = np.array(data, dtype=np.float32)
7
+ self.requires_grad = requires_grad
8
+ self.grad = np.zeros_like(self.data) if requires_grad else None
9
+ self._backward = lambda: None
10
+ self._prev = set(_children)
11
+
12
+ @property
13
+ def shape(self):
14
+ return self.data.shape
15
+ @property
16
+ def ndim(self):
17
+ """ Returns the number of dimensions of the underlying data matrix """
18
+ return self.data.ndim
19
+
20
+ def __repr__(self):
21
+ return f"Tensor(shape={self.shape}, data=\n{self.data})"
22
+
23
+ def __add__(self, other):
24
+ other = other if isinstance(other, Tensor) else Tensor(other)
25
+ out = Tensor(self.data + other.data, requires_grad=self.requires_grad or other.requires_grad, _children=(self, other))
26
+
27
+ def _backward():
28
+ if self.requires_grad:
29
+ grad_self = out.grad
30
+ # Collapse broadcasted dimensions for self
31
+ while grad_self.ndim > self.ndim:
32
+ grad_self = grad_self.sum(axis=0)
33
+ for axis, size in enumerate(self.shape):
34
+ if size == 1:
35
+ grad_self = grad_self.sum(axis=axis, keepdims=True)
36
+ self.grad += grad_self
37
+
38
+ if other.requires_grad:
39
+ grad_other = out.grad
40
+ # Collapse broadcasted dimensions for other
41
+ while grad_other.ndim > other.ndim:
42
+ grad_other = grad_other.sum(axis=0)
43
+ for axis, size in enumerate(other.shape):
44
+ if size == 1:
45
+ grad_other = grad_other.sum(axis=axis, keepdims=True)
46
+ other.grad += grad_other
47
+
48
+ out._backward = _backward
49
+ return out
50
+
51
+ def __radd__(self, other):
52
+ return self.__add__(other)
53
+
54
+ def __matmul__(self, other):
55
+ assert isinstance(other, Tensor), "Matrix multiplication requires another Tensor"
56
+ out = Tensor(self.data @ other.data, requires_grad=self.requires_grad or other.requires_grad, _children=(self, other))
57
+
58
+ def _backward():
59
+ if self.requires_grad:
60
+ self.grad += out.grad @ other.data.T
61
+ if other.requires_grad:
62
+ other.grad += self.data.T @ out.grad
63
+
64
+ out._backward = _backward
65
+ return out
66
+
67
+ def sum(self):
68
+ out = Tensor(np.sum(self.data), requires_grad=self.requires_grad, _children=(self,))
69
+
70
+ def _backward():
71
+ if self.requires_grad:
72
+ self.grad += out.grad * np.ones_like(self.data)
73
+
74
+ out._backward = _backward
75
+ return out
76
+
77
+ def relu(self):
78
+ out = Tensor(np.maximum(0, self.data), requires_grad=self.requires_grad, _children=(self,))
79
+
80
+ def _backward():
81
+ if self.requires_grad:
82
+ self.grad += out.grad * (self.data > 0)
83
+
84
+ out._backward = _backward
85
+ return out
86
+
87
+ def sigmoid(self):
88
+ clipped_data = np.clip(self.data, -500, 500)
89
+ out_data = 1.0 / (1.0 + np.exp(-clipped_data))
90
+ out = Tensor(out_data, requires_grad=self.requires_grad, _children=(self,))
91
+
92
+ def _backward():
93
+ if self.requires_grad:
94
+ self.grad += out.grad * (out.data * (1.0 - out.data))
95
+
96
+ out._backward = _backward
97
+ return out
98
+
99
+ def backward(self):
100
+ """ Dynamically sorts the graph topologially and executes the backward pass """
101
+ topo = []
102
+ visited = set()
103
+
104
+ def build_topo(v):
105
+ if v not in visited:
106
+ visited.add(v)
107
+ for child in v._prev:
108
+ build_topo(child)
109
+ topo.append(v)
110
+
111
+ build_topo(self)
112
+ self.grad = np.ones_like(self.data)
113
+
114
+ for node in reversed(topo):
115
+ node._backward()
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: Vishtorch
3
+ Version: 0.1.0
4
+ Summary: A deep learning framework built completely from scratch.
5
+ Author-email: Vish <your_email@example.com>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: numpy>=1.20.0
@@ -0,0 +1,10 @@
1
+ pyproject.toml
2
+ Vishtorch/__init__.py
3
+ Vishtorch/nn.py
4
+ Vishtorch/optim.py
5
+ Vishtorch/tensor.py
6
+ Vishtorch.egg-info/PKG-INFO
7
+ Vishtorch.egg-info/SOURCES.txt
8
+ Vishtorch.egg-info/dependency_links.txt
9
+ Vishtorch.egg-info/requires.txt
10
+ Vishtorch.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ numpy>=1.20.0
@@ -0,0 +1 @@
1
+ Vishtorch
@@ -0,0 +1,21 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "Vishtorch"
7
+ version = "0.1.0"
8
+ authors = [
9
+ { name="Vish", email="your_email@example.com" }
10
+ ]
11
+ description = "A deep learning framework built completely from scratch."
12
+ readme = "README.md"
13
+ requires-python = ">=3.8"
14
+ dependencies = [
15
+ "numpy>=1.20.0"
16
+ ]
17
+ classifiers = [
18
+ "Programming Language :: Python :: 3",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+