supervisely 6.73.243__py3-none-any.whl → 6.73.245__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 supervisely might be problematic. Click here for more details.
- supervisely/__init__.py +1 -1
- supervisely/_utils.py +18 -0
- supervisely/app/widgets/__init__.py +1 -0
- supervisely/app/widgets/card/card.py +3 -0
- supervisely/app/widgets/classes_table/classes_table.py +15 -1
- supervisely/app/widgets/custom_models_selector/custom_models_selector.py +25 -7
- supervisely/app/widgets/custom_models_selector/template.html +1 -1
- supervisely/app/widgets/experiment_selector/__init__.py +0 -0
- supervisely/app/widgets/experiment_selector/experiment_selector.py +500 -0
- supervisely/app/widgets/experiment_selector/style.css +27 -0
- supervisely/app/widgets/experiment_selector/template.html +82 -0
- supervisely/app/widgets/pretrained_models_selector/pretrained_models_selector.py +25 -3
- supervisely/app/widgets/random_splits_table/random_splits_table.py +41 -17
- supervisely/app/widgets/select_dataset_tree/select_dataset_tree.py +12 -5
- supervisely/app/widgets/train_val_splits/train_val_splits.py +99 -10
- supervisely/app/widgets/tree_select/tree_select.py +2 -0
- supervisely/nn/__init__.py +3 -1
- supervisely/nn/artifacts/artifacts.py +10 -0
- supervisely/nn/artifacts/detectron2.py +2 -0
- supervisely/nn/artifacts/hrda.py +3 -0
- supervisely/nn/artifacts/mmclassification.py +2 -0
- supervisely/nn/artifacts/mmdetection.py +6 -3
- supervisely/nn/artifacts/mmsegmentation.py +2 -0
- supervisely/nn/artifacts/ritm.py +3 -1
- supervisely/nn/artifacts/rtdetr.py +2 -0
- supervisely/nn/artifacts/unet.py +2 -0
- supervisely/nn/artifacts/yolov5.py +3 -0
- supervisely/nn/artifacts/yolov8.py +7 -1
- supervisely/nn/experiments.py +113 -0
- supervisely/nn/inference/gui/__init__.py +3 -1
- supervisely/nn/inference/gui/gui.py +31 -232
- supervisely/nn/inference/gui/serving_gui.py +223 -0
- supervisely/nn/inference/gui/serving_gui_template.py +240 -0
- supervisely/nn/inference/inference.py +225 -24
- supervisely/nn/training/__init__.py +0 -0
- supervisely/nn/training/gui/__init__.py +1 -0
- supervisely/nn/training/gui/classes_selector.py +100 -0
- supervisely/nn/training/gui/gui.py +539 -0
- supervisely/nn/training/gui/hyperparameters_selector.py +117 -0
- supervisely/nn/training/gui/input_selector.py +70 -0
- supervisely/nn/training/gui/model_selector.py +95 -0
- supervisely/nn/training/gui/train_val_splits_selector.py +200 -0
- supervisely/nn/training/gui/training_logs.py +93 -0
- supervisely/nn/training/gui/training_process.py +114 -0
- supervisely/nn/training/gui/utils.py +128 -0
- supervisely/nn/training/loggers/__init__.py +0 -0
- supervisely/nn/training/loggers/base_train_logger.py +58 -0
- supervisely/nn/training/loggers/tensorboard_logger.py +46 -0
- supervisely/nn/training/train_app.py +2038 -0
- supervisely/nn/utils.py +5 -0
- {supervisely-6.73.243.dist-info → supervisely-6.73.245.dist-info}/METADATA +3 -1
- {supervisely-6.73.243.dist-info → supervisely-6.73.245.dist-info}/RECORD +56 -34
- {supervisely-6.73.243.dist-info → supervisely-6.73.245.dist-info}/LICENSE +0 -0
- {supervisely-6.73.243.dist-info → supervisely-6.73.245.dist-info}/WHEEL +0 -0
- {supervisely-6.73.243.dist-info → supervisely-6.73.245.dist-info}/entry_points.txt +0 -0
- {supervisely-6.73.243.dist-info → supervisely-6.73.245.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
2
|
+
|
|
3
|
+
from supervisely.app import DataJson
|
|
4
|
+
from supervisely.app.widgets import Button, Card, Stepper, Text, Widget
|
|
5
|
+
|
|
6
|
+
button_clicked = {}
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def update_custom_params(
|
|
10
|
+
button: Button,
|
|
11
|
+
params_dct: Dict[str, Any],
|
|
12
|
+
) -> None:
|
|
13
|
+
button_state = button.get_json_data()
|
|
14
|
+
for key in params_dct.keys():
|
|
15
|
+
if key not in button_state:
|
|
16
|
+
raise AttributeError(f"Parameter {key} doesn't exists.")
|
|
17
|
+
else:
|
|
18
|
+
DataJson()[button.widget_id][key] = params_dct[key]
|
|
19
|
+
DataJson().send_changes()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def update_custom_button_params(
|
|
23
|
+
button: Button,
|
|
24
|
+
params_dct: Dict[str, Any],
|
|
25
|
+
) -> None:
|
|
26
|
+
params = params_dct.copy()
|
|
27
|
+
if "icon" in params and params["icon"] is not None:
|
|
28
|
+
new_icon = f'<i class="{params["icon"]}" style="margin-right: {button._icon_gap}px"></i>'
|
|
29
|
+
params["icon"] = new_icon
|
|
30
|
+
update_custom_params(button, params)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def disable_enable(widgets: List[Widget], disable: bool = True):
|
|
34
|
+
for w in widgets:
|
|
35
|
+
if disable:
|
|
36
|
+
w.disable()
|
|
37
|
+
else:
|
|
38
|
+
w.enable()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def unlock_lock(cards: List[Card], unlock: bool = True, message: str = None):
|
|
42
|
+
for w in cards:
|
|
43
|
+
if unlock:
|
|
44
|
+
w.unlock()
|
|
45
|
+
# w.uncollapse()
|
|
46
|
+
else:
|
|
47
|
+
w.lock(message)
|
|
48
|
+
# w.collapse()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def collapse_uncollapse(cards: List[Card], collapse: bool = True):
|
|
52
|
+
for w in cards:
|
|
53
|
+
if collapse:
|
|
54
|
+
w.collapse()
|
|
55
|
+
else:
|
|
56
|
+
w.uncollapse()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def wrap_button_click(
|
|
60
|
+
button: Button,
|
|
61
|
+
cards_to_unlock: List[Card],
|
|
62
|
+
widgets_to_disable: List[Widget],
|
|
63
|
+
callback: Optional[Callable] = None,
|
|
64
|
+
lock_msg: str = None,
|
|
65
|
+
upd_params: bool = True,
|
|
66
|
+
validation_text: Text = None,
|
|
67
|
+
validation_func: Optional[Callable] = None,
|
|
68
|
+
on_select_click: Optional[Callable] = None,
|
|
69
|
+
on_reselect_click: Optional[Callable] = None,
|
|
70
|
+
collapse_card: Tuple[Card, bool] = None,
|
|
71
|
+
) -> Callable[[Optional[bool]], None]:
|
|
72
|
+
global button_clicked
|
|
73
|
+
|
|
74
|
+
select_params = {"icon": None, "plain": False, "text": "Select"}
|
|
75
|
+
reselect_params = {"icon": "zmdi zmdi-refresh", "plain": True, "text": "Reselect"}
|
|
76
|
+
bid = button.widget_id
|
|
77
|
+
button_clicked[bid] = False
|
|
78
|
+
|
|
79
|
+
def button_click(button_clicked_value: Optional[bool] = None):
|
|
80
|
+
if button_clicked_value is None or button_clicked_value is False:
|
|
81
|
+
if validation_func is not None:
|
|
82
|
+
success = validation_func()
|
|
83
|
+
if not success:
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
if button_clicked_value is not None:
|
|
87
|
+
button_clicked[bid] = button_clicked_value
|
|
88
|
+
else:
|
|
89
|
+
button_clicked[bid] = not button_clicked[bid]
|
|
90
|
+
|
|
91
|
+
if button_clicked[bid] and upd_params:
|
|
92
|
+
update_custom_button_params(button, reselect_params)
|
|
93
|
+
if on_select_click is not None:
|
|
94
|
+
for func in on_select_click:
|
|
95
|
+
func()
|
|
96
|
+
else:
|
|
97
|
+
update_custom_button_params(button, select_params)
|
|
98
|
+
if on_reselect_click is not None:
|
|
99
|
+
for func in on_reselect_click:
|
|
100
|
+
func()
|
|
101
|
+
validation_text.hide()
|
|
102
|
+
|
|
103
|
+
unlock_lock(
|
|
104
|
+
cards_to_unlock,
|
|
105
|
+
unlock=button_clicked[bid],
|
|
106
|
+
message=lock_msg,
|
|
107
|
+
)
|
|
108
|
+
disable_enable(
|
|
109
|
+
widgets_to_disable,
|
|
110
|
+
disable=button_clicked[bid],
|
|
111
|
+
)
|
|
112
|
+
if callback is not None and not button_clicked[bid]:
|
|
113
|
+
callback(False)
|
|
114
|
+
|
|
115
|
+
if collapse_card is not None:
|
|
116
|
+
card, collapse = collapse_card
|
|
117
|
+
if collapse:
|
|
118
|
+
collapse_uncollapse([card], collapse)
|
|
119
|
+
|
|
120
|
+
return button_click
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def set_stepper_step(stepper: Stepper, button: Button, next_pos: int):
|
|
124
|
+
bid = button.widget_id
|
|
125
|
+
if button_clicked[bid] is True:
|
|
126
|
+
stepper.set_active_step(next_pos)
|
|
127
|
+
else:
|
|
128
|
+
stepper.set_active_step(next_pos - 1)
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BaseTrainLogger:
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self._on_train_started_callbacks = []
|
|
7
|
+
self._on_train_finished_callbacks = []
|
|
8
|
+
self._on_epoch_started_callbacks = []
|
|
9
|
+
self._on_epoch_finished_callbacks = []
|
|
10
|
+
self._on_step_callbacks = []
|
|
11
|
+
self.epoch_idx = 0
|
|
12
|
+
self.step_idx = 0
|
|
13
|
+
|
|
14
|
+
def train_started(self, total_epochs: int):
|
|
15
|
+
for callback in self._on_train_started_callbacks:
|
|
16
|
+
callback(total_epochs)
|
|
17
|
+
|
|
18
|
+
def train_finished(self):
|
|
19
|
+
for callback in self._on_train_finished_callbacks:
|
|
20
|
+
callback()
|
|
21
|
+
|
|
22
|
+
def epoch_started(self, total_steps: int):
|
|
23
|
+
for callback in self._on_epoch_started_callbacks:
|
|
24
|
+
callback(total_steps)
|
|
25
|
+
|
|
26
|
+
def epoch_finished(self):
|
|
27
|
+
self.epoch_idx += 1
|
|
28
|
+
for callback in self._on_epoch_finished_callbacks:
|
|
29
|
+
callback()
|
|
30
|
+
|
|
31
|
+
def on_step_end(self):
|
|
32
|
+
self.step_idx += 1
|
|
33
|
+
for callback in self._on_step_callbacks:
|
|
34
|
+
callback()
|
|
35
|
+
|
|
36
|
+
def add_on_train_started_callback(self, callback: Callable):
|
|
37
|
+
self._on_train_started_callbacks.append(callback)
|
|
38
|
+
|
|
39
|
+
def add_on_train_finish_callback(self, callback: Callable):
|
|
40
|
+
self._on_train_finished_callbacks.append(callback)
|
|
41
|
+
|
|
42
|
+
def add_on_epoch_started_callback(self, callback: Callable):
|
|
43
|
+
self._on_epoch_started_callbacks.append(callback)
|
|
44
|
+
|
|
45
|
+
def add_on_epoch_finish_callback(self, callback: Callable):
|
|
46
|
+
self._on_epoch_finished_callbacks.append(callback)
|
|
47
|
+
|
|
48
|
+
def add_on_step_callback(self, callback: Callable):
|
|
49
|
+
self._on_step_callbacks.append(callback)
|
|
50
|
+
|
|
51
|
+
def log(self, logs: dict, idx: int):
|
|
52
|
+
raise NotImplementedError
|
|
53
|
+
|
|
54
|
+
def log_step(self, logs: dict):
|
|
55
|
+
raise NotImplementedError
|
|
56
|
+
|
|
57
|
+
def log_epoch(self, logs: dict):
|
|
58
|
+
raise NotImplementedError
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from supervisely import logger
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
from tensorboardX import SummaryWriter
|
|
5
|
+
_tensorboard_supported = True
|
|
6
|
+
except ImportError:
|
|
7
|
+
logger.warning("TensorboardX is not installed. TensorboardLogger will not work.")
|
|
8
|
+
_tensorboard_supported = False
|
|
9
|
+
|
|
10
|
+
from supervisely.nn.training.loggers.base_train_logger import BaseTrainLogger
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TensorboardLogger(BaseTrainLogger):
|
|
14
|
+
def __init__(self, log_dir=None):
|
|
15
|
+
if log_dir is None:
|
|
16
|
+
self.log_dir = None
|
|
17
|
+
self.writer = None
|
|
18
|
+
else:
|
|
19
|
+
self.log_dir = log_dir
|
|
20
|
+
self.writer = SummaryWriter(log_dir)
|
|
21
|
+
super().__init__()
|
|
22
|
+
|
|
23
|
+
def set_log_dir(self, log_dir):
|
|
24
|
+
self.log_dir = log_dir
|
|
25
|
+
self.writer = SummaryWriter(log_dir)
|
|
26
|
+
|
|
27
|
+
def close(self):
|
|
28
|
+
if self.writer is not None:
|
|
29
|
+
self.writer.close()
|
|
30
|
+
self.writer = None
|
|
31
|
+
|
|
32
|
+
def log(self, logs: dict, idx: int):
|
|
33
|
+
for key, value in logs.items():
|
|
34
|
+
if isinstance(value, (int, float)):
|
|
35
|
+
self.writer.add_scalar(key, value, idx)
|
|
36
|
+
self.writer.flush()
|
|
37
|
+
|
|
38
|
+
def log_step(self, logs: dict):
|
|
39
|
+
self.log(logs, self.step_idx)
|
|
40
|
+
|
|
41
|
+
def log_epoch(self, logs: dict):
|
|
42
|
+
self.log(logs, self.epoch_idx)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if _tensorboard_supported:
|
|
46
|
+
tb_logger = TensorboardLogger()
|