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.
Files changed (60) hide show
  1. radnn/__init__.py +7 -5
  2. radnn/core.py +44 -28
  3. radnn/data/__init__.py +8 -0
  4. radnn/data/data_feed.py +147 -0
  5. radnn/data/dataset_base.py +3 -5
  6. radnn/data/dataset_folder.py +55 -0
  7. radnn/data/image_dataset.py +0 -2
  8. radnn/data/image_dataset_files.py +175 -0
  9. radnn/data/preprocess/normalizer.py +7 -1
  10. radnn/data/preprocess/standardizer.py +9 -2
  11. radnn/data/sample_set.py +30 -17
  12. radnn/data/sequence_dataset.py +0 -2
  13. radnn/data/subset_type.py +45 -0
  14. radnn/data/tf_classification_data_feed.py +113 -0
  15. radnn/errors.py +29 -0
  16. radnn/evaluation/evaluate_classification.py +7 -3
  17. radnn/experiment/ml_experiment.py +29 -0
  18. radnn/experiment/ml_experiment_config.py +61 -32
  19. radnn/experiment/ml_experiment_env.py +6 -2
  20. radnn/experiment/ml_experiment_store.py +0 -1
  21. radnn/images/__init__.py +2 -0
  22. radnn/images/colors.py +28 -0
  23. radnn/images/image_processor.py +513 -0
  24. radnn/learn/learning_algorithm.py +4 -3
  25. radnn/ml_system.py +59 -18
  26. radnn/plots/plot_auto_multi_image.py +27 -17
  27. radnn/plots/plot_confusion_matrix.py +7 -4
  28. radnn/plots/plot_learning_curve.py +7 -3
  29. radnn/plots/plot_multi_scatter.py +7 -3
  30. radnn/plots/plot_roc.py +8 -4
  31. radnn/plots/plot_voronoi_2d.py +8 -5
  32. radnn/stats/__init__.py +1 -0
  33. radnn/stats/descriptive_stats.py +45 -0
  34. radnn/system/files/__init__.py +1 -0
  35. radnn/system/files/csvfile.py +8 -5
  36. radnn/system/files/filelist.py +40 -0
  37. radnn/system/files/fileobject.py +9 -4
  38. radnn/system/files/imgfile.py +8 -4
  39. radnn/system/files/jsonfile.py +8 -4
  40. radnn/system/files/picklefile.py +8 -4
  41. radnn/system/files/textfile.py +37 -7
  42. radnn/system/filestore.py +36 -18
  43. radnn/system/filesystem.py +8 -3
  44. radnn/system/hosts/colab_host.py +29 -0
  45. radnn/system/hosts/linux_host.py +29 -0
  46. radnn/system/hosts/windows_host.py +39 -1
  47. radnn/system/tee_logger.py +7 -3
  48. radnn/system/threads/__init__.py +5 -0
  49. radnn/system/threads/semaphore_lock.py +58 -0
  50. radnn/system/threads/thread_context.py +175 -0
  51. radnn/system/threads/thread_safe_queue.py +163 -0
  52. radnn/system/threads/thread_safe_string_collection.py +66 -0
  53. radnn/system/threads/thread_worker.py +68 -0
  54. radnn/utils.py +96 -2
  55. {radnn-0.0.7.2.dist-info → radnn-0.0.8.dist-info}/METADATA +1 -1
  56. radnn-0.0.8.dist-info/RECORD +70 -0
  57. radnn-0.0.7.2.dist-info/RECORD +0 -53
  58. {radnn-0.0.7.2.dist-info → radnn-0.0.8.dist-info}/LICENSE.txt +0 -0
  59. {radnn-0.0.7.2.dist-info → radnn-0.0.8.dist-info}/WHEEL +0 -0
  60. {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
@@ -22,8 +22,6 @@
22
22
  # SOFTWARE.
23
23
 
24
24
  # ......................................................................................
25
-
26
-
27
25
  import numpy as np
28
26
  from .dataset_base import DataSetBase
29
27
 
@@ -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) 2020-2025 Pantelis I. Kaplanoglou
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) 2023-2025 Pantelis I. Kaplanoglou
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(dict):
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 isinstance(fs, FileSystem):
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 load_config(self, fs, filename_only):
221
- if isinstance(fs, FileSystem):
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.load(sFileName)
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
@@ -1,5 +1,4 @@
1
1
  from radnn import FileStore
2
-
3
2
  class MLExperimentStore(FileStore):
4
3
  def __init__(self, base_folder, is_verbose=False, must_exist=False):
5
4
  super(MLExperimentStore, self).__init__(base_folder, is_verbose, must_exist)
@@ -0,0 +1,2 @@
1
+ from .colors import image_rgb_to_hslb, image_rgb_to_hif
2
+ from .image_processor import ImageProcessor
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
+ # ------------------------------------------------------------------------------------