dlspit 1.0.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.
- dlspit-1.0.0/PKG-INFO +118 -0
- dlspit-1.0.0/README.md +85 -0
- dlspit-1.0.0/dl_experiments/__init__.py +56 -0
- dlspit-1.0.0/dl_experiments/__main__.py +40 -0
- dlspit-1.0.0/dl_experiments/experiments/__init__.py +32 -0
- dlspit-1.0.0/dl_experiments/experiments/exp10_transfer.py +220 -0
- dlspit-1.0.0/dl_experiments/experiments/exp1a_mcculloch_pitts.py +94 -0
- dlspit-1.0.0/dl_experiments/experiments/exp1b_mlp_binary.py +113 -0
- dlspit-1.0.0/dl_experiments/experiments/exp2a_activations.py +148 -0
- dlspit-1.0.0/dl_experiments/experiments/exp2b_backprop_mnist.py +128 -0
- dlspit-1.0.0/dl_experiments/experiments/exp3_regularisation.py +154 -0
- dlspit-1.0.0/dl_experiments/experiments/exp4_cnn.py +164 -0
- dlspit-1.0.0/dl_experiments/experiments/exp5_resnet.py +184 -0
- dlspit-1.0.0/dl_experiments/experiments/exp6_rnn.py +168 -0
- dlspit-1.0.0/dl_experiments/experiments/exp7_lstm.py +186 -0
- dlspit-1.0.0/dl_experiments/experiments/exp8_transformer.py +180 -0
- dlspit-1.0.0/dl_experiments/experiments/exp9_gan.py +189 -0
- dlspit-1.0.0/dl_experiments/experiments/exp9b_vae.py +257 -0
- dlspit-1.0.0/dl_experiments/utils/__init__.py +1 -0
- dlspit-1.0.0/dl_experiments/utils/registry.py +43 -0
- dlspit-1.0.0/pyproject.toml +73 -0
dlspit-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dlspit
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A collection of Deep Learning experiments: MLP, CNN, ResNet, RNN, LSTM, Transformer, GAN, VAE, Transfer Learning.
|
|
5
|
+
Project-URL: Repository, https://github.com/PrathamShid07/DL_Expts
|
|
6
|
+
Project-URL: Issues, https://github.com/PrathamShid07/DL_Expts/issues
|
|
7
|
+
Author-email: Pratham <pratham.shid23@spit.ac.in>
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: cnn,deep-learning,gan,lstm,mlp,neural-network,pytorch,resnet,rnn,transformer,vae
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Education
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Requires-Dist: numpy>=1.24
|
|
20
|
+
Provides-Extra: all
|
|
21
|
+
Requires-Dist: scikit-learn>=1.3; extra == 'all'
|
|
22
|
+
Requires-Dist: tensorflow>=2.12; extra == 'all'
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: hatchling>=1.18; extra == 'dev'
|
|
26
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
28
|
+
Provides-Extra: sklearn
|
|
29
|
+
Requires-Dist: scikit-learn>=1.3; extra == 'sklearn'
|
|
30
|
+
Provides-Extra: tensorflow
|
|
31
|
+
Requires-Dist: tensorflow>=2.12; extra == 'tensorflow'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# dl-experiments-ps07
|
|
35
|
+
|
|
36
|
+
A pip-installable collection of Deep Learning experiment modules covering
|
|
37
|
+
McCulloch-Pitts neurons, MLP, backpropagation, CNN, ResNet, RNN, LSTM,
|
|
38
|
+
Transformer, GAN, VAE, and Transfer Learning.
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Core (NumPy only — Exp 1a, 1b, 2a, 3)
|
|
44
|
+
pip install dl-experiments-ps07
|
|
45
|
+
|
|
46
|
+
# With scikit-learn (Exp 2b MNIST loader)
|
|
47
|
+
pip install "dl-experiments-ps07[sklearn]"
|
|
48
|
+
|
|
49
|
+
# With PyTorch (Exp 4–10)
|
|
50
|
+
pip install "dl-experiments-ps07[torch]"
|
|
51
|
+
|
|
52
|
+
# Everything
|
|
53
|
+
pip install "dl-experiments-ps07[all]"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
### Python API
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
import dl_experiments
|
|
62
|
+
|
|
63
|
+
# Run ALL experiments
|
|
64
|
+
dl_experiments.main()
|
|
65
|
+
|
|
66
|
+
# Run specific experiments
|
|
67
|
+
dl_experiments.main("1a") # McCulloch-Pitts
|
|
68
|
+
dl_experiments.main("4", "5") # CNN + ResNet
|
|
69
|
+
|
|
70
|
+
# List available keys
|
|
71
|
+
print(dl_experiments.list_experiments())
|
|
72
|
+
# ['1a', '1b', '2a', '2b', '3', '4', '5', '6', '7', '8', '9', '9b', '10']
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### CLI
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Run all experiments
|
|
79
|
+
dl-experiments
|
|
80
|
+
|
|
81
|
+
# Run specific experiments
|
|
82
|
+
dl-experiments 1a 2a 3
|
|
83
|
+
|
|
84
|
+
# List available experiments
|
|
85
|
+
dl-experiments --list
|
|
86
|
+
|
|
87
|
+
# As a module
|
|
88
|
+
python -m dl_experiments 1a 1b
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Experiment Index
|
|
92
|
+
|
|
93
|
+
| Key | Module | Description |
|
|
94
|
+
|-----|--------|-------------|
|
|
95
|
+
| 1a | McCulloch-Pitts | Binary threshold neuron, logic gates |
|
|
96
|
+
| 1b | MLP Binary | XOR with 2-layer MLP |
|
|
97
|
+
| 2a | Activations & Losses | Sigmoid, Tanh, ReLU, MSE, BCE |
|
|
98
|
+
| 2b | Backprop MNIST | NumPy backprop on MNIST |
|
|
99
|
+
| 3 | Regularisation | L2 + Dropout |
|
|
100
|
+
| 4 | CNN | Conv2d + MaxPool |
|
|
101
|
+
| 5 | ResNet | Skip connections |
|
|
102
|
+
| 6 | RNN | Vanilla RNN sequence prediction |
|
|
103
|
+
| 7 | LSTM | Long Short-Term Memory |
|
|
104
|
+
| 8 | Transformer | Multi-head self-attention |
|
|
105
|
+
| 9 | GAN | Generator + Discriminator |
|
|
106
|
+
| 9b | VAE | Variational Autoencoder |
|
|
107
|
+
| 10 | Transfer | Frozen backbone + custom head |
|
|
108
|
+
|
|
109
|
+
## Requirements
|
|
110
|
+
|
|
111
|
+
- Python ≥ 3.10
|
|
112
|
+
- numpy ≥ 1.24
|
|
113
|
+
- (Optional) scikit-learn ≥ 1.3 — for Exp 2b
|
|
114
|
+
- (Optional) torch ≥ 2.0, torchvision ≥ 0.15 — for Exp 4–10
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
MIT
|
dlspit-1.0.0/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# dl-experiments-ps07
|
|
2
|
+
|
|
3
|
+
A pip-installable collection of Deep Learning experiment modules covering
|
|
4
|
+
McCulloch-Pitts neurons, MLP, backpropagation, CNN, ResNet, RNN, LSTM,
|
|
5
|
+
Transformer, GAN, VAE, and Transfer Learning.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Core (NumPy only — Exp 1a, 1b, 2a, 3)
|
|
11
|
+
pip install dl-experiments-ps07
|
|
12
|
+
|
|
13
|
+
# With scikit-learn (Exp 2b MNIST loader)
|
|
14
|
+
pip install "dl-experiments-ps07[sklearn]"
|
|
15
|
+
|
|
16
|
+
# With PyTorch (Exp 4–10)
|
|
17
|
+
pip install "dl-experiments-ps07[torch]"
|
|
18
|
+
|
|
19
|
+
# Everything
|
|
20
|
+
pip install "dl-experiments-ps07[all]"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Python API
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
import dl_experiments
|
|
29
|
+
|
|
30
|
+
# Run ALL experiments
|
|
31
|
+
dl_experiments.main()
|
|
32
|
+
|
|
33
|
+
# Run specific experiments
|
|
34
|
+
dl_experiments.main("1a") # McCulloch-Pitts
|
|
35
|
+
dl_experiments.main("4", "5") # CNN + ResNet
|
|
36
|
+
|
|
37
|
+
# List available keys
|
|
38
|
+
print(dl_experiments.list_experiments())
|
|
39
|
+
# ['1a', '1b', '2a', '2b', '3', '4', '5', '6', '7', '8', '9', '9b', '10']
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### CLI
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Run all experiments
|
|
46
|
+
dl-experiments
|
|
47
|
+
|
|
48
|
+
# Run specific experiments
|
|
49
|
+
dl-experiments 1a 2a 3
|
|
50
|
+
|
|
51
|
+
# List available experiments
|
|
52
|
+
dl-experiments --list
|
|
53
|
+
|
|
54
|
+
# As a module
|
|
55
|
+
python -m dl_experiments 1a 1b
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Experiment Index
|
|
59
|
+
|
|
60
|
+
| Key | Module | Description |
|
|
61
|
+
|-----|--------|-------------|
|
|
62
|
+
| 1a | McCulloch-Pitts | Binary threshold neuron, logic gates |
|
|
63
|
+
| 1b | MLP Binary | XOR with 2-layer MLP |
|
|
64
|
+
| 2a | Activations & Losses | Sigmoid, Tanh, ReLU, MSE, BCE |
|
|
65
|
+
| 2b | Backprop MNIST | NumPy backprop on MNIST |
|
|
66
|
+
| 3 | Regularisation | L2 + Dropout |
|
|
67
|
+
| 4 | CNN | Conv2d + MaxPool |
|
|
68
|
+
| 5 | ResNet | Skip connections |
|
|
69
|
+
| 6 | RNN | Vanilla RNN sequence prediction |
|
|
70
|
+
| 7 | LSTM | Long Short-Term Memory |
|
|
71
|
+
| 8 | Transformer | Multi-head self-attention |
|
|
72
|
+
| 9 | GAN | Generator + Discriminator |
|
|
73
|
+
| 9b | VAE | Variational Autoencoder |
|
|
74
|
+
| 10 | Transfer | Frozen backbone + custom head |
|
|
75
|
+
|
|
76
|
+
## Requirements
|
|
77
|
+
|
|
78
|
+
- Python ≥ 3.10
|
|
79
|
+
- numpy ≥ 1.24
|
|
80
|
+
- (Optional) scikit-learn ≥ 1.3 — for Exp 2b
|
|
81
|
+
- (Optional) torch ≥ 2.0, torchvision ≥ 0.15 — for Exp 4–10
|
|
82
|
+
|
|
83
|
+
## License
|
|
84
|
+
|
|
85
|
+
MIT
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
dl_experiments
|
|
3
|
+
==============
|
|
4
|
+
A pip-installable collection of Deep Learning experiment modules.
|
|
5
|
+
|
|
6
|
+
Quick start
|
|
7
|
+
-----------
|
|
8
|
+
import dl_experiments
|
|
9
|
+
dl_experiments.main() # run all experiments
|
|
10
|
+
|
|
11
|
+
dl_experiments.main("1a") # run a single experiment
|
|
12
|
+
dl_experiments.main("4", "5") # run multiple experiments
|
|
13
|
+
|
|
14
|
+
dl_experiments.list_experiments() # see all available keys
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from .utils.registry import list_experiments, run_experiment
|
|
18
|
+
|
|
19
|
+
__version__ = "1.0.0"
|
|
20
|
+
__author__ = "Pratham"
|
|
21
|
+
__all__ = ["main", "list_experiments", "run_experiment", "__version__"]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def main(*experiments: str) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Orchestrate and run DL experiments.
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
*experiments : str
|
|
31
|
+
Experiment keys to run (e.g. "1a", "2b", "10").
|
|
32
|
+
If none are provided, ALL experiments are run in order.
|
|
33
|
+
|
|
34
|
+
Examples
|
|
35
|
+
--------
|
|
36
|
+
>>> import dl_experiments
|
|
37
|
+
>>> dl_experiments.main() # run all
|
|
38
|
+
>>> dl_experiments.main("1a") # run only Exp 1a
|
|
39
|
+
>>> dl_experiments.main("4","5") # run Exp 4 and 5
|
|
40
|
+
"""
|
|
41
|
+
keys = list(experiments) if experiments else list_experiments()
|
|
42
|
+
|
|
43
|
+
print("=" * 60)
|
|
44
|
+
print(" Deep Learning Experiments Suite")
|
|
45
|
+
print(f" Running: {', '.join(keys)}")
|
|
46
|
+
print("=" * 60)
|
|
47
|
+
|
|
48
|
+
for key in keys:
|
|
49
|
+
try:
|
|
50
|
+
run_experiment(key)
|
|
51
|
+
except Exception as exc: # noqa: BLE001
|
|
52
|
+
print(f"\n [ERROR] Experiment {key!r} failed: {exc}")
|
|
53
|
+
|
|
54
|
+
print("\n" + "=" * 60)
|
|
55
|
+
print(" All done!")
|
|
56
|
+
print("=" * 60)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Allows: python -m dl_experiments [exp_keys ...]
|
|
3
|
+
"""
|
|
4
|
+
import argparse
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from . import list_experiments, main
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def cli() -> None:
|
|
11
|
+
parser = argparse.ArgumentParser(
|
|
12
|
+
prog="dl_experiments",
|
|
13
|
+
description="Run Deep Learning experiment modules.",
|
|
14
|
+
)
|
|
15
|
+
parser.add_argument(
|
|
16
|
+
"experiments",
|
|
17
|
+
nargs="*",
|
|
18
|
+
metavar="EXP",
|
|
19
|
+
help=(
|
|
20
|
+
"Experiment keys to run (e.g. 1a 2b 10). "
|
|
21
|
+
f"Available: {', '.join(list_experiments())}. "
|
|
22
|
+
"Omit to run ALL."
|
|
23
|
+
),
|
|
24
|
+
)
|
|
25
|
+
parser.add_argument(
|
|
26
|
+
"--list",
|
|
27
|
+
action="store_true",
|
|
28
|
+
help="List available experiment keys and exit.",
|
|
29
|
+
)
|
|
30
|
+
args = parser.parse_args()
|
|
31
|
+
|
|
32
|
+
if args.list:
|
|
33
|
+
print("Available experiments:", ", ".join(list_experiments()))
|
|
34
|
+
sys.exit(0)
|
|
35
|
+
|
|
36
|
+
main(*args.experiments)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
cli()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""DL experiment modules."""
|
|
2
|
+
from . import (
|
|
3
|
+
exp1a_mcculloch_pitts,
|
|
4
|
+
exp1b_mlp_binary,
|
|
5
|
+
exp2a_activations,
|
|
6
|
+
exp2b_backprop_mnist,
|
|
7
|
+
exp3_regularisation,
|
|
8
|
+
exp4_cnn,
|
|
9
|
+
exp5_resnet,
|
|
10
|
+
exp6_rnn,
|
|
11
|
+
exp7_lstm,
|
|
12
|
+
exp8_transformer,
|
|
13
|
+
exp9_gan,
|
|
14
|
+
exp9b_vae,
|
|
15
|
+
exp10_transfer,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"exp1a_mcculloch_pitts",
|
|
20
|
+
"exp1b_mlp_binary",
|
|
21
|
+
"exp2a_activations",
|
|
22
|
+
"exp2b_backprop_mnist",
|
|
23
|
+
"exp3_regularisation",
|
|
24
|
+
"exp4_cnn",
|
|
25
|
+
"exp5_resnet",
|
|
26
|
+
"exp6_rnn",
|
|
27
|
+
"exp7_lstm",
|
|
28
|
+
"exp8_transformer",
|
|
29
|
+
"exp9_gan",
|
|
30
|
+
"exp9b_vae",
|
|
31
|
+
"exp10_transfer",
|
|
32
|
+
]
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# EXPERIMENT 10: Transfer Learning with MobileNetV2 on CIFAR-10
|
|
5
|
+
# =============================================================================
|
|
6
|
+
#
|
|
7
|
+
# THEORY:
|
|
8
|
+
# Transfer Learning reuses a neural network pre-trained on a large dataset
|
|
9
|
+
# as a starting point for a new, related task.
|
|
10
|
+
# This dramatically reduces training time and data requirements.
|
|
11
|
+
#
|
|
12
|
+
# ---- Why Transfer Learning? ----
|
|
13
|
+
# Training deep CNNs from scratch requires:
|
|
14
|
+
# - Millions of labeled images
|
|
15
|
+
# - Days/weeks of GPU compute
|
|
16
|
+
# Transfer Learning solves this: a model pre-trained on ImageNet already knows
|
|
17
|
+
# how to detect edges, textures, shapes, and high-level objects.
|
|
18
|
+
# We just need to adapt the FINAL layers to our specific classes.
|
|
19
|
+
#
|
|
20
|
+
# ---- MobileNetV2 ----
|
|
21
|
+
# Lightweight CNN architecture designed for efficiency on mobile/edge devices.
|
|
22
|
+
# Pre-trained on ImageNet: 1.2 million images, 1000 classes.
|
|
23
|
+
# Key innovation: Depthwise Separable Convolutions
|
|
24
|
+
# - Standard Conv: applies filter across all channels simultaneously
|
|
25
|
+
# - Depthwise Conv: applies ONE filter per channel (much fewer parameters)
|
|
26
|
+
# - Pointwise Conv: 1x1 convolution to combine channels
|
|
27
|
+
# - Result: ~8-9x fewer parameters with similar accuracy vs standard Conv
|
|
28
|
+
#
|
|
29
|
+
# ---- Transfer Learning Strategy (2 Phases) ----
|
|
30
|
+
#
|
|
31
|
+
# Phase 1 - Feature Extraction (Frozen Base):
|
|
32
|
+
# base_model.trainable = False
|
|
33
|
+
# Only the new Dense(10, softmax) head is trained.
|
|
34
|
+
# The pre-trained MobileNetV2 features are used as fixed feature extractors.
|
|
35
|
+
# Fast and safe: ImageNet knowledge is preserved.
|
|
36
|
+
#
|
|
37
|
+
# Phase 2 - Fine-Tuning (Unfrozen):
|
|
38
|
+
# base_model.trainable = True
|
|
39
|
+
# ALL layers are trainable, but with a very small learning rate (1e-5).
|
|
40
|
+
# The entire network adapts to the new domain (CIFAR-10).
|
|
41
|
+
# Small lr prevents catastrophic forgetting of pre-trained features.
|
|
42
|
+
#
|
|
43
|
+
# ---- preprocess_input (MobileNetV2 Preprocessing) ----
|
|
44
|
+
# MobileNetV2 was trained with specific pixel normalization:
|
|
45
|
+
# preprocess_input scales pixels from [0,255] to [-1, 1]
|
|
46
|
+
# MUST use this for correct behavior with pre-trained MobileNetV2 weights.
|
|
47
|
+
#
|
|
48
|
+
# ---- Dataset: CIFAR-10 (built-in, no external download needed) ----
|
|
49
|
+
# 60,000 color images (32x32 RGB) in 10 classes:
|
|
50
|
+
# airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck
|
|
51
|
+
# 2,000 training samples used here for speed.
|
|
52
|
+
#
|
|
53
|
+
# ---- GlobalAveragePooling2D ----
|
|
54
|
+
# Converts (7, 7, 1280) feature maps from MobileNetV2 base -> (1280,) vector.
|
|
55
|
+
# More efficient than Flatten: fewer parameters, less overfitting.
|
|
56
|
+
#
|
|
57
|
+
# ---- Evaluation Metrics ----
|
|
58
|
+
# Classification Report: Precision, Recall, F1-score per class
|
|
59
|
+
# Precision = TP / (TP + FP): of all predicted positive, how many are correct?
|
|
60
|
+
# Recall = TP / (TP + FN): of all actual positive, how many did we find?
|
|
61
|
+
# F1-score = 2 * (P * R) / (P + R): harmonic mean of precision and recall
|
|
62
|
+
#
|
|
63
|
+
# =============================================================================
|
|
64
|
+
# IF YOUR OWN IMAGE DATASET (changing from CIFAR-10):
|
|
65
|
+
#
|
|
66
|
+
# Option A: Images in folders (recommended):
|
|
67
|
+
# Replace the CIFAR-10 loading block with:
|
|
68
|
+
#
|
|
69
|
+
# IMG_SIZE = (96, 96) # MobileNetV2 min is 32x32, recommended 96x96+
|
|
70
|
+
# train_dataset = tf.keras.preprocessing.image_dataset_from_directory(
|
|
71
|
+
# "path/to/your/train_images/", # Each subfolder = one class
|
|
72
|
+
# image_size=IMG_SIZE,
|
|
73
|
+
# batch_size=BATCH_SIZE
|
|
74
|
+
# )
|
|
75
|
+
# test_dataset = tf.keras.preprocessing.image_dataset_from_directory(
|
|
76
|
+
# "path/to/your/test_images/",
|
|
77
|
+
# image_size=IMG_SIZE,
|
|
78
|
+
# batch_size=BATCH_SIZE
|
|
79
|
+
# )
|
|
80
|
+
# class_names = train_dataset.class_names # Auto-detected from folder names
|
|
81
|
+
#
|
|
82
|
+
# 🔴 CHANGE 1: Number of output classes
|
|
83
|
+
# Dense(num_classes, activation='softmax')
|
|
84
|
+
# loss='sparse_categorical_crossentropy'
|
|
85
|
+
#
|
|
86
|
+
# 🔴 CHANGE 2: EPOCHS - increase for small datasets (10-20+)
|
|
87
|
+
# =============================================================================
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def run():
|
|
91
|
+
print("\n=== Exp 10: Transfer Learning with MobileNetV2 on CIFAR-10 ===")
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
import tensorflow as tf
|
|
95
|
+
from tensorflow.keras.applications import MobileNetV2
|
|
96
|
+
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
|
|
97
|
+
from tensorflow.keras import layers, models
|
|
98
|
+
except ImportError:
|
|
99
|
+
print(" [SKIP] tensorflow not installed. Install with: pip install tensorflow")
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
from sklearn.metrics import classification_report, confusion_matrix
|
|
104
|
+
except ImportError:
|
|
105
|
+
print(" [SKIP] scikit-learn not installed. Install with: pip install scikit-learn")
|
|
106
|
+
return
|
|
107
|
+
|
|
108
|
+
# ==============================
|
|
109
|
+
# 1. PARAMETERS
|
|
110
|
+
# ==============================
|
|
111
|
+
# MobileNetV2 requires at least 32x32; using 96x96 is faster than 224x224
|
|
112
|
+
IMG_SIZE = (96, 96)
|
|
113
|
+
BATCH_SIZE = 32
|
|
114
|
+
EPOCHS = 3
|
|
115
|
+
N_TRAIN = 2000 # Use subset for speed; increase for better accuracy
|
|
116
|
+
|
|
117
|
+
CLASS_NAMES = [
|
|
118
|
+
'airplane', 'automobile', 'bird', 'cat', 'deer',
|
|
119
|
+
'dog', 'frog', 'horse', 'ship', 'truck'
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
# ==============================
|
|
123
|
+
# 2. LOAD & PREPROCESS CIFAR-10
|
|
124
|
+
# ==============================
|
|
125
|
+
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
|
|
126
|
+
|
|
127
|
+
# Use a small subset for speed
|
|
128
|
+
x_train, y_train = x_train[:N_TRAIN], y_train[:N_TRAIN]
|
|
129
|
+
x_test, y_test = x_test[:500], y_test[:500]
|
|
130
|
+
|
|
131
|
+
# Resize images from 32x32 to IMG_SIZE for MobileNetV2
|
|
132
|
+
x_train = tf.image.resize(x_train.astype("float32"), IMG_SIZE)
|
|
133
|
+
x_test = tf.image.resize(x_test.astype("float32"), IMG_SIZE)
|
|
134
|
+
|
|
135
|
+
# MobileNetV2-specific preprocessing: scales pixels to [-1, 1]
|
|
136
|
+
x_train = preprocess_input(x_train)
|
|
137
|
+
x_test = preprocess_input(x_test)
|
|
138
|
+
|
|
139
|
+
# Flatten labels from (N,1) -> (N,)
|
|
140
|
+
y_train = y_train.flatten()
|
|
141
|
+
y_test = y_test.flatten()
|
|
142
|
+
|
|
143
|
+
# ==============================
|
|
144
|
+
# 3. MODEL (TRANSFER LEARNING)
|
|
145
|
+
# ==============================
|
|
146
|
+
# Load MobileNetV2 pre-trained on ImageNet
|
|
147
|
+
# include_top=False: exclude the final 1000-class Dense layer
|
|
148
|
+
base_model = MobileNetV2(
|
|
149
|
+
input_shape=(IMG_SIZE[0], IMG_SIZE[1], 3),
|
|
150
|
+
include_top=False,
|
|
151
|
+
weights='imagenet'
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
# Phase 1: FREEZE the base model
|
|
155
|
+
base_model.trainable = False
|
|
156
|
+
|
|
157
|
+
model = models.Sequential([
|
|
158
|
+
base_model, # Pre-trained MobileNetV2 feature extractor
|
|
159
|
+
layers.GlobalAveragePooling2D(), # Spatial average: (7,7,1280) -> (1280,)
|
|
160
|
+
layers.Dense(10, activation='softmax') # 10-class CIFAR-10 output
|
|
161
|
+
])
|
|
162
|
+
|
|
163
|
+
# ==============================
|
|
164
|
+
# 4. COMPILE (Phase 1)
|
|
165
|
+
# ==============================
|
|
166
|
+
model.compile(
|
|
167
|
+
optimizer='adam',
|
|
168
|
+
loss='sparse_categorical_crossentropy',
|
|
169
|
+
metrics=['accuracy']
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
# ==============================
|
|
173
|
+
# 5. TRAIN PHASE 1 (Feature Extraction)
|
|
174
|
+
# ==============================
|
|
175
|
+
print("\n--- Phase 1: Feature Extraction (frozen base) ---")
|
|
176
|
+
model.fit(
|
|
177
|
+
x_train, y_train,
|
|
178
|
+
validation_data=(x_test, y_test),
|
|
179
|
+
epochs=EPOCHS,
|
|
180
|
+
batch_size=BATCH_SIZE,
|
|
181
|
+
verbose=1
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# ==============================
|
|
185
|
+
# 6. FINE-TUNING (Phase 2)
|
|
186
|
+
# ==============================
|
|
187
|
+
base_model.trainable = True # Unfreeze all layers
|
|
188
|
+
|
|
189
|
+
model.compile(
|
|
190
|
+
optimizer=tf.keras.optimizers.Adam(1e-5), # Very small lr to preserve features
|
|
191
|
+
loss='sparse_categorical_crossentropy',
|
|
192
|
+
metrics=['accuracy']
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
print("\n--- Phase 2: Fine-Tuning (unfrozen, lr=1e-5) ---")
|
|
196
|
+
model.fit(
|
|
197
|
+
x_train, y_train,
|
|
198
|
+
validation_data=(x_test, y_test),
|
|
199
|
+
epochs=2,
|
|
200
|
+
batch_size=BATCH_SIZE,
|
|
201
|
+
verbose=1
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# ==============================
|
|
205
|
+
# 7. EVALUATION
|
|
206
|
+
# ==============================
|
|
207
|
+
y_pred_probs = model.predict(x_test, verbose=0)
|
|
208
|
+
y_pred = np.argmax(y_pred_probs, axis=1)
|
|
209
|
+
|
|
210
|
+
print("\nClassification Report:")
|
|
211
|
+
print(classification_report(y_test, y_pred, target_names=CLASS_NAMES))
|
|
212
|
+
|
|
213
|
+
cm = confusion_matrix(y_test, y_pred)
|
|
214
|
+
print("Confusion Matrix (rows=Actual, cols=Predicted):")
|
|
215
|
+
# Print header
|
|
216
|
+
header = " " + " ".join(f"{n[:4]:>4}" for n in CLASS_NAMES)
|
|
217
|
+
print(header)
|
|
218
|
+
for i, row in enumerate(cm):
|
|
219
|
+
row_str = " ".join(f"{v:>4}" for v in row)
|
|
220
|
+
print(f"{CLASS_NAMES[i][:7]:<7} {row_str}")
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# EXPERIMENT 1a: McCulloch-Pitts (MP) Neuron Model
|
|
3
|
+
# =============================================================================
|
|
4
|
+
#
|
|
5
|
+
# THEORY:
|
|
6
|
+
# The McCulloch-Pitts (MP) Neuron (1943) is the earliest mathematical model
|
|
7
|
+
# of a biological neuron. It is a simple binary threshold unit.
|
|
8
|
+
#
|
|
9
|
+
# How it works:
|
|
10
|
+
# - Takes binary inputs (0 or 1)
|
|
11
|
+
# - Each input is multiplied by a weight (can be +1 for excitatory or -1 for inhibitory)
|
|
12
|
+
# - Computes a weighted sum: net = w1*x1 + w2*x2 + ...
|
|
13
|
+
# - Applies a threshold function: output = 1 if net >= theta, else 0
|
|
14
|
+
#
|
|
15
|
+
# Limitations:
|
|
16
|
+
# - Weights and threshold (theta) are FIXED (not learned automatically)
|
|
17
|
+
# - Only works with binary inputs and binary outputs
|
|
18
|
+
# - Cannot represent continuous / real-valued data
|
|
19
|
+
#
|
|
20
|
+
# This experiment implements XOR and XNOR using multi-layer MP neurons,
|
|
21
|
+
# demonstrating that non-linear functions need multiple neurons (layers).
|
|
22
|
+
#
|
|
23
|
+
# XOR Truth Table: XNOR Truth Table:
|
|
24
|
+
# 0,0 -> 0 0,0 -> 1
|
|
25
|
+
# 0,1 -> 1 0,1 -> 0
|
|
26
|
+
# 1,0 -> 1 1,0 -> 0
|
|
27
|
+
# 1,1 -> 0 1,1 -> 1
|
|
28
|
+
#
|
|
29
|
+
# =============================================================================
|
|
30
|
+
# IF CSV DATA IS GIVEN:
|
|
31
|
+
# This code does NOT use any dataset (it uses hardcoded logic).
|
|
32
|
+
# But if you want to test MP neuron on binary inputs from a CSV file:
|
|
33
|
+
#
|
|
34
|
+
# import pandas as pd
|
|
35
|
+
# df = pd.read_csv('your_data.csv')
|
|
36
|
+
# # CSV must have columns for inputs and expected output, e.g.:
|
|
37
|
+
# # x1, x2, label
|
|
38
|
+
# # 0, 0, 0
|
|
39
|
+
# # 0, 1, 1
|
|
40
|
+
# inputs = list(zip(df['x1'], df['x2']))
|
|
41
|
+
# # Then call mp_neuron() or xor() / xnor() for each row
|
|
42
|
+
# # NOTE: MP neuron only works with binary (0/1) inputs.
|
|
43
|
+
# # If your CSV has continuous values, you must binarize them first:
|
|
44
|
+
# # e.g., x1 = 1 if x1 > threshold else 0
|
|
45
|
+
# =============================================================================
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def run():
|
|
49
|
+
print("\n=== Exp 1a: McCulloch-Pitts Neuron (XOR & XNOR) ===")
|
|
50
|
+
|
|
51
|
+
# Core MP Neuron function
|
|
52
|
+
# x1, x2 : binary inputs (0 or 1)
|
|
53
|
+
# w1, w2 : weights (positive = excitatory, negative = inhibitory)
|
|
54
|
+
# theta : threshold - if weighted sum >= theta, neuron fires (output=1)
|
|
55
|
+
def mp_neuron(x1, x2, w1, w2, theta):
|
|
56
|
+
# Compute weighted sum of inputs
|
|
57
|
+
# If the sum meets or exceeds the threshold, neuron fires (outputs 1)
|
|
58
|
+
return 1 if (w1 * x1 + w2 * x2) >= theta else 0
|
|
59
|
+
|
|
60
|
+
# XOR Gate using 2 MP neurons in hidden layer + 1 output neuron
|
|
61
|
+
# XOR is a non-linearly separable function -> needs multiple MP neurons
|
|
62
|
+
def xor(x1, x2):
|
|
63
|
+
# h1 fires when x1=1, x2=0 (x1 ON, x2 inhibitory)
|
|
64
|
+
h1 = mp_neuron(x1, x2, 1, -1, 1)
|
|
65
|
+
|
|
66
|
+
# h2 fires when x1=0, x2=1 (x2 ON, x1 inhibitory)
|
|
67
|
+
h2 = mp_neuron(x1, x2, -1, 1, 1)
|
|
68
|
+
|
|
69
|
+
# Output fires when either h1 OR h2 fires (but not both -> XOR)
|
|
70
|
+
y = mp_neuron(h1, h2, 1, 1, 1)
|
|
71
|
+
return y
|
|
72
|
+
|
|
73
|
+
# XNOR Gate using 2 MP neurons in hidden layer + 1 output neuron
|
|
74
|
+
# XNOR is the complement of XOR: outputs 1 when both inputs are same
|
|
75
|
+
def xnor(x1, x2):
|
|
76
|
+
# h1 fires when both x1=1 AND x2=1 (requires both: threshold=2)
|
|
77
|
+
h1 = mp_neuron(x1, x2, 1, 1, 2)
|
|
78
|
+
|
|
79
|
+
# h2 fires when both x1=0 AND x2=0 (negative weights, threshold=0)
|
|
80
|
+
# -1*0 + -1*0 = 0 >= 0 -> fires; -1*1 + -1*0 = -1 < 0 -> doesn't fire
|
|
81
|
+
h2 = mp_neuron(x1, x2, -1, -1, 0)
|
|
82
|
+
|
|
83
|
+
# Output fires when either h1 OR h2 fires
|
|
84
|
+
y = mp_neuron(h1, h2, 1, 1, 1)
|
|
85
|
+
return y
|
|
86
|
+
|
|
87
|
+
# All possible binary input combinations
|
|
88
|
+
inputs = [(0, 0), (0, 1), (1, 0), (1, 1)]
|
|
89
|
+
|
|
90
|
+
# Test both gates on all input combinations and print results
|
|
91
|
+
print(f"{'x1':>4} {'x2':>4} {'XOR':>6} {'XNOR':>6}")
|
|
92
|
+
print("-" * 24)
|
|
93
|
+
for x1, x2 in inputs:
|
|
94
|
+
print(f"{x1:>4} {x2:>4} {xor(x1, x2):>6} {xnor(x1, x2):>6}")
|