radnn 0.0.8__py3-none-any.whl → 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. radnn/__init__.py +5 -5
  2. radnn/benchmark/__init__.py +1 -0
  3. radnn/benchmark/latency.py +55 -0
  4. radnn/core.py +146 -2
  5. radnn/data/__init__.py +5 -10
  6. radnn/data/dataset_base.py +100 -260
  7. radnn/data/dataset_base_legacy.py +280 -0
  8. radnn/data/errors.py +32 -0
  9. radnn/data/sample_preprocessor.py +58 -0
  10. radnn/data/sample_set.py +203 -90
  11. radnn/data/sample_set_kind.py +126 -0
  12. radnn/data/sequence_dataset.py +25 -30
  13. radnn/data/structs/__init__.py +1 -0
  14. radnn/data/structs/tree.py +322 -0
  15. radnn/data_beta/__init__.py +12 -0
  16. radnn/{data → data_beta}/data_feed.py +1 -1
  17. radnn/data_beta/dataset_base.py +337 -0
  18. radnn/data_beta/sample_set.py +166 -0
  19. radnn/data_beta/sequence_dataset.py +134 -0
  20. radnn/data_beta/structures/__init__.py +2 -0
  21. radnn/data_beta/structures/dictionary.py +41 -0
  22. radnn/{data → data_beta}/tf_classification_data_feed.py +5 -2
  23. radnn/errors.py +10 -2
  24. radnn/experiment/__init__.py +2 -0
  25. radnn/experiment/identification.py +7 -0
  26. radnn/experiment/ml_experiment.py +7 -2
  27. radnn/experiment/ml_experiment_log.py +47 -0
  28. radnn/images/image_processor.py +4 -1
  29. radnn/learn/__init__.py +0 -7
  30. radnn/learn/keras/__init__.py +4 -0
  31. radnn/learn/{state → keras}/keras_best_state_saver.py +5 -1
  32. radnn/learn/{learning_algorithm.py → keras/keras_learning_algorithm.py} +5 -9
  33. radnn/learn/{keras_learning_rate_scheduler.py → keras/keras_learning_rate_scheduler.py} +4 -1
  34. radnn/learn/{keras_optimization_algorithm.py → keras/keras_optimization_combo.py} +7 -3
  35. radnn/learn/torch/__init__.py +3 -0
  36. radnn/learn/torch/ml_model_freezer.py +330 -0
  37. radnn/learn/torch/ml_trainer.py +461 -0
  38. radnn/learn/torch/staircase_lr_scheduler.py +21 -0
  39. radnn/ml_system.py +68 -52
  40. radnn/models/__init__.py +5 -0
  41. radnn/models/cnn/__init__.py +0 -0
  42. radnn/models/cnn/cnn_stem_setup.py +35 -0
  43. radnn/models/model_factory.py +85 -0
  44. radnn/models/model_hyperparams.py +128 -0
  45. radnn/models/model_info.py +91 -0
  46. radnn/plots/plot_learning_curve.py +19 -8
  47. radnn/system/__init__.py +1 -0
  48. radnn/system/files/__init__.py +1 -1
  49. radnn/system/files/csvfile.py +37 -5
  50. radnn/system/files/filelist.py +30 -0
  51. radnn/system/files/fileobject.py +11 -1
  52. radnn/system/files/imgfile.py +1 -1
  53. radnn/system/files/jsonfile.py +37 -9
  54. radnn/system/files/picklefile.py +3 -3
  55. radnn/system/files/textfile.py +39 -10
  56. radnn/system/files/zipfile.py +96 -0
  57. radnn/system/filestore.py +147 -47
  58. radnn/system/filesystem.py +3 -3
  59. radnn/test/__init__.py +1 -0
  60. radnn/test/tensor_hash.py +130 -0
  61. radnn/utils.py +16 -2
  62. radnn-0.1.0.dist-info/METADATA +30 -0
  63. radnn-0.1.0.dist-info/RECORD +99 -0
  64. {radnn-0.0.8.dist-info → radnn-0.1.0.dist-info}/WHEEL +1 -1
  65. {radnn-0.0.8.dist-info → radnn-0.1.0.dist-info/licenses}/LICENSE.txt +1 -1
  66. radnn/learn/state/__init__.py +0 -4
  67. radnn-0.0.8.dist-info/METADATA +0 -58
  68. radnn-0.0.8.dist-info/RECORD +0 -70
  69. /radnn/{data → data_beta}/dataset_folder.py +0 -0
  70. /radnn/{data → data_beta}/image_dataset.py +0 -0
  71. /radnn/{data → data_beta}/image_dataset_files.py +0 -0
  72. /radnn/{data → data_beta}/preprocess/__init__.py +0 -0
  73. /radnn/{data → data_beta}/preprocess/normalizer.py +0 -0
  74. /radnn/{data → data_beta}/preprocess/standardizer.py +0 -0
  75. /radnn/{data → data_beta}/subset_type.py +0 -0
  76. {radnn-0.0.8.dist-info → radnn-0.1.0.dist-info}/top_level.txt +0 -0
radnn/data/sample_set.py CHANGED
@@ -22,30 +22,84 @@
22
22
  # SOFTWARE.
23
23
 
24
24
  # ......................................................................................
25
- from .dataset_base import DataSetBase
26
- from .subset_type import SubsetType
25
+ import numpy as np
26
+ import pandas as pd
27
+ from .errors import *
28
+ from sklearn.utils.class_weight import compute_class_weight
29
+ from .sample_set_kind import SampleSetKindInfo
27
30
 
31
+ from radnn.core import RequiredLibs
32
+ oReqs = RequiredLibs()
33
+ if oReqs.is_torch_installed:
34
+ # [TODO] Additional coupling to torch (+)->MANOLO
35
+ import platform
36
+ import torch
37
+ from torch.utils.data import DataLoader
28
38
 
29
39
 
30
40
  class SampleSet(object):
41
+ LOADER_NUM_WORKERS = 8
42
+
31
43
  # --------------------------------------------------------------------------------------------------------------------
32
- def __init__(self, subset_type="custom", has_ids=False):
33
- self.subset_type: SubsetType = SubsetType(subset_type)
34
- self.parent_dataset = None
44
+ def __init__(self, parent_dataset, subset_kind: str, **kwargs):
45
+ '''
46
+ Create a sample subset on a dataset
47
+
48
+ :param parent_dataset: The parent dataset that implements the composition relationship.
49
+ :param subset_kind: The kind of the subset. Can be one of:
50
+ training/train/ts for the known samples that are presented to an algorithm
51
+ validation/val/vs for the known samples that are not presented to an algorithm, used to validate during its execution
52
+ testing/test/ut for the unknown samples that are not given to the researcher that develops the algorithm
53
+
54
+ :**param sample_file_records: A Pandas dataframe that contains two columns: 1) The list of sample file absolute paths and 2) Correspondng labels.
55
+ :**param is_classification: True if the dataset used for a classification task.
56
+ :**param batch_size: The count of samples in a minibatch.
57
+ :**param sample_transform_augment: A callback method that performs a single sample preprocessing task.
58
+ '''
59
+ self.parent_dataset = parent_dataset
60
+ self.info = SampleSetKindInfo(subset_kind)
61
+ self.info.is_classification = kwargs.get("is_classification", False)
62
+ self.batch_size = kwargs.get("batch_size", None)
63
+ self.transform_augment = kwargs.get("sample_transform_augment", None)
64
+ self._sample_count = 0
35
65
 
36
- self.has_ids = has_ids
66
+ self.ids = None
67
+ self.samples: list|np.ndarray|None = kwargs.get("samples", None)
68
+ if (self.samples is not None) and isinstance(self.samples, list):
69
+ self.samples = np.array(self.samples, np.float32)
70
+ self._sample_count = self.samples.shape[0]
71
+ self.labels: list|np.ndarray|None = kwargs.get("labels", None)
37
72
 
38
- self.ids = None
39
- self.samples = None
40
- self.sample_count = None
41
- self.labels = None
73
+ self.files = None
74
+ self._sample_directory: pd.DataFrame | None = kwargs.get("sample_file_records", None)
75
+ if self._sample_directory is not None:
76
+ self.files = self._sample_directory.iloc[:, 0].to_list()
77
+ self._sample_count = len(self.files)
78
+ self.labels = self._sample_directory.iloc[:, 1].to_list()
42
79
 
80
+ assert self._sample_count > 0, ERR_SUBSET_MUST_HAVE_SAMPLES
43
81
  self._step = 1
44
82
  self._iter_start_pos = 0
45
83
  self._iter_counter = 0
84
+ self._are_samples_in_memory = self.samples is not None
85
+
86
+ self.has_sample_ids = self.ids is not None
46
87
 
47
- self.feed = None
88
+ self.minibatch_count = self._sample_count
89
+ if self.batch_size is not None:
90
+ self.loader = DataLoader(self, batch_size=self.batch_size, shuffle=self.info.must_shuffle,
91
+ num_workers=self.LOADER_NUM_WORKERS)
92
+ self.minibatch_count = len(self.loader)
93
+ else:
94
+ self.loader = DataLoader(self, shuffle=self.info.must_shuffle, num_workers=self.LOADER_NUM_WORKERS)
48
95
 
96
+ if self.info.is_classification:
97
+ self.info.class_indices = np.sort(np.unique(self.labels))
98
+ self.info.class_weights = compute_class_weight(class_weight='balanced', classes=self.info.class_indices, y=np.array(self.labels))
99
+ # --------------------------------------------------------------------------------------------------------------------
100
+ @property
101
+ def sample_count(self):
102
+ return self._sample_count
49
103
  # --------------------------------------------------------------------------------------------------------------------
50
104
  @property
51
105
  def has_labels(self):
@@ -53,114 +107,173 @@ class SampleSet(object):
53
107
  # --------------------------------------------------------------------------------------------------------------------
54
108
  @property
55
109
  def data_tuple(self):
56
- if self.has_ids:
57
- if self.labels is None:
58
- return (self.ids, self.samples)
110
+ '''
111
+ :return: For in-memory samples: A tuple with the samples, their respective labels and their ids.
112
+ For file-based dataiterators: None
113
+ '''
114
+ if self._are_samples_in_memory:
115
+ if self.has_sample_ids:
116
+ if self.labels is None:
117
+ return (self.ids, self.samples)
118
+ else:
119
+ return (self.ids, self.samples, self.labels)
59
120
  else:
60
- return (self.ids, self.samples, self.labels)
121
+ if self.labels is None:
122
+ return self.samples
123
+ else:
124
+ return (self.ids, self.samples, self.labels)
61
125
  else:
62
- if self.labels is None:
63
- return self.samples
64
- else:
65
- return (self.ids, self.samples, self.labels)
126
+ return None
66
127
  # --------------------------------------------------------------------------------------------------------------------
67
- def subset_of(self, parent_dataset: DataSetBase):
68
- self.parent_dataset = parent_dataset
69
- if self.parent_dataset is not None:
70
- if self.subset_type.is_training_set:
71
- if self.parent_dataset.ts_samples is not None:
72
- self.parent_dataset.ts = self
73
- self.ids = self.parent_dataset.ts_sample_ids
74
- self.samples = self.parent_dataset.ts_samples
75
- self.sample_count = self.parent_dataset.ts_sample_count
76
- self.labels = self.parent_dataset.ts_labels
77
- elif self.subset_type.is_validation_set:
78
- if self.parent_dataset.vs_samples is not None:
79
- self.parent_dataset.vs = self
80
- self.ids = self.parent_dataset.vs_sample_ids
81
- self.samples = self.parent_dataset.vs_samples
82
- self.sample_count = self.parent_dataset.vs_sample_count
83
- self.labels = self.parent_dataset.vs_labels
84
- elif self.subset_type.is_unknown_test_set:
85
- if self.parent_dataset.ut_samples is not None:
86
- self.parent_dataset.ut = self
87
- self.ids = self.parent_dataset.ut_sample_ids
88
- self.samples = self.parent_dataset.ut_samples
89
- self.sample_count = self.parent_dataset.ut_sample_count
90
- self.labels = self.parent_dataset.ut_labels
91
-
92
- self.has_ids = self.ids is not None
93
- # --------------------------------------------------------------------------------------------------------------------
94
- '''
95
- def create_feed(self, has_ids=False):
96
- self.has_ids = has_ids
97
- if is_tensorflow_installed:
98
- import tensorflow as tf
99
-
100
- if has_ids:
101
- self.feed = tf.data.Dataset.from_tensor_slices((self.ids, self.samples, self.labels))
102
- else:
103
- self.feed = tf.data.Dataset.from_tensor_slices((self.samples, self.labels))
104
-
105
- self.feed = self.feed.map(preprocess_tf, num_parallel_calls=8)
106
-
107
- if (self.subset_type == "training") or (self.subset_type == "train") or (self.subset_type == "ts"):
108
- # -----------------------------------------------------------------------------------
109
- def preprocess_tf(self, sample_pack):
110
-
111
- import tensorflow as tf
112
-
113
- if self.has_ids:
114
- nId, nSample, nLabel = sample_pack
128
+ def __len__(self):
129
+ return self._sample_count
130
+ # --------------------------------------------------------------------------------------------------------------------
131
+ def __getitem__(self, index):
132
+ if self._are_samples_in_memory:
133
+ tSample = self.do_load_sample(index)
115
134
  else:
116
- nSample, nLabel = sample_pack
117
-
118
- tImage = tf.cast(p_tImageInVS, tf.float32) # //[BF] overflow of standardization
119
- tNormalizedImage = self.normalizeImage(tImage)
120
-
121
- tTargetOneHot = tf.one_hot(p_tLabelInVS, self.ClassCount)
122
-
123
- return tNormalizedImage, tTargetOneHot
124
- '''
135
+ tSample = self.do_load_sample_from_file(index)
136
+ if self.transform_augment is not None:
137
+ tSample = self.transform_augment(tSample)
125
138
 
139
+ if self.ids is not None:
140
+ if self.labels is not None:
141
+ # Supervised with ids
142
+ return self.ids[index], tSample, self.do_load_target(index)
143
+ else:
144
+ # Unsupervised with ids
145
+ return self.ids[index], tSample
146
+ else:
147
+ if self.labels is not None:
148
+ # Supervised
149
+ return tSample, self.do_load_target(index)
150
+ else:
151
+ # Unsupervised
152
+ return tSample
126
153
  # --------------------------------------------------------------------------------------------------------------------
127
154
  def __iter__(self):
128
155
  self._iter_counter = 0
129
- if self.ids is not None:
130
- if self.labels is not None:
131
- yield from self._generator_for_supervised_with_ids()
156
+
157
+ if self._are_samples_in_memory:
158
+ if self.ids is not None:
159
+ if self.labels is not None:
160
+ yield from self._numpy_generator_for_supervised_with_ids()
161
+ else:
162
+ yield from self._numpy_generator_for_unsupervised_with_ids()
132
163
  else:
133
- yield from self._generator_for_unsupervised_with_ids()
164
+ if self.labels is not None:
165
+ yield from self._numpy_generator_for_supervised()
166
+ else:
167
+ yield from self._numpy_generator_for_unsupervised()
134
168
  else:
135
169
  if self.labels is not None:
136
- yield from self._generator_for_supervised()
170
+ yield from self._file_generator_for_supervised()
137
171
  else:
138
- yield from self._generator_for_unsupervised()
172
+ yield from self._file_generator_for_unsupervised()
173
+ # --------------------------------------------------------------------------------------------------------------------
174
+ def do_load_sample_from_file(self, index):
175
+ '''
176
+ Override this method with the custom code of loading a single sample file
177
+ :param index: The index of the sample in the sample file list
178
+ '''
179
+ pass
180
+ # --------------------------------------------------------------------------------------------------------------------
181
+ def do_load_sample(self, index):
182
+ '''
183
+ Override this method with the custom code of getting a single sample file from a numpy array
184
+ :param index: The index of the sample in the sample subset
185
+ :return:
186
+ '''
187
+ return torch.tensor(self.samples[index, ...], dtype=torch.float32)
188
+ # --------------------------------------------------------------------------------------------------------------------
189
+ def do_load_target(self, index):
190
+ '''
191
+ Override this method with some custom code that loads sample label(s) or transforms them into a training target (e.g. one-hot encoding)
192
+ :param index: The index of the sample in the sample subset
193
+ '''
194
+ return torch.tensor(self.labels[index, ...], dtype=torch.long)
195
+ # --------------------------------------------------------------------------------------------------------------------
196
+ def _file_generator_for_supervised(self):
197
+ nIndex = self._iter_start_pos
198
+ while self._iter_counter < self.sample_count:
199
+ tSample = self.do_load_sample_from_file(nIndex)
200
+ if self.transform_augment is not None:
201
+ tSample = self.transform_augment(tSample)
202
+ yield (tSample, self.do_load_target(nIndex))
203
+ nIndex += self._step
204
+ # --------------------------------------------------------------------------------------------------------------------
205
+ def _file_generator_for_unsupervised(self):
206
+ nIndex = self._iter_start_pos
207
+ while self._iter_counter < self.sample_count:
208
+ tSample = self.do_load_sample_from_file(nIndex)
209
+ if self.transform_augment is not None:
210
+ tSample = self.transform_augment(tSample)
211
+ yield (tSample)
212
+ nIndex += self._step
139
213
  # --------------------------------------------------------------------------------------------------------------------
140
- def _generator_for_supervised(self):
214
+ def _numpy_generator_for_supervised(self):
141
215
  nIndex = self._iter_start_pos
142
216
  while self._iter_counter < self.sample_count:
143
- yield (self.samples[nIndex, ...], self.labels[nIndex, ...])
217
+ tSample = self.do_load_sample(nIndex)
218
+ if self.transform_augment is not None:
219
+ tSample = self.transform_augment(tSample)
220
+ yield (tSample, self.do_load_target(nIndex))
144
221
  nIndex += self._step
145
222
  # --------------------------------------------------------------------------------------------------------------------
146
- def _generator_for_unsupervised(self):
223
+ def _numpy_generator_for_supervised_with_ids(self):
147
224
  nIndex = self._iter_start_pos
148
225
  while self._iter_counter < self.sample_count:
149
- yield self.samples[nIndex, ...]
226
+ tSample = self.do_load_sample(nIndex)
227
+ if self.transform_augment is not None:
228
+ tSample = self.transform_augment(tSample)
229
+ yield (self.ids[nIndex], tSample, self.do_load_target(nIndex))
150
230
  nIndex += self._step
151
231
  # --------------------------------------------------------------------------------------------------------------------
152
- def _generator_for_supervised_with_ids(self):
232
+ def _numpy_generator_for_unsupervised(self):
153
233
  nIndex = self._iter_start_pos
154
234
  while self._iter_counter < self.sample_count:
155
- yield (self.ids[nIndex], self.samples[nIndex, ...], self.labels[nIndex, ...])
235
+ tSample = self.do_load_sample(nIndex)
236
+ if self.transform_augment is not None:
237
+ tSample = self.transform_augment(tSample)
238
+ yield tSample
156
239
  nIndex += self._step
157
240
  # --------------------------------------------------------------------------------------------------------------------
158
- def _generator_for_unsupervised_with_ids(self):
241
+ def _numpy_generator_for_unsupervised_with_ids(self):
159
242
  nIndex = self._iter_start_pos
160
243
  while self._iter_counter < self.sample_count:
161
- yield (self.ids[nIndex], self.samples[nIndex, ...])
244
+ tSample = self.do_load_sample(nIndex)
245
+ if self.transform_augment is not None:
246
+ tSample = self.transform_augment(tSample)
247
+ yield (self.ids[nIndex], tSample)
162
248
  nIndex += self._step
163
249
  # --------------------------------------------------------------------------------------------------------------------
250
+ def print_info(self):
251
+ sDescription = self.info.kind_description
252
+ sDescription = sDescription[0].upper() + sDescription[1:]
253
+ sMinibatches = ""
254
+ if self.minibatch_count is not None:
255
+ sMinibatches = f" minbatches: {self.minibatch_count}"
256
+ if (self.samples is not None) and isinstance(self.samples, np.ndarray):
257
+ print(f" |__ {sDescription} set samples: {self.sample_count} shape: {self.samples.shape}{sMinibatches}")
258
+ print(f" |__ {sDescription} set labels: {self.sample_count} shape: {self.labels.shape}")
259
+ else:
260
+ print(f" |__ {sDescription} set samples: {self.sample_count} {sMinibatches}")
164
261
 
262
+ if (self.labels is not None) and isinstance(self.labels, np.ndarray):
263
+ print(f" |__ Labels: {self.sample_count} shape:{self.labels.shape}")
264
+ else:
265
+ print(f" |__ Labels: {self.sample_count}")
266
+ # --------------------------------------------------------------------------------------------------------------------
267
+ def __str__(self):
268
+ return f"{self.info.kind_description} samples:{self.sample_count} minibatches:{self.minibatch_count}"
269
+ # --------------------------------------------------------------------------------------------------------------------
270
+ def __repr__(self):
271
+ return self.__str__()
272
+ # --------------------------------------------------------------------------------------------------------------------
165
273
 
166
274
 
275
+ # Fix for torch on Windows
276
+ if platform.system().lower() == "windows":
277
+ SampleSet.LOADER_NUM_WORKERS = 0
278
+ else:
279
+ SampleSet.LOADER_NUM_WORKERS = 8
@@ -0,0 +1,126 @@
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
+ # ......................................................................................
26
+ from enum import Enum
27
+
28
+
29
+ # ======================================================================================================================
30
+ class SampleSetKind(Enum):
31
+ TRAINING_SET = 0
32
+ VALIDATION_SET = 1
33
+ UNKNOWN_TEST_SET = 2
34
+
35
+
36
+ # ======================================================================================================================
37
+ class SampleSetKindInfo(dict):
38
+ # --------------------------------------------------------------------------------------------------------------------
39
+ def __init__(self, kind_str: str|None=None, kind: int | None=None, **kwargs):
40
+ super().__init__(**kwargs)
41
+ self._kind: int | None = kind
42
+ self._kind_str: str | None = None
43
+ if kind_str is not None:
44
+ self._kind_str = kind_str.lower()
45
+
46
+ # Invoke the property getters
47
+ self["kind"] = self.kind
48
+ self["kind_str"] = self.kind_description
49
+ # --------------------------------------------------------------------------------------------------------------------
50
+ @property
51
+ def kind_description(self):
52
+ if (self._kind_str is None):
53
+ nKind = self.get("type", -1)
54
+ if nKind == SampleSetKind.TRAINING_SET.value:
55
+ self._kind_str = "training"
56
+ elif nKind == SampleSetKind.value:
57
+ self._kind_str = "validation"
58
+ elif nKind == SampleSetKind.value:
59
+ self._kind_str = "training"
60
+ return self._kind_str
61
+ # --------------------------------------------------------------------------------------------------------------------
62
+ @property
63
+ def kind(self):
64
+ if (self._kind is None):
65
+ nKind = -1 # Unknown
66
+ if self.is_training_set:
67
+ nKind = SampleSetKind.TRAINING_SET.value
68
+ elif self.is_validation_set:
69
+ nKind = SampleSetKind.VALIDATION_SET.value
70
+ elif self.is_unknown_test_set:
71
+ nKind = SampleSetKind.UNKNOWN_TEST_SET.value
72
+ self._kind = nKind
73
+ return self._kind
74
+ # --------------------------------------------------------------------------------------------------------------------
75
+ @property
76
+ def must_shuffle(self):
77
+ return self.kind == SampleSetKind.TRAINING_SET.value
78
+ # --------------------------------------------------------------------------------------------------------------------
79
+ @property
80
+ def is_training_set(self):
81
+ return (self._kind_str == "training") or (self._kind_str == "train") or (self._kind_str == "ts")
82
+ # --------------------------------------------------------------------------------------------------------------------
83
+ @property
84
+ def is_validation_set(self):
85
+ return (self._kind_str == "validation") or (self._kind_str == "val") or (self._kind_str == "vs")
86
+ # --------------------------------------------------------------------------------------------------------------------
87
+ @property
88
+ def is_unknown_test_set(self):
89
+ return (self._kind_str == "testing") or (self._kind_str == "test") or (self._kind_str == "ut")
90
+ # --------------------------------------------------------------------------------------------------------------------
91
+ @property
92
+ def is_classification(self):
93
+ return self["Task"] == "classification"
94
+ # --------------------------------------------------------------------------------------------------------------------
95
+ @is_classification.setter
96
+ def is_classification(self, value):
97
+ if value:
98
+ self["Task"] = "classification"
99
+ self["Classes.Count"] = None
100
+ self["Classes.Indices"] = None
101
+ self["Classes.Weights"] = None
102
+ # --------------------------------------------------------------------------------------------------------------------
103
+ @property
104
+ def class_count(self):
105
+ return self["Classes.Count"]
106
+ # --------------------------------------------------------------------------------------------------------------------
107
+ @class_count.setter
108
+ def class_count(self, value):
109
+ self["Classes.Count"] = value
110
+ # --------------------------------------------------------------------------------------------------------------------
111
+ @property
112
+ def class_indices(self):
113
+ return self["Classes.Indices"]
114
+ # --------------------------------------------------------------------------------------------------------------------
115
+ @class_indices.setter
116
+ def class_indices(self, value):
117
+ self["Classes.Indices"] = value
118
+ # --------------------------------------------------------------------------------------------------------------------
119
+ @property
120
+ def class_weights(self):
121
+ return self["Classes.Weights"]
122
+ # --------------------------------------------------------------------------------------------------------------------
123
+ @class_weights.setter
124
+ def class_weights(self, value):
125
+ self["Classes.Weights"] = value
126
+ # --------------------------------------------------------------------------------------------------------------------
@@ -23,7 +23,9 @@
23
23
 
24
24
  # ......................................................................................
25
25
  import numpy as np
26
- from .dataset_base import DataSetBase
26
+
27
+ from .sample_set import SampleSet
28
+ from .dataset_base import DataSetBase, DataSetCallbacks
27
29
 
28
30
 
29
31
  # ----------------------------------------------------------------------------------------------------------------------
@@ -54,37 +56,26 @@ def generate_sequence_clips(samples, labels, window_size, stride, is_padding_zer
54
56
 
55
57
 
56
58
 
57
- class SequenceDataset(DataSetBase):
58
- # --------------------------------------------------------------------------------------------------------------------
59
- def __init__(self, name, fs, clip_window_size=None, clip_stride=None, is_padding_zeros=False, random_seed=None, is_classification=True):
60
- super(SequenceDataset, self).__init__(name, fs, random_seed, is_classification)
61
- self.clip_window_size = clip_window_size
62
- self.clip_stride = clip_stride
63
- self.is_padding_zeros = is_padding_zeros
64
- self.card["clips.window_size"] = self.clip_window_size
65
- self.card["clips.stride"] = self.clip_stride
66
- self.card["clips.is_padding_zeros"] = self.is_padding_zeros
59
+ class SequenceDataSet(DataSetBase):
67
60
  # --------------------------------------------------------------------------------------------------------------------
68
- @property
69
- def ts_sequence_clips(self):
70
- return generate_sequence_clips(self.ts_samples, self.ts_labels, self.clip_window_size, self.clip_stride,
71
- self.is_padding_zeros)
61
+ def __init__(self, name: str, variant: str|None=None, file_store=None, random_seed: int | None=None, callbacks: DataSetCallbacks | None = None):
62
+ super().__init__(name, variant, file_store, random_seed, callbacks)
63
+
64
+ #self, name, fs, clip_window_size=None, clip_stride=None, is_padding_zeros=False, random_seed=None, is_classification=True):
65
+ #super(SequenceDataSet, self).__init__(name, fs, random_seed, is_classification)
66
+
67
+ self.clip_window_size: int|None = None
68
+ self.clip_stride: int|None = None
69
+ self.is_padding_zeros: bool|None = None
72
70
  # --------------------------------------------------------------------------------------------------------------------
73
- @property
74
- def vs_sequence_clips(self):
75
- if self.vs_samples is not None:
76
- return generate_sequence_clips(self.vs_samples, self.vs_labels, self.clip_window_size, self.clip_stride,
77
- self.is_padding_zeros)
78
- else:
79
- return None
71
+ def do_read_hyperparams(self):
72
+ self.clip_window_size = self.hparams.get("Data.Clip.WindowSize", None)
73
+ self.clip_stride = self.hparams.get("Data.Clip.Stride", None)
74
+ self.is_padding_zeros = self.hparams.get("Data.Clip.IsPaddingZeroes", None)
80
75
  # --------------------------------------------------------------------------------------------------------------------
81
- @property
82
- def ut_sequence_clips(self):
83
- if self.ut_samples is not None:
84
- return generate_sequence_clips(self.ut_samples, self.ut_labels, self.clip_window_size, self.clip_stride,
85
- self.is_padding_zeros)
86
- else:
87
- return None
76
+ def generate_clips(self, subset: SampleSet):
77
+ return generate_sequence_clips(self, subset.samples, subset.labels,
78
+ self.clip_window_size, self.clip_stride, self.is_padding_zeros)
88
79
  # --------------------------------------------------------------------------------------------------------------------
89
80
  def convert_samples_to_clips(self, clip_window_size=None, clip_stride=None, is_padding_zeros=False):
90
81
  if clip_window_size is not None:
@@ -94,14 +85,18 @@ class SequenceDataset(DataSetBase):
94
85
  if is_padding_zeros and (not self.is_padding_zeros):
95
86
  self.is_padding_zeros = is_padding_zeros
96
87
 
88
+ # TODO: Reinstate dataset card
89
+ '''
97
90
  self.card["clips.window_size"] = self.clip_window_size
98
91
  self.card["clips.stride"] = self.clip_stride
99
92
  self.card["clips.is_padding_zeros"] = self.is_padding_zeros
93
+ '''
100
94
 
101
95
  # Create training set clips
96
+ oSubsets = [self.ts, self.vs, self.us]
102
97
  nClips = []
103
98
  nClipLabels = []
104
- for (nClip, nClipLabel) in self.ts_sequence_clips:
99
+ for (nClip, nClipLabel) in self.generate_clips():
105
100
  nClips.append(nClip)
106
101
  nClipLabels.append(nClipLabel)
107
102
  nClips = np.asarray(nClips)
@@ -0,0 +1 @@
1
+ from .tree import Tree, TreeNode, TreeNodeList, TreeNodeQueue