Skip to content

Commit ae2c36e

Browse files
authored
Expose the parameters log_training_metrics and log_validation_loss for object detection and instance segmentation (Azure#31479)
* add log_training_metrics and log_validation_loss params into image_model_settings * add log params to automl_image_object_detection_base, use enum types, update unit tests * code reformatting using black * add log params to docstrings * remove hardcoded log_training_metrics from unit tests
1 parent 91d92f4 commit ae2c36e

File tree

6 files changed

+151
-23
lines changed

6 files changed

+151
-23
lines changed

sdk/ml/azure-ai-ml/azure/ai/ml/_schema/automl/image_vertical/image_model_settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ class ImageModelSettingsObjectDetectionSchema(ImageModelSettingsSchema):
8686
allowed_values=[o.value for o in ValidationMetricType],
8787
casing_transform=camel_to_snake,
8888
)
89+
log_training_metrics = fields.Str()
90+
log_validation_loss = fields.Str()
8991

9092
@post_load
9193
def make(self, data, **kwargs):

sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/automl/image/automl_image_object_detection_base.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
ModelSize,
1212
StochasticOptimizer,
1313
ValidationMetricType,
14+
LogTrainingMetrics,
15+
LogValidationLoss,
1416
)
1517
from azure.ai.ml._utils.utils import camel_to_snake
1618
from azure.ai.ml.entities._job.automl import SearchSpace
@@ -56,6 +58,8 @@ def training_parameters(self, value: Union[Dict, ImageModelSettingsObjectDetecti
5658
learning_rate_scheduler=value.learning_rate_scheduler,
5759
model_size=value.model_size,
5860
validation_metric_type=value.validation_metric_type,
61+
log_training_metrics=value.log_training_metrics,
62+
log_validation_loss=value.log_validation_loss,
5963
)
6064
elif value is None:
6165
self._training_parameters = value
@@ -148,6 +152,8 @@ def set_training_parameters(
148152
tile_predictions_nms_threshold: Optional[float] = None,
149153
validation_iou_threshold: Optional[float] = None,
150154
validation_metric_type: Optional[Union[str, ValidationMetricType]] = None,
155+
log_training_metrics: Optional[Union[str, LogTrainingMetrics]] = None,
156+
log_validation_loss: Optional[Union[str, LogValidationLoss]] = None,
151157
) -> None:
152158
"""Setting Image training parameters for for AutoML Image Object Detection and Image Instance Segmentation
153159
tasks.
@@ -288,6 +294,12 @@ def set_training_parameters(
288294
:keyword validation_metric_type: Metric computation method to use for validation metrics. Must
289295
be 'none', 'coco', 'voc', or 'coco_voc'.
290296
:type validation_metric_type: str or ~azure.mgmt.machinelearningservices.models.ValidationMetricType
297+
:keyword log_training_metrics: indicates whether or not to log training metrics. Must
298+
be 'Enable' or 'Disable'
299+
:type log_training_metrics: str or ~azure.mgmt.machinelearningservices.models.LogTrainingMetrics
300+
:keyword log_validation_loss: indicates whether or not to log validation loss. Must
301+
be 'Enable' or 'Disable'
302+
:type log_validation_loss: str or ~azure.mgmt.machinelearningservices.models.LogValidationLoss
291303
"""
292304
self._training_parameters = self._training_parameters or ImageModelSettingsObjectDetection()
293305

@@ -432,6 +444,16 @@ def set_training_parameters(
432444
if validation_metric_type is not None
433445
else self._training_parameters.validation_metric_type
434446
)
447+
self._training_parameters.log_training_metrics = (
448+
LogTrainingMetrics[camel_to_snake(log_training_metrics)]
449+
if log_training_metrics is not None
450+
else self._training_parameters.log_training_metrics
451+
)
452+
self._training_parameters.log_validation_loss = (
453+
LogValidationLoss[camel_to_snake(log_validation_loss)]
454+
if log_validation_loss is not None
455+
else self._training_parameters.log_validation_loss
456+
)
435457

436458
# pylint: enable=too-many-locals
437459

sdk/ml/azure-ai-ml/azure/ai/ml/entities/_job/automl/image/image_model_settings.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
ModelSize,
1717
StochasticOptimizer,
1818
ValidationMetricType,
19+
LogTrainingMetrics,
20+
LogValidationLoss,
1921
)
2022
from azure.ai.ml.entities._mixins import RestTranslatableMixin
2123

@@ -624,6 +626,12 @@ class ImageModelSettingsObjectDetection(ImageModelDistributionSettings):
624626
values include: "None", "Coco", "Voc", "CocoVoc".
625627
:type validation_metric_type: str or
626628
~azure.mgmt.machinelearningservices.models.ValidationMetricType
629+
:param log_training_metrics: indicates whether or not to log training metrics
630+
:type log_training_metrics: str or
631+
~azure.mgmt.machinelearningservices.models.LogTrainingMetrics
632+
:param log_validation_loss: indicates whether or not to log validation loss
633+
:type log_validation_loss: str or
634+
~azure.mgmt.machinelearningservices.models.LogValidationLoss
627635
"""
628636

629637
def __init__(
@@ -672,6 +680,8 @@ def __init__(
672680
tile_predictions_nms_threshold: Optional[float] = None,
673681
validation_iou_threshold: Optional[float] = None,
674682
validation_metric_type: Optional[ValidationMetricType] = None,
683+
log_training_metrics: Optional[LogTrainingMetrics] = None,
684+
log_validation_loss: Optional[LogValidationLoss] = None,
675685
**kwargs,
676686
):
677687
super(ImageModelSettingsObjectDetection, self).__init__(
@@ -720,11 +730,11 @@ def __init__(
720730
self.tile_predictions_nms_threshold = tile_predictions_nms_threshold
721731
self.validation_iou_threshold = validation_iou_threshold
722732
self.validation_metric_type = validation_metric_type
733+
self.log_training_metrics = log_training_metrics
734+
self.log_validation_loss = log_validation_loss
723735

724736
def _to_rest_object(self) -> RestImageModelSettingsObjectDetection:
725737
return RestImageModelSettingsObjectDetection(
726-
# Temporary fix for https://msdata.visualstudio.com/Vienna/_workitems/edit/2385143
727-
log_training_metrics="Disable",
728738
advanced_settings=self.advanced_settings,
729739
ams_gradient=self.ams_gradient,
730740
beta1=self.beta1,
@@ -768,6 +778,8 @@ def _to_rest_object(self) -> RestImageModelSettingsObjectDetection:
768778
tile_predictions_nms_threshold=self.tile_predictions_nms_threshold,
769779
validation_iou_threshold=self.validation_iou_threshold,
770780
validation_metric_type=self.validation_metric_type,
781+
log_training_metrics=self.log_training_metrics,
782+
log_validation_loss=self.log_validation_loss,
771783
)
772784

773785
@classmethod
@@ -816,6 +828,8 @@ def _from_rest_object(cls, obj: RestImageModelSettingsObjectDetection) -> "Image
816828
tile_predictions_nms_threshold=obj.tile_predictions_nms_threshold,
817829
validation_iou_threshold=obj.validation_iou_threshold,
818830
validation_metric_type=obj.validation_metric_type,
831+
log_training_metrics=obj.log_training_metrics,
832+
log_validation_loss=obj.log_validation_loss,
819833
)
820834

821835
def __eq__(self, other: object) -> bool:
@@ -837,6 +851,8 @@ def __eq__(self, other: object) -> bool:
837851
and self.tile_predictions_nms_threshold == other.tile_predictions_nms_threshold
838852
and self.validation_iou_threshold == other.validation_iou_threshold
839853
and self.validation_metric_type == other.validation_metric_type
854+
and self.log_training_metrics == other.log_training_metrics
855+
and self.log_validation_loss == other.log_validation_loss
840856
)
841857

842858
def __ne__(self, other: object) -> bool:

sdk/ml/azure-ai-ml/tests/automl_job/unittests/test_automl_image_instance_segmentation.py

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
ModelSize,
1313
SamplingAlgorithmType,
1414
StochasticOptimizer,
15+
LogTrainingMetrics,
16+
LogValidationLoss,
1517
)
1618
from azure.ai.ml._restclient.v2023_04_01_preview.models import UserIdentity as RestUserIdentity
1719
from azure.ai.ml._restclient.v2023_04_01_preview.models import ValidationMetricType
@@ -128,24 +130,38 @@ def _check_data_type(data, expected_type, expected_path, msg):
128130
"settings, expected",
129131
[
130132
(
131-
("adam", "warmup_cosine", "coco_voc", "large"),
133+
("adam", "warmup_cosine", "coco_voc", "large", "enable", "enable"),
132134
(
133135
StochasticOptimizer.ADAM,
134136
LearningRateScheduler.WARMUP_COSINE,
135137
ValidationMetricType.COCO_VOC,
136138
ModelSize.LARGE,
139+
LogTrainingMetrics.ENABLE,
140+
LogValidationLoss.ENABLE,
137141
),
138142
),
139143
(
140-
("Adam", "WarmupCosine", "CocoVoc", "Large"),
144+
("Adam", "WarmupCosine", "CocoVoc", "Large", "Enable", "Enable"),
141145
(
142146
StochasticOptimizer.ADAM,
143147
LearningRateScheduler.WARMUP_COSINE,
144148
ValidationMetricType.COCO_VOC,
145149
ModelSize.LARGE,
150+
LogTrainingMetrics.ENABLE,
151+
LogValidationLoss.ENABLE,
152+
),
153+
),
154+
(
155+
(None, None, "coco_voc", "large", "enable", "enable"),
156+
(
157+
None,
158+
None,
159+
ValidationMetricType.COCO_VOC,
160+
ModelSize.LARGE,
161+
LogTrainingMetrics.ENABLE,
162+
LogValidationLoss.ENABLE,
146163
),
147164
),
148-
((None, None, "coco_voc", "large"), (None, None, ValidationMetricType.COCO_VOC, ModelSize.LARGE)),
149165
],
150166
ids=["snake case", "camel case", "with None"],
151167
)
@@ -159,25 +175,33 @@ def test_image_set_training_parameters_with_valid_values(self, settings, expecte
159175
learning_rate_scheduler=settings[1],
160176
validation_metric_type=settings[2],
161177
model_size=settings[3],
178+
log_training_metrics=settings[4],
179+
log_validation_loss=settings[5],
162180
)
163181
assert image_instance_segmentation_job.training_parameters.optimizer == expected[0]
164182
assert image_instance_segmentation_job.training_parameters.learning_rate_scheduler == expected[1]
165183
assert image_instance_segmentation_job.training_parameters.validation_metric_type == expected[2]
166184
assert image_instance_segmentation_job.training_parameters.model_size == expected[3]
185+
assert image_instance_segmentation_job.training_parameters.log_training_metrics == expected[4]
186+
assert image_instance_segmentation_job.training_parameters.log_validation_loss == expected[5]
167187

168188
@pytest.mark.parametrize(
169189
"settings, expected",
170190
[
171-
(("adamW", None, None, None), pytest.raises(KeyError)),
172-
((None, "Warmup_Cosine", None, None), pytest.raises(KeyError)),
173-
((None, None, "Coco_Voc", "large"), pytest.raises(KeyError)),
174-
((None, None, None, "Extra_Large"), pytest.raises(KeyError)),
191+
(("adamW", None, None, None, "Enable", "Enable"), pytest.raises(KeyError)),
192+
((None, "Warmup_Cosine", None, None, "Enable", "Enable"), pytest.raises(KeyError)),
193+
((None, None, "Coco_Voc", "large", "Enable", "Enable"), pytest.raises(KeyError)),
194+
((None, None, None, "Extra_Large", "Enable", "Enable"), pytest.raises(KeyError)),
195+
((None, None, None, None, "false", "Enable"), pytest.raises(KeyError)),
196+
((None, None, None, None, "Enable", "false"), pytest.raises(KeyError)),
175197
],
176198
ids=[
177199
"optimizer invalid",
178200
"learning rate scheduler invalid",
179201
"validation metric type invalid",
180202
"model size invalid",
203+
"log_training_metrics invalid",
204+
"log_validation_loss invalid",
181205
],
182206
)
183207
def test_image_set_training_parameters_with_invalid_values(self, settings, expected):
@@ -191,30 +215,46 @@ def test_image_set_training_parameters_with_invalid_values(self, settings, expec
191215
learning_rate_scheduler=settings[1],
192216
validation_metric_type=settings[2],
193217
model_size=settings[3],
218+
log_training_metrics=settings[4],
219+
log_validation_loss=settings[5],
194220
)
195221

196222
@pytest.mark.parametrize(
197223
"settings, expected",
198224
[
199225
(
200-
("adam", "warmup_cosine", "coco_voc", "large"),
226+
("adam", "warmup_cosine", "coco_voc", "large", "enable", "enable"),
201227
(
202228
StochasticOptimizer.ADAM,
203229
LearningRateScheduler.WARMUP_COSINE,
204230
ValidationMetricType.COCO_VOC,
205231
ModelSize.LARGE,
232+
LogTrainingMetrics.ENABLE,
233+
LogValidationLoss.ENABLE,
206234
),
207235
),
208236
(
209-
("Adam", "WarmupCosine", "CocoVoc", "Large"),
237+
("Adam", "WarmupCosine", "CocoVoc", "Large", "Enable", "Enable"),
210238
(
211239
StochasticOptimizer.ADAM,
212240
LearningRateScheduler.WARMUP_COSINE,
213241
ValidationMetricType.COCO_VOC,
214242
ModelSize.LARGE,
243+
LogTrainingMetrics.ENABLE,
244+
LogValidationLoss.ENABLE,
245+
),
246+
),
247+
(
248+
(None, None, "coco_voc", "large", "enable", "enable"),
249+
(
250+
None,
251+
None,
252+
ValidationMetricType.COCO_VOC,
253+
ModelSize.LARGE,
254+
LogTrainingMetrics.ENABLE,
255+
LogValidationLoss.ENABLE,
215256
),
216257
),
217-
((None, None, "coco_voc", "large"), (None, None, ValidationMetricType.COCO_VOC, ModelSize.LARGE)),
218258
],
219259
ids=["snake case", "camel case", "with None"],
220260
)
@@ -224,13 +264,18 @@ def test_image_set_training_parameters_with_settings_object(self, settings, expe
224264
learning_rate_scheduler=settings[1],
225265
validation_metric_type=settings[2],
226266
model_size=settings[3],
267+
log_training_metrics=settings[4],
268+
log_validation_loss=settings[5],
227269
)
228270
image_instance_segmentation_job = image_instance_segmentation(
229271
training_data=Input(type=AssetTypes.MLTABLE, path="https://foo/bar/train.csv"),
230272
target_column_name="label",
231273
training_parameters=image_model_settings,
232274
)
275+
233276
assert image_instance_segmentation_job.training_parameters.optimizer == expected[0]
234277
assert image_instance_segmentation_job.training_parameters.learning_rate_scheduler == expected[1]
235278
assert image_instance_segmentation_job.training_parameters.validation_metric_type == expected[2]
236279
assert image_instance_segmentation_job.training_parameters.model_size == expected[3]
280+
assert image_instance_segmentation_job.training_parameters.log_training_metrics == expected[4]
281+
assert image_instance_segmentation_job.training_parameters.log_validation_loss == expected[5]

0 commit comments

Comments
 (0)