supervisely 6.73.279__py3-none-any.whl → 6.73.280__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.

@@ -64,6 +64,7 @@ class TrainGUI:
64
64
  self.hyperparameters = hyperparameters
65
65
  self.app_options = app_options
66
66
  self.collapsable = app_options.get("collapsable", False)
67
+ self.need_convert_shapes_for_bm = False
67
68
 
68
69
  self.team_id = sly_env.team_id(raise_not_found=False)
69
70
  self.workspace_id = sly_env.workspace_id(raise_not_found=False)
@@ -141,24 +142,33 @@ class TrainGUI:
141
142
  self.training_process.set_experiment_name(experiment_name)
142
143
 
143
144
  def need_convert_class_shapes() -> bool:
144
- task_type = self.model_selector.get_selected_task_type()
145
-
146
- def _need_convert(shape):
147
- if task_type == TaskType.OBJECT_DETECTION:
148
- return shape != Rectangle.geometry_name()
149
- elif task_type in [TaskType.INSTANCE_SEGMENTATION, TaskType.SEMANTIC_SEGMENTATION]:
150
- return shape == Polygon.geometry_name()
151
- return
152
-
153
- data = self.classes_selector.classes_table._table_data
154
- selected_classes = set(self.classes_selector.classes_table.get_selected_classes())
155
- empty = set(r[0]["data"] for r in data if r[2]["data"] == 0 and r[3]["data"] == 0)
156
- need_convert = set(r[0]["data"] for r in data if _need_convert(r[1]["data"]))
157
-
158
- if need_convert.intersection(selected_classes - empty):
159
- self.hyperparameters_selector.model_benchmark_auto_convert_warning.show()
160
- else:
145
+ if not self.hyperparameters_selector.run_model_benchmark_checkbox.is_checked():
161
146
  self.hyperparameters_selector.model_benchmark_auto_convert_warning.hide()
147
+ self.need_convert_shapes_for_bm = False
148
+ else:
149
+ task_type = self.model_selector.get_selected_task_type()
150
+
151
+ def _need_convert(shape):
152
+ if task_type == TaskType.OBJECT_DETECTION:
153
+ return shape != Rectangle.geometry_name()
154
+ elif task_type in [
155
+ TaskType.INSTANCE_SEGMENTATION,
156
+ TaskType.SEMANTIC_SEGMENTATION,
157
+ ]:
158
+ return shape == Polygon.geometry_name()
159
+ return
160
+
161
+ data = self.classes_selector.classes_table._table_data
162
+ selected_classes = set(self.classes_selector.classes_table.get_selected_classes())
163
+ empty = set(r[0]["data"] for r in data if r[2]["data"] == 0 and r[3]["data"] == 0)
164
+ need_convert = set(r[0]["data"] for r in data if _need_convert(r[1]["data"]))
165
+
166
+ if need_convert.intersection(selected_classes - empty):
167
+ self.hyperparameters_selector.model_benchmark_auto_convert_warning.show()
168
+ self.need_convert_shapes_for_bm = True
169
+ else:
170
+ self.hyperparameters_selector.model_benchmark_auto_convert_warning.hide()
171
+ self.need_convert_shapes_for_bm = False
162
172
 
163
173
  # ------------------------------------------------- #
164
174
 
@@ -482,7 +482,6 @@ class TrainApp:
482
482
  downloading project and model data.
483
483
  """
484
484
  logger.info("Preparing for training")
485
- self.gui.disable_select_buttons()
486
485
 
487
486
  # Step 1. Workflow Input
488
487
  if is_production():
@@ -503,40 +502,40 @@ class TrainApp:
503
502
  :type experiment_info: dict
504
503
  """
505
504
  logger.info("Finalizing training")
505
+ # Step 1. Validate experiment TaskType
506
+ experiment_info = self._validate_experiment_task_type(experiment_info)
506
507
 
507
- # Step 1. Validate experiment_info
508
+ # Step 2. Validate experiment_info
508
509
  success, reason = self._validate_experiment_info(experiment_info)
509
510
  if not success:
510
511
  raise ValueError(f"{reason}. Failed to upload artifacts")
511
512
 
512
- # Step 2. Preprocess artifacts
513
+ # Step 3. Preprocess artifacts
513
514
  experiment_info = self._preprocess_artifacts(experiment_info)
514
515
 
515
- # Step3. Postprocess splits
516
+ # Step 4. Postprocess splits
516
517
  train_splits_data = self._postprocess_splits()
517
518
 
518
- # Step 3. Upload artifacts
519
+ # Step 5. Upload artifacts
519
520
  self._set_text_status("uploading")
520
521
  remote_dir, file_info = self._upload_artifacts()
521
522
 
522
- # Step 4. Run Model Benchmark
523
+ # Step 6. Create model meta according to model CV task type
523
524
  model_meta = self.create_model_meta(experiment_info["task_type"])
524
- mb_eval_lnk_file_info, mb_eval_report, mb_eval_report_id, eval_metrics = (
525
- None,
526
- None,
527
- None,
528
- {},
529
- )
525
+
526
+ # Step 7. [Optional] Run Model Benchmark
527
+ mb_eval_lnk_file_info, mb_eval_report = None, None
528
+ mb_eval_report_id, eval_metrics = None, {}
530
529
  if self.is_model_benchmark_enabled:
531
530
  try:
532
531
  # Convert GT project
532
+ gt_project_id, bm_splits_data = None, train_splits_data
533
533
  if self._app_options.get("auto_convert_classes", True):
534
- self._set_text_status("convert_gt_project")
535
- gt_project_id, bm_splits_data = self._convert_and_split_gt_project(
536
- experiment_info["task_type"]
537
- )
538
- else:
539
- gt_project_id, bm_splits_data = None, train_splits_data
534
+ if self.gui.need_convert_shapes_for_bm:
535
+ self._set_text_status("convert_gt_project")
536
+ gt_project_id, bm_splits_data = self._convert_and_split_gt_project(
537
+ experiment_info["task_type"]
538
+ )
540
539
 
541
540
  self._set_text_status("benchmark")
542
541
  (
@@ -555,7 +554,7 @@ class TrainApp:
555
554
  except Exception as e:
556
555
  logger.error(f"Model benchmark failed: {e}")
557
556
 
558
- # Step 5. [Optional] Convert weights
557
+ # Step 8. [Optional] Convert weights
559
558
  export_weights = {}
560
559
  if self.gui.hyperparameters_selector.is_export_required():
561
560
  try:
@@ -564,7 +563,7 @@ class TrainApp:
564
563
  except Exception as e:
565
564
  logger.error(f"Export weights failed: {e}")
566
565
 
567
- # Step 6. Generate and upload additional files
566
+ # Step 9. Generate and upload additional files
568
567
  self._set_text_status("metadata")
569
568
  self._generate_experiment_info(
570
569
  remote_dir, experiment_info, eval_metrics, mb_eval_report_id, export_weights
@@ -575,12 +574,12 @@ class TrainApp:
575
574
  self._generate_model_meta(remote_dir, model_meta)
576
575
  self._upload_demo_files(remote_dir)
577
576
 
578
- # Step 7. Set output widgets
577
+ # Step 10. Set output widgets
579
578
  self._set_text_status("reset")
580
579
  self._set_training_output(remote_dir, file_info, mb_eval_report)
581
580
  self._set_ws_progress_status("completed")
582
581
 
583
- # Step 8. Workflow output
582
+ # Step 11. Workflow output
584
583
  if is_production():
585
584
  self._workflow_output(remote_dir, file_info, mb_eval_lnk_file_info, mb_eval_report_id)
586
585
 
@@ -1120,6 +1119,24 @@ class TrainApp:
1120
1119
  # ----------------------------------------- #
1121
1120
 
1122
1121
  # Postprocess
1122
+ def _validate_experiment_task_type(self, experiment_info: dict) -> dict:
1123
+ """
1124
+ Checks if the task_type key if returned from the user's training function.
1125
+ If not, it will be set to the task type of the model selected in the model selector.
1126
+
1127
+ :param experiment_info: Information about the experiment results.
1128
+ :type experiment_info: dict
1129
+ :return: Experiment info with task_type key.
1130
+ :rtype: dict
1131
+ """
1132
+ task_type = experiment_info.get("task_type", None)
1133
+ if task_type is None:
1134
+ logger.debug(
1135
+ "Task type not found in experiment_info. Task type from model config will be used."
1136
+ )
1137
+ task_type = self.gui.model_selector.get_selected_task_type()
1138
+ experiment_info["task_type"] = task_type
1139
+ return experiment_info
1123
1140
 
1124
1141
  def _validate_experiment_info(self, experiment_info: dict) -> tuple:
1125
1142
  """
@@ -2218,6 +2235,7 @@ class TrainApp:
2218
2235
  Wrapper function to wrap the training process.
2219
2236
  """
2220
2237
  experiment_info = None
2238
+ check_logs_text = "Please check the logs for more details."
2221
2239
 
2222
2240
  try:
2223
2241
  self._set_train_widgets_state_on_start()
@@ -2226,7 +2244,7 @@ class TrainApp:
2226
2244
  self._prepare_working_dir()
2227
2245
  self._init_logger()
2228
2246
  except Exception as e:
2229
- message = "Error occurred during training initialization. Please check the logs for more details."
2247
+ message = f"Error occurred during training initialization. {check_logs_text}"
2230
2248
  self._show_error(message, e)
2231
2249
  self._restore_train_widgets_state_on_error()
2232
2250
  self._set_ws_progress_status("reset")
@@ -2237,9 +2255,7 @@ class TrainApp:
2237
2255
  self._set_ws_progress_status("preparing")
2238
2256
  self._prepare()
2239
2257
  except Exception as e:
2240
- message = (
2241
- "Error occurred during data preparation. Please check the logs for more details."
2242
- )
2258
+ message = f"Error occurred during data preparation. {check_logs_text}"
2243
2259
  self._show_error(message, e)
2244
2260
  self._restore_train_widgets_state_on_error()
2245
2261
  self._set_ws_progress_status("reset")
@@ -2250,8 +2266,18 @@ class TrainApp:
2250
2266
  if self._app_options.get("train_logger", None) is None:
2251
2267
  self._set_ws_progress_status("training")
2252
2268
  experiment_info = self._train_func()
2269
+ except ZeroDivisionError as e:
2270
+ message = (
2271
+ "'ZeroDivisionError' occurred during training. "
2272
+ "The error was caused by an insufficient dataset size relative to the specified batch size in hyperparameters. "
2273
+ "Please check input data and hyperparameters."
2274
+ )
2275
+ self._show_error(message, e)
2276
+ self._restore_train_widgets_state_on_error()
2277
+ self._set_ws_progress_status("reset")
2278
+ return
2253
2279
  except Exception as e:
2254
- message = "Error occurred during training. Please check the logs for more details."
2280
+ message = f"Error occurred during training. {check_logs_text}"
2255
2281
  self._show_error(message, e)
2256
2282
  self._restore_train_widgets_state_on_error()
2257
2283
  self._set_ws_progress_status("reset")
@@ -2263,7 +2289,7 @@ class TrainApp:
2263
2289
  self._finalize(experiment_info)
2264
2290
  self.gui.training_process.start_button.loading = False
2265
2291
  except Exception as e:
2266
- message = "Error occurred during finalizing and uploading training artifacts . Please check the logs for more details."
2292
+ message = f"Error occurred during finalizing and uploading training artifacts. {check_logs_text}"
2267
2293
  self._show_error(message, e)
2268
2294
  self._restore_train_widgets_state_on_error()
2269
2295
  self._set_ws_progress_status("reset")
@@ -2280,6 +2306,7 @@ class TrainApp:
2280
2306
  self._restore_train_widgets_state_on_error()
2281
2307
 
2282
2308
  def _set_train_widgets_state_on_start(self):
2309
+ self.gui.disable_select_buttons()
2283
2310
  self.gui.training_artifacts.validator_text.hide()
2284
2311
  self._validate_experiment_name()
2285
2312
  self.gui.training_process.experiment_name_input.disable()
@@ -2305,6 +2332,7 @@ class TrainApp:
2305
2332
  if self._app_options.get("device_selector", False):
2306
2333
  self.gui.training_process.select_device._select.enable()
2307
2334
  self.gui.training_process.select_device.enable()
2335
+ self.gui.enable_select_buttons()
2308
2336
 
2309
2337
  def _validate_experiment_name(self) -> bool:
2310
2338
  experiment_name = self.gui.training_process.get_experiment_name()
@@ -2475,7 +2503,7 @@ class TrainApp:
2475
2503
  change_name_if_conflict=True,
2476
2504
  )
2477
2505
 
2478
- # 3. Upload gt project to benchmark workspace
2506
+ # 3. Upload converted gt project
2479
2507
  project = Project("tmp_project", OpenMode.READ)
2480
2508
  self._api.project.update_meta(gt_project_info.id, project.meta)
2481
2509
  for dataset in project.datasets:
@@ -2491,6 +2519,7 @@ class TrainApp:
2491
2519
  img_infos = self._api.image.copy_batch(ds_info.id, img_ids)
2492
2520
  img_ids = [img_info.id for img_info in img_infos]
2493
2521
  self._api.annotation.upload_anns(img_ids, anns)
2522
+ sly_fs.remove_dir(project.directory)
2494
2523
 
2495
2524
  # 4. Match splits with original project
2496
2525
  gt_split_data = self._postprocess_splits(gt_project_info.id)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.279
3
+ Version: 6.73.280
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -968,10 +968,10 @@ supervisely/nn/tracker/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
968
968
  supervisely/nn/tracker/utils/gmc.py,sha256=3JX8979H3NA-YHNaRQyj9Z-xb9qtyMittPEjGw8y2Jo,11557
969
969
  supervisely/nn/tracker/utils/kalman_filter.py,sha256=eSFmCjM0mikHCAFvj-KCVzw-0Jxpoc3Cfc2NWEjJC1Q,17268
970
970
  supervisely/nn/training/__init__.py,sha256=gY4PCykJ-42MWKsqb9kl-skemKa8yB6t_fb5kzqR66U,111
971
- supervisely/nn/training/train_app.py,sha256=mxoD8sgSuIc3B-LcieP9m1lEaUawuOuLeceRqDU6l6U,100168
971
+ supervisely/nn/training/train_app.py,sha256=PZ4zWMYRvOFj97vy2rOofCBYqnpkDtmouzFTjs9UyN4,101747
972
972
  supervisely/nn/training/gui/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
973
973
  supervisely/nn/training/gui/classes_selector.py,sha256=8UgzA4aogOAr1s42smwEcDbgaBj_i0JLhjwlZ9bFdIA,3772
974
- supervisely/nn/training/gui/gui.py,sha256=uXpNWU6q741PimYGZ5aFWpr0boewa0yDrpIz8JGcqXE,25004
974
+ supervisely/nn/training/gui/gui.py,sha256=CnT_QhihrxdSHKybpI0pXhPLwCaXEana_qdn0DhXByg,25558
975
975
  supervisely/nn/training/gui/hyperparameters_selector.py,sha256=UAXZYyhuUOY7d2ZKAx4R5Kz-KQaiFZ7AnY8BDoj3_30,7071
976
976
  supervisely/nn/training/gui/input_selector.py,sha256=Jp9PnVVADv1fhndPuZdMlKuzWTOBQZogrOks5dwATlc,2179
977
977
  supervisely/nn/training/gui/model_selector.py,sha256=n2Xn6as60bNPtSlImJtyrVEo0gjKnvHLT3yq_m39TXk,4334
@@ -1070,9 +1070,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
1070
1070
  supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
1071
1071
  supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
1072
1072
  supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
1073
- supervisely-6.73.279.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1074
- supervisely-6.73.279.dist-info/METADATA,sha256=LtI71cTqLVkLsxFnPgUIWaWidSe5J_2h2Pt7DzEVWXA,33573
1075
- supervisely-6.73.279.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
1076
- supervisely-6.73.279.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1077
- supervisely-6.73.279.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1078
- supervisely-6.73.279.dist-info/RECORD,,
1073
+ supervisely-6.73.280.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1074
+ supervisely-6.73.280.dist-info/METADATA,sha256=xY-ujb2oWVk6XMCZER18NgoGnfZYef8Lt6UAzVtDvkI,33573
1075
+ supervisely-6.73.280.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
1076
+ supervisely-6.73.280.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1077
+ supervisely-6.73.280.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1078
+ supervisely-6.73.280.dist-info/RECORD,,