numpyv 1.0.0__tar.gz → 1.0.1__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.
- {numpyv-1.0.0 → numpyv-1.0.1}/PKG-INFO +14 -14
- {numpyv-1.0.0 → numpyv-1.0.1}/README.md +12 -12
- {numpyv-1.0.0 → numpyv-1.0.1}/numpyv.egg-info/PKG-INFO +14 -14
- {numpyv-1.0.0 → numpyv-1.0.1}/numpyv.egg-info/SOURCES.txt +1 -0
- numpyv-1.0.1/numpyv.egg-info/entry_points.txt +2 -0
- numpyv-1.0.1/numpyv.egg-info/top_level.txt +1 -0
- numpyv-1.0.1/numpyv.py +692 -0
- {numpyv-1.0.0 → numpyv-1.0.1}/pyproject.toml +4 -4
- numpyv-1.0.0/numpyv.egg-info/entry_points.txt +0 -2
- numpyv-1.0.0/numpyv.egg-info/top_level.txt +0 -1
- {numpyv-1.0.0 → numpyv-1.0.1}/LICENSE +0 -0
- {numpyv-1.0.0 → numpyv-1.0.1}/numpyv.egg-info/dependency_links.txt +0 -0
- {numpyv-1.0.0 → numpyv-1.0.1}/numpyv.egg-info/requires.txt +0 -0
- {numpyv-1.0.0 → numpyv-1.0.1}/setup.cfg +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: numpyv
|
|
3
|
-
Version: 1.0.
|
|
4
|
-
Summary: Deep Learning lab experiments 1-8 - import to print aim, explanation and full code
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Deep Learning lab experiments 1-8 - import to print aim, theory, explanation and full code
|
|
5
5
|
Requires-Python: >=3.8
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
License-File: LICENSE
|
|
@@ -14,7 +14,7 @@ Requires-Dist: scikit-learn
|
|
|
14
14
|
Requires-Dist: seaborn
|
|
15
15
|
Dynamic: license-file
|
|
16
16
|
|
|
17
|
-
#
|
|
17
|
+
# numpyv
|
|
18
18
|
|
|
19
19
|
A single-file Python package containing the 8 Deep Learning laboratory experiments.
|
|
20
20
|
|
|
@@ -23,36 +23,36 @@ A single-file Python package containing the 8 Deep Learning laboratory experimen
|
|
|
23
23
|
Importing the package automatically displays the AIM, explanation, full code and output explanation of each experiment in the terminal. **Press Enter** to move to the next experiment. The experiments are **not executed** during import.
|
|
24
24
|
|
|
25
25
|
```python
|
|
26
|
-
import
|
|
26
|
+
import numpyv
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
To import silently, set the environment variable `
|
|
29
|
+
To import silently, set the environment variable `NUMPYV_QUIET=1`.
|
|
30
30
|
|
|
31
31
|
## Show the experiment code
|
|
32
32
|
|
|
33
33
|
```python
|
|
34
|
-
import
|
|
34
|
+
import numpyv
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
numpyv.experiment1()
|
|
37
|
+
numpyv.experiment2()
|
|
38
38
|
# ... up to
|
|
39
|
-
|
|
39
|
+
numpyv.experiment8()
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
Each `experimentN()` prints and returns the complete text for that experiment. You can also use `
|
|
42
|
+
Each `experimentN()` prints and returns the complete text for that experiment. You can also use `numpyv.show_experiment_code(1)`, `numpyv.show_all()` and `numpyv.save_code()`.
|
|
43
43
|
|
|
44
44
|
## Execute an experiment
|
|
45
45
|
|
|
46
46
|
```python
|
|
47
|
-
|
|
47
|
+
numpyv.run_experiment(1)
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
From the command line:
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
python -m
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
python -m numpyv 1 # show code
|
|
54
|
+
numpyv 1 # show code
|
|
55
|
+
numpyv 2 --run # execute
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
Replace the number with any value from `1` to `8`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# numpyv
|
|
2
2
|
|
|
3
3
|
A single-file Python package containing the 8 Deep Learning laboratory experiments.
|
|
4
4
|
|
|
@@ -7,36 +7,36 @@ A single-file Python package containing the 8 Deep Learning laboratory experimen
|
|
|
7
7
|
Importing the package automatically displays the AIM, explanation, full code and output explanation of each experiment in the terminal. **Press Enter** to move to the next experiment. The experiments are **not executed** during import.
|
|
8
8
|
|
|
9
9
|
```python
|
|
10
|
-
import
|
|
10
|
+
import numpyv
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
To import silently, set the environment variable `
|
|
13
|
+
To import silently, set the environment variable `NUMPYV_QUIET=1`.
|
|
14
14
|
|
|
15
15
|
## Show the experiment code
|
|
16
16
|
|
|
17
17
|
```python
|
|
18
|
-
import
|
|
18
|
+
import numpyv
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
numpyv.experiment1()
|
|
21
|
+
numpyv.experiment2()
|
|
22
22
|
# ... up to
|
|
23
|
-
|
|
23
|
+
numpyv.experiment8()
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Each `experimentN()` prints and returns the complete text for that experiment. You can also use `
|
|
26
|
+
Each `experimentN()` prints and returns the complete text for that experiment. You can also use `numpyv.show_experiment_code(1)`, `numpyv.show_all()` and `numpyv.save_code()`.
|
|
27
27
|
|
|
28
28
|
## Execute an experiment
|
|
29
29
|
|
|
30
30
|
```python
|
|
31
|
-
|
|
31
|
+
numpyv.run_experiment(1)
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
From the command line:
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
python -m
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
python -m numpyv 1 # show code
|
|
38
|
+
numpyv 1 # show code
|
|
39
|
+
numpyv 2 --run # execute
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
Replace the number with any value from `1` to `8`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: numpyv
|
|
3
|
-
Version: 1.0.
|
|
4
|
-
Summary: Deep Learning lab experiments 1-8 - import to print aim, explanation and full code
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Deep Learning lab experiments 1-8 - import to print aim, theory, explanation and full code
|
|
5
5
|
Requires-Python: >=3.8
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
License-File: LICENSE
|
|
@@ -14,7 +14,7 @@ Requires-Dist: scikit-learn
|
|
|
14
14
|
Requires-Dist: seaborn
|
|
15
15
|
Dynamic: license-file
|
|
16
16
|
|
|
17
|
-
#
|
|
17
|
+
# numpyv
|
|
18
18
|
|
|
19
19
|
A single-file Python package containing the 8 Deep Learning laboratory experiments.
|
|
20
20
|
|
|
@@ -23,36 +23,36 @@ A single-file Python package containing the 8 Deep Learning laboratory experimen
|
|
|
23
23
|
Importing the package automatically displays the AIM, explanation, full code and output explanation of each experiment in the terminal. **Press Enter** to move to the next experiment. The experiments are **not executed** during import.
|
|
24
24
|
|
|
25
25
|
```python
|
|
26
|
-
import
|
|
26
|
+
import numpyv
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
To import silently, set the environment variable `
|
|
29
|
+
To import silently, set the environment variable `NUMPYV_QUIET=1`.
|
|
30
30
|
|
|
31
31
|
## Show the experiment code
|
|
32
32
|
|
|
33
33
|
```python
|
|
34
|
-
import
|
|
34
|
+
import numpyv
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
numpyv.experiment1()
|
|
37
|
+
numpyv.experiment2()
|
|
38
38
|
# ... up to
|
|
39
|
-
|
|
39
|
+
numpyv.experiment8()
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
Each `experimentN()` prints and returns the complete text for that experiment. You can also use `
|
|
42
|
+
Each `experimentN()` prints and returns the complete text for that experiment. You can also use `numpyv.show_experiment_code(1)`, `numpyv.show_all()` and `numpyv.save_code()`.
|
|
43
43
|
|
|
44
44
|
## Execute an experiment
|
|
45
45
|
|
|
46
46
|
```python
|
|
47
|
-
|
|
47
|
+
numpyv.run_experiment(1)
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
From the command line:
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
python -m
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
python -m numpyv 1 # show code
|
|
54
|
+
numpyv 1 # show code
|
|
55
|
+
numpyv 2 --run # execute
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
Replace the number with any value from `1` to `8`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
numpyv
|
numpyv-1.0.1/numpyv.py
ADDED
|
@@ -0,0 +1,692 @@
|
|
|
1
|
+
"""Numpyv: Deep Learning laboratory experiments 1-8.
|
|
2
|
+
|
|
3
|
+
Importing this module prints, for every experiment, the AIM, THEORY, what the code
|
|
4
|
+
does, the FULL CODE and the output EXPLANATION. Press Enter to move on to the next experiment.
|
|
5
|
+
|
|
6
|
+
import numpyv # code + explanation of experiments 1-8
|
|
7
|
+
numpyv.experiment3() # code + explanation of one experiment
|
|
8
|
+
numpyv.run_experiment(3) # actually execute an experiment
|
|
9
|
+
numpyv.save_code() # save everything into a text file
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
import textwrap
|
|
15
|
+
|
|
16
|
+
# Make sure symbols print correctly on Windows.
|
|
17
|
+
for _stream in (sys.stdout, sys.stderr):
|
|
18
|
+
if hasattr(_stream, "reconfigure"):
|
|
19
|
+
try:
|
|
20
|
+
_stream.reconfigure(encoding="utf-8", errors="replace")
|
|
21
|
+
except Exception:
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# ======================================================================
|
|
26
|
+
# CODE OF EACH EXPERIMENT
|
|
27
|
+
# ======================================================================
|
|
28
|
+
CODE = {}
|
|
29
|
+
CODE[1] = r'''
|
|
30
|
+
# Experiment 1: Study on Deep Learning Frameworks and Ethical Considerations
|
|
31
|
+
import importlib
|
|
32
|
+
import platform
|
|
33
|
+
import sys
|
|
34
|
+
|
|
35
|
+
print("Python:", sys.version.split()[0], "| OS:", platform.system())
|
|
36
|
+
|
|
37
|
+
# 1) Check which deep learning frameworks are installed
|
|
38
|
+
frameworks = {
|
|
39
|
+
"TensorFlow": "tensorflow",
|
|
40
|
+
"Keras": "keras",
|
|
41
|
+
"PyTorch": "torch",
|
|
42
|
+
"JAX": "jax",
|
|
43
|
+
"scikit-learn": "sklearn",
|
|
44
|
+
"ONNX": "onnx",
|
|
45
|
+
}
|
|
46
|
+
print("\n--- Installed Frameworks ---")
|
|
47
|
+
for name, module in frameworks.items():
|
|
48
|
+
try:
|
|
49
|
+
m = importlib.import_module(module)
|
|
50
|
+
print(f"{name:<14}: {getattr(m, '__version__', 'installed')}")
|
|
51
|
+
except Exception:
|
|
52
|
+
print(f"{name:<14}: not installed")
|
|
53
|
+
|
|
54
|
+
# 2) GPU availability
|
|
55
|
+
try:
|
|
56
|
+
import tensorflow as tf
|
|
57
|
+
print("\nTensorFlow GPUs:", tf.config.list_physical_devices("GPU"))
|
|
58
|
+
except Exception:
|
|
59
|
+
pass
|
|
60
|
+
try:
|
|
61
|
+
import torch
|
|
62
|
+
print("PyTorch CUDA available:", torch.cuda.is_available())
|
|
63
|
+
except Exception:
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
# 3) Framework comparison
|
|
67
|
+
comparison = {
|
|
68
|
+
"TensorFlow": "Google; production deployment (TF Lite, TF Serving), Keras API",
|
|
69
|
+
"PyTorch": "Meta; dynamic graphs, preferred in research, easy debugging",
|
|
70
|
+
"Keras": "High-level API; fast prototyping on top of TensorFlow/JAX/PyTorch",
|
|
71
|
+
"JAX": "Google; NumPy-like, JIT + autograd, high-performance research",
|
|
72
|
+
}
|
|
73
|
+
print("\n--- Framework Comparison ---")
|
|
74
|
+
for k, v in comparison.items():
|
|
75
|
+
print(f"{k:<11}: {v}")
|
|
76
|
+
|
|
77
|
+
# 4) Ethical considerations
|
|
78
|
+
ethics = [
|
|
79
|
+
"Bias and fairness: models inherit bias present in training data",
|
|
80
|
+
"Privacy: personal data must be protected (consent, anonymization, GDPR)",
|
|
81
|
+
"Transparency / explainability: decisions should be interpretable",
|
|
82
|
+
"Accountability: clear responsibility for model decisions and failures",
|
|
83
|
+
"Safety and security: robustness against adversarial attacks",
|
|
84
|
+
"Misuse: deepfakes, surveillance, misinformation",
|
|
85
|
+
"Environmental impact: large models consume significant energy",
|
|
86
|
+
"Job displacement and societal impact of automation",
|
|
87
|
+
]
|
|
88
|
+
print("\n--- Ethical Considerations in Deep Learning ---")
|
|
89
|
+
for i, e in enumerate(ethics, 1):
|
|
90
|
+
print(f"{i}. {e}")
|
|
91
|
+
'''
|
|
92
|
+
CODE[2] = r'''
|
|
93
|
+
import tensorflow as tf
|
|
94
|
+
from tensorflow.keras import layers, models
|
|
95
|
+
import matplotlib.pyplot as plt
|
|
96
|
+
|
|
97
|
+
# Load dataset (e.g., MNIST dataset for classification)
|
|
98
|
+
mnist = tf.keras.datasets.mnist
|
|
99
|
+
(x_train, y_train), (x_test, y_test) = mnist.load_data()
|
|
100
|
+
|
|
101
|
+
# Preprocess data
|
|
102
|
+
x_train = x_train / 255.0
|
|
103
|
+
x_test = x_test / 255.0
|
|
104
|
+
|
|
105
|
+
# Build Deep Neural Network with at least 2 hidden layers
|
|
106
|
+
model = models.Sequential([
|
|
107
|
+
layers.Flatten(input_shape=(28, 28)),
|
|
108
|
+
layers.Dense(128, activation='relu'), # Hidden Layer 1
|
|
109
|
+
layers.Dense(64, activation='relu'), # Hidden Layer 2
|
|
110
|
+
layers.Dense(10, activation='softmax') # Output layer
|
|
111
|
+
])
|
|
112
|
+
|
|
113
|
+
# Compile the model
|
|
114
|
+
model.compile(optimizer='adam',
|
|
115
|
+
loss='sparse_categorical_crossentropy',
|
|
116
|
+
metrics=['accuracy'])
|
|
117
|
+
|
|
118
|
+
# Train the model
|
|
119
|
+
history = model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test))
|
|
120
|
+
|
|
121
|
+
# Evaluate the model
|
|
122
|
+
test_loss, test_acc = model.evaluate(x_test, y_test)
|
|
123
|
+
print(f"Test Accuracy: {test_acc}")
|
|
124
|
+
'''
|
|
125
|
+
CODE[3] = r'''
|
|
126
|
+
import tensorflow as tf
|
|
127
|
+
import tensorflow_hub as hub
|
|
128
|
+
import cv2
|
|
129
|
+
from pathlib import Path
|
|
130
|
+
|
|
131
|
+
# Load a pre-trained object detection model from TensorFlow Hub
|
|
132
|
+
detector = hub.load("https://tfhub.dev/tensorflow/efficientdet/d0/1")
|
|
133
|
+
|
|
134
|
+
# Load and preprocess image
|
|
135
|
+
project_dir = Path(__file__).resolve().parent
|
|
136
|
+
image_path = project_dir / "image.jpg"
|
|
137
|
+
if not image_path.is_file():
|
|
138
|
+
image_path = project_dir / "sample_digits.png"
|
|
139
|
+
if not image_path.is_file():
|
|
140
|
+
raise FileNotFoundError(
|
|
141
|
+
"Place image.jpg or sample_digits.png next to exp3.py before running."
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
image_np = cv2.imread(str(image_path))
|
|
145
|
+
if image_np is None:
|
|
146
|
+
raise ValueError(f"OpenCV could not read the image: {image_path}")
|
|
147
|
+
|
|
148
|
+
image_np = cv2.cvtColor(image_np, cv2.COLOR_BGR2RGB)
|
|
149
|
+
input_tensor = tf.convert_to_tensor(image_np)
|
|
150
|
+
input_tensor = input_tensor[tf.newaxis, ...]
|
|
151
|
+
|
|
152
|
+
# Perform detection
|
|
153
|
+
detections = detector(input_tensor)
|
|
154
|
+
|
|
155
|
+
import numpy as np
|
|
156
|
+
import cv2
|
|
157
|
+
|
|
158
|
+
# Extract detection results
|
|
159
|
+
boxes = detections['detection_boxes'][0].numpy()
|
|
160
|
+
classes = detections['detection_classes'][0].numpy()
|
|
161
|
+
scores = detections['detection_scores'][0].numpy()
|
|
162
|
+
|
|
163
|
+
# Draw bounding boxes with a score > 0.5
|
|
164
|
+
output_image = image_np.copy()
|
|
165
|
+
h, w, _ = output_image.shape
|
|
166
|
+
|
|
167
|
+
for i in range(len(scores)):
|
|
168
|
+
if scores[i] > 0.5: # Confidence threshold
|
|
169
|
+
ymin, xmin, ymax, xmax = boxes[i]
|
|
170
|
+
start_point = (int(xmin * w), int(ymin * h))
|
|
171
|
+
end_point = (int(xmax * w), int(ymax * h))
|
|
172
|
+
|
|
173
|
+
# Draw rectangle and score label
|
|
174
|
+
cv2.rectangle(output_image, start_point, end_point, (0, 255, 0), 2)
|
|
175
|
+
text = f"Score: {scores[i]:.2f}"
|
|
176
|
+
cv2.putText(output_image, text, (start_point[0], start_point[1] - 10),
|
|
177
|
+
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
|
|
178
|
+
|
|
179
|
+
# Save the visualized result
|
|
180
|
+
output_path = project_dir / "detected_output.jpg"
|
|
181
|
+
cv2.imwrite(str(output_path), cv2.cvtColor(output_image, cv2.COLOR_RGB2BGR))
|
|
182
|
+
print(f"Bounding boxes drawn and saved to: {output_path}")
|
|
183
|
+
|
|
184
|
+
# Process results
|
|
185
|
+
print(f"Object detection completed successfully for {image_path.name}.")
|
|
186
|
+
'''
|
|
187
|
+
CODE[4] = r'''
|
|
188
|
+
import cv2
|
|
189
|
+
import matplotlib.pyplot as plt
|
|
190
|
+
from pathlib import Path
|
|
191
|
+
|
|
192
|
+
project_dir = Path(__file__).resolve().parent
|
|
193
|
+
image_path = project_dir / "image.jpg"
|
|
194
|
+
if not image_path.is_file():
|
|
195
|
+
image_path = project_dir / "sample_digits.png"
|
|
196
|
+
if not image_path.is_file():
|
|
197
|
+
raise FileNotFoundError(
|
|
198
|
+
"Place image.jpg or sample_digits.png next to exp4.py before running."
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
image = cv2.imread(str(image_path))
|
|
202
|
+
if image is None:
|
|
203
|
+
raise ValueError(f"OpenCV could not read the image: {image_path}")
|
|
204
|
+
|
|
205
|
+
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
|
206
|
+
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
|
|
207
|
+
gray = cv2.GaussianBlur(gray, (5, 5), 0)
|
|
208
|
+
_, mask = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
|
|
209
|
+
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
|
|
210
|
+
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
|
|
211
|
+
segmented = cv2.bitwise_and(image, image, mask=mask)
|
|
212
|
+
|
|
213
|
+
plt.figure(figsize=(12,4))
|
|
214
|
+
plt.subplot(1,3,1)
|
|
215
|
+
plt.imshow(image)
|
|
216
|
+
plt.title("Original Image")
|
|
217
|
+
plt.axis("off")
|
|
218
|
+
|
|
219
|
+
plt.subplot(1,3,2)
|
|
220
|
+
plt.imshow(mask, cmap="gray")
|
|
221
|
+
plt.title("Segmentation Mask")
|
|
222
|
+
plt.axis("off")
|
|
223
|
+
|
|
224
|
+
plt.subplot(1,3,3)
|
|
225
|
+
plt.imshow(segmented)
|
|
226
|
+
plt.title("Segmented Image")
|
|
227
|
+
plt.axis("off")
|
|
228
|
+
plt.tight_layout()
|
|
229
|
+
plt.show()
|
|
230
|
+
'''
|
|
231
|
+
CODE[5] = r'''
|
|
232
|
+
import tensorflow as tf
|
|
233
|
+
from tensorflow.keras.layers import Input, Dense
|
|
234
|
+
from tensorflow.keras.models import Model
|
|
235
|
+
import matplotlib.pyplot as plt
|
|
236
|
+
|
|
237
|
+
(x_train, _), (x_test, _) = tf.keras.datasets.mnist.load_data()
|
|
238
|
+
x_train = x_train.astype("float32") / 255.0
|
|
239
|
+
x_test = x_test.astype("float32") / 255.0
|
|
240
|
+
x_train = x_train.reshape(-1, 784)
|
|
241
|
+
x_test = x_test.reshape(-1, 784)
|
|
242
|
+
|
|
243
|
+
input_img = Input(shape=(784,))
|
|
244
|
+
encoded = Dense(64, activation="relu")(input_img)
|
|
245
|
+
decoded = Dense(784, activation="sigmoid")(encoded)
|
|
246
|
+
|
|
247
|
+
autoencoder = Model(input_img, decoded)
|
|
248
|
+
autoencoder.compile(optimizer="adam", loss="mse")
|
|
249
|
+
|
|
250
|
+
autoencoder.fit(
|
|
251
|
+
x_train,
|
|
252
|
+
x_train,
|
|
253
|
+
epochs=5,
|
|
254
|
+
batch_size=256,
|
|
255
|
+
shuffle=True,
|
|
256
|
+
validation_data=(x_test, x_test)
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
decoded_imgs = autoencoder.predict(x_test[:5])
|
|
260
|
+
|
|
261
|
+
plt.figure(figsize=(10,4))
|
|
262
|
+
for i in range(5):
|
|
263
|
+
plt.subplot(2,5,i+1)
|
|
264
|
+
plt.imshow(x_test[i].reshape(28,28), cmap="gray")
|
|
265
|
+
plt.axis("off")
|
|
266
|
+
plt.subplot(2,5,i+6)
|
|
267
|
+
plt.imshow(decoded_imgs[i].reshape(28,28), cmap="gray")
|
|
268
|
+
plt.axis("off")
|
|
269
|
+
|
|
270
|
+
plt.show()
|
|
271
|
+
'''
|
|
272
|
+
CODE[6] = r'''
|
|
273
|
+
import tensorflow as tf
|
|
274
|
+
from tensorflow.keras import layers, Model
|
|
275
|
+
import matplotlib.pyplot as plt
|
|
276
|
+
|
|
277
|
+
latent_dim = 2
|
|
278
|
+
(x_train, _), (x_test, _) = tf.keras.datasets.mnist.load_data()
|
|
279
|
+
x_train = x_train.astype("float32") / 255.0
|
|
280
|
+
x_test = x_test.astype("float32") / 255.0
|
|
281
|
+
x_train = x_train.reshape(-1, 784)
|
|
282
|
+
x_test = x_test.reshape(-1, 784)
|
|
283
|
+
|
|
284
|
+
encoder_inputs = layers.Input(shape=(784,))
|
|
285
|
+
x = layers.Dense(256, activation="relu")(encoder_inputs)
|
|
286
|
+
z_mean = layers.Dense(latent_dim)(x)
|
|
287
|
+
z_log_var = layers.Dense(latent_dim)(x)
|
|
288
|
+
|
|
289
|
+
def sampling(args):
|
|
290
|
+
z_mean, z_log_var = args
|
|
291
|
+
epsilon = tf.random.normal(shape=tf.shape(z_mean))
|
|
292
|
+
return z_mean + tf.exp(0.5 * z_log_var) * epsilon
|
|
293
|
+
|
|
294
|
+
z = layers.Lambda(sampling)([z_mean, z_log_var])
|
|
295
|
+
encoder = Model(encoder_inputs, [z_mean, z_log_var, z], name="encoder")
|
|
296
|
+
|
|
297
|
+
latent_inputs = layers.Input(shape=(latent_dim,))
|
|
298
|
+
x_dec = layers.Dense(256, activation="relu")(latent_inputs)
|
|
299
|
+
decoder_outputs = layers.Dense(784, activation="sigmoid")(x_dec)
|
|
300
|
+
decoder = Model(latent_inputs, decoder_outputs, name="decoder")
|
|
301
|
+
|
|
302
|
+
class VAE(Model):
|
|
303
|
+
def __init__(self, encoder, decoder, **kwargs):
|
|
304
|
+
super().__init__(**kwargs)
|
|
305
|
+
self.encoder = encoder
|
|
306
|
+
self.decoder = decoder
|
|
307
|
+
|
|
308
|
+
self.total_loss_tracker = tf.keras.metrics.Mean(name="loss")
|
|
309
|
+
self.reconstruction_loss_tracker = tf.keras.metrics.Mean(
|
|
310
|
+
name="reconstruction_loss"
|
|
311
|
+
)
|
|
312
|
+
self.kl_loss_tracker = tf.keras.metrics.Mean(name="kl_loss")
|
|
313
|
+
|
|
314
|
+
@property
|
|
315
|
+
def metrics(self):
|
|
316
|
+
return [
|
|
317
|
+
self.total_loss_tracker,
|
|
318
|
+
self.reconstruction_loss_tracker,
|
|
319
|
+
self.kl_loss_tracker,
|
|
320
|
+
]
|
|
321
|
+
|
|
322
|
+
def compute_losses(self, data, training):
|
|
323
|
+
z_mean, z_log_var, z = self.encoder(data, training=training)
|
|
324
|
+
reconstruction = self.decoder(z, training=training)
|
|
325
|
+
reconstruction_loss = tf.reduce_mean(
|
|
326
|
+
tf.reduce_sum(
|
|
327
|
+
tf.keras.losses.binary_crossentropy(data, reconstruction), axis=-1
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
kl_loss = -0.5 * tf.reduce_mean(
|
|
331
|
+
tf.reduce_sum(
|
|
332
|
+
1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var), axis=-1
|
|
333
|
+
)
|
|
334
|
+
)
|
|
335
|
+
return reconstruction_loss + kl_loss, reconstruction_loss, kl_loss
|
|
336
|
+
|
|
337
|
+
def update_loss_trackers(self, total_loss, reconstruction_loss, kl_loss):
|
|
338
|
+
self.total_loss_tracker.update_state(total_loss)
|
|
339
|
+
self.reconstruction_loss_tracker.update_state(reconstruction_loss)
|
|
340
|
+
self.kl_loss_tracker.update_state(kl_loss)
|
|
341
|
+
return {metric.name: metric.result() for metric in self.metrics}
|
|
342
|
+
|
|
343
|
+
def call(self, inputs, training=False):
|
|
344
|
+
_, _, z = self.encoder(inputs, training=training)
|
|
345
|
+
return self.decoder(z, training=training)
|
|
346
|
+
|
|
347
|
+
def train_step(self, data):
|
|
348
|
+
data = tf.keras.utils.unpack_x_y_sample_weight(data)[0]
|
|
349
|
+
with tf.GradientTape() as tape:
|
|
350
|
+
losses = self.compute_losses(data, training=True)
|
|
351
|
+
gradients = tape.gradient(losses[0], self.trainable_weights)
|
|
352
|
+
self.optimizer.apply_gradients(zip(gradients, self.trainable_weights))
|
|
353
|
+
return self.update_loss_trackers(*losses)
|
|
354
|
+
|
|
355
|
+
def test_step(self, data):
|
|
356
|
+
data = tf.keras.utils.unpack_x_y_sample_weight(data)[0]
|
|
357
|
+
losses = self.compute_losses(data, training=False)
|
|
358
|
+
return self.update_loss_trackers(*losses)
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
vae = VAE(encoder, decoder, name="vae")
|
|
362
|
+
vae.compile(optimizer=tf.keras.optimizers.Adam())
|
|
363
|
+
|
|
364
|
+
print("Training Variational Autoencoder...")
|
|
365
|
+
history = vae.fit(
|
|
366
|
+
x_train,
|
|
367
|
+
epochs=5,
|
|
368
|
+
batch_size=128,
|
|
369
|
+
shuffle=True,
|
|
370
|
+
validation_data=(x_test,),
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
reconstructed_imgs = vae.predict(x_test[:5], verbose=0)
|
|
374
|
+
plt.figure(figsize=(10, 4))
|
|
375
|
+
for i in range(5):
|
|
376
|
+
plt.subplot(2, 5, i + 1)
|
|
377
|
+
plt.imshow(x_test[i].reshape(28, 28), cmap="gray")
|
|
378
|
+
plt.axis("off")
|
|
379
|
+
plt.subplot(2, 5, i + 6)
|
|
380
|
+
plt.imshow(reconstructed_imgs[i].reshape(28, 28), cmap="gray")
|
|
381
|
+
plt.axis("off")
|
|
382
|
+
|
|
383
|
+
plt.tight_layout()
|
|
384
|
+
plt.savefig("vae_reconstructions.png")
|
|
385
|
+
plt.show()
|
|
386
|
+
'''
|
|
387
|
+
CODE[7] = r'''
|
|
388
|
+
from tensorflow import keras
|
|
389
|
+
from tensorflow.keras import layers
|
|
390
|
+
from tensorflow.keras.datasets import imdb
|
|
391
|
+
from tensorflow.keras.preprocessing import sequence
|
|
392
|
+
|
|
393
|
+
print("=" * 70)
|
|
394
|
+
print("DL Experiment 7: RNN (LSTM) for Sentiment Analysis")
|
|
395
|
+
print("=" * 70)
|
|
396
|
+
print()
|
|
397
|
+
|
|
398
|
+
# Load IMDB dataset with word index limit
|
|
399
|
+
max_features = 10000
|
|
400
|
+
maxlen = 500
|
|
401
|
+
|
|
402
|
+
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
|
|
403
|
+
|
|
404
|
+
print(f"Training samples: {len(x_train)}")
|
|
405
|
+
print(f"Test samples: {len(x_test)}")
|
|
406
|
+
print(f"Max features (vocabulary): {max_features}")
|
|
407
|
+
print(f"Max sequence length: {maxlen}")
|
|
408
|
+
print()
|
|
409
|
+
|
|
410
|
+
print("-" * 70)
|
|
411
|
+
print("Preprocessing Text Data...")
|
|
412
|
+
print("-" * 70)
|
|
413
|
+
|
|
414
|
+
# Pad sequences to same length
|
|
415
|
+
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
|
|
416
|
+
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
|
|
417
|
+
|
|
418
|
+
model = keras.Sequential([
|
|
419
|
+
layers.Embedding(max_features, 128),
|
|
420
|
+
layers.LSTM(64),
|
|
421
|
+
layers.Dense(1, activation="sigmoid"),
|
|
422
|
+
])
|
|
423
|
+
model.compile(
|
|
424
|
+
optimizer="adam",
|
|
425
|
+
loss="binary_crossentropy",
|
|
426
|
+
metrics=["accuracy"],
|
|
427
|
+
)
|
|
428
|
+
|
|
429
|
+
print()
|
|
430
|
+
print("-" * 70)
|
|
431
|
+
print("Training LSTM Model...")
|
|
432
|
+
print("-" * 70)
|
|
433
|
+
model.fit(
|
|
434
|
+
x_train,
|
|
435
|
+
y_train,
|
|
436
|
+
epochs=3,
|
|
437
|
+
batch_size=128,
|
|
438
|
+
validation_data=(x_test, y_test),
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
test_loss, test_accuracy = model.evaluate(x_test, y_test, verbose=0)
|
|
442
|
+
print(f"Test loss: {test_loss:.4f}")
|
|
443
|
+
print(f"Test accuracy: {test_accuracy:.4f}")
|
|
444
|
+
'''
|
|
445
|
+
CODE[8] = r'''
|
|
446
|
+
import numpy as np
|
|
447
|
+
import matplotlib.pyplot as plt
|
|
448
|
+
from tensorflow import keras
|
|
449
|
+
from tensorflow.keras import layers
|
|
450
|
+
from tensorflow.keras.datasets import mnist
|
|
451
|
+
from sklearn.metrics import confusion_matrix, classification_report
|
|
452
|
+
import seaborn as sns
|
|
453
|
+
|
|
454
|
+
print("DL CNN for Digit Recognition")
|
|
455
|
+
print("=" * 70)
|
|
456
|
+
print()
|
|
457
|
+
|
|
458
|
+
# Load MNIST dataset
|
|
459
|
+
print("-" * 70)
|
|
460
|
+
print("Loading MNIST Dataset...")
|
|
461
|
+
print("-" * 70)
|
|
462
|
+
(x_train, y_train), (x_test, y_test) = mnist.load_data()
|
|
463
|
+
|
|
464
|
+
# Preprocess data
|
|
465
|
+
x_train = x_train.astype("float32") / 255.0
|
|
466
|
+
x_test = x_test.astype("float32") / 255.0
|
|
467
|
+
|
|
468
|
+
# Reshape for CNN (add channel dimension)
|
|
469
|
+
x_train = x_train.reshape(-1, 28, 28, 1)
|
|
470
|
+
x_test = x_test.reshape(-1, 28, 28, 1)
|
|
471
|
+
|
|
472
|
+
# Convert labels to one-hot
|
|
473
|
+
y_train = keras.utils.to_categorical(y_train, 10)
|
|
474
|
+
y_test = keras.utils.to_categorical(y_test, 10)
|
|
475
|
+
|
|
476
|
+
print(f"Training data shape: {x_train.shape}")
|
|
477
|
+
print(f"Training labels shape: {y_train.shape}")
|
|
478
|
+
print(f"Test data shape: {x_test.shape}")
|
|
479
|
+
print(f"Test labels shape: {y_test.shape}")
|
|
480
|
+
print()
|
|
481
|
+
|
|
482
|
+
# Show sample digits
|
|
483
|
+
print("-" * 70)
|
|
484
|
+
print("Sample Training Digits...")
|
|
485
|
+
print("-" * 70)
|
|
486
|
+
|
|
487
|
+
fig, axes = plt.subplots(2, 5, figsize=(12, 4))
|
|
488
|
+
for i in range(10):
|
|
489
|
+
ax = axes[i // 5, i % 5]
|
|
490
|
+
ax.imshow(x_train[i].reshape(28, 28), cmap='gray')
|
|
491
|
+
ax.set_title(f"Label: {np.argmax(y_train[i])}")
|
|
492
|
+
ax.axis('off')
|
|
493
|
+
|
|
494
|
+
plt.tight_layout()
|
|
495
|
+
plt.savefig('sample_digits.png', dpi=100)
|
|
496
|
+
print("Sample digits saved as 'sample_digits.png'")
|
|
497
|
+
print()
|
|
498
|
+
|
|
499
|
+
# Build CNN model
|
|
500
|
+
print("-" * 70)
|
|
501
|
+
print("Building CNN Model...")
|
|
502
|
+
print("-" * 70)
|
|
503
|
+
|
|
504
|
+
model = keras.Sequential([
|
|
505
|
+
layers.Input(shape=(28, 28, 1)),
|
|
506
|
+
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
|
|
507
|
+
layers.MaxPooling2D(pool_size=(2, 2)),
|
|
508
|
+
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
|
|
509
|
+
layers.MaxPooling2D(pool_size=(2, 2)),
|
|
510
|
+
layers.Flatten(),
|
|
511
|
+
layers.Dropout(0.5),
|
|
512
|
+
layers.Dense(10, activation="softmax")
|
|
513
|
+
])
|
|
514
|
+
|
|
515
|
+
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
|
|
516
|
+
model.summary()
|
|
517
|
+
'''
|
|
518
|
+
|
|
519
|
+
# ======================================================================
|
|
520
|
+
# AIM, STEPS AND EXPLANATION
|
|
521
|
+
# ======================================================================
|
|
522
|
+
AIM = {1: 'To study the major deep learning frameworks (TensorFlow, Keras, PyTorch, JAX), check which are installed, and discuss the ethical considerations of deep learning.', 2: 'To implement a fully connected deep neural network with at least 2 hidden layers for classifying MNIST handwritten digits.', 3: 'To perform object detection on an image using a pre-trained EfficientDet model from TensorFlow Hub.', 4: 'To perform image segmentation using Gaussian blur, thresholding and morphological operations with OpenCV.', 5: 'To implement an undercomplete autoencoder that compresses MNIST images to 64 dimensions and reconstructs them.', 6: 'To implement a Variational Autoencoder (VAE) with a 2-D latent space using reparameterization sampling and a custom training step.', 7: 'To develop an RNN (LSTM) based model for sentiment analysis on the IMDB movie review dataset.', 8: 'To design and implement a CNN model for handwritten digit recognition on MNIST.'}
|
|
523
|
+
THEORY = {
|
|
524
|
+
1: ["Deep learning uses multi-layer neural networks that learn features automatically from data.",
|
|
525
|
+
"TensorFlow (Google) supports large-scale training and deployment through TF Lite and TF Serving.",
|
|
526
|
+
"Keras is a high-level API that makes building and training models quick.",
|
|
527
|
+
"PyTorch (Meta) uses dynamic computation graphs, which makes debugging easy and suits research.",
|
|
528
|
+
"JAX combines NumPy-style code with automatic differentiation and JIT compilation for speed.",
|
|
529
|
+
"Ethical issues: bias and fairness, privacy of data, transparency (explainability) and accountability.",
|
|
530
|
+
"Other concerns: safety against adversarial attacks, misuse (deepfakes, surveillance), energy use and job impact.",
|
|
531
|
+
"Responsible AI means using diverse data, protecting privacy, documenting models and keeping human oversight."],
|
|
532
|
+
2: ["A fully connected (dense) network has layers in which every neuron is linked to all neurons of the next layer.",
|
|
533
|
+
"Hidden layers with ReLU, f(x) = max(0, x), let the network learn non-linear patterns.",
|
|
534
|
+
"The softmax output layer converts scores into probabilities over the 10 digit classes.",
|
|
535
|
+
"Sparse categorical crossentropy measures the error between predicted probabilities and integer labels.",
|
|
536
|
+
"Backpropagation computes gradients and the Adam optimizer updates the weights.",
|
|
537
|
+
"Pixel values are scaled to 0-1 so training is faster and more stable.",
|
|
538
|
+
"Accuracy on the unseen test set shows how well the model generalizes."],
|
|
539
|
+
3: ["Object detection finds what objects are in an image (classification) and where they are (bounding boxes).",
|
|
540
|
+
"A pre-trained model is already trained on a large dataset (such as COCO), so no training is needed (transfer learning).",
|
|
541
|
+
"EfficientDet uses an EfficientNet backbone with a BiFPN to detect objects at several scales efficiently.",
|
|
542
|
+
"TensorFlow Hub provides ready-to-use pre-trained models that can be loaded with a single call.",
|
|
543
|
+
"The model returns boxes (normalized coordinates), class ids and confidence scores.",
|
|
544
|
+
"A confidence threshold (here 0.5) removes weak detections.",
|
|
545
|
+
"OpenCV reads images in BGR order, so they are converted to RGB before going to the model."],
|
|
546
|
+
4: ["Image segmentation divides an image into regions so that pixels of the same object or area are grouped together.",
|
|
547
|
+
"Gaussian blur smooths the image and reduces noise before thresholding.",
|
|
548
|
+
"Thresholding turns the grayscale image into a binary mask: pixels above 127 become white (255), the rest black (0).",
|
|
549
|
+
"Morphological opening (erosion followed by dilation) removes small noisy regions from the mask.",
|
|
550
|
+
"A bitwise AND of the image with the mask keeps only the foreground region.",
|
|
551
|
+
"This is classical (threshold-based) segmentation; deep models such as U-Net or DeepLab segment more accurately.",
|
|
552
|
+
"Segmentation is used in medical imaging, autonomous vehicles and satellite image analysis."],
|
|
553
|
+
5: ["An autoencoder is an unsupervised network that learns to copy its input to its output through a smaller bottleneck.",
|
|
554
|
+
"The encoder compresses the 784-pixel image into a 64-value code (latent representation).",
|
|
555
|
+
"The decoder reconstructs the 784 pixels from that code using a sigmoid activation.",
|
|
556
|
+
"Such an undercomplete autoencoder is forced to learn the most important features, which gives compression.",
|
|
557
|
+
"Mean Squared Error (MSE) between the input and the reconstruction is the loss to minimize.",
|
|
558
|
+
"The input images are used as both features and targets, so no labels are needed.",
|
|
559
|
+
"Uses: dimensionality reduction, image compression, denoising and anomaly detection."],
|
|
560
|
+
6: ["A Variational Autoencoder (VAE) is a generative model that learns a probability distribution in latent space.",
|
|
561
|
+
"The encoder outputs a mean (z_mean) and a log-variance (z_log_var) instead of a single point.",
|
|
562
|
+
"The reparameterization trick, z = mean + exp(0.5 * log_var) * epsilon, makes sampling differentiable for backpropagation.",
|
|
563
|
+
"The decoder reconstructs the image from the sampled latent vector z.",
|
|
564
|
+
"The loss = reconstruction loss (binary crossentropy) + KL divergence.",
|
|
565
|
+
"KL divergence pushes the latent distribution towards a standard normal, giving a smooth, continuous latent space.",
|
|
566
|
+
"Because the space is smooth, new images can be generated by sampling random latent vectors."],
|
|
567
|
+
7: ["A Recurrent Neural Network (RNN) processes sequences step by step and keeps a hidden state as memory.",
|
|
568
|
+
"Plain RNNs suffer from vanishing gradients on long sequences.",
|
|
569
|
+
"LSTM solves this with a cell state and input, forget and output gates that control what to remember.",
|
|
570
|
+
"An Embedding layer maps each word id to a dense vector (here 128 dimensions).",
|
|
571
|
+
"Reviews are padded or truncated to the same length (500 words) so they can be batched.",
|
|
572
|
+
"A sigmoid output gives the probability that a review is positive (binary classification).",
|
|
573
|
+
"Sentiment analysis is used for reviews, social media monitoring and customer feedback."],
|
|
574
|
+
8: ["A Convolutional Neural Network (CNN) is designed for images and learns spatial features automatically.",
|
|
575
|
+
"Conv2D layers slide small filters (3x3) over the image to detect edges, then shapes and patterns.",
|
|
576
|
+
"MaxPooling reduces the size of the feature maps, lowering computation and giving some translation invariance.",
|
|
577
|
+
"Flatten converts the feature maps to a vector for the final Dense layer.",
|
|
578
|
+
"Dropout (0.5) randomly switches off neurons during training to prevent overfitting.",
|
|
579
|
+
"The softmax output gives probabilities for the digits 0-9, trained with categorical crossentropy on one-hot labels.",
|
|
580
|
+
"CNNs need far fewer parameters than dense networks for images (34,826 here) and give higher accuracy."],
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
STEPS = {1: ['Import the frameworks (TensorFlow, Keras, PyTorch, JAX, scikit-learn, ONNX) and print the version of each installed one.', 'Check whether a GPU is available in TensorFlow and PyTorch.', 'Print a short comparison of the frameworks.', 'Print the main ethical considerations: bias, privacy, transparency, accountability, safety, misuse, environment, jobs.'], 2: ['Load the MNIST dataset and scale pixel values to the range 0-1 by dividing by 255.', 'Build a Sequential model: Flatten, Dense(128, ReLU), Dense(64, ReLU), Dense(10, softmax).', 'Compile with the Adam optimizer and sparse categorical crossentropy loss.', 'Train for 5 epochs with the test set as validation data.', 'Evaluate on the test data and print the test accuracy.'], 3: ['Load the EfficientDet-D0 detector from TensorFlow Hub.', 'Read image.jpg with OpenCV (falls back to sample_digits.png), convert BGR to RGB and make a tensor.', 'Run the detector to get bounding boxes, classes and scores.', 'Draw a green box and score for every detection with confidence above 0.5.', 'Save the result as detected_output.jpg and print a success message.'], 4: ['Load the image and convert it to grayscale.', 'Apply a 5x5 Gaussian blur to reduce noise.', 'Apply binary thresholding at 127 to create a black-and-white mask.', 'Apply morphological opening with a 3x3 rectangular kernel to remove small noise.', 'Use bitwise AND with the mask to isolate the segmented region.', 'Plot the original, mask and segmented image side by side with Matplotlib.'], 5: ['Load MNIST, normalize to 0-1 and flatten each image to 784 values.', 'Build the encoder Dense(64, ReLU) as the bottleneck and the decoder Dense(784, sigmoid).', 'Compile with Adam and MSE loss.', 'Train for 5 epochs using the images as both input and target.', 'Reconstruct 5 test images and plot originals above reconstructions.'], 6: ['Load and flatten MNIST (784 values per image).', 'Build the encoder that outputs z_mean and z_log_var, and sample z with the reparameterization trick.', 'Build the decoder Dense(256, ReLU) -> Dense(784, sigmoid).', 'Define a VAE class whose train_step/test_step compute reconstruction loss (binary crossentropy) plus KL divergence.', 'Train for 5 epochs and print training and validation losses.', 'Reconstruct 5 test digits and save the comparison as vae_reconstructions.png.'], 7: ['Load the IMDB dataset limited to the 10,000 most frequent words.', 'Pad/truncate every review to 500 tokens.', 'Build Embedding(10000,128) -> LSTM(64) -> Dense(1, sigmoid).', 'Compile with Adam and binary crossentropy.', 'Train for 3 epochs, evaluate on the test set and print the test loss and accuracy.'], 8: ['Load MNIST, normalize, add a channel dimension (28x28x1) and one-hot encode the labels.', 'Print the dataset shapes.', 'Plot 10 sample digits with their labels and save them as sample_digits.png.', 'Build the CNN: Conv2D(32) -> MaxPool -> Conv2D(64) -> MaxPool -> Flatten -> Dropout(0.5) -> Dense(10, softmax).', 'Compile with categorical crossentropy and Adam and print the model summary (the model is built but not trained).']}
|
|
584
|
+
EXPLANATION = {1: "The program lists the Python/OS details, prints the version of every deep learning framework that is installed (and 'not installed' for the rest), reports GPU availability, and then prints a framework comparison and eight ethical considerations. No image is produced.", 2: 'Training progress for 5 epochs is printed, followed by the test accuracy. The network reaches about 0.977 (97.7%) test accuracy on MNIST. No image is produced.', 3: 'A detected_output.jpg image is saved with green boxes around detections above the 0.5 confidence threshold, and two success messages are printed. If image.jpg is not present, sample_digits.png is used instead, so few or no boxes may appear.', 4: 'Nothing is printed to the console. A figure with three panels appears: the original image, the black-and-white segmentation mask and the segmented result. sample_digits.png is used if image.jpg is not available. In a non-interactive environment plt.show() cannot open a window.', 5: 'Training progress is printed for 5 epochs; the final loss is about 0.0105 and the validation loss about 0.0092. A 2-row figure shows five original MNIST digits above their five reconstructions.', 6: 'Training and validation losses are printed for 5 epochs. The final loss is about 29.93 (reconstruction 27.52 + KL 2.41) and the validation loss about 29.59. A comparison image of five original and five reconstructed digits is saved as vae_reconstructions.png.', 7: 'Dataset sizes (25000 training and 25000 test reviews) and preprocessing details are printed, followed by 3 epochs of LSTM training. The final test loss is about 0.4111 and the test accuracy about 0.8324 (83.2%).', 8: 'The console prints the dataset shapes ((60000, 28, 28, 1) for training and (10000, 28, 28, 1) for test) and the CNN model summary with 34,826 parameters. A 2-by-5 grid of labeled digits is saved as sample_digits.png. The model is built but not trained.'}
|
|
585
|
+
|
|
586
|
+
_BAR = "=" * 80
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
def _check(number):
|
|
590
|
+
if number not in CODE:
|
|
591
|
+
raise ValueError("Experiment number must be between 1 and 8.")
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
def _render(number):
|
|
595
|
+
"""Return the full text (aim, steps, code, explanation) of one experiment."""
|
|
596
|
+
_check(number)
|
|
597
|
+
aim = textwrap.fill(AIM[number], width=78)
|
|
598
|
+
steps = "\n".join(
|
|
599
|
+
textwrap.fill(f"{i}. {t}", width=78, subsequent_indent=" ")
|
|
600
|
+
for i, t in enumerate(STEPS[number], 1)
|
|
601
|
+
)
|
|
602
|
+
explanation = textwrap.fill(EXPLANATION[number], width=78)
|
|
603
|
+
theory = "\n".join(
|
|
604
|
+
textwrap.fill(f"- {t}", width=78, subsequent_indent=" ")
|
|
605
|
+
for t in THEORY[number]
|
|
606
|
+
)
|
|
607
|
+
return (
|
|
608
|
+
f"\n{_BAR}\nEXPERIMENT {number}\n{_BAR}\n"
|
|
609
|
+
f"AIM:\n{aim}\n"
|
|
610
|
+
f"\nTHEORY:\n{theory}\n"
|
|
611
|
+
f"\nWHAT THE CODE DOES:\n{steps}\n"
|
|
612
|
+
f"\n{_BAR}\nEXPERIMENT {number} - CODE\n{_BAR}\n"
|
|
613
|
+
f"{CODE[number].strip()}\n"
|
|
614
|
+
f"\n{_BAR}\nEXPERIMENT {number} - OUTPUT EXPLANATION\n{_BAR}\n"
|
|
615
|
+
f"{explanation}\n"
|
|
616
|
+
)
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
def show_experiment_code(number):
|
|
620
|
+
"""Print the code and explanation of one experiment (1-8)."""
|
|
621
|
+
text = _render(number)
|
|
622
|
+
print(text)
|
|
623
|
+
return text
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
def experiment1(): return show_experiment_code(1)
|
|
627
|
+
def experiment2(): return show_experiment_code(2)
|
|
628
|
+
def experiment3(): return show_experiment_code(3)
|
|
629
|
+
def experiment4(): return show_experiment_code(4)
|
|
630
|
+
def experiment5(): return show_experiment_code(5)
|
|
631
|
+
def experiment6(): return show_experiment_code(6)
|
|
632
|
+
def experiment7(): return show_experiment_code(7)
|
|
633
|
+
def experiment8(): return show_experiment_code(8)
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
def show_all(pause=True):
|
|
637
|
+
"""Print code + explanation of experiments 1-8.
|
|
638
|
+
|
|
639
|
+
In a normal terminal it waits for Enter after each experiment so nothing
|
|
640
|
+
scrolls out of view. In Jupyter / pipes it prints everything at once.
|
|
641
|
+
"""
|
|
642
|
+
interactive = pause and sys.stdin is not None and sys.stdin.isatty()
|
|
643
|
+
for number in range(1, 9):
|
|
644
|
+
show_experiment_code(number)
|
|
645
|
+
if number < 8 and interactive:
|
|
646
|
+
try:
|
|
647
|
+
input(f"--- End of Experiment {number}. "
|
|
648
|
+
f"Press Enter for Experiment {number + 1} ---")
|
|
649
|
+
except (EOFError, KeyboardInterrupt):
|
|
650
|
+
interactive = False
|
|
651
|
+
print(_BAR)
|
|
652
|
+
print("ALL 8 EXPERIMENTS DISPLAYED")
|
|
653
|
+
print(_BAR)
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
def save_code(path="numpyv_all_code.txt"):
|
|
657
|
+
"""Save code + explanation of experiments 1-8 into one text file."""
|
|
658
|
+
with open(path, "w", encoding="utf-8") as f:
|
|
659
|
+
for number in range(1, 9):
|
|
660
|
+
f.write(_render(number))
|
|
661
|
+
print("Saved:", os.path.abspath(path))
|
|
662
|
+
return path
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
def run_experiment(number):
|
|
666
|
+
"""Execute experiment 1-8 (runs the code, shows its real output)."""
|
|
667
|
+
_check(number)
|
|
668
|
+
namespace = {
|
|
669
|
+
"__name__": "__main__",
|
|
670
|
+
"__file__": os.path.join(os.getcwd(), f"exp{number}.py"),
|
|
671
|
+
}
|
|
672
|
+
exec(compile(CODE[number], f"<numpyv experiment {number}>", "exec"), namespace)
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
def main():
|
|
676
|
+
import argparse
|
|
677
|
+
parser = argparse.ArgumentParser(description="Show or run a Numpyv Deep Learning experiment.")
|
|
678
|
+
parser.add_argument("number", type=int, choices=range(1, 9))
|
|
679
|
+
parser.add_argument("--run", action="store_true", help="execute instead of showing code")
|
|
680
|
+
args = parser.parse_args()
|
|
681
|
+
if args.run:
|
|
682
|
+
run_experiment(args.number)
|
|
683
|
+
else:
|
|
684
|
+
show_experiment_code(args.number)
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
# Show everything automatically when the module is imported.
|
|
688
|
+
if __name__ != "__main__" and not os.environ.get("NUMPYV_QUIET"):
|
|
689
|
+
show_all()
|
|
690
|
+
|
|
691
|
+
if __name__ == "__main__":
|
|
692
|
+
main()
|
|
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "numpyv"
|
|
7
|
-
version = "1.0.
|
|
8
|
-
description = "Deep Learning lab experiments 1-8 - import to print aim, explanation and full code"
|
|
7
|
+
version = "1.0.1"
|
|
8
|
+
description = "Deep Learning lab experiments 1-8 - import to print aim, theory, explanation and full code"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
11
11
|
dependencies = ["numpy", "matplotlib", "tensorflow", "tensorflow-hub", "opencv-python", "scikit-learn", "seaborn"]
|
|
12
12
|
|
|
13
13
|
[project.scripts]
|
|
14
|
-
|
|
14
|
+
numpyv = "numpyv:main"
|
|
15
15
|
|
|
16
16
|
[tool.setuptools]
|
|
17
|
-
py-modules = ["
|
|
17
|
+
py-modules = ["numpyv"]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
numpyc
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|