Skip to content

Commit

Permalink
also measure performance using benign predictions as labels (#1225)
Browse files Browse the repository at this point in the history
  • Loading branch information
lcadalzo authored Dec 13, 2021
1 parent 6ca38f7 commit 6012339
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
39 changes: 38 additions & 1 deletion armory/scenarios/carla_object_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""

import logging
import copy

from armory.scenarios.scenario import Scenario
from armory.utils import metrics
Expand All @@ -17,7 +18,12 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.skip_misclassified:
raise ValueError(
"skip_misclassified shouldn't be set for carla_video_tracking scenario"
"skip_misclassified shouldn't be set for carla_object_detection scenario"
)
if self.skip_benign:
raise ValueError(
"skip_benign shouldn't be set for carla_object_detection scenario, as "
"adversarial predictions are measured against benign predictions"
)

def load_dataset(self):
Expand Down Expand Up @@ -65,6 +71,9 @@ def run_attack(self):
x_adv.flags.writeable = False
y_pred_adv = self.model.predict(x_adv, **self.predict_kwargs)
self.metrics_logger.update_task(y_object, y_pred_adv, adversarial=True)
self.metrics_logger_wrt_benign_preds.update_task(
self.y_pred, y_pred_adv, adversarial=True
)
if self.targeted:
self.metrics_logger.update_task(
y_target, y_pred_adv, adversarial=True, targeted=True
Expand All @@ -80,3 +89,31 @@ def run_attack(self):
self.sample_exporter.export(x, x_adv, y, y_pred_adv)

self.x_adv, self.y_target, self.y_pred_adv = x_adv, y_target, y_pred_adv

def finalize_results(self):
super(CarlaObjectDetectionTask, self).finalize_results()

self.metrics_logger_wrt_benign_preds.log_task(
adversarial=True, used_preds_as_labels=True
)
self.results_wrt_benign_preds = {
metric_name + "_wrt_benign_preds": result
for metric_name, result in self.metrics_logger_wrt_benign_preds.results().items()
}
self.results = {**self.results, **self.results_wrt_benign_preds}

def _evaluate(self) -> dict:
"""
Evaluate the config and return a results dict
"""
self.load()

# Add a MetricsLogger to measure adversarial results using benign predictions as labels
self.metrics_logger_wrt_benign_preds = metrics.MetricsLogger()
self.metrics_logger_wrt_benign_preds.adversarial_tasks = copy.deepcopy(
self.metrics_logger.adversarial_tasks
)

self.evaluate_all()
self.finalize_results()
return self.results
11 changes: 9 additions & 2 deletions armory/utils/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1675,7 +1675,11 @@ def update_perturbation(self, x, x_adv):
for metric in self.perturbations:
metric.add_results(x, x_adv)

def log_task(self, adversarial=False, targeted=False):
def log_task(self, adversarial=False, targeted=False, used_preds_as_labels=False):
if used_preds_as_labels and not adversarial:
raise ValueError("benign task shouldn't use benign predictions as labels")
if used_preds_as_labels and targeted:
raise ValueError("targeted task shouldn't use benign predictions as labels")
if targeted:
if adversarial:
metrics = self.targeted_tasks
Expand All @@ -1685,7 +1689,10 @@ def log_task(self, adversarial=False, targeted=False):
raise ValueError("benign task cannot be targeted")
elif adversarial:
metrics = self.adversarial_tasks
wrt = "ground truth"
if used_preds_as_labels:
wrt = "benign predictions as"
else:
wrt = "ground truth"
task_type = "adversarial"
else:
metrics = self.tasks
Expand Down

0 comments on commit 6012339

Please sign in to comment.