learning-loop-node 0.13.0__py3-none-any.whl → 0.13.3__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.
Potentially problematic release.
This version of learning-loop-node might be problematic. Click here for more details.
- learning_loop_node/detector/detector_logic.py +3 -2
- learning_loop_node/detector/detector_node.py +21 -9
- learning_loop_node/detector/inbox_filter/cam_observation_history.py +2 -2
- learning_loop_node/detector/outbox.py +11 -5
- learning_loop_node/tests/trainer/conftest.py +4 -4
- learning_loop_node/trainer/trainer_logic_generic.py +1 -1
- {learning_loop_node-0.13.0.dist-info → learning_loop_node-0.13.3.dist-info}/METADATA +1 -1
- {learning_loop_node-0.13.0.dist-info → learning_loop_node-0.13.3.dist-info}/RECORD +9 -9
- {learning_loop_node-0.13.0.dist-info → learning_loop_node-0.13.3.dist-info}/WHEEL +0 -0
|
@@ -31,14 +31,15 @@ class DetectorLogic():
|
|
|
31
31
|
logging.info('Loading model from %s', GLOBALS.data_folder)
|
|
32
32
|
model_info = ModelInformation.load_from_disk(f'{GLOBALS.data_folder}/model')
|
|
33
33
|
if model_info is None:
|
|
34
|
-
logging.
|
|
34
|
+
logging.error('No model found')
|
|
35
35
|
self._model_info = None
|
|
36
|
-
|
|
36
|
+
raise Exception('No model found')
|
|
37
37
|
try:
|
|
38
38
|
self._model_info = model_info
|
|
39
39
|
self.init()
|
|
40
40
|
logging.info('Successfully loaded model %s', self._model_info)
|
|
41
41
|
except Exception:
|
|
42
|
+
self._model_info = None
|
|
42
43
|
logging.error('Could not init model %s', model_info)
|
|
43
44
|
raise
|
|
44
45
|
|
|
@@ -107,6 +107,8 @@ class DetectorNode(Node):
|
|
|
107
107
|
|
|
108
108
|
async def set_model_version_mode(self, version_control_mode: str) -> None:
|
|
109
109
|
|
|
110
|
+
self.log.info('Setting model version mode to %s', version_control_mode)
|
|
111
|
+
|
|
110
112
|
if version_control_mode == 'follow_loop':
|
|
111
113
|
self.version_control = VersionMode.FollowLoop
|
|
112
114
|
elif version_control_mode == 'pause':
|
|
@@ -215,7 +217,8 @@ class DetectorNode(Node):
|
|
|
215
217
|
camera_id=data.get('camera-id', None) or data.get('mac', None),
|
|
216
218
|
tags=data.get('tags', []),
|
|
217
219
|
source=data.get('source', None),
|
|
218
|
-
autoupload=data.get('autoupload', None)
|
|
220
|
+
autoupload=data.get('autoupload', None),
|
|
221
|
+
creation_date=data.get('creation_date', None)
|
|
219
222
|
)
|
|
220
223
|
if det is None:
|
|
221
224
|
return {'error': 'no model loaded'}
|
|
@@ -324,13 +327,16 @@ class DetectorNode(Node):
|
|
|
324
327
|
with step_into(GLOBALS.data_folder):
|
|
325
328
|
model_symlink = 'model'
|
|
326
329
|
target_model_folder = f'models/{self.target_model.version}'
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
330
|
+
if not os.path.exists(target_model_folder):
|
|
331
|
+
os.makedirs(target_model_folder)
|
|
332
|
+
await self.data_exchanger.download_model(target_model_folder,
|
|
333
|
+
Context(organization=self.organization,
|
|
334
|
+
project=self.project),
|
|
335
|
+
self.target_model.id,
|
|
336
|
+
self.detector_logic.model_format)
|
|
337
|
+
self.log.info('Downloaded model %s', self.target_model.version)
|
|
338
|
+
else:
|
|
339
|
+
self.log.info('No need to download model %s (already exists)', self.target_model.version)
|
|
334
340
|
try:
|
|
335
341
|
os.unlink(model_symlink)
|
|
336
342
|
os.remove(model_symlink)
|
|
@@ -339,7 +345,12 @@ class DetectorNode(Node):
|
|
|
339
345
|
os.symlink(target_model_folder, model_symlink)
|
|
340
346
|
self.log.info('Updated symlink for model to %s', os.readlink(model_symlink))
|
|
341
347
|
|
|
342
|
-
|
|
348
|
+
try:
|
|
349
|
+
self.detector_logic.load_model()
|
|
350
|
+
except Exception:
|
|
351
|
+
self.log.exception('Could not load model, will retry download on next check')
|
|
352
|
+
shutil.rmtree(target_model_folder, ignore_errors=True)
|
|
353
|
+
return
|
|
343
354
|
try:
|
|
344
355
|
await self.sync_status_with_learning_loop()
|
|
345
356
|
except Exception:
|
|
@@ -390,6 +401,7 @@ class DetectorNode(Node):
|
|
|
390
401
|
|
|
391
402
|
self.log_status_on_change(status.state or 'None', status)
|
|
392
403
|
|
|
404
|
+
# NOTE: sending organization and project is no longer required!
|
|
393
405
|
response = await self.sio_client.call('update_detector', (self.organization, self.project, jsonable_encoder(asdict(status))))
|
|
394
406
|
if not response:
|
|
395
407
|
self.socket_connection_broken = True
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import List, Union
|
|
3
3
|
|
|
4
|
-
from
|
|
5
|
-
|
|
4
|
+
from ...data_classes import (BoxDetection, ClassificationDetection, ImageMetadata, Observation, PointDetection,
|
|
5
|
+
SegmentationDetection)
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class CamObservationHistory:
|
|
@@ -79,10 +79,10 @@ class Outbox():
|
|
|
79
79
|
image_metadata.source = source or 'unknown'
|
|
80
80
|
os.makedirs(tmp, exist_ok=True)
|
|
81
81
|
|
|
82
|
-
with open(tmp + '/
|
|
82
|
+
with open(tmp + f'/image_{identifier}.json', 'w') as f:
|
|
83
83
|
json.dump(jsonable_encoder(asdict(image_metadata)), f)
|
|
84
84
|
|
|
85
|
-
with open(tmp + '/
|
|
85
|
+
with open(tmp + f'/image_{identifier}.jpg', 'wb') as f:
|
|
86
86
|
f.write(image)
|
|
87
87
|
|
|
88
88
|
if os.path.exists(tmp):
|
|
@@ -141,8 +141,10 @@ class Outbox():
|
|
|
141
141
|
# results in a post failure on the first run of the test in a docker environment (WTF)
|
|
142
142
|
|
|
143
143
|
data: List[Tuple[str, Union[TextIOWrapper, BufferedReader]]] = []
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
for item in items:
|
|
145
|
+
identifier = os.path.basename(item)
|
|
146
|
+
data.append(('files', open(f'{item}/image_{identifier}.json', 'r')))
|
|
147
|
+
data.append(('files', open(f'{item}/image_{identifier}.jpg', 'rb')))
|
|
146
148
|
|
|
147
149
|
try:
|
|
148
150
|
async with aiohttp.ClientSession() as session:
|
|
@@ -158,7 +160,11 @@ class Outbox():
|
|
|
158
160
|
if response.status == 200:
|
|
159
161
|
self.upload_counter += len(items)
|
|
160
162
|
for item in items:
|
|
161
|
-
|
|
163
|
+
try:
|
|
164
|
+
shutil.rmtree(item)
|
|
165
|
+
self.log.debug('Deleted %s', item)
|
|
166
|
+
except Exception:
|
|
167
|
+
self.log.exception('Failed to delete %s', item)
|
|
162
168
|
self.log.info('Uploaded %s images successfully', len(items))
|
|
163
169
|
|
|
164
170
|
elif response.status == 422:
|
|
@@ -36,8 +36,8 @@ async def test_initialized_trainer_node():
|
|
|
36
36
|
'model_variant': '',
|
|
37
37
|
'hyperparameters': {
|
|
38
38
|
'resolution': 800,
|
|
39
|
-
'
|
|
40
|
-
'
|
|
39
|
+
'fliplr': 0.5,
|
|
40
|
+
'flipud': 0.5}
|
|
41
41
|
})
|
|
42
42
|
await node._on_startup()
|
|
43
43
|
yield node
|
|
@@ -59,8 +59,8 @@ async def test_initialized_trainer():
|
|
|
59
59
|
'model_variant': '',
|
|
60
60
|
'hyperparameters': {
|
|
61
61
|
'resolution': 800,
|
|
62
|
-
'
|
|
63
|
-
'
|
|
62
|
+
'fliplr': 0.5,
|
|
63
|
+
'flipud': 0.5}
|
|
64
64
|
})
|
|
65
65
|
yield trainer
|
|
66
66
|
try:
|
|
@@ -402,7 +402,7 @@ class TrainerLogicGeneric(ABC):
|
|
|
402
402
|
"""
|
|
403
403
|
|
|
404
404
|
files = await self._get_latest_model_files()
|
|
405
|
-
if files is None:
|
|
405
|
+
if files is None or len(files) == 0:
|
|
406
406
|
raise CriticalError('Could not get latest model files. Training might have failed.')
|
|
407
407
|
|
|
408
408
|
if isinstance(files, List):
|
|
@@ -11,12 +11,12 @@ learning_loop_node/data_classes/socket_response.py,sha256=tIdt-oYf6ULoJIDYQCecNM
|
|
|
11
11
|
learning_loop_node/data_classes/training.py,sha256=FFPsr2AA7ynYz39MLZaFJ0sF_9Axll5HHbAA8nnirp0,5726
|
|
12
12
|
learning_loop_node/data_exchanger.py,sha256=IG5ki3f3IsVuXbyw6q_gUIakgv-GMT6e9nhOhzjKgW4,9055
|
|
13
13
|
learning_loop_node/detector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
learning_loop_node/detector/detector_logic.py,sha256=
|
|
15
|
-
learning_loop_node/detector/detector_node.py,sha256=
|
|
14
|
+
learning_loop_node/detector/detector_logic.py,sha256=FhGbu0mdF0tW0Gg8cr8xM6ZmZzEigGf0IcAWBjoxFrs,2191
|
|
15
|
+
learning_loop_node/detector/detector_node.py,sha256=TMypE1Z0KnuPcJ9wLiflhdvd9oe0t86gAQyK7UvuDpA,25060
|
|
16
16
|
learning_loop_node/detector/inbox_filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
learning_loop_node/detector/inbox_filter/cam_observation_history.py,sha256=
|
|
17
|
+
learning_loop_node/detector/inbox_filter/cam_observation_history.py,sha256=1PHgXRrhSQ34HSFw7mdX8ndRxHf_i1aP5nXXnrZxhAY,3312
|
|
18
18
|
learning_loop_node/detector/inbox_filter/relevance_filter.py,sha256=NPEmrAtuGjIWCtHS0B3zDmnYWkhVFCLbd_7RUp08_AM,1372
|
|
19
|
-
learning_loop_node/detector/outbox.py,sha256=
|
|
19
|
+
learning_loop_node/detector/outbox.py,sha256=i12X28FJka8HMm4iqE7SCODT1uCEtM53tIBul3uxKFw,8828
|
|
20
20
|
learning_loop_node/detector/rest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
learning_loop_node/detector/rest/about.py,sha256=evHJ2svUZY_DFz0FSef5u9c5KW4Uc3GL7EbPinG9-dg,583
|
|
22
22
|
learning_loop_node/detector/rest/backdoor_controls.py,sha256=ZNaFOvC0OLWNtcLiG-NIqS_y1kkLP4csgk3CHhp8Gis,885
|
|
@@ -70,7 +70,7 @@ learning_loop_node/tests/general/test_downloader.py,sha256=y4GcUyR0OAfrwltd6eyQg
|
|
|
70
70
|
learning_loop_node/tests/general/test_learning_loop_node.py,sha256=SZd-VChpWnnsPN46pr4E_LL3ZevYx6psU-AWdVeOFpQ,770
|
|
71
71
|
learning_loop_node/tests/test_helper.py,sha256=Xajn6BWJqeD36YAETwdcJd6awY2NPmaOis3gWgFc97k,2909
|
|
72
72
|
learning_loop_node/tests/trainer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
73
|
-
learning_loop_node/tests/trainer/conftest.py,sha256=
|
|
73
|
+
learning_loop_node/tests/trainer/conftest.py,sha256=F8b8cVJeDRG08OufAE4TuG4Dm-ViSyK_PzM2DrHUzJQ,3660
|
|
74
74
|
learning_loop_node/tests/trainer/pytest.ini,sha256=8QdjmawLy1zAzXrJ88or1kpFDhJw0W5UOnDfGGs_igU,262
|
|
75
75
|
learning_loop_node/tests/trainer/state_helper.py,sha256=MDe9opeKruip74FoRFff8MSWGiQNFqDpPtIEIbgPnFc,919
|
|
76
76
|
learning_loop_node/tests/trainer/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -94,8 +94,8 @@ learning_loop_node/trainer/rest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
|
|
|
94
94
|
learning_loop_node/trainer/rest/backdoor_controls.py,sha256=ZnK8ypY5r_q0-YZbtaOxhQThzuZvMsQHM5gJGESd_dE,5131
|
|
95
95
|
learning_loop_node/trainer/test_executor.py,sha256=6BVGDN_6f5GEMMEvDLSG1yzMybSvgXaP5uYpSfsVPP0,2224
|
|
96
96
|
learning_loop_node/trainer/trainer_logic.py,sha256=eK-01qZzi10UjLMCQX8vy5eW2FoghPj3rzzDC-s3Si4,8792
|
|
97
|
-
learning_loop_node/trainer/trainer_logic_generic.py,sha256=
|
|
97
|
+
learning_loop_node/trainer/trainer_logic_generic.py,sha256=RQqon8JIVzxaNh0KdEe6tMxebsY0DgZllEohHR-AgqU,26846
|
|
98
98
|
learning_loop_node/trainer/trainer_node.py,sha256=Dl4ZQAjjXQggibeBjvhXAoFClw1ZX2Kkt3v_fjrJnCI,4508
|
|
99
|
-
learning_loop_node-0.13.
|
|
100
|
-
learning_loop_node-0.13.
|
|
101
|
-
learning_loop_node-0.13.
|
|
99
|
+
learning_loop_node-0.13.3.dist-info/METADATA,sha256=zB6JXpeyUlyfBVDgEV8kABmdQ2QgqjaCn2U8wib5288,12761
|
|
100
|
+
learning_loop_node-0.13.3.dist-info/WHEEL,sha256=WGfLGfLX43Ei_YORXSnT54hxFygu34kMpcQdmgmEwCQ,88
|
|
101
|
+
learning_loop_node-0.13.3.dist-info/RECORD,,
|
|
File without changes
|