vectorphile 0.1.0__py3-none-any.whl
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.
- vectorphile/__init__.py +154 -0
- vectorphile/amp/__init__.py +52 -0
- vectorphile/autograd/__init__.py +13 -0
- vectorphile/autograd/engine.py +208 -0
- vectorphile/core/__init__.py +21 -0
- vectorphile/core/tensor.py +696 -0
- vectorphile/data/__init__.py +23 -0
- vectorphile/data/frame.py +537 -0
- vectorphile/data/groupby.py +98 -0
- vectorphile/data/index.py +86 -0
- vectorphile/data/series.py +228 -0
- vectorphile/fft/__init__.py +34 -0
- vectorphile/linalg/__init__.py +63 -0
- vectorphile/ml/__init__.py +44 -0
- vectorphile/ml/boost/__init__.py +133 -0
- vectorphile/ml/cluster.py +218 -0
- vectorphile/ml/decomposition.py +161 -0
- vectorphile/ml/ensemble.py +209 -0
- vectorphile/ml/linear.py +250 -0
- vectorphile/ml/metrics.py +148 -0
- vectorphile/ml/model_selection.py +171 -0
- vectorphile/ml/naive_bayes.py +113 -0
- vectorphile/ml/neighbors.py +95 -0
- vectorphile/ml/preprocessing.py +202 -0
- vectorphile/ml/svm.py +165 -0
- vectorphile/ml/tree.py +155 -0
- vectorphile/nn/__init__.py +20 -0
- vectorphile/nn/activations.py +97 -0
- vectorphile/nn/layers.py +231 -0
- vectorphile/nn/losses.py +172 -0
- vectorphile/nn/module.py +97 -0
- vectorphile/nn/sequential.py +47 -0
- vectorphile/optim/__init__.py +12 -0
- vectorphile/optim/adagrad.py +31 -0
- vectorphile/optim/adam.py +71 -0
- vectorphile/optim/lr_scheduler.py +110 -0
- vectorphile/optim/optimizer.py +30 -0
- vectorphile/optim/rmsprop.py +34 -0
- vectorphile/optim/sgd.py +38 -0
- vectorphile/optimize/__init__.py +97 -0
- vectorphile/random/__init__.py +64 -0
- vectorphile/signal/__init__.py +67 -0
- vectorphile/sparse/__init__.py +129 -0
- vectorphile/stats/__init__.py +90 -0
- vectorphile/utils/__init__.py +3 -0
- vectorphile/utils/data/__init__.py +4 -0
- vectorphile/utils/data/dataloader.py +47 -0
- vectorphile/utils/data/dataset.py +29 -0
- vectorphile-0.1.0.dist-info/METADATA +208 -0
- vectorphile-0.1.0.dist-info/RECORD +53 -0
- vectorphile-0.1.0.dist-info/WHEEL +5 -0
- vectorphile-0.1.0.dist-info/licenses/LICENSE +201 -0
- vectorphile-0.1.0.dist-info/top_level.txt +1 -0
vectorphile/__init__.py
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"""
|
|
2
|
+
vectorphile — Unified ML/DL Python Library
|
|
3
|
+
==========================================
|
|
4
|
+
|
|
5
|
+
The one library that replaces PyTorch + scikit-learn + NumPy + Pandas + SciPy.
|
|
6
|
+
|
|
7
|
+
Quick start:
|
|
8
|
+
import vectorphile as vp
|
|
9
|
+
|
|
10
|
+
# Tensors (PyTorch-like)
|
|
11
|
+
x = vp.tensor([1, 2, 3], dtype='float32')
|
|
12
|
+
y = vp.randn(3, 4)
|
|
13
|
+
z = x @ y
|
|
14
|
+
|
|
15
|
+
# Neural networks
|
|
16
|
+
model = vp.nn.Sequential(
|
|
17
|
+
vp.nn.Linear(4, 128),
|
|
18
|
+
vp.nn.ReLU(),
|
|
19
|
+
vp.nn.Linear(128, 10),
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# ML algorithms
|
|
23
|
+
clf = vp.ml.RandomForestClassifier(n_estimators=100)
|
|
24
|
+
clf.fit(X_train, y_train)
|
|
25
|
+
|
|
26
|
+
# DataFrames
|
|
27
|
+
df = vp.data.read_csv('data.csv')
|
|
28
|
+
df.groupby('category').mean()
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
__version__ = '0.1.0'
|
|
32
|
+
__author__ = 'vectorphile'
|
|
33
|
+
__license__ = 'Apache-2.0'
|
|
34
|
+
|
|
35
|
+
# ── Core tensor operations ───────────────────────────────────────────────────
|
|
36
|
+
from vectorphile.core.tensor import (
|
|
37
|
+
Tensor,
|
|
38
|
+
tensor, zeros, ones, eye, arange, linspace, full, empty,
|
|
39
|
+
rand, randn, randint, from_numpy,
|
|
40
|
+
zeros_like, ones_like, empty_like,
|
|
41
|
+
cat, stack, split, chunk, squeeze, unsqueeze, flatten, transpose, permute,
|
|
42
|
+
matmul, dot, where,
|
|
43
|
+
exp, log, sqrt, clamp,
|
|
44
|
+
softmax, log_softmax, sigmoid, relu, tanh, einsum,
|
|
45
|
+
)
|
|
46
|
+
# shadow builtins only in the vp namespace
|
|
47
|
+
from vectorphile.core.tensor import sum as sum
|
|
48
|
+
from vectorphile.core.tensor import mean as mean
|
|
49
|
+
from vectorphile.core.tensor import max as max
|
|
50
|
+
from vectorphile.core.tensor import min as min
|
|
51
|
+
from vectorphile.core.tensor import abs as abs
|
|
52
|
+
|
|
53
|
+
# ── Autograd ─────────────────────────────────────────────────────────────────
|
|
54
|
+
from vectorphile import autograd
|
|
55
|
+
from vectorphile.autograd import no_grad
|
|
56
|
+
|
|
57
|
+
# ── Neural network ───────────────────────────────────────────────────────────
|
|
58
|
+
from vectorphile import nn
|
|
59
|
+
|
|
60
|
+
# ── Optimizers ───────────────────────────────────────────────────────────────
|
|
61
|
+
from vectorphile import optim
|
|
62
|
+
|
|
63
|
+
# ── Linear algebra ───────────────────────────────────────────────────────────
|
|
64
|
+
from vectorphile import linalg
|
|
65
|
+
|
|
66
|
+
# ── Statistics ───────────────────────────────────────────────────────────────
|
|
67
|
+
from vectorphile import stats
|
|
68
|
+
|
|
69
|
+
# ── Random ───────────────────────────────────────────────────────────────────
|
|
70
|
+
from vectorphile import random
|
|
71
|
+
|
|
72
|
+
# ── FFT ──────────────────────────────────────────────────────────────────────
|
|
73
|
+
from vectorphile import fft
|
|
74
|
+
|
|
75
|
+
# ── Signal ───────────────────────────────────────────────────────────────────
|
|
76
|
+
from vectorphile import signal
|
|
77
|
+
|
|
78
|
+
# ── Sparse ───────────────────────────────────────────────────────────────────
|
|
79
|
+
from vectorphile import sparse
|
|
80
|
+
|
|
81
|
+
# ── Optimization ─────────────────────────────────────────────────────────────
|
|
82
|
+
from vectorphile import optimize
|
|
83
|
+
|
|
84
|
+
# ── Automatic Mixed Precision ────────────────────────────────────────────────
|
|
85
|
+
from vectorphile import amp
|
|
86
|
+
|
|
87
|
+
# ── Data (DataFrame/Series) ──────────────────────────────────────────────────
|
|
88
|
+
from vectorphile import data
|
|
89
|
+
|
|
90
|
+
# ── Machine learning ─────────────────────────────────────────────────────────
|
|
91
|
+
from vectorphile import ml
|
|
92
|
+
|
|
93
|
+
# ── Utils (DataLoader, Dataset) ──────────────────────────────────────────────
|
|
94
|
+
from vectorphile import utils
|
|
95
|
+
from vectorphile.utils.data import Dataset, TensorDataset, DataLoader
|
|
96
|
+
|
|
97
|
+
# ── Convenience re-exports ───────────────────────────────────────────────────
|
|
98
|
+
from vectorphile.data import DataFrame, Series, read_csv, read_json
|
|
99
|
+
from vectorphile.ml import (
|
|
100
|
+
LinearRegression, Ridge, Lasso, ElasticNet, LogisticRegression,
|
|
101
|
+
DecisionTreeClassifier, DecisionTreeRegressor,
|
|
102
|
+
RandomForestClassifier, RandomForestRegressor,
|
|
103
|
+
KMeans, PCA, StandardScaler, MinMaxScaler,
|
|
104
|
+
train_test_split, accuracy_score,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# Device helpers (Phase 1: always CPU)
|
|
108
|
+
def device(dev: str) -> str:
|
|
109
|
+
return dev
|
|
110
|
+
|
|
111
|
+
def is_available() -> bool:
|
|
112
|
+
"""Returns True if CUDA is available (always False in Phase 1)."""
|
|
113
|
+
return False
|
|
114
|
+
|
|
115
|
+
cuda = type('cuda', (), {
|
|
116
|
+
'is_available': staticmethod(lambda: False),
|
|
117
|
+
'device_count': staticmethod(lambda: 0),
|
|
118
|
+
'get_device_name': staticmethod(lambda i=0: 'CPU'),
|
|
119
|
+
})()
|
|
120
|
+
|
|
121
|
+
# Type aliases
|
|
122
|
+
float32 = 'float32'
|
|
123
|
+
float64 = 'float64'
|
|
124
|
+
float16 = 'float16'
|
|
125
|
+
int32 = 'int32'
|
|
126
|
+
int64 = 'int64'
|
|
127
|
+
int8 = 'int8'
|
|
128
|
+
uint8 = 'uint8'
|
|
129
|
+
bool_ = 'bool'
|
|
130
|
+
half = 'float16'
|
|
131
|
+
double = 'float64'
|
|
132
|
+
long = 'int64'
|
|
133
|
+
|
|
134
|
+
__all__ = [
|
|
135
|
+
'Tensor', '__version__',
|
|
136
|
+
'tensor', 'zeros', 'ones', 'eye', 'arange', 'linspace', 'full', 'empty',
|
|
137
|
+
'rand', 'randn', 'randint', 'from_numpy',
|
|
138
|
+
'zeros_like', 'ones_like', 'empty_like',
|
|
139
|
+
'cat', 'stack', 'split', 'chunk', 'squeeze', 'unsqueeze', 'flatten',
|
|
140
|
+
'transpose', 'permute', 'matmul', 'dot', 'where', 'sum', 'mean', 'max', 'min',
|
|
141
|
+
'exp', 'log', 'sqrt', 'abs', 'clamp', 'softmax', 'log_softmax', 'sigmoid', 'relu', 'tanh', 'einsum',
|
|
142
|
+
'autograd', 'no_grad',
|
|
143
|
+
'nn', 'optim', 'linalg', 'stats', 'random', 'fft', 'signal', 'sparse', 'optimize', 'amp',
|
|
144
|
+
'data', 'ml', 'utils',
|
|
145
|
+
'Dataset', 'TensorDataset', 'DataLoader',
|
|
146
|
+
'DataFrame', 'Series', 'read_csv', 'read_json',
|
|
147
|
+
'LinearRegression', 'Ridge', 'Lasso', 'ElasticNet', 'LogisticRegression',
|
|
148
|
+
'DecisionTreeClassifier', 'DecisionTreeRegressor',
|
|
149
|
+
'RandomForestClassifier', 'RandomForestRegressor',
|
|
150
|
+
'KMeans', 'PCA', 'StandardScaler', 'MinMaxScaler',
|
|
151
|
+
'train_test_split', 'accuracy_score',
|
|
152
|
+
'cuda', 'device', 'is_available',
|
|
153
|
+
'float32', 'float64', 'float16', 'int32', 'int64', 'int8', 'uint8', 'bool_', 'half', 'double', 'long',
|
|
154
|
+
]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Automatic Mixed Precision (AMP) — Phase 2 will add real CUDA fp16 support."""
|
|
2
|
+
from contextlib import contextmanager
|
|
3
|
+
from typing import Optional
|
|
4
|
+
import numpy as np
|
|
5
|
+
from vectorphile.core.tensor import Tensor
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GradScaler:
|
|
9
|
+
"""Gradient scaler stub — no-op in Phase 1 (CPU only)."""
|
|
10
|
+
def __init__(self, init_scale=65536.0, growth_factor=2.0, backoff_factor=0.5,
|
|
11
|
+
growth_interval=2000, enabled=True):
|
|
12
|
+
self.enabled = enabled
|
|
13
|
+
self._scale = init_scale
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def scale(self):
|
|
17
|
+
return self._scale
|
|
18
|
+
|
|
19
|
+
def scale(self, loss):
|
|
20
|
+
return loss
|
|
21
|
+
|
|
22
|
+
def step(self, optimizer):
|
|
23
|
+
optimizer.step()
|
|
24
|
+
|
|
25
|
+
def update(self):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
def unscale_(self, optimizer):
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
def get_scale(self) -> float:
|
|
32
|
+
return self._scale
|
|
33
|
+
|
|
34
|
+
def is_enabled(self) -> bool:
|
|
35
|
+
return self.enabled
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@contextmanager
|
|
39
|
+
def autocast(device_type='cpu', dtype=None, enabled=True, cache_enabled=None):
|
|
40
|
+
"""Context manager for automatic mixed precision.
|
|
41
|
+
|
|
42
|
+
In Phase 1 (CPU), this is a no-op. Phase 2 will add real fp16/bf16 on CUDA.
|
|
43
|
+
"""
|
|
44
|
+
yield
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def is_autocast_enabled() -> bool:
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_autocast_dtype() -> str:
|
|
52
|
+
return 'float32'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from vectorphile.autograd.engine import (
|
|
2
|
+
backward, no_grad,
|
|
3
|
+
AddBackward, SubBackward, MulBackward, DivBackward, MatMulBackward,
|
|
4
|
+
ExpBackward, LogBackward, SqrtBackward, SumBackward, MeanBackward,
|
|
5
|
+
ReLUBackward, SigmoidBackward, TanhBackward,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
'backward', 'no_grad',
|
|
10
|
+
'AddBackward', 'SubBackward', 'MulBackward', 'DivBackward', 'MatMulBackward',
|
|
11
|
+
'ExpBackward', 'LogBackward', 'SqrtBackward', 'SumBackward', 'MeanBackward',
|
|
12
|
+
'ReLUBackward', 'SigmoidBackward', 'TanhBackward',
|
|
13
|
+
]
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"""Reverse-mode automatic differentiation engine."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
import numpy as np
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from vectorphile.core.tensor import Tensor
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _topo_sort(root: 'Tensor'):
|
|
11
|
+
visited, order = set(), []
|
|
12
|
+
def visit(node):
|
|
13
|
+
if id(node) not in visited:
|
|
14
|
+
visited.add(id(node))
|
|
15
|
+
if node.grad_fn is not None:
|
|
16
|
+
for inp in node.grad_fn.inputs:
|
|
17
|
+
if hasattr(inp, 'grad_fn'):
|
|
18
|
+
visit(inp)
|
|
19
|
+
order.append(node)
|
|
20
|
+
visit(root)
|
|
21
|
+
return reversed(order)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def backward(root: 'Tensor', gradient: 'Tensor'):
|
|
25
|
+
from vectorphile.core.tensor import Tensor
|
|
26
|
+
root.grad = gradient
|
|
27
|
+
for node in _topo_sort(root):
|
|
28
|
+
if node.grad_fn is None:
|
|
29
|
+
continue
|
|
30
|
+
grads = node.grad_fn.backward(node.grad)
|
|
31
|
+
for inp, g in zip(node.grad_fn.inputs, grads):
|
|
32
|
+
if not isinstance(inp, Tensor) or not inp.requires_grad:
|
|
33
|
+
continue
|
|
34
|
+
if g is None:
|
|
35
|
+
continue
|
|
36
|
+
if inp.grad is None:
|
|
37
|
+
inp.grad = Tensor(np.zeros_like(inp._data))
|
|
38
|
+
# Sum gradient over broadcast dimensions
|
|
39
|
+
g_data = _sum_to_shape(g._data if isinstance(g, Tensor) else g, inp._data.shape)
|
|
40
|
+
inp.grad._data += g_data
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _sum_to_shape(g: np.ndarray, shape) -> np.ndarray:
|
|
44
|
+
while g.ndim > len(shape):
|
|
45
|
+
g = g.sum(axis=0)
|
|
46
|
+
for i, (gs, s) in enumerate(zip(g.shape, shape)):
|
|
47
|
+
if s == 1 and gs != 1:
|
|
48
|
+
g = g.sum(axis=i, keepdims=True)
|
|
49
|
+
return g
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class Function:
|
|
53
|
+
def __init__(self, *inputs):
|
|
54
|
+
self.inputs = inputs
|
|
55
|
+
|
|
56
|
+
def backward(self, grad):
|
|
57
|
+
raise NotImplementedError
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class AddBackward(Function):
|
|
61
|
+
def backward(self, grad):
|
|
62
|
+
return grad, grad
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class SubBackward(Function):
|
|
66
|
+
def backward(self, grad):
|
|
67
|
+
from vectorphile.core.tensor import Tensor
|
|
68
|
+
neg = Tensor(-grad._data, device=grad.device)
|
|
69
|
+
return grad, neg
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class MulBackward(Function):
|
|
73
|
+
def __init__(self, a, b):
|
|
74
|
+
super().__init__(a, b)
|
|
75
|
+
self.a, self.b = a, b
|
|
76
|
+
|
|
77
|
+
def backward(self, grad):
|
|
78
|
+
from vectorphile.core.tensor import Tensor
|
|
79
|
+
a_data = self.a._data if hasattr(self.a, '_data') else np.array(self.a)
|
|
80
|
+
b_data = self.b._data if hasattr(self.b, '_data') else np.array(self.b)
|
|
81
|
+
return Tensor(grad._data * b_data), Tensor(grad._data * a_data)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class DivBackward(Function):
|
|
85
|
+
def __init__(self, a, b):
|
|
86
|
+
super().__init__(a, b)
|
|
87
|
+
self.a, self.b = a, b
|
|
88
|
+
|
|
89
|
+
def backward(self, grad):
|
|
90
|
+
from vectorphile.core.tensor import Tensor
|
|
91
|
+
a_data = self.a._data if hasattr(self.a, '_data') else np.array(self.a)
|
|
92
|
+
b_data = self.b._data if hasattr(self.b, '_data') else np.array(self.b)
|
|
93
|
+
da = grad._data / b_data
|
|
94
|
+
db = -grad._data * a_data / (b_data ** 2)
|
|
95
|
+
return Tensor(da), Tensor(db)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class MatMulBackward(Function):
|
|
99
|
+
def __init__(self, a, b):
|
|
100
|
+
super().__init__(a, b)
|
|
101
|
+
self.a, self.b = a, b
|
|
102
|
+
|
|
103
|
+
def backward(self, grad):
|
|
104
|
+
from vectorphile.core.tensor import Tensor
|
|
105
|
+
return Tensor(np.matmul(grad._data, self.b._data.T)), Tensor(np.matmul(self.a._data.T, grad._data))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class ExpBackward(Function):
|
|
109
|
+
def __init__(self, inp, out):
|
|
110
|
+
super().__init__(inp)
|
|
111
|
+
self.out = out
|
|
112
|
+
|
|
113
|
+
def backward(self, grad):
|
|
114
|
+
from vectorphile.core.tensor import Tensor
|
|
115
|
+
return (Tensor(grad._data * self.out._data),)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class LogBackward(Function):
|
|
119
|
+
def __init__(self, inp):
|
|
120
|
+
super().__init__(inp)
|
|
121
|
+
self.inp = inp
|
|
122
|
+
|
|
123
|
+
def backward(self, grad):
|
|
124
|
+
from vectorphile.core.tensor import Tensor
|
|
125
|
+
return (Tensor(grad._data / (self.inp._data + 1e-12)),)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class SqrtBackward(Function):
|
|
129
|
+
def __init__(self, inp, out):
|
|
130
|
+
super().__init__(inp)
|
|
131
|
+
self.out = out
|
|
132
|
+
|
|
133
|
+
def backward(self, grad):
|
|
134
|
+
from vectorphile.core.tensor import Tensor
|
|
135
|
+
return (Tensor(0.5 * grad._data / (self.out._data + 1e-12)),)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class SumBackward(Function):
|
|
139
|
+
def __init__(self, inp, dim, keepdim):
|
|
140
|
+
super().__init__(inp)
|
|
141
|
+
self.inp = inp
|
|
142
|
+
self.dim = dim
|
|
143
|
+
self.keepdim = keepdim
|
|
144
|
+
|
|
145
|
+
def backward(self, grad):
|
|
146
|
+
from vectorphile.core.tensor import Tensor
|
|
147
|
+
g = grad._data
|
|
148
|
+
if self.dim is not None and not self.keepdim:
|
|
149
|
+
g = np.expand_dims(g, axis=self.dim)
|
|
150
|
+
return (Tensor(np.broadcast_to(g, self.inp._data.shape).copy()),)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class MeanBackward(Function):
|
|
154
|
+
def __init__(self, inp, dim, keepdim):
|
|
155
|
+
super().__init__(inp)
|
|
156
|
+
self.inp = inp
|
|
157
|
+
self.dim = dim
|
|
158
|
+
self.keepdim = keepdim
|
|
159
|
+
|
|
160
|
+
def backward(self, grad):
|
|
161
|
+
from vectorphile.core.tensor import Tensor
|
|
162
|
+
g = grad._data
|
|
163
|
+
if self.dim is not None and not self.keepdim:
|
|
164
|
+
g = np.expand_dims(g, axis=self.dim)
|
|
165
|
+
n = self.inp._data.size if self.dim is None else self.inp._data.shape[self.dim]
|
|
166
|
+
return (Tensor(np.broadcast_to(g / n, self.inp._data.shape).copy()),)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class ReLUBackward(Function):
|
|
170
|
+
def __init__(self, inp):
|
|
171
|
+
super().__init__(inp)
|
|
172
|
+
self.inp = inp
|
|
173
|
+
|
|
174
|
+
def backward(self, grad):
|
|
175
|
+
from vectorphile.core.tensor import Tensor
|
|
176
|
+
return (Tensor(grad._data * (self.inp._data > 0).astype(np.float32)),)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class SigmoidBackward(Function):
|
|
180
|
+
def __init__(self, inp, out):
|
|
181
|
+
super().__init__(inp)
|
|
182
|
+
self.out = out
|
|
183
|
+
|
|
184
|
+
def backward(self, grad):
|
|
185
|
+
from vectorphile.core.tensor import Tensor
|
|
186
|
+
s = self.out._data
|
|
187
|
+
return (Tensor(grad._data * s * (1 - s)),)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class TanhBackward(Function):
|
|
191
|
+
def __init__(self, inp, out):
|
|
192
|
+
super().__init__(inp)
|
|
193
|
+
self.out = out
|
|
194
|
+
|
|
195
|
+
def backward(self, grad):
|
|
196
|
+
from vectorphile.core.tensor import Tensor
|
|
197
|
+
return (Tensor(grad._data * (1 - self.out._data ** 2)),)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class no_grad:
|
|
201
|
+
"""Context manager to disable gradient tracking."""
|
|
202
|
+
_enabled = True
|
|
203
|
+
|
|
204
|
+
def __enter__(self):
|
|
205
|
+
no_grad._enabled = False
|
|
206
|
+
|
|
207
|
+
def __exit__(self, *args):
|
|
208
|
+
no_grad._enabled = True
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from vectorphile.core.tensor import (
|
|
2
|
+
Tensor,
|
|
3
|
+
tensor, zeros, ones, eye, arange, linspace, full, empty,
|
|
4
|
+
rand, randn, randint, from_numpy,
|
|
5
|
+
zeros_like, ones_like, empty_like,
|
|
6
|
+
cat, stack, split, chunk, squeeze, unsqueeze, flatten, transpose, permute,
|
|
7
|
+
matmul, dot, where, max, min, sum, mean,
|
|
8
|
+
exp, log, sqrt, abs, clamp,
|
|
9
|
+
softmax, log_softmax, sigmoid, relu, tanh, einsum,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
'Tensor',
|
|
14
|
+
'tensor', 'zeros', 'ones', 'eye', 'arange', 'linspace', 'full', 'empty',
|
|
15
|
+
'rand', 'randn', 'randint', 'from_numpy',
|
|
16
|
+
'zeros_like', 'ones_like', 'empty_like',
|
|
17
|
+
'cat', 'stack', 'split', 'chunk', 'squeeze', 'unsqueeze', 'flatten',
|
|
18
|
+
'transpose', 'permute', 'matmul', 'dot', 'where', 'max', 'min', 'sum', 'mean',
|
|
19
|
+
'exp', 'log', 'sqrt', 'abs', 'clamp',
|
|
20
|
+
'softmax', 'log_softmax', 'sigmoid', 'relu', 'tanh', 'einsum',
|
|
21
|
+
]
|