modelit 0.1.0__tar.gz → 0.2.2__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.
- modelit-0.2.2/.github/workflows/publish.yml +39 -0
- modelit-0.2.2/.github/workflows/test.yml +19 -0
- modelit-0.2.2/.gitignore +15 -0
- {modelit-0.1.0/modelit.egg-info → modelit-0.2.2}/PKG-INFO +50 -29
- modelit-0.2.2/README.md +95 -0
- {modelit-0.1.0 → modelit-0.2.2}/modelit/registry.py +6 -26
- modelit-0.2.2/modelit/templates/backpropogation/template.py +483 -0
- {modelit-0.1.0 → modelit-0.2.2/modelit.egg-info}/PKG-INFO +50 -29
- {modelit-0.1.0 → modelit-0.2.2}/modelit.egg-info/SOURCES.txt +4 -1
- {modelit-0.1.0 → modelit-0.2.2}/pyproject.toml +7 -3
- modelit-0.1.0/README.md +0 -74
- modelit-0.1.0/modelit/templates/perceptron/metadata.json +0 -6
- {modelit-0.1.0 → modelit-0.2.2}/LICENSE +0 -0
- {modelit-0.1.0 → modelit-0.2.2}/MANIFEST.in +0 -0
- {modelit-0.1.0 → modelit-0.2.2}/modelit/__init__.py +0 -0
- {modelit-0.1.0 → modelit-0.2.2}/modelit/__main__.py +0 -0
- {modelit-0.1.0 → modelit-0.2.2}/modelit/cli.py +0 -0
- {modelit-0.1.0 → modelit-0.2.2}/modelit/templates/perceptron/template.py +0 -0
- {modelit-0.1.0 → modelit-0.2.2}/modelit.egg-info/dependency_links.txt +0 -0
- {modelit-0.1.0 → modelit-0.2.2}/modelit.egg-info/entry_points.txt +0 -0
- {modelit-0.1.0 → modelit-0.2.2}/modelit.egg-info/top_level.txt +0 -0
- {modelit-0.1.0 → modelit-0.2.2}/setup.cfg +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
with:
|
|
15
|
+
fetch-depth: 0
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.12"
|
|
19
|
+
- run: python -m pip install --upgrade pip build setuptools-scm
|
|
20
|
+
- run: python -m build
|
|
21
|
+
- uses: actions/upload-artifact@v4
|
|
22
|
+
with:
|
|
23
|
+
name: dist
|
|
24
|
+
path: dist/*
|
|
25
|
+
|
|
26
|
+
publish:
|
|
27
|
+
needs: build
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
environment:
|
|
30
|
+
name: pypi
|
|
31
|
+
url: https://pypi.org/p/modelit
|
|
32
|
+
permissions:
|
|
33
|
+
id-token: write
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/download-artifact@v4
|
|
36
|
+
with:
|
|
37
|
+
name: dist
|
|
38
|
+
path: dist
|
|
39
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: actions/setup-python@v5
|
|
13
|
+
with:
|
|
14
|
+
python-version: "3.12"
|
|
15
|
+
- run: python -m pip install --upgrade pip build twine
|
|
16
|
+
- run: python -m build
|
|
17
|
+
- run: twine check dist/*
|
|
18
|
+
- run: pip install dist/*.whl
|
|
19
|
+
- run: python -c "from modelit import perceptron; print(perceptron.__name__)"
|
modelit-0.2.2/.gitignore
ADDED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modelit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Local-first ML starter templates you can print or save
|
|
5
5
|
Author: Yashsmith
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,7 +20,14 @@ Dynamic: license-file
|
|
|
20
20
|
|
|
21
21
|
# ModelIt
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
ModelIt is a tiny Python package for storing your ML/DL boilerplate templates.
|
|
24
|
+
|
|
25
|
+
## What it does
|
|
26
|
+
|
|
27
|
+
- `from modelit import perceptron`
|
|
28
|
+
- `perceptron()` prints the full code
|
|
29
|
+
- `perceptron(output="code1.py")` saves it to a file
|
|
30
|
+
- `modelit create perceptron` works from the terminal
|
|
24
31
|
|
|
25
32
|
## Install
|
|
26
33
|
|
|
@@ -28,13 +35,15 @@ Tiny local-first ML template printer.
|
|
|
28
35
|
pip install modelit
|
|
29
36
|
```
|
|
30
37
|
|
|
31
|
-
For development
|
|
38
|
+
For local development:
|
|
32
39
|
|
|
33
40
|
```bash
|
|
34
41
|
pip install -e .
|
|
35
42
|
```
|
|
36
43
|
|
|
37
|
-
##
|
|
44
|
+
## Use it
|
|
45
|
+
|
|
46
|
+
### Simple Python Run which prints the code.
|
|
38
47
|
|
|
39
48
|
```python
|
|
40
49
|
from modelit import perceptron
|
|
@@ -42,13 +51,7 @@ from modelit import perceptron
|
|
|
42
51
|
perceptron()
|
|
43
52
|
```
|
|
44
53
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
modelit create perceptron
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Save to file
|
|
54
|
+
### Save to file And then Run so the file is created with code in it.
|
|
52
55
|
|
|
53
56
|
```python
|
|
54
57
|
from modelit import perceptron
|
|
@@ -56,39 +59,57 @@ from modelit import perceptron
|
|
|
56
59
|
perceptron(output="code1.py")
|
|
57
60
|
```
|
|
58
61
|
|
|
59
|
-
Or:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
modelit create perceptron --output code1.py
|
|
63
|
-
```
|
|
64
|
-
|
|
65
62
|
Then run:
|
|
66
63
|
|
|
67
64
|
```bash
|
|
68
65
|
python3 code1.py
|
|
69
66
|
```
|
|
70
67
|
|
|
71
|
-
|
|
68
|
+
### CLI
|
|
72
69
|
|
|
73
|
-
|
|
70
|
+
```bash
|
|
71
|
+
modelit create perceptron
|
|
72
|
+
modelit create perceptron --output code1.py
|
|
73
|
+
```
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
2. GitHub Actions builds and publishes to PyPI
|
|
77
|
-
3. Users install with `pip install modelit`
|
|
75
|
+
## Add a new code
|
|
78
76
|
|
|
79
|
-
|
|
77
|
+
1. Create a folder:
|
|
80
78
|
|
|
81
|
-
|
|
79
|
+
```text
|
|
80
|
+
modelit/templates/mycode/
|
|
81
|
+
```
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
2. Add your code file:
|
|
84
84
|
|
|
85
85
|
```text
|
|
86
|
-
modelit/templates
|
|
87
|
-
modelit/templates/<name>/metadata.json
|
|
86
|
+
modelit/templates/mycode/template.py
|
|
88
87
|
```
|
|
89
88
|
|
|
90
|
-
|
|
89
|
+
3. Done. The folder name becomes the function name.
|
|
90
|
+
|
|
91
|
+
That means this will work automatically:
|
|
91
92
|
|
|
92
93
|
```python
|
|
93
|
-
from modelit import
|
|
94
|
+
from modelit import mycode
|
|
95
|
+
|
|
96
|
+
mycode()
|
|
94
97
|
```
|
|
98
|
+
|
|
99
|
+
And this too:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
modelit create mycode
|
|
103
|
+
modelit create mycode --output mycode.py
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Publish flow
|
|
107
|
+
|
|
108
|
+
1. Add a new template folder.
|
|
109
|
+
2. `git add .`
|
|
110
|
+
3. `git commit -m "..."`
|
|
111
|
+
4. `git push`
|
|
112
|
+
5. `git tag v0.x.y`
|
|
113
|
+
6. `git push origin v0.x.y`
|
|
114
|
+
|
|
115
|
+
The version is taken from the git tag, so you do not edit `pyproject.toml` for releases.
|
modelit-0.2.2/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# ModelIt
|
|
2
|
+
|
|
3
|
+
ModelIt is a tiny Python package for storing your ML/DL boilerplate templates.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
- `from modelit import perceptron`
|
|
8
|
+
- `perceptron()` prints the full code
|
|
9
|
+
- `perceptron(output="code1.py")` saves it to a file
|
|
10
|
+
- `modelit create perceptron` works from the terminal
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install modelit
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
For local development:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install -e .
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Use it
|
|
25
|
+
|
|
26
|
+
### Simple Python Run which prints the code.
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from modelit import perceptron
|
|
30
|
+
|
|
31
|
+
perceptron()
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Save to file And then Run so the file is created with code in it.
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from modelit import perceptron
|
|
38
|
+
|
|
39
|
+
perceptron(output="code1.py")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Then run:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
python3 code1.py
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### CLI
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
modelit create perceptron
|
|
52
|
+
modelit create perceptron --output code1.py
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Add a new code
|
|
56
|
+
|
|
57
|
+
1. Create a folder:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
modelit/templates/mycode/
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
2. Add your code file:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
modelit/templates/mycode/template.py
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
3. Done. The folder name becomes the function name.
|
|
70
|
+
|
|
71
|
+
That means this will work automatically:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from modelit import mycode
|
|
75
|
+
|
|
76
|
+
mycode()
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
And this too:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
modelit create mycode
|
|
83
|
+
modelit create mycode --output mycode.py
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Publish flow
|
|
87
|
+
|
|
88
|
+
1. Add a new template folder.
|
|
89
|
+
2. `git add .`
|
|
90
|
+
3. `git commit -m "..."`
|
|
91
|
+
4. `git push`
|
|
92
|
+
5. `git tag v0.x.y`
|
|
93
|
+
6. `git push origin v0.x.y`
|
|
94
|
+
|
|
95
|
+
The version is taken from the git tag, so you do not edit `pyproject.toml` for releases.
|
|
@@ -5,22 +5,16 @@ from __future__ import annotations
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from importlib.resources import files
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
import json
|
|
9
|
-
import sys
|
|
10
8
|
|
|
11
9
|
|
|
12
10
|
PACKAGE_NAME = "modelit"
|
|
13
11
|
TEMPLATES_DIR = "templates"
|
|
14
12
|
TEMPLATE_FILENAME = "template.py"
|
|
15
|
-
METADATA_FILENAME = "metadata.json"
|
|
16
13
|
|
|
17
14
|
|
|
18
15
|
@dataclass(frozen=True)
|
|
19
16
|
class TemplateInfo:
|
|
20
17
|
name: str
|
|
21
|
-
title: str
|
|
22
|
-
output_file: str
|
|
23
|
-
description: str
|
|
24
18
|
|
|
25
19
|
|
|
26
20
|
def _templates_root():
|
|
@@ -44,21 +38,7 @@ def available_models() -> tuple[str, ...]:
|
|
|
44
38
|
|
|
45
39
|
|
|
46
40
|
def load_metadata(name: str) -> TemplateInfo:
|
|
47
|
-
|
|
48
|
-
data: dict[str, str] = {}
|
|
49
|
-
if metadata_path.is_file():
|
|
50
|
-
data = json.loads(metadata_path.read_text(encoding="utf-8"))
|
|
51
|
-
|
|
52
|
-
title = data.get("title") or name.replace("_", " ").title()
|
|
53
|
-
output_file = data.get("output_file") or f"{name}.py"
|
|
54
|
-
description = data.get("description") or f"Print the {title} template."
|
|
55
|
-
|
|
56
|
-
return TemplateInfo(
|
|
57
|
-
name=name,
|
|
58
|
-
title=title,
|
|
59
|
-
output_file=output_file,
|
|
60
|
-
description=description,
|
|
61
|
-
)
|
|
41
|
+
return TemplateInfo(name=name)
|
|
62
42
|
|
|
63
43
|
|
|
64
44
|
def load_source(name: str) -> str:
|
|
@@ -69,8 +49,9 @@ def load_source(name: str) -> str:
|
|
|
69
49
|
|
|
70
50
|
|
|
71
51
|
def build_template_callable(name: str):
|
|
72
|
-
info = load_metadata(name)
|
|
73
52
|
source = load_source(name)
|
|
53
|
+
info = load_metadata(name)
|
|
54
|
+
output_file = f"{name}.py"
|
|
74
55
|
|
|
75
56
|
def runner(output: str | None = None) -> None:
|
|
76
57
|
if output:
|
|
@@ -82,13 +63,12 @@ def build_template_callable(name: str):
|
|
|
82
63
|
print(f"Generated {path}")
|
|
83
64
|
return None
|
|
84
65
|
|
|
85
|
-
|
|
86
|
-
sys.stdout.write(chunk)
|
|
66
|
+
print(source, end="")
|
|
87
67
|
|
|
88
68
|
runner.__name__ = name
|
|
89
69
|
runner.__qualname__ = name
|
|
90
70
|
runner.__module__ = "modelit"
|
|
91
|
-
runner.__doc__ =
|
|
92
|
-
runner.output_file =
|
|
71
|
+
runner.__doc__ = f"Print or save the {name} template."
|
|
72
|
+
runner.output_file = output_file # type: ignore[attr-defined]
|
|
93
73
|
runner.template_info = info # type: ignore[attr-defined]
|
|
94
74
|
return runner
|
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
# =========================================================
|
|
2
|
+
# BACKPROPAGATION FROM SCRATCH
|
|
3
|
+
# XOR using SGD
|
|
4
|
+
# Xavier Initialization
|
|
5
|
+
# Titanic Dataset using MLPClassifier
|
|
6
|
+
# =========================================================
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# =========================================================
|
|
10
|
+
# IMPORTS
|
|
11
|
+
# =========================================================
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
import pandas as pd
|
|
15
|
+
|
|
16
|
+
from sklearn.datasets import load_breast_cancer
|
|
17
|
+
from sklearn.model_selection import train_test_split
|
|
18
|
+
from sklearn.neural_network import MLPClassifier
|
|
19
|
+
from sklearn.preprocessing import StandardScaler
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# =========================================================
|
|
23
|
+
# ACTIVATION FUNCTION
|
|
24
|
+
# SIGMOID
|
|
25
|
+
# =========================================================
|
|
26
|
+
|
|
27
|
+
def activation_func(net):
|
|
28
|
+
|
|
29
|
+
return 1 / (1 + np.exp(-net))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# =========================================================
|
|
33
|
+
# ERROR FUNCTION
|
|
34
|
+
# E = 1/2 (d - o)^2
|
|
35
|
+
# =========================================================
|
|
36
|
+
|
|
37
|
+
def calc_error(output, det_output):
|
|
38
|
+
|
|
39
|
+
return (1 / 2) * (det_output - output) ** 2
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# =========================================================
|
|
43
|
+
# FORWARD PASS
|
|
44
|
+
#
|
|
45
|
+
# Architecture:
|
|
46
|
+
# 2 Input Neurons
|
|
47
|
+
# 2 Hidden Neurons
|
|
48
|
+
# 1 Output Neuron
|
|
49
|
+
# =========================================================
|
|
50
|
+
|
|
51
|
+
def forward_pass(x_input, weights, biases):
|
|
52
|
+
|
|
53
|
+
# Hidden Neuron h0
|
|
54
|
+
net_h0 = (
|
|
55
|
+
(x_input[0] * weights[0]) +
|
|
56
|
+
(x_input[1] * weights[1]) +
|
|
57
|
+
biases[0]
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
outh0 = activation_func(net_h0)
|
|
61
|
+
|
|
62
|
+
# Hidden Neuron h1
|
|
63
|
+
net_h1 = (
|
|
64
|
+
(x_input[0] * weights[2]) +
|
|
65
|
+
(x_input[1] * weights[3]) +
|
|
66
|
+
biases[1]
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
outh1 = activation_func(net_h1)
|
|
70
|
+
|
|
71
|
+
# Output Neuron
|
|
72
|
+
net_o0 = (
|
|
73
|
+
(outh0 * weights[4]) +
|
|
74
|
+
(outh1 * weights[5]) +
|
|
75
|
+
biases[2]
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
out_o0 = activation_func(net_o0)
|
|
79
|
+
|
|
80
|
+
return outh0, outh1, out_o0
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# =========================================================
|
|
84
|
+
# BACKWARD PASS
|
|
85
|
+
# =========================================================
|
|
86
|
+
|
|
87
|
+
def backward_pass(
|
|
88
|
+
x_input,
|
|
89
|
+
weights,
|
|
90
|
+
biases,
|
|
91
|
+
desired_output,
|
|
92
|
+
learning_rate,
|
|
93
|
+
outh0,
|
|
94
|
+
outh1,
|
|
95
|
+
out_o0
|
|
96
|
+
):
|
|
97
|
+
|
|
98
|
+
# Output layer delta
|
|
99
|
+
delta_o0 = (
|
|
100
|
+
(desired_output - out_o0) *
|
|
101
|
+
out_o0 *
|
|
102
|
+
(1 - out_o0)
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
# Hidden layer deltas
|
|
106
|
+
delta_h0 = (
|
|
107
|
+
delta_o0 *
|
|
108
|
+
weights[4] *
|
|
109
|
+
outh0 *
|
|
110
|
+
(1 - outh0)
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
delta_h1 = (
|
|
114
|
+
delta_o0 *
|
|
115
|
+
weights[5] *
|
|
116
|
+
outh1 *
|
|
117
|
+
(1 - outh1)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Weight updates
|
|
121
|
+
dw0 = learning_rate * delta_h0 * x_input[0]
|
|
122
|
+
dw1 = learning_rate * delta_h0 * x_input[1]
|
|
123
|
+
|
|
124
|
+
dw2 = learning_rate * delta_h1 * x_input[0]
|
|
125
|
+
dw3 = learning_rate * delta_h1 * x_input[1]
|
|
126
|
+
|
|
127
|
+
dw4 = learning_rate * delta_o0 * outh0
|
|
128
|
+
dw5 = learning_rate * delta_o0 * outh1
|
|
129
|
+
|
|
130
|
+
dw_values = [dw0, dw1, dw2, dw3, dw4, dw5]
|
|
131
|
+
|
|
132
|
+
# Bias updates
|
|
133
|
+
db0 = learning_rate * delta_h0
|
|
134
|
+
db1 = learning_rate * delta_h1
|
|
135
|
+
db2 = learning_rate * delta_o0
|
|
136
|
+
|
|
137
|
+
db_values = [db0, db1, db2]
|
|
138
|
+
|
|
139
|
+
return dw_values, db_values
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# =========================================================
|
|
143
|
+
# XOR DATASET
|
|
144
|
+
# =========================================================
|
|
145
|
+
|
|
146
|
+
x1 = [0, 0]
|
|
147
|
+
x2 = [0, 1]
|
|
148
|
+
x3 = [1, 0]
|
|
149
|
+
x4 = [1, 1]
|
|
150
|
+
|
|
151
|
+
y = [0, 1, 1, 0]
|
|
152
|
+
|
|
153
|
+
X = [x1, x2, x3, x4]
|
|
154
|
+
d = y
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
# =========================================================
|
|
158
|
+
# INITIAL WEIGHTS AND BIASES
|
|
159
|
+
# =========================================================
|
|
160
|
+
|
|
161
|
+
w = [0.5, -0.3, 0.8, 0.2, 0.6, -0.5]
|
|
162
|
+
|
|
163
|
+
b = [0.2, -0.4, 0.3]
|
|
164
|
+
|
|
165
|
+
learning_rate_initial = 0.01
|
|
166
|
+
|
|
167
|
+
epochs = 2000
|
|
168
|
+
|
|
169
|
+
error_threshold = 0.001
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# =========================================================
|
|
173
|
+
# TRAINING USING SGD
|
|
174
|
+
# =========================================================
|
|
175
|
+
|
|
176
|
+
def train_SGD(
|
|
177
|
+
X_data,
|
|
178
|
+
y_data,
|
|
179
|
+
epochs_count,
|
|
180
|
+
lr_val,
|
|
181
|
+
initial_weights_list,
|
|
182
|
+
initial_biases_list
|
|
183
|
+
):
|
|
184
|
+
|
|
185
|
+
w1, w2, w3, w4, w5, w6 = (
|
|
186
|
+
initial_weights_list[0],
|
|
187
|
+
initial_weights_list[1],
|
|
188
|
+
initial_weights_list[2],
|
|
189
|
+
initial_weights_list[3],
|
|
190
|
+
initial_weights_list[4],
|
|
191
|
+
initial_weights_list[5]
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
b1, b2, b3 = (
|
|
195
|
+
initial_biases_list[0],
|
|
196
|
+
initial_biases_list[1],
|
|
197
|
+
initial_biases_list[2]
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
for epoch in range(epochs_count):
|
|
201
|
+
|
|
202
|
+
total_loss = 0
|
|
203
|
+
|
|
204
|
+
for i in range(len(X_data)):
|
|
205
|
+
|
|
206
|
+
x_input = X_data[i]
|
|
207
|
+
|
|
208
|
+
target = y_data[i]
|
|
209
|
+
|
|
210
|
+
current_weights = [w1, w2, w3, w4, w5, w6]
|
|
211
|
+
|
|
212
|
+
current_biases = [b1, b2, b3]
|
|
213
|
+
|
|
214
|
+
# Forward pass
|
|
215
|
+
outh0, outh1, out_o0 = forward_pass(
|
|
216
|
+
x_input,
|
|
217
|
+
current_weights,
|
|
218
|
+
current_biases
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# Loss
|
|
222
|
+
current_loss = calc_error(out_o0, target)
|
|
223
|
+
|
|
224
|
+
total_loss += current_loss
|
|
225
|
+
|
|
226
|
+
# Backpropagation
|
|
227
|
+
dw_values, db_values = backward_pass(
|
|
228
|
+
x_input,
|
|
229
|
+
current_weights,
|
|
230
|
+
current_biases,
|
|
231
|
+
target,
|
|
232
|
+
lr_val,
|
|
233
|
+
outh0,
|
|
234
|
+
outh1,
|
|
235
|
+
out_o0
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
# Update weights
|
|
239
|
+
w1 += dw_values[0]
|
|
240
|
+
w2 += dw_values[1]
|
|
241
|
+
w3 += dw_values[2]
|
|
242
|
+
w4 += dw_values[3]
|
|
243
|
+
w5 += dw_values[4]
|
|
244
|
+
w6 += dw_values[5]
|
|
245
|
+
|
|
246
|
+
# Update biases
|
|
247
|
+
b1 += db_values[0]
|
|
248
|
+
b2 += db_values[1]
|
|
249
|
+
b3 += db_values[2]
|
|
250
|
+
|
|
251
|
+
# Print every 100 epochs
|
|
252
|
+
if epoch % 100 == 0 or total_loss < error_threshold:
|
|
253
|
+
|
|
254
|
+
print(f"\nEpoch {epoch}")
|
|
255
|
+
|
|
256
|
+
print(f"Total Error = {total_loss:.6f}")
|
|
257
|
+
|
|
258
|
+
output_example = forward_pass(
|
|
259
|
+
X_data[0],
|
|
260
|
+
[w1, w2, w3, w4, w5, w6],
|
|
261
|
+
[b1, b2, b3]
|
|
262
|
+
)[2]
|
|
263
|
+
|
|
264
|
+
print(
|
|
265
|
+
f"Output for input {X_data[0]} : "
|
|
266
|
+
f"{output_example:.4f}"
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
# Early stopping
|
|
270
|
+
if total_loss < error_threshold:
|
|
271
|
+
|
|
272
|
+
print(
|
|
273
|
+
f"\nStopping condition met at epoch "
|
|
274
|
+
f"{epoch + 1}"
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
print(
|
|
278
|
+
f"Total Error ({total_loss:.6f}) "
|
|
279
|
+
f"<= Threshold ({error_threshold:.6f})"
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
break
|
|
283
|
+
|
|
284
|
+
updated_weights = [w1, w2, w3, w4, w5, w6]
|
|
285
|
+
|
|
286
|
+
updated_biases = [b1, b2, b3]
|
|
287
|
+
|
|
288
|
+
return updated_weights, updated_biases
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
# =========================================================
|
|
292
|
+
# TRAIN XOR NETWORK
|
|
293
|
+
# =========================================================
|
|
294
|
+
|
|
295
|
+
updated_w, updated_b = train_SGD(
|
|
296
|
+
X,
|
|
297
|
+
d,
|
|
298
|
+
epochs,
|
|
299
|
+
learning_rate_initial,
|
|
300
|
+
w,
|
|
301
|
+
b
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
# =========================================================
|
|
306
|
+
# FINAL WEIGHTS
|
|
307
|
+
# =========================================================
|
|
308
|
+
|
|
309
|
+
print("\nFinal Updated Weights:")
|
|
310
|
+
|
|
311
|
+
for i, weight in enumerate(updated_w):
|
|
312
|
+
|
|
313
|
+
print(f"w{i + 1} = {weight:.4f}")
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
# =========================================================
|
|
317
|
+
# FINAL BIASES
|
|
318
|
+
# =========================================================
|
|
319
|
+
|
|
320
|
+
print("\nFinal Updated Biases:")
|
|
321
|
+
|
|
322
|
+
for i, bias in enumerate(updated_b):
|
|
323
|
+
|
|
324
|
+
print(f"b{i + 1} = {bias:.4f}")
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
# =========================================================
|
|
328
|
+
# TEST XOR OUTPUTS
|
|
329
|
+
# =========================================================
|
|
330
|
+
|
|
331
|
+
print("\n=================================================")
|
|
332
|
+
print("XOR Predictions")
|
|
333
|
+
print("=================================================")
|
|
334
|
+
|
|
335
|
+
for i in range(len(X)):
|
|
336
|
+
|
|
337
|
+
_, _, prediction = forward_pass(
|
|
338
|
+
X[i],
|
|
339
|
+
updated_w,
|
|
340
|
+
updated_b
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
print(
|
|
344
|
+
f"Input: {X[i]} "
|
|
345
|
+
f"Target: {d[i]} "
|
|
346
|
+
f"Prediction: {prediction:.4f}"
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
# =========================================================
|
|
351
|
+
# XAVIER INITIALIZATION
|
|
352
|
+
# =========================================================
|
|
353
|
+
|
|
354
|
+
print("\n=================================================")
|
|
355
|
+
print("Xavier Initialization")
|
|
356
|
+
print("=================================================")
|
|
357
|
+
|
|
358
|
+
nin = 2
|
|
359
|
+
nhidden = 2
|
|
360
|
+
nout = 1
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def xavier(nin, nout):
|
|
364
|
+
|
|
365
|
+
limit = np.sqrt(6 / (nin + nout))
|
|
366
|
+
|
|
367
|
+
return np.random.uniform(
|
|
368
|
+
-limit,
|
|
369
|
+
limit,
|
|
370
|
+
(nin, nout)
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
w1_xavier = xavier(nin, nhidden)
|
|
375
|
+
|
|
376
|
+
w2_xavier = xavier(nhidden, nout)
|
|
377
|
+
|
|
378
|
+
print("\nWeights between Input -> Hidden:")
|
|
379
|
+
print(w1_xavier)
|
|
380
|
+
|
|
381
|
+
print("\nWeights between Hidden -> Output:")
|
|
382
|
+
print(w2_xavier)
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
# =========================================================
|
|
386
|
+
# TITANIC DATASET USING MLPClassifier
|
|
387
|
+
# =========================================================
|
|
388
|
+
|
|
389
|
+
print("\n=================================================")
|
|
390
|
+
print("Breast Cancer Dataset using MLPClassifier")
|
|
391
|
+
print("=================================================")
|
|
392
|
+
|
|
393
|
+
dataset = load_breast_cancer(as_frame=True)
|
|
394
|
+
df = dataset.frame
|
|
395
|
+
|
|
396
|
+
print("\nDataset Head:")
|
|
397
|
+
print(df.head())
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
# =========================================================
|
|
401
|
+
# FEATURES AND LABELS
|
|
402
|
+
# =========================================================
|
|
403
|
+
|
|
404
|
+
X_cancer = df.drop(columns=["target"])
|
|
405
|
+
y_cancer = df["target"]
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
# =========================================================
|
|
409
|
+
# FEATURE SCALING
|
|
410
|
+
# =========================================================
|
|
411
|
+
|
|
412
|
+
scaler = StandardScaler()
|
|
413
|
+
X_scaled = scaler.fit_transform(X_cancer)
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
# =========================================================
|
|
417
|
+
# TRAIN TEST SPLIT
|
|
418
|
+
# =========================================================
|
|
419
|
+
|
|
420
|
+
X_train, X_test, y_train, y_test = train_test_split(
|
|
421
|
+
X_scaled,
|
|
422
|
+
y_cancer,
|
|
423
|
+
test_size=0.2,
|
|
424
|
+
random_state=42
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
# =========================================================
|
|
429
|
+
# MLP MODEL
|
|
430
|
+
# =========================================================
|
|
431
|
+
|
|
432
|
+
mlp = MLPClassifier(
|
|
433
|
+
hidden_layer_sizes=(10,),
|
|
434
|
+
activation="logistic",
|
|
435
|
+
solver="sgd",
|
|
436
|
+
learning_rate_init=0.01,
|
|
437
|
+
random_state=42,
|
|
438
|
+
max_iter=2000
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
# =========================================================
|
|
443
|
+
# TRAIN MODEL
|
|
444
|
+
# =========================================================
|
|
445
|
+
|
|
446
|
+
mlp.fit(X_train, y_train)
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
# =========================================================
|
|
450
|
+
# PRINT WEIGHTS
|
|
451
|
+
# =========================================================
|
|
452
|
+
|
|
453
|
+
print("\nWeights (Coefficients):")
|
|
454
|
+
|
|
455
|
+
for i, coef in enumerate(mlp.coefs_):
|
|
456
|
+
|
|
457
|
+
print(f"\nLayer {i} weights:\n")
|
|
458
|
+
|
|
459
|
+
print(coef)
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
# =========================================================
|
|
463
|
+
# PRINT BIASES
|
|
464
|
+
# =========================================================
|
|
465
|
+
|
|
466
|
+
print("\nBiases (Intercepts):")
|
|
467
|
+
|
|
468
|
+
for i, intercept in enumerate(mlp.intercepts_):
|
|
469
|
+
|
|
470
|
+
print(f"\nLayer {i} biases:\n")
|
|
471
|
+
|
|
472
|
+
print(intercept)
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
# =========================================================
|
|
476
|
+
# MODEL ACCURACY
|
|
477
|
+
# =========================================================
|
|
478
|
+
|
|
479
|
+
accuracy = mlp.score(X_test, y_test)
|
|
480
|
+
|
|
481
|
+
print("\n=================================================")
|
|
482
|
+
print(f"Model Accuracy: {accuracy * 100:.2f}%")
|
|
483
|
+
print("=================================================")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modelit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Local-first ML starter templates you can print or save
|
|
5
5
|
Author: Yashsmith
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,7 +20,14 @@ Dynamic: license-file
|
|
|
20
20
|
|
|
21
21
|
# ModelIt
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
ModelIt is a tiny Python package for storing your ML/DL boilerplate templates.
|
|
24
|
+
|
|
25
|
+
## What it does
|
|
26
|
+
|
|
27
|
+
- `from modelit import perceptron`
|
|
28
|
+
- `perceptron()` prints the full code
|
|
29
|
+
- `perceptron(output="code1.py")` saves it to a file
|
|
30
|
+
- `modelit create perceptron` works from the terminal
|
|
24
31
|
|
|
25
32
|
## Install
|
|
26
33
|
|
|
@@ -28,13 +35,15 @@ Tiny local-first ML template printer.
|
|
|
28
35
|
pip install modelit
|
|
29
36
|
```
|
|
30
37
|
|
|
31
|
-
For development
|
|
38
|
+
For local development:
|
|
32
39
|
|
|
33
40
|
```bash
|
|
34
41
|
pip install -e .
|
|
35
42
|
```
|
|
36
43
|
|
|
37
|
-
##
|
|
44
|
+
## Use it
|
|
45
|
+
|
|
46
|
+
### Simple Python Run which prints the code.
|
|
38
47
|
|
|
39
48
|
```python
|
|
40
49
|
from modelit import perceptron
|
|
@@ -42,13 +51,7 @@ from modelit import perceptron
|
|
|
42
51
|
perceptron()
|
|
43
52
|
```
|
|
44
53
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
modelit create perceptron
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Save to file
|
|
54
|
+
### Save to file And then Run so the file is created with code in it.
|
|
52
55
|
|
|
53
56
|
```python
|
|
54
57
|
from modelit import perceptron
|
|
@@ -56,39 +59,57 @@ from modelit import perceptron
|
|
|
56
59
|
perceptron(output="code1.py")
|
|
57
60
|
```
|
|
58
61
|
|
|
59
|
-
Or:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
modelit create perceptron --output code1.py
|
|
63
|
-
```
|
|
64
|
-
|
|
65
62
|
Then run:
|
|
66
63
|
|
|
67
64
|
```bash
|
|
68
65
|
python3 code1.py
|
|
69
66
|
```
|
|
70
67
|
|
|
71
|
-
|
|
68
|
+
### CLI
|
|
72
69
|
|
|
73
|
-
|
|
70
|
+
```bash
|
|
71
|
+
modelit create perceptron
|
|
72
|
+
modelit create perceptron --output code1.py
|
|
73
|
+
```
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
2. GitHub Actions builds and publishes to PyPI
|
|
77
|
-
3. Users install with `pip install modelit`
|
|
75
|
+
## Add a new code
|
|
78
76
|
|
|
79
|
-
|
|
77
|
+
1. Create a folder:
|
|
80
78
|
|
|
81
|
-
|
|
79
|
+
```text
|
|
80
|
+
modelit/templates/mycode/
|
|
81
|
+
```
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
2. Add your code file:
|
|
84
84
|
|
|
85
85
|
```text
|
|
86
|
-
modelit/templates
|
|
87
|
-
modelit/templates/<name>/metadata.json
|
|
86
|
+
modelit/templates/mycode/template.py
|
|
88
87
|
```
|
|
89
88
|
|
|
90
|
-
|
|
89
|
+
3. Done. The folder name becomes the function name.
|
|
90
|
+
|
|
91
|
+
That means this will work automatically:
|
|
91
92
|
|
|
92
93
|
```python
|
|
93
|
-
from modelit import
|
|
94
|
+
from modelit import mycode
|
|
95
|
+
|
|
96
|
+
mycode()
|
|
94
97
|
```
|
|
98
|
+
|
|
99
|
+
And this too:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
modelit create mycode
|
|
103
|
+
modelit create mycode --output mycode.py
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Publish flow
|
|
107
|
+
|
|
108
|
+
1. Add a new template folder.
|
|
109
|
+
2. `git add .`
|
|
110
|
+
3. `git commit -m "..."`
|
|
111
|
+
4. `git push`
|
|
112
|
+
5. `git tag v0.x.y`
|
|
113
|
+
6. `git push origin v0.x.y`
|
|
114
|
+
|
|
115
|
+
The version is taken from the git tag, so you do not edit `pyproject.toml` for releases.
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
.gitignore
|
|
1
2
|
LICENSE
|
|
2
3
|
MANIFEST.in
|
|
3
4
|
README.md
|
|
4
5
|
pyproject.toml
|
|
6
|
+
.github/workflows/publish.yml
|
|
7
|
+
.github/workflows/test.yml
|
|
5
8
|
modelit/__init__.py
|
|
6
9
|
modelit/__main__.py
|
|
7
10
|
modelit/cli.py
|
|
@@ -11,5 +14,5 @@ modelit.egg-info/SOURCES.txt
|
|
|
11
14
|
modelit.egg-info/dependency_links.txt
|
|
12
15
|
modelit.egg-info/entry_points.txt
|
|
13
16
|
modelit.egg-info/top_level.txt
|
|
14
|
-
modelit/templates/
|
|
17
|
+
modelit/templates/backpropogation/template.py
|
|
15
18
|
modelit/templates/perceptron/template.py
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=77", "wheel"]
|
|
2
|
+
requires = ["setuptools>=77", "wheel", "setuptools-scm>=8"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "modelit"
|
|
7
|
-
|
|
7
|
+
dynamic = ["version"]
|
|
8
8
|
description = "Local-first ML starter templates you can print or save"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -36,4 +36,8 @@ where = ["."]
|
|
|
36
36
|
include = ["modelit*"]
|
|
37
37
|
|
|
38
38
|
[tool.setuptools.package-data]
|
|
39
|
-
modelit = ["templates/*/*.py"
|
|
39
|
+
modelit = ["templates/*/*.py"]
|
|
40
|
+
|
|
41
|
+
[tool.setuptools_scm]
|
|
42
|
+
version_scheme = "guess-next-dev"
|
|
43
|
+
local_scheme = "no-local-version"
|
modelit-0.1.0/README.md
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# ModelIt
|
|
2
|
-
|
|
3
|
-
Tiny local-first ML template printer.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pip install modelit
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
For development from a clone, use:
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
pip install -e .
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Run
|
|
18
|
-
|
|
19
|
-
```python
|
|
20
|
-
from modelit import perceptron
|
|
21
|
-
|
|
22
|
-
perceptron()
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Or from CLI:
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
modelit create perceptron
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Save to file
|
|
32
|
-
|
|
33
|
-
```python
|
|
34
|
-
from modelit import perceptron
|
|
35
|
-
|
|
36
|
-
perceptron(output="code1.py")
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Or:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
modelit create perceptron --output code1.py
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Then run:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
python3 code1.py
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Publish
|
|
52
|
-
|
|
53
|
-
This project is set up for PyPI publishing with GitHub Actions.
|
|
54
|
-
|
|
55
|
-
1. Push a tag like `v0.1.0`
|
|
56
|
-
2. GitHub Actions builds and publishes to PyPI
|
|
57
|
-
3. Users install with `pip install modelit`
|
|
58
|
-
|
|
59
|
-
To update later, change the version, add your new templates, and publish a new tag.
|
|
60
|
-
|
|
61
|
-
## Add a new code
|
|
62
|
-
|
|
63
|
-
Create:
|
|
64
|
-
|
|
65
|
-
```text
|
|
66
|
-
modelit/templates/<name>/template.py
|
|
67
|
-
modelit/templates/<name>/metadata.json
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Then the new name is exposed automatically as:
|
|
71
|
-
|
|
72
|
-
```python
|
|
73
|
-
from modelit import <name>
|
|
74
|
-
```
|
|
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
|