dl-experiment-code 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,66 @@
1
+ """
2
+ Experiment 7 - Autoencoder dimensionality reduction using Keras MNIST.
3
+ """
4
+
5
+ import numpy as np
6
+ import tensorflow as tf
7
+ from tensorflow import keras
8
+ import matplotlib.pyplot as plt
9
+
10
+ (x_train, _), (x_test, _) = keras.datasets.mnist.load_data()
11
+
12
+ x_train = x_train.astype("float32") / 255.0
13
+ x_test = x_test.astype("float32") / 255.0
14
+
15
+ x_train = x_train.reshape(len(x_train), -1)
16
+ x_test = x_test.reshape(len(x_test), -1)
17
+
18
+ input_dim = x_train.shape[1]
19
+ encoding_dim = 32
20
+
21
+ encoder = keras.Sequential([
22
+ keras.layers.Input(shape=(input_dim,)),
23
+ keras.layers.Dense(128, activation="relu"),
24
+ keras.layers.Dense(encoding_dim, activation="relu"),
25
+ ], name="encoder")
26
+
27
+ decoder = keras.Sequential([
28
+ keras.layers.Input(shape=(encoding_dim,)),
29
+ keras.layers.Dense(128, activation="relu"),
30
+ keras.layers.Dense(input_dim, activation="sigmoid"),
31
+ ], name="decoder")
32
+
33
+ autoencoder = keras.Sequential([encoder, decoder])
34
+
35
+ autoencoder.compile(
36
+ optimizer="adam",
37
+ loss="binary_crossentropy",
38
+ )
39
+
40
+ autoencoder.fit(
41
+ x_train,
42
+ x_train,
43
+ epochs=10,
44
+ batch_size=256,
45
+ validation_data=(x_test, x_test),
46
+ )
47
+
48
+ encoded = encoder.predict(x_test, verbose=0)
49
+ decoded = autoencoder.predict(x_test, verbose=0)
50
+
51
+ print("Original dimension:", input_dim)
52
+ print("Reduced dimension :", encoded.shape[1])
53
+
54
+ plt.figure(figsize=(10, 4))
55
+
56
+ for i in range(5):
57
+ plt.subplot(2, 5, i + 1)
58
+ plt.imshow(x_test[i].reshape(28, 28), cmap="gray")
59
+ plt.axis("off")
60
+
61
+ plt.subplot(2, 5, i + 6)
62
+ plt.imshow(decoded[i].reshape(28, 28), cmap="gray")
63
+ plt.axis("off")
64
+
65
+ plt.suptitle("Original (top) vs Reconstructed (bottom)")
66
+ plt.show()
@@ -0,0 +1,135 @@
1
+ """
2
+ Experiment 8 - Educational single-object detector using a LOCAL Pascal VOC dataset.
3
+
4
+ Expected structure:
5
+ data/object_dataset/
6
+ images/
7
+ annotations/
8
+
9
+ Each XML annotation should contain at least one object.
10
+ This experiment predicts one object class and one bounding box.
11
+ """
12
+
13
+ import os
14
+ import xml.etree.ElementTree as ET
15
+ import numpy as np
16
+ import tensorflow as tf
17
+ from tensorflow import keras
18
+ from sklearn.model_selection import train_test_split
19
+ from PIL import Image
20
+
21
+ IMAGE_DIR = "data/object_dataset/images"
22
+ ANNOTATION_DIR = "data/object_dataset/annotations"
23
+ IMAGE_SIZE = (128, 128)
24
+
25
+ def parse_annotation(xml_path):
26
+ root = ET.parse(xml_path).getroot()
27
+ size = root.find("size")
28
+ width = float(size.find("width").text)
29
+ height = float(size.find("height").text)
30
+
31
+ obj = root.find("object")
32
+ label = obj.find("name").text
33
+ box = obj.find("bndbox")
34
+
35
+ xmin = float(box.find("xmin").text) / width
36
+ ymin = float(box.find("ymin").text) / height
37
+ xmax = float(box.find("xmax").text) / width
38
+ ymax = float(box.find("ymax").text) / height
39
+
40
+ return label, [xmin, ymin, xmax, ymax]
41
+
42
+ image_files, labels, boxes = [], [], []
43
+
44
+ for filename in os.listdir(ANNOTATION_DIR):
45
+ if not filename.endswith(".xml"):
46
+ continue
47
+
48
+ xml_path = os.path.join(ANNOTATION_DIR, filename)
49
+ image_name = os.path.splitext(filename)[0]
50
+
51
+ for extension in [".jpg", ".jpeg", ".png"]:
52
+ candidate = os.path.join(IMAGE_DIR, image_name + extension)
53
+ if os.path.exists(candidate):
54
+ label, box = parse_annotation(xml_path)
55
+ image_files.append(candidate)
56
+ labels.append(label)
57
+ boxes.append(box)
58
+ break
59
+
60
+ classes = sorted(set(labels))
61
+ class_to_id = {name: i for i, name in enumerate(classes)}
62
+
63
+ X, y_class, y_box = [], [], []
64
+
65
+ for image_path, label, box in zip(image_files, labels, boxes):
66
+ image = Image.open(image_path).convert("RGB").resize(IMAGE_SIZE)
67
+ X.append(np.asarray(image, dtype="float32") / 255.0)
68
+ y_class.append(class_to_id[label])
69
+ y_box.append(box)
70
+
71
+ X = np.array(X)
72
+ y_class = np.array(y_class)
73
+ y_box = np.array(y_box, dtype="float32")
74
+
75
+ X_train, X_test, yc_train, yc_test, yb_train, yb_test = train_test_split(
76
+ X, y_class, y_box,
77
+ test_size=0.2,
78
+ random_state=42,
79
+ stratify=y_class,
80
+ )
81
+
82
+ inputs = keras.Input(shape=(128, 128, 3))
83
+
84
+ x = keras.layers.Conv2D(32, 3, activation="relu")(inputs)
85
+ x = keras.layers.MaxPooling2D()(x)
86
+ x = keras.layers.Conv2D(64, 3, activation="relu")(x)
87
+ x = keras.layers.MaxPooling2D()(x)
88
+ x = keras.layers.Conv2D(128, 3, activation="relu")(x)
89
+ x = keras.layers.MaxPooling2D()(x)
90
+ x = keras.layers.Flatten()(x)
91
+ x = keras.layers.Dense(128, activation="relu")(x)
92
+
93
+ class_output = keras.layers.Dense(
94
+ len(classes),
95
+ activation="softmax",
96
+ name="class_output",
97
+ )(x)
98
+
99
+ box_output = keras.layers.Dense(
100
+ 4,
101
+ activation="sigmoid",
102
+ name="box_output",
103
+ )(x)
104
+
105
+ model = keras.Model(inputs=inputs, outputs=[class_output, box_output])
106
+
107
+ model.compile(
108
+ optimizer="adam",
109
+ loss={
110
+ "class_output": "sparse_categorical_crossentropy",
111
+ "box_output": "mse",
112
+ },
113
+ metrics={
114
+ "class_output": "accuracy",
115
+ "box_output": "mae",
116
+ },
117
+ )
118
+
119
+ model.summary()
120
+
121
+ model.fit(
122
+ X_train,
123
+ {"class_output": yc_train, "box_output": yb_train},
124
+ validation_split=0.2,
125
+ epochs=10,
126
+ batch_size=16,
127
+ )
128
+
129
+ results = model.evaluate(
130
+ X_test,
131
+ {"class_output": yc_test, "box_output": yb_test},
132
+ )
133
+
134
+ print("\nClasses:", classes)
135
+ print("Evaluation:", results)
@@ -0,0 +1,118 @@
1
+ """
2
+ Experiment 8 - Educational single-object detector using Pascal VOC via TFDS.
3
+
4
+ Dataset is downloaded automatically from the TensorFlow Datasets catalogue.
5
+
6
+ Note:
7
+ This is intentionally a simple one-object educational detector, matching
8
+ the original experiment concept. It uses the first annotated object per image.
9
+ It is NOT a production multi-object detector like YOLO/SSD/Faster R-CNN.
10
+ """
11
+
12
+ import numpy as np
13
+ import tensorflow as tf
14
+ from tensorflow import keras
15
+ import tensorflow_datasets as tfds
16
+
17
+ IMAGE_SIZE = (128, 128)
18
+ MAX_SAMPLES = 3000
19
+
20
+ (ds, info) = tfds.load(
21
+ "voc",
22
+ split="train",
23
+ with_info=True,
24
+ )
25
+
26
+ class_names = info.features["objects"]["label"].names
27
+ X, y_class, y_box = [], [], []
28
+
29
+ for example in tfds.as_numpy(ds):
30
+ objects = example["objects"]
31
+ if len(objects["label"]) == 0:
32
+ continue
33
+
34
+ image = tf.image.resize(example["image"], IMAGE_SIZE).numpy()
35
+ image = image.astype("float32") / 255.0
36
+
37
+ # Use the first object for this educational single-object experiment.
38
+ label = int(objects["label"][0])
39
+ ymin = float(objects["bbox"]["ymin"][0])
40
+ xmin = float(objects["bbox"]["xmin"][0])
41
+ ymax = float(objects["bbox"]["ymax"][0])
42
+ xmax = float(objects["bbox"]["xmax"][0])
43
+
44
+ X.append(image)
45
+ y_class.append(label)
46
+ y_box.append([xmin, ymin, xmax, ymax])
47
+
48
+ if len(X) >= MAX_SAMPLES:
49
+ break
50
+
51
+ X = np.array(X, dtype="float32")
52
+ y_class = np.array(y_class, dtype="int32")
53
+ y_box = np.array(y_box, dtype="float32")
54
+
55
+ # Keep only classes represented in the selected sample.
56
+ used_classes = sorted(np.unique(y_class))
57
+ class_remap = {old: new for new, old in enumerate(used_classes)}
58
+ y_class = np.array([class_remap[x] for x in y_class])
59
+
60
+ X_train, X_test, yc_train, yc_test, yb_train, yb_test = (
61
+ __import__("sklearn.model_selection", fromlist=["train_test_split"])
62
+ .train_test_split(
63
+ X, y_class, y_box,
64
+ test_size=0.2,
65
+ random_state=42,
66
+ stratify=y_class,
67
+ )
68
+ )
69
+
70
+ inputs = keras.Input(shape=(128, 128, 3))
71
+ x = keras.layers.Conv2D(32, 3, activation="relu")(inputs)
72
+ x = keras.layers.MaxPooling2D()(x)
73
+ x = keras.layers.Conv2D(64, 3, activation="relu")(x)
74
+ x = keras.layers.MaxPooling2D()(x)
75
+ x = keras.layers.Conv2D(128, 3, activation="relu")(x)
76
+ x = keras.layers.MaxPooling2D()(x)
77
+ x = keras.layers.Flatten()(x)
78
+ x = keras.layers.Dense(128, activation="relu")(x)
79
+
80
+ class_output = keras.layers.Dense(
81
+ len(used_classes), activation="softmax", name="class_output"
82
+ )(x)
83
+
84
+ box_output = keras.layers.Dense(
85
+ 4, activation="sigmoid", name="box_output"
86
+ )(x)
87
+
88
+ model = keras.Model(inputs, [class_output, box_output])
89
+
90
+ model.compile(
91
+ optimizer="adam",
92
+ loss={
93
+ "class_output": "sparse_categorical_crossentropy",
94
+ "box_output": "mse",
95
+ },
96
+ metrics={
97
+ "class_output": "accuracy",
98
+ "box_output": "mae",
99
+ },
100
+ )
101
+
102
+ model.summary()
103
+
104
+ model.fit(
105
+ X_train,
106
+ {"class_output": yc_train, "box_output": yb_train},
107
+ validation_split=0.2,
108
+ epochs=10,
109
+ batch_size=16,
110
+ )
111
+
112
+ results = model.evaluate(
113
+ X_test,
114
+ {"class_output": yc_test, "box_output": yb_test},
115
+ )
116
+
117
+ print("\nUsed VOC classes:", [class_names[i] for i in used_classes])
118
+ print("Evaluation:", results)
@@ -0,0 +1,84 @@
1
+ """
2
+ Experiment 9 - LSTM sentiment analysis using a LOCAL CSV.
3
+
4
+ CSV format:
5
+ text,label
6
+ "I loved this movie",positive
7
+ "The movie was terrible",negative
8
+ """
9
+
10
+ import tensorflow as tf
11
+ from tensorflow import keras
12
+ import pandas as pd
13
+ from sklearn.model_selection import train_test_split
14
+ from sklearn.preprocessing import LabelEncoder
15
+
16
+ CSV_PATH = "data/sentiment.csv"
17
+ TEXT_COLUMN = "text"
18
+ LABEL_COLUMN = "label"
19
+ MAX_WORDS = 10000
20
+ MAX_LENGTH = 150
21
+
22
+ df = pd.read_csv(CSV_PATH)[[TEXT_COLUMN, LABEL_COLUMN]].dropna()
23
+
24
+ texts = df[TEXT_COLUMN].astype(str).values
25
+ encoder = LabelEncoder()
26
+ labels = encoder.fit_transform(df[LABEL_COLUMN])
27
+
28
+ X_train, X_test, y_train, y_test = train_test_split(
29
+ texts,
30
+ labels,
31
+ test_size=0.2,
32
+ random_state=42,
33
+ stratify=labels,
34
+ )
35
+
36
+ vectorizer = keras.layers.TextVectorization(
37
+ max_tokens=MAX_WORDS,
38
+ output_sequence_length=MAX_LENGTH,
39
+ )
40
+ vectorizer.adapt(X_train)
41
+
42
+ model = keras.Sequential([
43
+ keras.layers.Input(shape=(), dtype=tf.string),
44
+ vectorizer,
45
+ keras.layers.Embedding(
46
+ input_dim=MAX_WORDS,
47
+ output_dim=128,
48
+ mask_zero=True,
49
+ ),
50
+ keras.layers.LSTM(64),
51
+ keras.layers.Dense(32, activation="relu"),
52
+ keras.layers.Dropout(0.4),
53
+ keras.layers.Dense(len(encoder.classes_), activation="softmax"),
54
+ ])
55
+
56
+ model.compile(
57
+ optimizer="adam",
58
+ loss="sparse_categorical_crossentropy",
59
+ metrics=["accuracy"],
60
+ )
61
+
62
+ model.summary()
63
+
64
+ model.fit(
65
+ X_train,
66
+ y_train,
67
+ validation_split=0.2,
68
+ epochs=10,
69
+ batch_size=32,
70
+ )
71
+
72
+ loss, accuracy = model.evaluate(X_test, y_test)
73
+ print("\nTest accuracy:", round(accuracy, 4))
74
+
75
+ sample_texts = [
76
+ "This product is excellent",
77
+ "I hate this product",
78
+ ]
79
+
80
+ predictions = model.predict(sample_texts, verbose=0)
81
+
82
+ for text, prediction in zip(sample_texts, predictions):
83
+ index = prediction.argmax()
84
+ print(f"{text} -> {encoder.inverse_transform([index])[0]}")
@@ -0,0 +1,49 @@
1
+ """
2
+ Experiment 9 - LSTM sentiment analysis using the Keras IMDB dataset.
3
+ """
4
+
5
+ import numpy as np
6
+ import tensorflow as tf
7
+ from tensorflow import keras
8
+
9
+ MAX_WORDS = 10000
10
+ MAX_LENGTH = 150
11
+
12
+ (x_train, y_train), (x_test, y_test) = keras.datasets.imdb.load_data(
13
+ num_words=MAX_WORDS
14
+ )
15
+
16
+ x_train = keras.preprocessing.sequence.pad_sequences(
17
+ x_train, maxlen=MAX_LENGTH
18
+ )
19
+ x_test = keras.preprocessing.sequence.pad_sequences(
20
+ x_test, maxlen=MAX_LENGTH
21
+ )
22
+
23
+ model = keras.Sequential([
24
+ keras.layers.Input(shape=(MAX_LENGTH,)),
25
+ keras.layers.Embedding(MAX_WORDS, 128),
26
+ keras.layers.LSTM(64),
27
+ keras.layers.Dense(32, activation="relu"),
28
+ keras.layers.Dropout(0.4),
29
+ keras.layers.Dense(1, activation="sigmoid"),
30
+ ])
31
+
32
+ model.compile(
33
+ optimizer="adam",
34
+ loss="binary_crossentropy",
35
+ metrics=["accuracy"],
36
+ )
37
+
38
+ model.summary()
39
+
40
+ history = model.fit(
41
+ x_train,
42
+ y_train,
43
+ validation_split=0.2,
44
+ epochs=10,
45
+ batch_size=32,
46
+ )
47
+
48
+ loss, accuracy = model.evaluate(x_test, y_test)
49
+ print("\nTest accuracy:", round(accuracy, 4))
@@ -0,0 +1,130 @@
1
+ """
2
+ Additional Experiment - Vanilla RNN implemented from scratch with NumPy.
3
+
4
+ No TensorFlow/Keras recurrent layer is used.
5
+
6
+ Task:
7
+ Predict the next value of a sine-wave sequence.
8
+
9
+ The RNN equations implemented manually are:
10
+
11
+ h_t = tanh(Wxh x_t + Whh h_(t-1) + bh)
12
+ y_t = Why h_t + by
13
+
14
+ Training uses manually implemented backpropagation through time (BPTT).
15
+ """
16
+
17
+ import numpy as np
18
+
19
+ np.random.seed(42)
20
+
21
+ # Generate a simple sequence dataset.
22
+ t = np.linspace(0, 100, 2000)
23
+ sequence = np.sin(t).astype(np.float32)
24
+
25
+ SEQ_LEN = 20
26
+ HIDDEN_SIZE = 32
27
+ LEARNING_RATE = 0.01
28
+ EPOCHS = 20
29
+
30
+ X = []
31
+ Y = []
32
+
33
+ for i in range(len(sequence) - SEQ_LEN):
34
+ X.append(sequence[i:i + SEQ_LEN])
35
+ Y.append(sequence[i + SEQ_LEN])
36
+
37
+ X = np.array(X)
38
+ Y = np.array(Y)
39
+
40
+ split = int(0.8 * len(X))
41
+ X_train, X_test = X[:split], X[split:]
42
+ Y_train, Y_test = Y[:split], Y[split:]
43
+
44
+ # Parameters.
45
+ Wxh = np.random.randn(HIDDEN_SIZE, 1) * 0.1
46
+ Whh = np.random.randn(HIDDEN_SIZE, HIDDEN_SIZE) * 0.1
47
+ Why = np.random.randn(1, HIDDEN_SIZE) * 0.1
48
+
49
+ bh = np.zeros((HIDDEN_SIZE, 1))
50
+ by = np.zeros((1, 1))
51
+
52
+ def forward(sequence):
53
+ h = np.zeros((HIDDEN_SIZE, 1))
54
+ states = [(None, h)]
55
+ outputs = []
56
+
57
+ for value in sequence:
58
+ x = np.array([[value]], dtype=np.float32)
59
+ h = np.tanh(Wxh @ x + Whh @ h + bh)
60
+ y = Why @ h + by
61
+ states.append((x, h))
62
+ outputs.append(y.item())
63
+
64
+ return np.array(outputs), states
65
+
66
+ def train_step(sequence, target):
67
+ global Wxh, Whh, Why, bh, by
68
+
69
+ predictions, states = forward(sequence)
70
+
71
+ # Loss is based on the final prediction.
72
+ error = predictions[-1] - target
73
+ loss = 0.5 * error ** 2
74
+
75
+ dWxh = np.zeros_like(Wxh)
76
+ dWhh = np.zeros_like(Whh)
77
+ dWhy = np.zeros_like(Why)
78
+ dbh = np.zeros_like(bh)
79
+ dby = np.array([[error]])
80
+
81
+ # Gradient from the final output.
82
+ dWhy += error * states[-1][1]
83
+
84
+ dh = Why.T * error
85
+
86
+ # Backpropagation through time.
87
+ for step in reversed(range(1, len(states))):
88
+ x, h = states[step]
89
+ h_prev = states[step - 1][1]
90
+
91
+ dh_raw = (1 - h * h) * dh
92
+
93
+ dWxh += dh_raw @ x.T
94
+ dWhh += dh_raw @ h_prev.T
95
+ dbh += dh_raw
96
+
97
+ dh = Whh.T @ dh_raw
98
+
99
+ # Clip gradients for stability.
100
+ for grad in [dWxh, dWhh, dWhy, dbh, dby]:
101
+ np.clip(grad, -1, 1, out=grad)
102
+
103
+ Wxh -= LEARNING_RATE * dWxh
104
+ Whh -= LEARNING_RATE * dWhh
105
+ Why -= LEARNING_RATE * dWhy
106
+ bh -= LEARNING_RATE * dbh
107
+ by -= LEARNING_RATE * dby
108
+
109
+ return loss
110
+
111
+ for epoch in range(EPOCHS):
112
+ total_loss = 0.0
113
+
114
+ for sequence, target in zip(X_train, Y_train):
115
+ total_loss += train_step(sequence, target)
116
+
117
+ average_loss = total_loss / len(X_train)
118
+ print(f"Epoch {epoch + 1:02d}/{EPOCHS} - loss: {average_loss:.6f}")
119
+
120
+ test_losses = []
121
+
122
+ for sequence, target in zip(X_test[:200], Y_test[:200]):
123
+ prediction, _ = forward(sequence)
124
+ test_losses.append(0.5 * (prediction[-1] - target) ** 2)
125
+
126
+ print("\nMean test loss:", np.mean(test_losses))
127
+
128
+ sample_prediction, _ = forward(X_test[0])
129
+ print("Actual next value :", Y_test[0])
130
+ print("Predicted next value:", sample_prediction[-1])