radnn 0.0.7.2__py3-none-any.whl → 0.0.8__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.
- radnn/__init__.py +7 -5
- radnn/core.py +44 -28
- radnn/data/__init__.py +8 -0
- radnn/data/data_feed.py +147 -0
- radnn/data/dataset_base.py +3 -5
- radnn/data/dataset_folder.py +55 -0
- radnn/data/image_dataset.py +0 -2
- radnn/data/image_dataset_files.py +175 -0
- radnn/data/preprocess/normalizer.py +7 -1
- radnn/data/preprocess/standardizer.py +9 -2
- radnn/data/sample_set.py +30 -17
- radnn/data/sequence_dataset.py +0 -2
- radnn/data/subset_type.py +45 -0
- radnn/data/tf_classification_data_feed.py +113 -0
- radnn/errors.py +29 -0
- radnn/evaluation/evaluate_classification.py +7 -3
- radnn/experiment/ml_experiment.py +29 -0
- radnn/experiment/ml_experiment_config.py +61 -32
- radnn/experiment/ml_experiment_env.py +6 -2
- radnn/experiment/ml_experiment_store.py +0 -1
- radnn/images/__init__.py +2 -0
- radnn/images/colors.py +28 -0
- radnn/images/image_processor.py +513 -0
- radnn/learn/learning_algorithm.py +4 -3
- radnn/ml_system.py +59 -18
- radnn/plots/plot_auto_multi_image.py +27 -17
- radnn/plots/plot_confusion_matrix.py +7 -4
- radnn/plots/plot_learning_curve.py +7 -3
- radnn/plots/plot_multi_scatter.py +7 -3
- radnn/plots/plot_roc.py +8 -4
- radnn/plots/plot_voronoi_2d.py +8 -5
- radnn/stats/__init__.py +1 -0
- radnn/stats/descriptive_stats.py +45 -0
- radnn/system/files/__init__.py +1 -0
- radnn/system/files/csvfile.py +8 -5
- radnn/system/files/filelist.py +40 -0
- radnn/system/files/fileobject.py +9 -4
- radnn/system/files/imgfile.py +8 -4
- radnn/system/files/jsonfile.py +8 -4
- radnn/system/files/picklefile.py +8 -4
- radnn/system/files/textfile.py +37 -7
- radnn/system/filestore.py +36 -18
- radnn/system/filesystem.py +8 -3
- radnn/system/hosts/colab_host.py +29 -0
- radnn/system/hosts/linux_host.py +29 -0
- radnn/system/hosts/windows_host.py +39 -1
- radnn/system/tee_logger.py +7 -3
- radnn/system/threads/__init__.py +5 -0
- radnn/system/threads/semaphore_lock.py +58 -0
- radnn/system/threads/thread_context.py +175 -0
- radnn/system/threads/thread_safe_queue.py +163 -0
- radnn/system/threads/thread_safe_string_collection.py +66 -0
- radnn/system/threads/thread_worker.py +68 -0
- radnn/utils.py +96 -2
- {radnn-0.0.7.2.dist-info → radnn-0.0.8.dist-info}/METADATA +1 -1
- radnn-0.0.8.dist-info/RECORD +70 -0
- radnn-0.0.7.2.dist-info/RECORD +0 -53
- {radnn-0.0.7.2.dist-info → radnn-0.0.8.dist-info}/LICENSE.txt +0 -0
- {radnn-0.0.7.2.dist-info → radnn-0.0.8.dist-info}/WHEEL +0 -0
- {radnn-0.0.7.2.dist-info → radnn-0.0.8.dist-info}/top_level.txt +0 -0
radnn/data/sample_set.py
CHANGED
|
@@ -1,12 +1,36 @@
|
|
|
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
|
+
# ......................................................................................
|
|
1
25
|
from .dataset_base import DataSetBase
|
|
2
|
-
|
|
26
|
+
from .subset_type import SubsetType
|
|
3
27
|
|
|
4
28
|
|
|
5
29
|
|
|
6
30
|
class SampleSet(object):
|
|
7
31
|
# --------------------------------------------------------------------------------------------------------------------
|
|
8
32
|
def __init__(self, subset_type="custom", has_ids=False):
|
|
9
|
-
self.subset_type = subset_type
|
|
33
|
+
self.subset_type: SubsetType = SubsetType(subset_type)
|
|
10
34
|
self.parent_dataset = None
|
|
11
35
|
|
|
12
36
|
self.has_ids = has_ids
|
|
@@ -21,18 +45,7 @@ class SampleSet(object):
|
|
|
21
45
|
self._iter_counter = 0
|
|
22
46
|
|
|
23
47
|
self.feed = None
|
|
24
|
-
|
|
25
|
-
@property
|
|
26
|
-
def is_training_set(self):
|
|
27
|
-
return (self.subset_type == "training") or (self.subset_type == "train") or (self.subset_type == "ts")
|
|
28
|
-
# --------------------------------------------------------------------------------------------------------------------
|
|
29
|
-
@property
|
|
30
|
-
def is_validation_set(self):
|
|
31
|
-
return (self.subset_type == "validation") or (self.subset_type == "val") or (self.subset_type == "vs")
|
|
32
|
-
# --------------------------------------------------------------------------------------------------------------------
|
|
33
|
-
@property
|
|
34
|
-
def is_unknown_test_set(self):
|
|
35
|
-
return (self.subset_type == "testing") or (self.subset_type == "test") or (self.subset_type == "ut")
|
|
48
|
+
|
|
36
49
|
# --------------------------------------------------------------------------------------------------------------------
|
|
37
50
|
@property
|
|
38
51
|
def has_labels(self):
|
|
@@ -54,21 +67,21 @@ class SampleSet(object):
|
|
|
54
67
|
def subset_of(self, parent_dataset: DataSetBase):
|
|
55
68
|
self.parent_dataset = parent_dataset
|
|
56
69
|
if self.parent_dataset is not None:
|
|
57
|
-
if self.is_training_set:
|
|
70
|
+
if self.subset_type.is_training_set:
|
|
58
71
|
if self.parent_dataset.ts_samples is not None:
|
|
59
72
|
self.parent_dataset.ts = self
|
|
60
73
|
self.ids = self.parent_dataset.ts_sample_ids
|
|
61
74
|
self.samples = self.parent_dataset.ts_samples
|
|
62
75
|
self.sample_count = self.parent_dataset.ts_sample_count
|
|
63
76
|
self.labels = self.parent_dataset.ts_labels
|
|
64
|
-
elif self.is_validation_set:
|
|
77
|
+
elif self.subset_type.is_validation_set:
|
|
65
78
|
if self.parent_dataset.vs_samples is not None:
|
|
66
79
|
self.parent_dataset.vs = self
|
|
67
80
|
self.ids = self.parent_dataset.vs_sample_ids
|
|
68
81
|
self.samples = self.parent_dataset.vs_samples
|
|
69
82
|
self.sample_count = self.parent_dataset.vs_sample_count
|
|
70
83
|
self.labels = self.parent_dataset.vs_labels
|
|
71
|
-
elif self.is_unknown_test_set:
|
|
84
|
+
elif self.subset_type.is_unknown_test_set:
|
|
72
85
|
if self.parent_dataset.ut_samples is not None:
|
|
73
86
|
self.parent_dataset.ut = self
|
|
74
87
|
self.ids = self.parent_dataset.ut_sample_ids
|
radnn/data/sequence_dataset.py
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
class SubsetType(object):
|
|
26
|
+
def __init__(self, name):
|
|
27
|
+
self.name = name.lower()
|
|
28
|
+
self.type = -1 # Unknown
|
|
29
|
+
if self.is_training_set:
|
|
30
|
+
self.type = 0
|
|
31
|
+
elif self.is_validation_set:
|
|
32
|
+
self.type = 1
|
|
33
|
+
elif self.is_unknown_test_set:
|
|
34
|
+
self.type = 2
|
|
35
|
+
@property
|
|
36
|
+
def is_training_set(self):
|
|
37
|
+
return (self.name == "training") or (self.name == "train") or (self.name == "ts")
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def is_validation_set(self):
|
|
41
|
+
return (self.name == "validation") or (self.name == "val") or (self.name == "vs")
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def is_unknown_test_set(self):
|
|
45
|
+
return (self.name == "testing") or (self.name == "test") or (self.name == "ut")
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# ======================================================================================
|
|
2
|
+
#
|
|
3
|
+
# Rapid Deep Neural Networks
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the MIT License
|
|
6
|
+
# ______________________________________________________________________________________
|
|
7
|
+
# ......................................................................................
|
|
8
|
+
|
|
9
|
+
# Copyright (c) 2019-2025 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
|
+
|
|
31
|
+
import tensorflow as tf
|
|
32
|
+
from radnn import mlsys
|
|
33
|
+
from radnn.data.preprocess import Normalizer, Standardizer
|
|
34
|
+
from .data_feed import DataFeed
|
|
35
|
+
|
|
36
|
+
class TFClassificationDataFeed(DataFeed):
|
|
37
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
38
|
+
def do_random_crop(self, samples, labels):
|
|
39
|
+
tPaddedImage = tf.image.pad_to_bounding_box(samples, self.padding_offset, self.padding_offset
|
|
40
|
+
, self.padding_target, self.padding_target)
|
|
41
|
+
tResult = tf.image.random_crop(tPaddedImage, self.input_shape, seed=mlsys.seed)
|
|
42
|
+
print("crop", tResult)
|
|
43
|
+
return tResult, labels
|
|
44
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
45
|
+
def do_flip_left_right(self, samples, labels):
|
|
46
|
+
tResult = tf.image.random_flip_left_right(samples, seed=mlsys.seed)
|
|
47
|
+
print("flip", tResult)
|
|
48
|
+
return tResult, labels
|
|
49
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
50
|
+
def build_augmentation(self, feed, augmentation_kind):
|
|
51
|
+
if augmentation_kind == "random_crop":
|
|
52
|
+
feed = feed.map(self.do_random_crop, num_parallel_calls=8)
|
|
53
|
+
elif augmentation_kind == "random_flip_left_right":
|
|
54
|
+
feed = feed.map(self.do_flip_left_right, num_parallel_calls=8)
|
|
55
|
+
elif augmentation_kind == "random_cutout":
|
|
56
|
+
pass # //TODO: Cutout
|
|
57
|
+
return feed
|
|
58
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
59
|
+
def build_iterator(self):
|
|
60
|
+
feed = None
|
|
61
|
+
if self.subset_type.is_training_set:
|
|
62
|
+
feed = tf.data.Dataset.from_tensor_slices((self.dataset.ts_samples, self.dataset.ts_labels))
|
|
63
|
+
elif self.subset_type.is_validation_set:
|
|
64
|
+
feed = tf.data.Dataset.from_tensor_slices((self.dataset.vs_samples, self.dataset.vs_labels))
|
|
65
|
+
elif self.subset_type.is_unknown_test_set:
|
|
66
|
+
feed = tf.data.Dataset.from_tensor_slices((self.dataset.ut_samples, self.dataset.ut_labels))
|
|
67
|
+
return feed
|
|
68
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
69
|
+
def preprocess_normalize_onehot(self, samples, labels):
|
|
70
|
+
tSamples = tf.cast(samples, tf.float32)
|
|
71
|
+
tSamples = (tSamples - self.value_preprocessor.min) / (self.value_preprocessor.max - self.value_preprocessor.min)
|
|
72
|
+
tTargetsOneHot = tf.one_hot(labels, self.dataset.class_count)
|
|
73
|
+
return tSamples, tTargetsOneHot
|
|
74
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
75
|
+
def preprocess_standardize_onehot(self, samples, labels):
|
|
76
|
+
tSamples = tf.cast(samples, tf.float32)
|
|
77
|
+
tSamples = (tSamples - self.value_preprocessor.mean) / self.value_preprocessor.std
|
|
78
|
+
tTargetsOneHot = tf.one_hot(labels, self.dataset.class_count)
|
|
79
|
+
return tSamples, tTargetsOneHot
|
|
80
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
81
|
+
def preprocess_normalize(self, samples, labels):
|
|
82
|
+
tSamples = tf.cast(samples, tf.float32)
|
|
83
|
+
tSamples = (tSamples - self.value_preprocessor.min) / (self.value_preprocessor.max - self.value_preprocessor.min)
|
|
84
|
+
return tSamples, labels
|
|
85
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
86
|
+
def preprocess_standardize(self, samples, labels):
|
|
87
|
+
tSamples = tf.cast(samples, tf.float32)
|
|
88
|
+
tSamples = (tSamples - self.value_preprocessor.mean) / self.value_preprocessor.std
|
|
89
|
+
return tSamples, labels
|
|
90
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
91
|
+
def build_preprocessor(self, feed):
|
|
92
|
+
if self._is_multiclass:
|
|
93
|
+
if isinstance(self.value_preprocessor, Standardizer):
|
|
94
|
+
feed = feed.map(self.preprocess_standardize_onehot, num_parallel_calls=8)
|
|
95
|
+
elif isinstance(self.value_preprocessor, Normalizer):
|
|
96
|
+
feed = feed.map(self.preprocess_normalize_onehot, num_parallel_calls=8)
|
|
97
|
+
else:
|
|
98
|
+
if isinstance(self.value_preprocessor, Standardizer):
|
|
99
|
+
feed = feed.map(self.preprocess_standardize, num_parallel_calls=8)
|
|
100
|
+
elif isinstance(self.value_preprocessor, Normalizer):
|
|
101
|
+
feed = feed.map(self.preprocess_normalize, num_parallel_calls=8)
|
|
102
|
+
return feed
|
|
103
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
104
|
+
def build_random_shuffler(self, feed):
|
|
105
|
+
feed = feed.shuffle(self.sample_count_to_shuffle, seed=mlsys.seed)
|
|
106
|
+
return feed
|
|
107
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
108
|
+
def build_minibatch_maker(self, feed):
|
|
109
|
+
feed = feed.batch(self.batch_size)
|
|
110
|
+
return feed
|
|
111
|
+
# --------------------------------------------------------------------------------------------------------------------
|
|
112
|
+
|
|
113
|
+
|
radnn/errors.py
CHANGED
|
@@ -1,2 +1,31 @@
|
|
|
1
|
+
# ======================================================================================
|
|
2
|
+
#
|
|
3
|
+
# Rapid Deep Neural Networks
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the MIT License
|
|
6
|
+
# ______________________________________________________________________________________
|
|
7
|
+
# ......................................................................................
|
|
8
|
+
|
|
9
|
+
# Copyright (c) 2018-2025 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
|
+
# .......................................................................................
|
|
1
30
|
class Errors:
|
|
2
31
|
MLSYS_NO_FILESYS = "No file system defined for the machine learning system. Create the object and assign the mlsys.filesys property."
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
# ======================================================================================
|
|
2
|
+
#
|
|
3
|
+
# Rapid Deep Neural Networks
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the MIT License
|
|
6
|
+
# ______________________________________________________________________________________
|
|
1
7
|
# ......................................................................................
|
|
2
|
-
# MIT License
|
|
3
8
|
|
|
4
|
-
# Copyright (c)
|
|
9
|
+
# Copyright (c) 2019-2025 Pantelis I. Kaplanoglou
|
|
5
10
|
|
|
6
11
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
12
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -22,7 +27,6 @@
|
|
|
22
27
|
# SOFTWARE.
|
|
23
28
|
|
|
24
29
|
# ......................................................................................
|
|
25
|
-
|
|
26
30
|
import numpy as np
|
|
27
31
|
from sklearn import metrics
|
|
28
32
|
|
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
# ======================================================================================
|
|
2
|
+
#
|
|
3
|
+
# Rapid Deep Neural Networks
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the MIT License
|
|
6
|
+
# ______________________________________________________________________________________
|
|
7
|
+
# ......................................................................................
|
|
8
|
+
|
|
9
|
+
# Copyright (c) 2019-2025 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
|
+
# ......................................................................................
|
|
1
30
|
import os
|
|
2
31
|
import numpy as np
|
|
3
32
|
from datetime import datetime
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
# ======================================================================================
|
|
2
|
+
#
|
|
3
|
+
# Rapid Deep Neural Networks
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the MIT License
|
|
6
|
+
# ______________________________________________________________________________________
|
|
1
7
|
# ......................................................................................
|
|
2
|
-
# MIT License
|
|
3
8
|
|
|
4
|
-
# Copyright (c)
|
|
9
|
+
# Copyright (c) 2019-2025 Pantelis I. Kaplanoglou
|
|
5
10
|
|
|
6
11
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
12
|
# of this software and associated documentation files (the "Software"), to deal
|
|
@@ -22,13 +27,12 @@
|
|
|
22
27
|
# SOFTWARE.
|
|
23
28
|
|
|
24
29
|
# ......................................................................................
|
|
25
|
-
|
|
26
30
|
import os
|
|
27
31
|
import json
|
|
28
32
|
import re
|
|
29
33
|
from datetime import datetime
|
|
30
|
-
|
|
31
|
-
from radnn.system import FileSystem
|
|
34
|
+
from radnn.ml_system import mlsys
|
|
35
|
+
from radnn.system import FileSystem, FileStore
|
|
32
36
|
|
|
33
37
|
# --------------------------------------------------------------------------------------
|
|
34
38
|
def model_code_mllib(p_oDict):
|
|
@@ -142,9 +146,11 @@ def experiment_code_and_timestamp(filename):
|
|
|
142
146
|
|
|
143
147
|
|
|
144
148
|
# =========================================================================================================================
|
|
145
|
-
class MLExperimentConfig(
|
|
149
|
+
class MLExperimentConfig(object):
|
|
146
150
|
# --------------------------------------------------------------------------------------
|
|
147
151
|
def __init__(self, filename=None, base_name=None, number=None, variation=None, fold_number=None, hyperparams=None):
|
|
152
|
+
self._kv = dict()
|
|
153
|
+
|
|
148
154
|
self["Experiment.BaseName"] = base_name
|
|
149
155
|
self.filename = filename
|
|
150
156
|
if self.filename is not None:
|
|
@@ -160,28 +166,19 @@ class MLExperimentConfig(dict):
|
|
|
160
166
|
if hyperparams is not None:
|
|
161
167
|
self.assign(hyperparams)
|
|
162
168
|
# --------------------------------------------------------------------------------------
|
|
169
|
+
def __getitem__(self, key):
|
|
170
|
+
return self._kv[key]
|
|
171
|
+
# --------------------------------------------------------------------------------------
|
|
172
|
+
def __setitem__(self, key, value):
|
|
173
|
+
self._kv[key] = value
|
|
174
|
+
# --------------------------------------------------------------------------------------
|
|
175
|
+
def __contains__(self, key):
|
|
176
|
+
return key in self._kv
|
|
177
|
+
# --------------------------------------------------------------------------------------
|
|
163
178
|
@property
|
|
164
179
|
def experiment_code(self):
|
|
165
180
|
return get_experiment_code(self)
|
|
166
181
|
# --------------------------------------------------------------------------------------
|
|
167
|
-
def load(self, filename=None, must_exist=False):
|
|
168
|
-
if filename is None:
|
|
169
|
-
filename = self.filename
|
|
170
|
-
|
|
171
|
-
# reading the data from the file
|
|
172
|
-
if os.path.exists(filename):
|
|
173
|
-
with open(filename) as oFile:
|
|
174
|
-
sConfig = oFile.read()
|
|
175
|
-
self.setDefaults()
|
|
176
|
-
dConfigDict = json.loads(sConfig)
|
|
177
|
-
|
|
178
|
-
for sKey in dConfigDict.keys():
|
|
179
|
-
self[sKey] = dConfigDict[sKey]
|
|
180
|
-
else:
|
|
181
|
-
if must_exist:
|
|
182
|
-
raise Exception("Experiment configuration file %s is not found." % filename)
|
|
183
|
-
return self
|
|
184
|
-
# --------------------------------------------------------------------------------------
|
|
185
182
|
def assign(self, config_dict):
|
|
186
183
|
for sKey in config_dict.keys():
|
|
187
184
|
self[sKey] = config_dict[sKey]
|
|
@@ -196,16 +193,19 @@ class MLExperimentConfig(dict):
|
|
|
196
193
|
if filename is not None:
|
|
197
194
|
self.filename = filename
|
|
198
195
|
|
|
199
|
-
sJSON = json.dumps(self, sort_keys=False, indent=4)
|
|
196
|
+
sJSON = json.dumps(self._kv, sort_keys=False, indent=4)
|
|
200
197
|
with open(self.filename, "w") as oFile:
|
|
201
198
|
oFile.write(sJSON)
|
|
202
199
|
oFile.close()
|
|
203
|
-
|
|
204
200
|
return self
|
|
205
201
|
# --------------------------------------------------------------------------------------
|
|
206
|
-
def save(self, fs, filename_only=None):
|
|
207
|
-
if
|
|
202
|
+
def save(self, fs=None, filename_only=None):
|
|
203
|
+
if fs is None:
|
|
204
|
+
fs = mlsys.filesys.configs
|
|
205
|
+
elif isinstance(fs, FileSystem):
|
|
208
206
|
fs = fs.configs
|
|
207
|
+
elif not isinstance(fs, FileStore):
|
|
208
|
+
raise Exception("Unsupporting persistent storage")
|
|
209
209
|
|
|
210
210
|
if filename_only is None:
|
|
211
211
|
filename_only = get_experiment_code(self)
|
|
@@ -217,19 +217,48 @@ class MLExperimentConfig(dict):
|
|
|
217
217
|
# Backwards compatibility 0.6.0
|
|
218
218
|
return self.save()
|
|
219
219
|
# --------------------------------------------------------------------------------------
|
|
220
|
-
def
|
|
221
|
-
if
|
|
220
|
+
def load_from_json(self, filename=None, must_exist=False):
|
|
221
|
+
if filename is None:
|
|
222
|
+
filename = self.filename
|
|
223
|
+
|
|
224
|
+
# reading the data from the file
|
|
225
|
+
if os.path.exists(filename):
|
|
226
|
+
with open(filename) as oFile:
|
|
227
|
+
sConfig = oFile.read()
|
|
228
|
+
self.setDefaults()
|
|
229
|
+
dConfigDict = json.loads(sConfig)
|
|
230
|
+
|
|
231
|
+
for sKey in dConfigDict.keys():
|
|
232
|
+
self._kv[sKey] = dConfigDict[sKey]
|
|
233
|
+
else:
|
|
234
|
+
if must_exist:
|
|
235
|
+
raise Exception("Experiment configuration file %s is not found." % filename)
|
|
236
|
+
return self
|
|
237
|
+
# --------------------------------------------------------------------------------------
|
|
238
|
+
def load(self, fs=None, filename_only=None):
|
|
239
|
+
if fs is None:
|
|
240
|
+
fs = mlsys.filesys.configs
|
|
241
|
+
elif isinstance(fs, FileSystem):
|
|
222
242
|
fs = fs.configs
|
|
243
|
+
elif not isinstance(fs, FileStore):
|
|
244
|
+
raise Exception("Unsupporting persistent storage")
|
|
245
|
+
|
|
246
|
+
if filename_only is None:
|
|
247
|
+
filename_only = get_experiment_code(self)
|
|
223
248
|
|
|
224
249
|
sFileName = fs.file(filename_only + ".json")
|
|
225
|
-
return self.
|
|
250
|
+
return self.load_from_json(sFileName)
|
|
251
|
+
# --------------------------------------------------------------------------------------
|
|
252
|
+
def load_config(self, fs, filename_only):
|
|
253
|
+
# Backwards compatibility 0.6.0
|
|
254
|
+
return self.load(fs, filename_only)
|
|
226
255
|
# --------------------------------------------------------------------------------------
|
|
227
256
|
def setDefaults(self):
|
|
228
257
|
pass
|
|
229
258
|
# --------------------------------------------------------------------------------------
|
|
230
259
|
def __str__(self)->str:
|
|
231
260
|
sResult = ""
|
|
232
|
-
for sKey in self.keys():
|
|
261
|
+
for sKey in self._kv.keys():
|
|
233
262
|
sResult += f' {sKey}: \"{self[sKey]}\",\n'
|
|
234
263
|
|
|
235
264
|
sResult = "{\n" + sResult + "}"
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
# ======================================================================================
|
|
2
|
+
#
|
|
3
|
+
# Rapid Deep Neural Networks
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the MIT License
|
|
6
|
+
# ______________________________________________________________________________________
|
|
1
7
|
# ......................................................................................
|
|
2
|
-
# MIT License
|
|
3
8
|
|
|
4
9
|
# Copyright (c) 2023-2025 Pantelis I. Kaplanoglou
|
|
5
10
|
|
|
@@ -22,7 +27,6 @@
|
|
|
22
27
|
# SOFTWARE.
|
|
23
28
|
|
|
24
29
|
# ......................................................................................
|
|
25
|
-
|
|
26
30
|
import os
|
|
27
31
|
import shutil
|
|
28
32
|
import sys
|
radnn/images/__init__.py
ADDED
radnn/images/colors.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from matplotlib import colors
|
|
3
|
+
from matplotlib.colors import to_rgba
|
|
4
|
+
|
|
5
|
+
LUMA_W = np.asarray([0.29889531 / 255.0, 0.58662247 / 255.0, 0.11448223 / 255.0], dtype=np.float32)
|
|
6
|
+
|
|
7
|
+
# ------------------------------------------------------------------------------------
|
|
8
|
+
# Analyse the image to H,S,L, B
|
|
9
|
+
def image_rgb_to_hslb(image):
|
|
10
|
+
'''
|
|
11
|
+
Analyzes an image and returns the hue, saturation, luma and brightness
|
|
12
|
+
:param image:
|
|
13
|
+
:return: image in HSLB format
|
|
14
|
+
'''
|
|
15
|
+
img_hsv = colors.rgb_to_hsv(image / 255.0)
|
|
16
|
+
luma = np.dot(image, LUMA_W.T)
|
|
17
|
+
return np.stack([img_hsv[..., 0], img_hsv[..., 1], luma, img_hsv[..., 2]], axis=-1).astype(np.float32)
|
|
18
|
+
# ------------------------------------------------------------------------------------
|
|
19
|
+
def image_rgb_to_hif(image):
|
|
20
|
+
oImageHSLB = image_rgb_to_hslb(image)
|
|
21
|
+
|
|
22
|
+
img_hsv = colors.rgb_to_hsv(image / 255.0)
|
|
23
|
+
luma = np.dot(image, LUMA_W.T)
|
|
24
|
+
return np.stack([img_hsv[..., 0], img_hsv[..., 1], luma], axis=-1).astype(np.float32)
|
|
25
|
+
# ------------------------------------------------------------------------------------
|
|
26
|
+
def color(name):
|
|
27
|
+
return tuple([int(x*255) for x in to_rgba(name)])
|
|
28
|
+
# ------------------------------------------------------------------------------------
|