radnn 0.0.9__tar.gz → 0.1.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.
- {radnn-0.0.9 → radnn-0.1.0}/LICENSE.txt +1 -1
- {radnn-0.0.9/src/radnn.egg-info → radnn-0.1.0}/PKG-INFO +4 -11
- {radnn-0.0.9 → radnn-0.1.0}/pyproject.toml +8 -6
- {radnn-0.0.9 → radnn-0.1.0}/setup.cfg +1 -1
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/__init__.py +4 -5
- radnn-0.1.0/src/radnn/benchmark/__init__.py +1 -0
- radnn-0.1.0/src/radnn/benchmark/latency.py +55 -0
- radnn-0.1.0/src/radnn/core.py +243 -0
- radnn-0.1.0/src/radnn/data/__init__.py +7 -0
- radnn-0.1.0/src/radnn/data/dataset_base.py +165 -0
- radnn-0.1.0/src/radnn/data/dataset_base_legacy.py +280 -0
- radnn-0.1.0/src/radnn/data/errors.py +32 -0
- radnn-0.1.0/src/radnn/data/sample_preprocessor.py +58 -0
- radnn-0.1.0/src/radnn/data/sample_set.py +279 -0
- radnn-0.1.0/src/radnn/data/sample_set_kind.py +126 -0
- radnn-0.1.0/src/radnn/data/sequence_dataset.py +129 -0
- radnn-0.1.0/src/radnn/data/structs/__init__.py +1 -0
- radnn-0.1.0/src/radnn/data/structs/tree.py +322 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/data_feed.py +1 -1
- radnn-0.1.0/src/radnn/data_beta/structures/__init__.py +2 -0
- radnn-0.1.0/src/radnn/data_beta/structures/dictionary.py +41 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/tf_classification_data_feed.py +5 -2
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/errors.py +10 -2
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/experiment/__init__.py +2 -0
- radnn-0.1.0/src/radnn/experiment/identification.py +7 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/experiment/ml_experiment.py +7 -2
- radnn-0.1.0/src/radnn/experiment/ml_experiment_log.py +47 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/images/image_processor.py +4 -1
- radnn-0.1.0/src/radnn/learn/__init__.py +0 -0
- radnn-0.1.0/src/radnn/learn/keras/__init__.py +4 -0
- {radnn-0.0.9/src/radnn/learn/state → radnn-0.1.0/src/radnn/learn/keras}/keras_best_state_saver.py +5 -1
- radnn-0.0.9/src/radnn/learn/learning_algorithm.py → radnn-0.1.0/src/radnn/learn/keras/keras_learning_algorithm.py +5 -9
- {radnn-0.0.9/src/radnn/learn → radnn-0.1.0/src/radnn/learn/keras}/keras_learning_rate_scheduler.py +4 -1
- radnn-0.0.9/src/radnn/learn/keras_optimization_algorithm.py → radnn-0.1.0/src/radnn/learn/keras/keras_optimization_combo.py +7 -3
- radnn-0.1.0/src/radnn/learn/torch/__init__.py +3 -0
- radnn-0.1.0/src/radnn/learn/torch/ml_model_freezer.py +330 -0
- radnn-0.1.0/src/radnn/learn/torch/ml_trainer.py +461 -0
- radnn-0.1.0/src/radnn/learn/torch/staircase_lr_scheduler.py +21 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/ml_system.py +68 -52
- radnn-0.1.0/src/radnn/models/__init__.py +5 -0
- radnn-0.1.0/src/radnn/models/cnn/__init__.py +0 -0
- radnn-0.1.0/src/radnn/models/cnn/cnn_stem_setup.py +35 -0
- radnn-0.1.0/src/radnn/models/model_factory.py +85 -0
- radnn-0.1.0/src/radnn/models/model_hyperparams.py +128 -0
- radnn-0.1.0/src/radnn/models/model_info.py +91 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/plots/plot_learning_curve.py +19 -8
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/__init__.py +1 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/files/__init__.py +1 -1
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/files/csvfile.py +37 -5
- radnn-0.0.9/src/radnn/core.py → radnn-0.1.0/src/radnn/system/files/filelist.py +28 -57
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/files/fileobject.py +11 -1
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/files/imgfile.py +1 -1
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/files/jsonfile.py +34 -9
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/files/picklefile.py +3 -3
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/files/textfile.py +48 -16
- radnn-0.1.0/src/radnn/system/files/zipfile.py +96 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/filestore.py +147 -47
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/filesystem.py +3 -3
- radnn-0.1.0/src/radnn/test/__init__.py +1 -0
- radnn-0.1.0/src/radnn/test/tensor_hash.py +130 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/utils.py +16 -2
- {radnn-0.0.9 → radnn-0.1.0/src/radnn.egg-info}/PKG-INFO +4 -11
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn.egg-info/SOURCES.txt +43 -33
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn.egg-info/requires.txt +1 -0
- radnn-0.0.9/README.md +0 -8
- radnn-0.0.9/src/radnn/learn/__init__.py +0 -7
- radnn-0.0.9/src/radnn/learn/state/__init__.py +0 -4
- radnn-0.0.9/src/radnn/system/files/filelist.py +0 -40
- radnn-0.0.9/test/test_config.py +0 -25
- radnn-0.0.9/test/test_corpus.py +0 -91
- radnn-0.0.9/test/test_corpus_load.py +0 -209
- radnn-0.0.9/test/test_data_feed.py +0 -47
- radnn-0.0.9/test/test_dataset_base.py +0 -56
- radnn-0.0.9/test/test_dataset_from_pandas.py +0 -41
- radnn-0.0.9/test/test_experiment_env.py +0 -42
- radnn-0.0.9/test/test_image_dataset_from_files.py +0 -166
- radnn-0.0.9/test/test_ml_experiment_config.py +0 -25
- radnn-0.0.9/test/test_ml_system.py +0 -6
- radnn-0.0.9/test/test_mlsystem.py +0 -3
- radnn-0.0.9/test/test_mnist.py +0 -43
- radnn-0.0.9/test/test_normalizer.py +0 -45
- radnn-0.0.9/test/test_normalizer_div_zero.py +0 -23
- radnn-0.0.9/test/test_sample_set.py +0 -42
- radnn-0.0.9/test/test_standardizer.py +0 -46
- radnn-0.0.9/test/test_text_pipeline.py +0 -17
- radnn-0.0.9/test/test_train.py +0 -57
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/__init__.py +0 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/dataset_base.py +0 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/dataset_folder.py +0 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/image_dataset.py +0 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/image_dataset_files.py +0 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/preprocess/__init__.py +0 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/preprocess/normalizer.py +0 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/preprocess/standardizer.py +0 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/sample_set.py +0 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/sequence_dataset.py +0 -0
- {radnn-0.0.9/src/radnn/data → radnn-0.1.0/src/radnn/data_beta}/subset_type.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/evaluation/__init__.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/evaluation/evaluate_classification.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/experiment/ml_experiment_config.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/experiment/ml_experiment_env.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/experiment/ml_experiment_store.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/images/__init__.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/images/colors.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/plots/__init__.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/plots/plot_auto_multi_image.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/plots/plot_confusion_matrix.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/plots/plot_multi_scatter.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/plots/plot_roc.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/plots/plot_voronoi_2d.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/stats/__init__.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/stats/descriptive_stats.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/hosts/__init__.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/hosts/colab_host.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/hosts/linux_host.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/hosts/windows_host.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/tee_logger.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/threads/__init__.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/threads/semaphore_lock.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/threads/thread_context.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/threads/thread_safe_queue.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/threads/thread_safe_string_collection.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn/system/threads/thread_worker.py +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn.egg-info/dependency_links.txt +0 -0
- {radnn-0.0.9 → radnn-0.1.0}/src/radnn.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2017-
|
|
3
|
+
Copyright (c) 2017-2026 Pantelis I. Kaplanoglou
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: radnn
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: Rapid Deep Neural Networks
|
|
5
5
|
Author-email: "Pantelis I. Kaplanoglou" <pikaplanoglou@ihu.gr>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -18,20 +18,13 @@ Classifier: Programming Language :: Python :: 3
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.9
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
-
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Requires-Python: >=3.10
|
|
22
23
|
Description-Content-Type: text/markdown
|
|
23
24
|
License-File: LICENSE.txt
|
|
24
25
|
Requires-Dist: numpy>=1.26.4
|
|
25
26
|
Requires-Dist: matplotlib>=3.8.4
|
|
26
27
|
Requires-Dist: pandas>=2.2.1
|
|
27
28
|
Requires-Dist: scikit-learn>=1.4.2
|
|
29
|
+
Requires-Dist: tqdm>=4.67.1
|
|
28
30
|
Dynamic: license-file
|
|
29
|
-
|
|
30
|
-
# radnn - Rapid Deep Neural Networks
|
|
31
|
-
|
|
32
|
-
A library that brings the Rapid Application Development (RAD) approach into the lifecycle of Deep Learning models. Adapts objects from other frameworks and hides their implementation details to put emphasis on:
|
|
33
|
-
|
|
34
|
-
- Experiments: Data, Models, Training, Reproducibility
|
|
35
|
-
- Management: Process, Storage, Deployment
|
|
36
|
-
- Evaluation: Metrics, Plots, Visualizations
|
|
37
|
-
- Integration: IPC, Web API
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "radnn"
|
|
3
|
-
version = "0.0
|
|
3
|
+
version = "0.1.0"
|
|
4
4
|
description = "Rapid Deep Neural Networks"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
7
7
|
{name = "Pantelis I. Kaplanoglou", email = "pikaplanoglou@ihu.gr"}
|
|
8
8
|
]
|
|
9
|
-
requires-python = ">=3.
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
10
|
license = "MIT"
|
|
11
11
|
license-files = ["LICENSE.txt"]
|
|
12
12
|
classifiers=[
|
|
@@ -22,12 +22,14 @@ classifiers=[
|
|
|
22
22
|
"Programming Language :: Python :: 3.9",
|
|
23
23
|
"Programming Language :: Python :: 3.10",
|
|
24
24
|
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12"
|
|
25
26
|
]
|
|
26
27
|
dependencies = [
|
|
27
|
-
"numpy >= 1.26.4",
|
|
28
|
-
"matplotlib >= 3.8.4",
|
|
29
|
-
"pandas >= 2.2.1",
|
|
30
|
-
"scikit-learn >= 1.4.2"
|
|
28
|
+
"numpy >= 1.26.4",
|
|
29
|
+
"matplotlib >= 3.8.4",
|
|
30
|
+
"pandas >= 2.2.1",
|
|
31
|
+
"scikit-learn >= 1.4.2",
|
|
32
|
+
"tqdm >= 4.67.1"
|
|
31
33
|
]
|
|
32
34
|
|
|
33
35
|
[project.urls]
|
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
# Version 0.0.7.2 [2025-02-17]
|
|
5
5
|
# Version 0.0.7.3 [2025-02-21]
|
|
6
6
|
# Version 0.0.8 [2025-02-25]
|
|
7
|
-
# Version 0.0.9 [2025-
|
|
8
|
-
|
|
7
|
+
# Version 0.0.9 [2025-04-15]
|
|
8
|
+
# Version 0.1.0 [2026-01-06]
|
|
9
|
+
# Version 0.1.1 [2025-01-xx]
|
|
10
|
+
__version__ = "0.1.0"
|
|
9
11
|
|
|
10
12
|
from .system import FileStore, FileSystem
|
|
11
13
|
from .ml_system import MLSystem
|
|
12
14
|
from .ml_system import mlsys
|
|
13
15
|
from .utils import print_tensor
|
|
14
16
|
from .errors import Errors
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .latency import timed_method, mlbench
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import time
|
|
3
|
+
import functools
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LatencyBenchmark(dict):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self.enabled = False
|
|
9
|
+
|
|
10
|
+
def stats(self, key):
|
|
11
|
+
nSeries = np.asarray(self.get(key, [0.0]), np.float32)
|
|
12
|
+
nMean = np.mean(nSeries)
|
|
13
|
+
nStd = np.std(nSeries)
|
|
14
|
+
nMax = np.max(nSeries)
|
|
15
|
+
nMin = np.min(nSeries)
|
|
16
|
+
return nMin, nMax, nMean, nStd
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
mlbench = LatencyBenchmark()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def timed_method(name: str | None = None):
|
|
24
|
+
"""
|
|
25
|
+
Decorator to measure elapsed time using a high-resolution timer.
|
|
26
|
+
|
|
27
|
+
Usage:
|
|
28
|
+
@timeit()
|
|
29
|
+
def f(...):
|
|
30
|
+
|
|
31
|
+
@timeit("custom_name")
|
|
32
|
+
def g(...):
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def decorator(func):
|
|
36
|
+
label = name or func.__qualname__
|
|
37
|
+
|
|
38
|
+
@functools.wraps(func)
|
|
39
|
+
def wrapper(*args, **kwargs):
|
|
40
|
+
if not mlbench.enabled:
|
|
41
|
+
return func(*args, **kwargs)
|
|
42
|
+
else:
|
|
43
|
+
start = time.perf_counter()
|
|
44
|
+
try:
|
|
45
|
+
return func(*args, **kwargs)
|
|
46
|
+
finally:
|
|
47
|
+
end = time.perf_counter()
|
|
48
|
+
elapsed = end - start
|
|
49
|
+
if not label in mlbench:
|
|
50
|
+
mlbench[label] = []
|
|
51
|
+
mlbench[label].append(elapsed * 1e3)
|
|
52
|
+
|
|
53
|
+
return wrapper
|
|
54
|
+
|
|
55
|
+
return decorator
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# ======================================================================================
|
|
2
|
+
#
|
|
3
|
+
# Rapid Deep Neural Networks
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the MIT License
|
|
6
|
+
# ______________________________________________________________________________________
|
|
7
|
+
# ......................................................................................
|
|
8
|
+
|
|
9
|
+
# Copyright (c) 2018-2026 Pantelis I. Kaplanoglou
|
|
10
|
+
|
|
11
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
# in the Software without restriction, including without limitation the rights
|
|
14
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
# furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
# copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
# SOFTWARE.
|
|
28
|
+
|
|
29
|
+
# .......................................................................................
|
|
30
|
+
import sys
|
|
31
|
+
import socket
|
|
32
|
+
import platform
|
|
33
|
+
import psutil
|
|
34
|
+
import subprocess
|
|
35
|
+
from datetime import datetime
|
|
36
|
+
import importlib
|
|
37
|
+
import importlib.util
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class RequiredLibs(object):
|
|
41
|
+
def __init__(self):
|
|
42
|
+
self.is_tensorflow_installed = importlib.util.find_spec("tensorflow") is not None
|
|
43
|
+
if not self.is_tensorflow_installed:
|
|
44
|
+
self.is_tensorflow_installed = importlib.util.find_spec("tensorflow-gpu") is not None
|
|
45
|
+
self.is_torch_installed = importlib.util.find_spec("torch") is not None
|
|
46
|
+
self.is_opencv_installed = importlib.util.find_spec("cv2") is not None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
52
|
+
def system_name() -> str:
|
|
53
|
+
return MLInfrastructure.host_name(False)
|
|
54
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
55
|
+
def now_iso():
|
|
56
|
+
return datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
|
|
57
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
58
|
+
def shell_command_output(command_string):
|
|
59
|
+
oOutput = subprocess.check_output(command_string, shell=True)
|
|
60
|
+
oOutputLines = oOutput.decode().splitlines()
|
|
61
|
+
|
|
62
|
+
oResult = []
|
|
63
|
+
for sLine in oOutputLines:
|
|
64
|
+
oResult.append(sLine)
|
|
65
|
+
|
|
66
|
+
return oResult
|
|
67
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# ======================================================================================================================
|
|
74
|
+
class MLInfrastructure(object):
|
|
75
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
76
|
+
@classmethod
|
|
77
|
+
def is_linux(cls):
|
|
78
|
+
return not (cls.is_windows or cls.is_colab or cls.is_macos())
|
|
79
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
80
|
+
@classmethod
|
|
81
|
+
def is_windows(cls):
|
|
82
|
+
sPlatform = platform.system()
|
|
83
|
+
return (sPlatform == "Windows")
|
|
84
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
85
|
+
@classmethod
|
|
86
|
+
def is_colab(cls):
|
|
87
|
+
return "google.colab" in sys.modules
|
|
88
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
89
|
+
@classmethod
|
|
90
|
+
def is_macos(cls):
|
|
91
|
+
sPlatform = platform.system()
|
|
92
|
+
return (sPlatform == "Darwin")
|
|
93
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
94
|
+
@classmethod
|
|
95
|
+
def host_name(cls, is_using_ip_address=True) -> str:
|
|
96
|
+
sPlatform = platform.system()
|
|
97
|
+
sHostName = socket.gethostname()
|
|
98
|
+
sIPAddress = socket.gethostbyname(sHostName)
|
|
99
|
+
|
|
100
|
+
bIsColab = "google.colab" in sys.modules
|
|
101
|
+
if bIsColab:
|
|
102
|
+
sResult = "(colab)"
|
|
103
|
+
if is_using_ip_address:
|
|
104
|
+
sResult += "-" + sIPAddress
|
|
105
|
+
else:
|
|
106
|
+
if sPlatform == "Windows":
|
|
107
|
+
sResult = "(windows)-" + sHostName
|
|
108
|
+
elif sPlatform == "Darwin":
|
|
109
|
+
sResult = "(macos)-" + sHostName
|
|
110
|
+
else:
|
|
111
|
+
sResult = "(linux)-" + sHostName
|
|
112
|
+
return sResult
|
|
113
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
114
|
+
# ======================================================================================================================
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# ======================================================================================================================
|
|
119
|
+
class HardwareDevice(object):
|
|
120
|
+
def __init__(self, name):
|
|
121
|
+
self.name = name
|
|
122
|
+
|
|
123
|
+
def __str__(self):
|
|
124
|
+
return self.name
|
|
125
|
+
|
|
126
|
+
def __repr__(self):
|
|
127
|
+
return self.__str__()
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# ======================================================================================================================
|
|
131
|
+
class CPU(HardwareDevice):
|
|
132
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
133
|
+
def __init__(self, name):
|
|
134
|
+
super(CPU, self).__init__(name)
|
|
135
|
+
self._cpuid()
|
|
136
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
137
|
+
def _cpuid(self):
|
|
138
|
+
'''
|
|
139
|
+
CPU Identification for both Windows and Linux
|
|
140
|
+
'''
|
|
141
|
+
sPlatform = platform.system()
|
|
142
|
+
|
|
143
|
+
if sPlatform == "Windows":
|
|
144
|
+
oCPUs = subprocess.check_output(
|
|
145
|
+
["powershell", "-Command",
|
|
146
|
+
"(Get-CimInstance Win32_Processor | Select-Object -ExpandProperty Name) -join \"\n\""],
|
|
147
|
+
text=True
|
|
148
|
+
).strip().splitlines()
|
|
149
|
+
|
|
150
|
+
self.name = ""
|
|
151
|
+
for sCPU in oCPUs:
|
|
152
|
+
self.name += f', {sCPU}'
|
|
153
|
+
|
|
154
|
+
elif sPlatform == "Darwin":
|
|
155
|
+
pass #MacOS
|
|
156
|
+
else:
|
|
157
|
+
self.name = ""
|
|
158
|
+
with open("/proc/cpuinfo") as f:
|
|
159
|
+
for line in f:
|
|
160
|
+
line = line.strip()
|
|
161
|
+
if line.startswith("model name"):
|
|
162
|
+
self.name += f', {line.split(":", 1)[1].strip()}'
|
|
163
|
+
if self.name.startswith(", "):
|
|
164
|
+
self.name = self.name[2:]
|
|
165
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
# ======================================================================================================================
|
|
169
|
+
class NeuralProcessingUnit(HardwareDevice):
|
|
170
|
+
def __init__(self, name):
|
|
171
|
+
super(NeuralProcessingUnit, self).__init__(name)
|
|
172
|
+
self.compute_capability = None
|
|
173
|
+
self.vram_in_gb = None
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# ======================================================================================================================
|
|
177
|
+
class AIGridInfo(HardwareDevice):
|
|
178
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
179
|
+
def __init__(self, name=None):
|
|
180
|
+
self.name = name
|
|
181
|
+
if self.name is None:
|
|
182
|
+
self.name = socket.gethostname()
|
|
183
|
+
self.cpu = CPU(platform.processor())
|
|
184
|
+
|
|
185
|
+
mem = psutil.virtual_memory()
|
|
186
|
+
total_bytes = mem.total
|
|
187
|
+
self.ram_in_gb = round(total_bytes / (1024 ** 3))
|
|
188
|
+
|
|
189
|
+
self.devices = []
|
|
190
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
191
|
+
@property
|
|
192
|
+
def device(self):
|
|
193
|
+
if len(self.devices) > 0:
|
|
194
|
+
return self.devices[0]
|
|
195
|
+
else:
|
|
196
|
+
return self.cpu
|
|
197
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
198
|
+
def discover_devices(self, framework_type: str = "torch"):
|
|
199
|
+
'''
|
|
200
|
+
Detects the AI accelerators using the framework libraries
|
|
201
|
+
:param framework_type: The framework that is used "torch" or "tensorflow"
|
|
202
|
+
:return:
|
|
203
|
+
'''
|
|
204
|
+
self.cpu = CPU(platform.processor())
|
|
205
|
+
|
|
206
|
+
if framework_type == "torch":
|
|
207
|
+
import torch
|
|
208
|
+
device_count = torch.cuda.device_count()
|
|
209
|
+
for i in range(device_count):
|
|
210
|
+
oUnit = NeuralProcessingUnit(torch.cuda.get_device_name(i))
|
|
211
|
+
oUnit.compute_capability = torch.cuda.get_device_capability(i)
|
|
212
|
+
oUnit.vram_in_gb = round(torch.cuda.get_device_properties(i).total_memory / (1024 ** 3))
|
|
213
|
+
self.devices.append(oUnit)
|
|
214
|
+
elif framework_type == "tensorflow":
|
|
215
|
+
import tensorflow as tf
|
|
216
|
+
gpus = tf.config.list_physical_devices("GPU")
|
|
217
|
+
for gpu in gpus:
|
|
218
|
+
details = tf.config.experimental.get_device_details(gpu)
|
|
219
|
+
oUnit = NeuralProcessingUnit(details["device_name"])
|
|
220
|
+
oUnit.compute_capability = details["compute_capability"]
|
|
221
|
+
print(details)
|
|
222
|
+
return self
|
|
223
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
224
|
+
def __str__(self):
|
|
225
|
+
sResult = f'{"|"*24}\n'
|
|
226
|
+
sResult += f"|| [{self.name[:16]:^16}] ||\n"
|
|
227
|
+
sResult = f'{"|"*24}\n'
|
|
228
|
+
sResult += f" |__ CPU: {self.cpu}\n"
|
|
229
|
+
sResult += f" |__ RAM: {self.ram_in_gb} GB\n"
|
|
230
|
+
sResult += f" |__ NPUs\n"
|
|
231
|
+
for oDevice in self.devices:
|
|
232
|
+
if isinstance(oDevice, NeuralProcessingUnit):
|
|
233
|
+
sResult += f'{" "*5} |__ {oDevice.name} {oDevice.vram_in_gb} GB\n'
|
|
234
|
+
else:
|
|
235
|
+
sResult += f'{" "*5} |__ {oDevice} \n'
|
|
236
|
+
return sResult
|
|
237
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
238
|
+
def __repr__(self):
|
|
239
|
+
return self.__str__()
|
|
240
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
241
|
+
|
|
242
|
+
# ======================================================================================================================
|
|
243
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from .dataset_base import DataSetBase, DataSetCallbacks
|
|
2
|
+
from .dataset_base_legacy import CDataSetBase
|
|
3
|
+
from .sequence_dataset import SequenceDataSet
|
|
4
|
+
from .sample_set import SampleSet
|
|
5
|
+
from .sample_set_kind import SampleSetKind
|
|
6
|
+
from .sample_preprocessor import SamplePreprocessor
|
|
7
|
+
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# ......................................................................................
|
|
2
|
+
# MIT License
|
|
3
|
+
|
|
4
|
+
# Copyright (c) 2019-2025 Pantelis I. Kaplanoglou
|
|
5
|
+
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
# furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
# copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
# SOFTWARE.
|
|
23
|
+
|
|
24
|
+
# ......................................................................................
|
|
25
|
+
import os
|
|
26
|
+
import numpy as np
|
|
27
|
+
import pandas as pd
|
|
28
|
+
from abc import ABC, abstractmethod
|
|
29
|
+
from .sample_set import SampleSet
|
|
30
|
+
from .sample_set_kind import SampleSetKind
|
|
31
|
+
from .sample_preprocessor import SamplePreprocessor, VoidPreprocessor
|
|
32
|
+
from .errors import *
|
|
33
|
+
from radnn import FileStore
|
|
34
|
+
|
|
35
|
+
# ======================================================================================================================
|
|
36
|
+
class DataSetCallbacks(object):
|
|
37
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
38
|
+
def __init__(self, lazy_loader=None, random_seeder=None):
|
|
39
|
+
self.lazy_loader = lazy_loader
|
|
40
|
+
self.random_seeder = random_seeder
|
|
41
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
42
|
+
def lazy_load(self):
|
|
43
|
+
self.lazy_loader()
|
|
44
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
45
|
+
def initialize_random_seed(self, seed: int):
|
|
46
|
+
self.random_seeder(seed)
|
|
47
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# ======================================================================================================================
|
|
51
|
+
class DataSetBase(ABC):
|
|
52
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
53
|
+
# Constructor
|
|
54
|
+
def __init__(self, name: str, variant: str|None=None, file_store=None, random_seed: int | None=None, callbacks: DataSetCallbacks | None = None):
|
|
55
|
+
# ..................// Instance Fields \\.........................
|
|
56
|
+
self.fs: FileStore|None = file_store
|
|
57
|
+
if (file_store is not None) and isinstance(file_store, str):
|
|
58
|
+
if not os.path.exists(file_store):
|
|
59
|
+
raise Exception(ERR_DATASET_FOLDER_NOT_FOUND % file_store)
|
|
60
|
+
self.fs = FileStore(file_store)
|
|
61
|
+
assert self.fs is not None, ERR_DATASET_MUST_PROVIDE_LOCAL_FILESTORE
|
|
62
|
+
|
|
63
|
+
self.name = name
|
|
64
|
+
self.variant = variant
|
|
65
|
+
self.random_seed = random_seed
|
|
66
|
+
self.callbacks: DataSetCallbacks = callbacks
|
|
67
|
+
|
|
68
|
+
self.hparams :dict|None = None
|
|
69
|
+
self.ts: SampleSet|None = None
|
|
70
|
+
self.vs: SampleSet|None = None
|
|
71
|
+
self.ut: SampleSet|None = None
|
|
72
|
+
self.preprocessor: SamplePreprocessor = VoidPreprocessor(self)
|
|
73
|
+
# ................................................................
|
|
74
|
+
if (self.random_seed is not None):
|
|
75
|
+
assert self.callbacks is not None, ERR_NO_CALLBACKS
|
|
76
|
+
assert self.callbacks.random_seeder is not None, ERR_NO_RANDOM_SEED_INITIALIZER_CALLBACK
|
|
77
|
+
self.callbacks.initialize_random_seed(self.random_seed)
|
|
78
|
+
|
|
79
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
80
|
+
@property
|
|
81
|
+
def filesystem_folder(self):
|
|
82
|
+
return self.fs.absolute_path
|
|
83
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
84
|
+
@abstractmethod
|
|
85
|
+
def do_read_hyperparams(self):
|
|
86
|
+
pass # must implement concrete method
|
|
87
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
88
|
+
@abstractmethod
|
|
89
|
+
def do_import_data(self):
|
|
90
|
+
pass # must implement concrete method
|
|
91
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
92
|
+
@abstractmethod
|
|
93
|
+
def do_prepare_data(self):
|
|
94
|
+
pass # could optionally override
|
|
95
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
96
|
+
@abstractmethod
|
|
97
|
+
def do_create_sample_sets(self):
|
|
98
|
+
pass # must implement concrete method
|
|
99
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
100
|
+
def prepare(self, hyperparams: dict|None = None):
|
|
101
|
+
self.hparams = hyperparams
|
|
102
|
+
if self.hparams is not None:
|
|
103
|
+
self.do_read_hyperparams()
|
|
104
|
+
|
|
105
|
+
if (self.callbacks is not None):
|
|
106
|
+
if self.callbacks.lazy_loader is not None:
|
|
107
|
+
self.callbacks.lazy_loader()
|
|
108
|
+
self.do_import_data()
|
|
109
|
+
self.do_prepare_data()
|
|
110
|
+
|
|
111
|
+
self.ts = None
|
|
112
|
+
self.vs = None
|
|
113
|
+
self.us = None
|
|
114
|
+
self.do_create_sample_sets()
|
|
115
|
+
|
|
116
|
+
assert self.ts is not None, ERR_SUBSET_MUST_HAVE_TS
|
|
117
|
+
assert self.ts.info.kind == SampleSetKind.TRAINING_SET.value, ERR_SUBSET_INVALID_SETUP
|
|
118
|
+
if self.vs is not None:
|
|
119
|
+
assert self.ts.info.kind == SampleSetKind.TRAINING_SET.value, ERR_SUBSET_INVALID_SETUP
|
|
120
|
+
if self.us is not None:
|
|
121
|
+
assert self.ts.info.kind == SampleSetKind.TRAINING_SET.value, ERR_SUBSET_INVALID_SETUP
|
|
122
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
123
|
+
def assign(self, data, label_columns: range):
|
|
124
|
+
if isinstance(data, tuple):
|
|
125
|
+
self.samples, self.labels = data
|
|
126
|
+
elif isinstance(data, np.ndarray):
|
|
127
|
+
self.samples = data
|
|
128
|
+
elif isinstance(data, dict):
|
|
129
|
+
if ("samples" in dict) and ("labels" in dict):
|
|
130
|
+
self.samples = data["samples"]
|
|
131
|
+
self.labels = data["labels"]
|
|
132
|
+
else:
|
|
133
|
+
pass # Support other formats
|
|
134
|
+
elif isinstance(data, pd.DataFrame):
|
|
135
|
+
if isinstance(data.columns, pd.Index):
|
|
136
|
+
nData = data.iloc[1:].to_numpy()
|
|
137
|
+
else:
|
|
138
|
+
nData = data.to_numpy()
|
|
139
|
+
|
|
140
|
+
if label_columns is None:
|
|
141
|
+
self.samples = nData
|
|
142
|
+
else:
|
|
143
|
+
if label_columns.start >= 0:
|
|
144
|
+
if label_columns.stop is None:
|
|
145
|
+
self.labels = nData[:, label_columns.start]
|
|
146
|
+
self.samples = nData[:, label_columns.start + 1:]
|
|
147
|
+
else:
|
|
148
|
+
self.labels = nData[:, label_columns.start:label_columns.stop + 1]
|
|
149
|
+
self.samples = nData[:, label_columns.stop + 1:]
|
|
150
|
+
else:
|
|
151
|
+
self.samples = nData[:, :label_columns.start]
|
|
152
|
+
self.labels = nData[:, label_columns.start:]
|
|
153
|
+
return self
|
|
154
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
155
|
+
def print_info(self):
|
|
156
|
+
if self.variant is not None:
|
|
157
|
+
print(f"Dataset [{self.name}] {self.variant}")
|
|
158
|
+
else:
|
|
159
|
+
print(f"Dataset [{self.name}]")
|
|
160
|
+
self.ts.print_info()
|
|
161
|
+
if self.vs is not None:
|
|
162
|
+
self.vs.print_info()
|
|
163
|
+
if self.ut is not None:
|
|
164
|
+
self.ut.print_info()
|
|
165
|
+
# --------------------------------------------------------------------------------------------------------------------
|