dl-experiment-code 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.
- dl_experiment_code-1.0.0/PKG-INFO +146 -0
- dl_experiment_code-1.0.0/README.md +139 -0
- dl_experiment_code-1.0.0/dl_experiment_code/__init__.py +1 -0
- dl_experiment_code-1.0.0/dl_experiment_code/cli.py +94 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp10_local.py +120 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp10_online.py +95 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp5_local.py +87 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp5_online.py +60 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp6_local.py +97 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp6_online.py +68 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp7_local.py +66 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp7_online.py +66 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp8_local.py +135 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp8_online.py +118 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp9_local.py +84 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/exp9_online.py +49 -0
- dl_experiment_code-1.0.0/dl_experiment_code/templates/rnn_scratch.py +130 -0
- dl_experiment_code-1.0.0/dl_experiment_code.egg-info/PKG-INFO +146 -0
- dl_experiment_code-1.0.0/dl_experiment_code.egg-info/SOURCES.txt +22 -0
- dl_experiment_code-1.0.0/dl_experiment_code.egg-info/dependency_links.txt +1 -0
- dl_experiment_code-1.0.0/dl_experiment_code.egg-info/entry_points.txt +2 -0
- dl_experiment_code-1.0.0/dl_experiment_code.egg-info/top_level.txt +1 -0
- dl_experiment_code-1.0.0/pyproject.toml +20 -0
- dl_experiment_code-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dl-experiment-code
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Ready-to-use Deep Learning experiment code for experiments 5-10 and a NumPy RNN from scratch
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
|
|
8
|
+
# Deep Learning Experiment Code Package
|
|
9
|
+
|
|
10
|
+
This package provides ready-to-use code for:
|
|
11
|
+
|
|
12
|
+
- Experiment 5: CNN image classification
|
|
13
|
+
- Experiment 6: CNN hyperparameter tuning
|
|
14
|
+
- Experiment 7: Autoencoder dimensionality reduction
|
|
15
|
+
- Experiment 8: Educational single-object detection
|
|
16
|
+
- Experiment 9: LSTM sentiment analysis
|
|
17
|
+
- Experiment 10: LSTM hyperparameter tuning
|
|
18
|
+
- Additional: Vanilla RNN implemented from scratch with NumPy
|
|
19
|
+
|
|
20
|
+
For experiments 5-10 there are two versions:
|
|
21
|
+
|
|
22
|
+
1. `local` - uses a local CSV/image/Pascal VOC dataset.
|
|
23
|
+
2. `online` - uses a Keras dataset or an online TensorFlow Datasets dataset.
|
|
24
|
+
|
|
25
|
+
The code follows the structure and concepts of the supplied original experiments.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
From this folder:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
For development/editable installation:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install -e .
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## List experiments
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
dlab-code list
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Get code
|
|
48
|
+
|
|
49
|
+
Online/Keras dataset version:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
dlab-code get 5 --dataset online
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Local dataset version:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
dlab-code get 5 --dataset local
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Experiments 6-10 work the same way:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
dlab-code get 6 --dataset online
|
|
65
|
+
dlab-code get 7 --dataset local
|
|
66
|
+
dlab-code get 8 --dataset online
|
|
67
|
+
dlab-code get 9 --dataset local
|
|
68
|
+
dlab-code get 10 --dataset online
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Save directly to a Python file
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
dlab-code get 5 --dataset online --save exp5.py
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Then:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
python exp5.py
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## RNN from scratch
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
dlab-code get rnn-scratch
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Or save it:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
dlab-code get rnn-scratch --save rnn_from_scratch.py
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The RNN uses NumPy only for the recurrent computation and manually implements:
|
|
96
|
+
|
|
97
|
+
- hidden-state calculation
|
|
98
|
+
- output calculation
|
|
99
|
+
- loss
|
|
100
|
+
- backpropagation through time
|
|
101
|
+
- gradient clipping
|
|
102
|
+
- parameter updates
|
|
103
|
+
|
|
104
|
+
## Dataset notes
|
|
105
|
+
|
|
106
|
+
### Experiment 5
|
|
107
|
+
- Online: Keras CIFAR-10
|
|
108
|
+
- Local: image directory with one folder per class
|
|
109
|
+
|
|
110
|
+
### Experiment 6
|
|
111
|
+
- Online: Keras CIFAR-10
|
|
112
|
+
- Local: image directory with one folder per class
|
|
113
|
+
|
|
114
|
+
### Experiment 7
|
|
115
|
+
- Online: Keras MNIST
|
|
116
|
+
- Local: numeric CSV
|
|
117
|
+
|
|
118
|
+
### Experiment 8
|
|
119
|
+
- Online: Pascal VOC through TensorFlow Datasets
|
|
120
|
+
- Local: Pascal VOC-style images + XML annotations
|
|
121
|
+
|
|
122
|
+
The object detector is deliberately educational and predicts the first object in an image. It is not a production multi-object detector.
|
|
123
|
+
|
|
124
|
+
### Experiment 9
|
|
125
|
+
- Online: Keras IMDB
|
|
126
|
+
- Local: `text,label` CSV
|
|
127
|
+
|
|
128
|
+
### Experiment 10
|
|
129
|
+
- Online: Keras IMDB
|
|
130
|
+
- Local: `text,label` CSV
|
|
131
|
+
|
|
132
|
+
## Dependencies for running generated code
|
|
133
|
+
|
|
134
|
+
Install the common ML stack:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
pip install tensorflow scikit-learn pandas numpy matplotlib pillow
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Experiment 8 online additionally needs:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pip install tensorflow-datasets
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The package itself has no heavy ML dependency because it only generates/prints the code.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Deep Learning Experiment Code Package
|
|
2
|
+
|
|
3
|
+
This package provides ready-to-use code for:
|
|
4
|
+
|
|
5
|
+
- Experiment 5: CNN image classification
|
|
6
|
+
- Experiment 6: CNN hyperparameter tuning
|
|
7
|
+
- Experiment 7: Autoencoder dimensionality reduction
|
|
8
|
+
- Experiment 8: Educational single-object detection
|
|
9
|
+
- Experiment 9: LSTM sentiment analysis
|
|
10
|
+
- Experiment 10: LSTM hyperparameter tuning
|
|
11
|
+
- Additional: Vanilla RNN implemented from scratch with NumPy
|
|
12
|
+
|
|
13
|
+
For experiments 5-10 there are two versions:
|
|
14
|
+
|
|
15
|
+
1. `local` - uses a local CSV/image/Pascal VOC dataset.
|
|
16
|
+
2. `online` - uses a Keras dataset or an online TensorFlow Datasets dataset.
|
|
17
|
+
|
|
18
|
+
The code follows the structure and concepts of the supplied original experiments.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
From this folder:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For development/editable installation:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install -e .
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## List experiments
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
dlab-code list
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Get code
|
|
41
|
+
|
|
42
|
+
Online/Keras dataset version:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
dlab-code get 5 --dataset online
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Local dataset version:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
dlab-code get 5 --dataset local
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Experiments 6-10 work the same way:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
dlab-code get 6 --dataset online
|
|
58
|
+
dlab-code get 7 --dataset local
|
|
59
|
+
dlab-code get 8 --dataset online
|
|
60
|
+
dlab-code get 9 --dataset local
|
|
61
|
+
dlab-code get 10 --dataset online
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Save directly to a Python file
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
dlab-code get 5 --dataset online --save exp5.py
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Then:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
python exp5.py
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## RNN from scratch
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
dlab-code get rnn-scratch
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Or save it:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
dlab-code get rnn-scratch --save rnn_from_scratch.py
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The RNN uses NumPy only for the recurrent computation and manually implements:
|
|
89
|
+
|
|
90
|
+
- hidden-state calculation
|
|
91
|
+
- output calculation
|
|
92
|
+
- loss
|
|
93
|
+
- backpropagation through time
|
|
94
|
+
- gradient clipping
|
|
95
|
+
- parameter updates
|
|
96
|
+
|
|
97
|
+
## Dataset notes
|
|
98
|
+
|
|
99
|
+
### Experiment 5
|
|
100
|
+
- Online: Keras CIFAR-10
|
|
101
|
+
- Local: image directory with one folder per class
|
|
102
|
+
|
|
103
|
+
### Experiment 6
|
|
104
|
+
- Online: Keras CIFAR-10
|
|
105
|
+
- Local: image directory with one folder per class
|
|
106
|
+
|
|
107
|
+
### Experiment 7
|
|
108
|
+
- Online: Keras MNIST
|
|
109
|
+
- Local: numeric CSV
|
|
110
|
+
|
|
111
|
+
### Experiment 8
|
|
112
|
+
- Online: Pascal VOC through TensorFlow Datasets
|
|
113
|
+
- Local: Pascal VOC-style images + XML annotations
|
|
114
|
+
|
|
115
|
+
The object detector is deliberately educational and predicts the first object in an image. It is not a production multi-object detector.
|
|
116
|
+
|
|
117
|
+
### Experiment 9
|
|
118
|
+
- Online: Keras IMDB
|
|
119
|
+
- Local: `text,label` CSV
|
|
120
|
+
|
|
121
|
+
### Experiment 10
|
|
122
|
+
- Online: Keras IMDB
|
|
123
|
+
- Local: `text,label` CSV
|
|
124
|
+
|
|
125
|
+
## Dependencies for running generated code
|
|
126
|
+
|
|
127
|
+
Install the common ML stack:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pip install tensorflow scikit-learn pandas numpy matplotlib pillow
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Experiment 8 online additionally needs:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pip install tensorflow-datasets
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The package itself has no heavy ML dependency because it only generates/prints the code.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.0"
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import shutil
|
|
4
|
+
|
|
5
|
+
TEMPLATE_DIR = Path(__file__).parent / "templates"
|
|
6
|
+
|
|
7
|
+
EXPERIMENTS = {
|
|
8
|
+
"5": {
|
|
9
|
+
"local": ("exp5_local.py", "CNN image classification - local dataset"),
|
|
10
|
+
"online": ("exp5_online.py", "CNN image classification - Keras CIFAR-10"),
|
|
11
|
+
},
|
|
12
|
+
"6": {
|
|
13
|
+
"local": ("exp6_local.py", "CNN hyperparameter tuning - local dataset"),
|
|
14
|
+
"online": ("exp6_online.py", "CNN hyperparameter tuning - Keras CIFAR-10"),
|
|
15
|
+
},
|
|
16
|
+
"7": {
|
|
17
|
+
"local": ("exp7_local.py", "Autoencoder dimensionality reduction - local CSV"),
|
|
18
|
+
"online": ("exp7_online.py", "Autoencoder dimensionality reduction - Keras MNIST"),
|
|
19
|
+
},
|
|
20
|
+
"8": {
|
|
21
|
+
"local": ("exp8_local.py", "Educational object detection - local Pascal VOC XML"),
|
|
22
|
+
"online": ("exp8_online.py", "Educational object detection - Pascal VOC via TFDS"),
|
|
23
|
+
},
|
|
24
|
+
"9": {
|
|
25
|
+
"local": ("exp9_local.py", "LSTM sentiment analysis - local CSV"),
|
|
26
|
+
"online": ("exp9_online.py", "LSTM sentiment analysis - Keras IMDB"),
|
|
27
|
+
},
|
|
28
|
+
"10": {
|
|
29
|
+
"local": ("exp10_local.py", "LSTM hyperparameter tuning - local CSV"),
|
|
30
|
+
"online": ("exp10_online.py", "LSTM hyperparameter tuning - Keras IMDB"),
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
def read_template(filename):
|
|
35
|
+
return (TEMPLATE_DIR / filename).read_text(encoding="utf-8")
|
|
36
|
+
|
|
37
|
+
def main():
|
|
38
|
+
parser = argparse.ArgumentParser(
|
|
39
|
+
prog="dlab-code",
|
|
40
|
+
description="Get ready-to-use Deep Learning experiment code.",
|
|
41
|
+
)
|
|
42
|
+
sub = parser.add_subparsers(dest="command", required=True)
|
|
43
|
+
|
|
44
|
+
get = sub.add_parser("get", help="Print or save experiment code")
|
|
45
|
+
get.add_argument("experiment", help="Experiment number: 5-10 or rnn-scratch")
|
|
46
|
+
get.add_argument(
|
|
47
|
+
"--dataset",
|
|
48
|
+
choices=["local", "online"],
|
|
49
|
+
default="online",
|
|
50
|
+
help="Dataset variant for experiments 5-10 (default: online)",
|
|
51
|
+
)
|
|
52
|
+
get.add_argument(
|
|
53
|
+
"--save",
|
|
54
|
+
metavar="FILE",
|
|
55
|
+
help="Save the generated code to a .py file instead of only printing it",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
ls = sub.add_parser("list", help="List available experiments")
|
|
59
|
+
|
|
60
|
+
args = parser.parse_args()
|
|
61
|
+
|
|
62
|
+
if args.command == "list":
|
|
63
|
+
print("Available experiments:")
|
|
64
|
+
for number, variants in EXPERIMENTS.items():
|
|
65
|
+
print(f"\nExperiment {number}:")
|
|
66
|
+
for dataset, (_, description) in variants.items():
|
|
67
|
+
print(f" {dataset:7s} - {description}")
|
|
68
|
+
print("\nAdditional:")
|
|
69
|
+
print(" rnn-scratch - Vanilla RNN from scratch using NumPy")
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
exp = args.experiment.lower()
|
|
73
|
+
|
|
74
|
+
if exp in {"rnn-scratch", "rnn_scratch", "rnn"}:
|
|
75
|
+
code = read_template("rnn_scratch.py")
|
|
76
|
+
default_name = "rnn_from_scratch.py"
|
|
77
|
+
elif exp in EXPERIMENTS:
|
|
78
|
+
filename, _ = EXPERIMENTS[exp][args.dataset]
|
|
79
|
+
code = read_template(filename)
|
|
80
|
+
default_name = filename
|
|
81
|
+
else:
|
|
82
|
+
raise SystemExit(
|
|
83
|
+
"Unknown experiment. Use 'dlab-code list' to see available options."
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
if args.save:
|
|
87
|
+
output = Path(args.save)
|
|
88
|
+
output.write_text(code, encoding="utf-8")
|
|
89
|
+
print(f"Code saved to: {output.resolve()}")
|
|
90
|
+
else:
|
|
91
|
+
print(code)
|
|
92
|
+
|
|
93
|
+
if __name__ == "__main__":
|
|
94
|
+
main()
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Experiment 10 - LSTM hyperparameter tuning using a LOCAL CSV.
|
|
3
|
+
|
|
4
|
+
CSV format:
|
|
5
|
+
text,label
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import pandas as pd
|
|
9
|
+
import tensorflow as tf
|
|
10
|
+
from tensorflow import keras
|
|
11
|
+
from sklearn.model_selection import train_test_split
|
|
12
|
+
from sklearn.preprocessing import LabelEncoder
|
|
13
|
+
|
|
14
|
+
CSV_PATH = "data/sentiment.csv"
|
|
15
|
+
TEXT_COLUMN = "text"
|
|
16
|
+
LABEL_COLUMN = "label"
|
|
17
|
+
MAX_WORDS = 10000
|
|
18
|
+
MAX_LENGTH = 150
|
|
19
|
+
|
|
20
|
+
df = pd.read_csv(CSV_PATH)[[TEXT_COLUMN, LABEL_COLUMN]].dropna()
|
|
21
|
+
|
|
22
|
+
texts = df[TEXT_COLUMN].astype(str).values
|
|
23
|
+
encoder = LabelEncoder()
|
|
24
|
+
labels = encoder.fit_transform(df[LABEL_COLUMN])
|
|
25
|
+
|
|
26
|
+
X_train, X_test, y_train, y_test = train_test_split(
|
|
27
|
+
texts,
|
|
28
|
+
labels,
|
|
29
|
+
test_size=0.2,
|
|
30
|
+
random_state=42,
|
|
31
|
+
stratify=labels,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
vectorizer = keras.layers.TextVectorization(
|
|
35
|
+
max_tokens=MAX_WORDS,
|
|
36
|
+
output_sequence_length=MAX_LENGTH,
|
|
37
|
+
)
|
|
38
|
+
vectorizer.adapt(X_train)
|
|
39
|
+
|
|
40
|
+
def build_model(embedding_dim, lstm_units, dropout, learning_rate):
|
|
41
|
+
model = keras.Sequential([
|
|
42
|
+
keras.layers.Input(shape=(), dtype=tf.string),
|
|
43
|
+
vectorizer,
|
|
44
|
+
keras.layers.Embedding(
|
|
45
|
+
input_dim=MAX_WORDS,
|
|
46
|
+
output_dim=embedding_dim,
|
|
47
|
+
mask_zero=True,
|
|
48
|
+
),
|
|
49
|
+
keras.layers.LSTM(lstm_units),
|
|
50
|
+
keras.layers.Dropout(dropout),
|
|
51
|
+
keras.layers.Dense(
|
|
52
|
+
len(encoder.classes_),
|
|
53
|
+
activation="softmax",
|
|
54
|
+
),
|
|
55
|
+
])
|
|
56
|
+
|
|
57
|
+
model.compile(
|
|
58
|
+
optimizer=keras.optimizers.Adam(learning_rate=learning_rate),
|
|
59
|
+
loss="sparse_categorical_crossentropy",
|
|
60
|
+
metrics=["accuracy"],
|
|
61
|
+
)
|
|
62
|
+
return model
|
|
63
|
+
|
|
64
|
+
best_accuracy = -1
|
|
65
|
+
best_config = None
|
|
66
|
+
|
|
67
|
+
embedding_dims = [64, 128]
|
|
68
|
+
lstm_units_list = [32, 64]
|
|
69
|
+
dropouts = [0.3, 0.5]
|
|
70
|
+
learning_rates = [0.001, 0.0005]
|
|
71
|
+
|
|
72
|
+
for embedding_dim in embedding_dims:
|
|
73
|
+
for lstm_units in lstm_units_list:
|
|
74
|
+
for dropout in dropouts:
|
|
75
|
+
for learning_rate in learning_rates:
|
|
76
|
+
print(
|
|
77
|
+
f"\nembedding={embedding_dim}, "
|
|
78
|
+
f"LSTM={lstm_units}, dropout={dropout}, "
|
|
79
|
+
f"lr={learning_rate}"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
model = build_model(
|
|
83
|
+
embedding_dim,
|
|
84
|
+
lstm_units,
|
|
85
|
+
dropout,
|
|
86
|
+
learning_rate,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
model.fit(
|
|
90
|
+
X_train,
|
|
91
|
+
y_train,
|
|
92
|
+
validation_split=0.2,
|
|
93
|
+
epochs=5,
|
|
94
|
+
batch_size=32,
|
|
95
|
+
verbose=0,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
_, accuracy = model.evaluate(
|
|
99
|
+
X_test,
|
|
100
|
+
y_test,
|
|
101
|
+
verbose=0,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
print("Test accuracy:", round(accuracy, 4))
|
|
105
|
+
|
|
106
|
+
if accuracy > best_accuracy:
|
|
107
|
+
best_accuracy = accuracy
|
|
108
|
+
best_config = (
|
|
109
|
+
embedding_dim,
|
|
110
|
+
lstm_units,
|
|
111
|
+
dropout,
|
|
112
|
+
learning_rate,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
print("\nBest LSTM configuration:")
|
|
116
|
+
print("Embedding dimension:", best_config[0])
|
|
117
|
+
print("LSTM units :", best_config[1])
|
|
118
|
+
print("Dropout :", best_config[2])
|
|
119
|
+
print("Learning rate :", best_config[3])
|
|
120
|
+
print("Test accuracy :", round(best_accuracy, 4))
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Experiment 10 - LSTM hyperparameter tuning 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
|
+
def build_model(embedding_dim, lstm_units, dropout, learning_rate):
|
|
24
|
+
model = keras.Sequential([
|
|
25
|
+
keras.layers.Input(shape=(MAX_LENGTH,)),
|
|
26
|
+
keras.layers.Embedding(MAX_WORDS, embedding_dim),
|
|
27
|
+
keras.layers.LSTM(lstm_units),
|
|
28
|
+
keras.layers.Dropout(dropout),
|
|
29
|
+
keras.layers.Dense(1, activation="sigmoid"),
|
|
30
|
+
])
|
|
31
|
+
|
|
32
|
+
model.compile(
|
|
33
|
+
optimizer=keras.optimizers.Adam(learning_rate=learning_rate),
|
|
34
|
+
loss="binary_crossentropy",
|
|
35
|
+
metrics=["accuracy"],
|
|
36
|
+
)
|
|
37
|
+
return model
|
|
38
|
+
|
|
39
|
+
best_accuracy = -1
|
|
40
|
+
best_config = None
|
|
41
|
+
|
|
42
|
+
embedding_dims = [64, 128]
|
|
43
|
+
lstm_units_list = [32, 64]
|
|
44
|
+
dropouts = [0.3, 0.5]
|
|
45
|
+
learning_rates = [0.001, 0.0005]
|
|
46
|
+
|
|
47
|
+
for embedding_dim in embedding_dims:
|
|
48
|
+
for lstm_units in lstm_units_list:
|
|
49
|
+
for dropout in dropouts:
|
|
50
|
+
for learning_rate in learning_rates:
|
|
51
|
+
print(
|
|
52
|
+
f"\nembedding={embedding_dim}, "
|
|
53
|
+
f"LSTM={lstm_units}, dropout={dropout}, "
|
|
54
|
+
f"lr={learning_rate}"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
model = build_model(
|
|
58
|
+
embedding_dim,
|
|
59
|
+
lstm_units,
|
|
60
|
+
dropout,
|
|
61
|
+
learning_rate,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
model.fit(
|
|
65
|
+
x_train,
|
|
66
|
+
y_train,
|
|
67
|
+
validation_split=0.2,
|
|
68
|
+
epochs=5,
|
|
69
|
+
batch_size=32,
|
|
70
|
+
verbose=0,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
_, accuracy = model.evaluate(
|
|
74
|
+
x_test,
|
|
75
|
+
y_test,
|
|
76
|
+
verbose=0,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
print("Test accuracy:", round(accuracy, 4))
|
|
80
|
+
|
|
81
|
+
if accuracy > best_accuracy:
|
|
82
|
+
best_accuracy = accuracy
|
|
83
|
+
best_config = (
|
|
84
|
+
embedding_dim,
|
|
85
|
+
lstm_units,
|
|
86
|
+
dropout,
|
|
87
|
+
learning_rate,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
print("\nBest LSTM configuration:")
|
|
91
|
+
print("Embedding dimension:", best_config[0])
|
|
92
|
+
print("LSTM units :", best_config[1])
|
|
93
|
+
print("Dropout :", best_config[2])
|
|
94
|
+
print("Learning rate :", best_config[3])
|
|
95
|
+
print("Test accuracy :", round(best_accuracy, 4))
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Experiment 5 - CNN image classification using a LOCAL image directory.
|
|
3
|
+
|
|
4
|
+
Expected structure:
|
|
5
|
+
dataset/
|
|
6
|
+
class_a/
|
|
7
|
+
image1.jpg
|
|
8
|
+
image2.jpg
|
|
9
|
+
class_b/
|
|
10
|
+
image3.jpg
|
|
11
|
+
...
|
|
12
|
+
|
|
13
|
+
Change DATASET_PATH if required.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import tensorflow as tf
|
|
17
|
+
from tensorflow import keras
|
|
18
|
+
import matplotlib.pyplot as plt
|
|
19
|
+
|
|
20
|
+
DATASET_PATH = "dataset"
|
|
21
|
+
IMAGE_SIZE = (128, 128)
|
|
22
|
+
BATCH_SIZE = 32
|
|
23
|
+
EPOCHS = 10
|
|
24
|
+
|
|
25
|
+
train_ds = keras.utils.image_dataset_from_directory(
|
|
26
|
+
DATASET_PATH,
|
|
27
|
+
image_size=IMAGE_SIZE,
|
|
28
|
+
batch_size=BATCH_SIZE,
|
|
29
|
+
validation_split=0.2,
|
|
30
|
+
subset="training",
|
|
31
|
+
seed=42,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
val_ds = keras.utils.image_dataset_from_directory(
|
|
35
|
+
DATASET_PATH,
|
|
36
|
+
image_size=IMAGE_SIZE,
|
|
37
|
+
batch_size=BATCH_SIZE,
|
|
38
|
+
validation_split=0.2,
|
|
39
|
+
subset="validation",
|
|
40
|
+
seed=42,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
class_names = train_ds.class_names
|
|
44
|
+
num_classes = len(class_names)
|
|
45
|
+
|
|
46
|
+
normalization = keras.layers.Rescaling(1.0 / 255)
|
|
47
|
+
train_ds = train_ds.map(lambda x, y: (normalization(x), y))
|
|
48
|
+
val_ds = val_ds.map(lambda x, y: (normalization(x), y))
|
|
49
|
+
|
|
50
|
+
model = keras.Sequential([
|
|
51
|
+
keras.layers.Input(shape=(*IMAGE_SIZE, 3)),
|
|
52
|
+
keras.layers.Conv2D(32, 3, activation="relu"),
|
|
53
|
+
keras.layers.MaxPooling2D(),
|
|
54
|
+
keras.layers.Conv2D(64, 3, activation="relu"),
|
|
55
|
+
keras.layers.MaxPooling2D(),
|
|
56
|
+
keras.layers.Conv2D(128, 3, activation="relu"),
|
|
57
|
+
keras.layers.MaxPooling2D(),
|
|
58
|
+
keras.layers.Flatten(),
|
|
59
|
+
keras.layers.Dense(128, activation="relu"),
|
|
60
|
+
keras.layers.Dropout(0.5),
|
|
61
|
+
keras.layers.Dense(num_classes, activation="softmax"),
|
|
62
|
+
])
|
|
63
|
+
|
|
64
|
+
model.compile(
|
|
65
|
+
optimizer="adam",
|
|
66
|
+
loss="sparse_categorical_crossentropy",
|
|
67
|
+
metrics=["accuracy"],
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
model.summary()
|
|
71
|
+
|
|
72
|
+
history = model.fit(
|
|
73
|
+
train_ds,
|
|
74
|
+
validation_data=val_ds,
|
|
75
|
+
epochs=EPOCHS,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
loss, accuracy = model.evaluate(val_ds)
|
|
79
|
+
print(f"\nValidation accuracy: {accuracy:.4f}")
|
|
80
|
+
|
|
81
|
+
plt.plot(history.history["accuracy"], label="Training")
|
|
82
|
+
plt.plot(history.history["val_accuracy"], label="Validation")
|
|
83
|
+
plt.xlabel("Epoch")
|
|
84
|
+
plt.ylabel("Accuracy")
|
|
85
|
+
plt.legend()
|
|
86
|
+
plt.title("CNN Image Classification - Local Dataset")
|
|
87
|
+
plt.show()
|