@@ -222,21 +222,25 @@ class Attack: | |||
- numpy.ndarray, the number of objects that are correctly detected. | |||
""" | |||
model = check_model('model', model, BlackModel) | |||
box_and_confi, pred_labels = model.predict(*inputs) | |||
boxes_and_confi, pred_labels = model.predict(*inputs) | |||
det_scores = [] | |||
correct_labels_num = [] | |||
gt_boxes_num = gt_boxes.shape[0] | |||
# repeat gt_boxes and gt_labels for all particles cloned from the same sample in PSOAttack/GeneticAttack | |||
if gt_boxes.shape[0] == 1 and boxes_and_confi.shape[0] > 1: | |||
gt_boxes = np.repeat(gt_boxes, boxes_and_confi.shape[0], axis=0) | |||
gt_labels = np.repeat(gt_labels, boxes_and_confi.shape[0], axis=0) | |||
iou_thres = 0.5 | |||
for boxes, labels in zip(box_and_confi, pred_labels): | |||
for boxes, labels, gt_box, gt_label in zip(boxes_and_confi, pred_labels, gt_boxes, gt_labels): | |||
gt_box_num = gt_box.shape[0] | |||
score = 0 | |||
box_num = boxes.shape[0] | |||
correct_label_flag = np.zeros(gt_labels.shape) | |||
correct_label_flag = np.zeros(gt_label.shape) | |||
for i in range(box_num): | |||
pred_box = boxes[i] | |||
max_iou_confi = 0 | |||
for j in range(gt_boxes_num): | |||
iou = calculate_iou(pred_box[:4], gt_boxes[j][:4]) | |||
if labels[i] == gt_labels[j] and iou > iou_thres: | |||
for j in range(gt_box_num): | |||
iou = calculate_iou(pred_box[:4], gt_box[j][:4]) | |||
if labels[i] == gt_label[j] and iou > iou_thres: | |||
max_iou_confi = max(max_iou_confi, pred_box[-1] + iou) | |||
correct_label_flag[j] = 1 | |||
score += max_iou_confi | |||
@@ -47,10 +47,11 @@ class GeneticAttack(Attack): | |||
turns on untargeted attack. It should be noted that only untargeted attack | |||
is supproted for model_type='detection', Default: False. | |||
reserve_ratio (Union[int, float]): The percentage of objects that can be detected after attacks, | |||
specifically for model_type='detection'. Default: 0.3. | |||
specifically for model_type='detection'. Reserve_ratio should be in the range of (0, 1). Default: 0.3. | |||
pop_size (int): The number of particles, which should be greater than | |||
zero. Default: 6. | |||
mutation_rate (Union[int, float]): The probability of mutations. Default: 0.005. | |||
mutation_rate (Union[int, float]): The probability of mutations, which should be in the range of (0, 1). | |||
Default: 0.005. | |||
per_bounds (Union[int, float]): Maximum L_inf distance. | |||
max_steps (int): The maximum round of iteration for each adversarial | |||
example. Default: 1000. | |||
@@ -83,7 +84,7 @@ class GeneticAttack(Attack): | |||
self._targeted = check_param_type('targeted', targeted, bool) | |||
self._reserve_ratio = check_value_non_negative('reserve_ratio', reserve_ratio) | |||
if self._reserve_ratio > 1: | |||
msg = "reserve_ratio should be less than 1.0, but got {}.".format(self._reserve_ratio) | |||
msg = "reserve_ratio should not be greater than 1.0, but got {}.".format(self._reserve_ratio) | |||
LOGGER.error(TAG, msg) | |||
raise ValueError(msg) | |||
self._sparse = check_param_type('sparse', sparse, bool) | |||
@@ -92,8 +93,11 @@ class GeneticAttack(Attack): | |||
self._step_size = check_value_positive('step_size', step_size) | |||
self._temp = check_value_positive('temp', temp) | |||
self._max_steps = check_int_positive('max_steps', max_steps) | |||
self._mutation_rate = check_value_positive('mutation_rate', | |||
mutation_rate) | |||
self._mutation_rate = check_value_non_negative('mutation_rate', mutation_rate) | |||
if self._mutation_rate > 1: | |||
msg = "mutation_rate should not be greater than 1.0, but got {}.".format(self._mutation_rate) | |||
LOGGER.error(TAG, msg) | |||
raise ValueError(msg) | |||
self._adaptive = check_param_type('adaptive', adaptive, bool) | |||
# initial global optimum fitness value | |||
self._best_fit = -np.inf | |||
@@ -163,7 +167,7 @@ class GeneticAttack(Attack): | |||
msg = "The parameter 'sparse' of GeneticAttack is True, but the input labels is not sparse style " \ | |||
"and got its shape as {}.".format(labels.shape) | |||
LOGGER.error(TAG, msg) | |||
raise ValueError | |||
raise ValueError(msg) | |||
else: | |||
labels = np.argmax(labels, axis=1) | |||
images = inputs | |||
@@ -186,7 +190,7 @@ class GeneticAttack(Attack): | |||
auxiliary_input_i = tuple() | |||
for item in auxiliary_inputs: | |||
auxiliary_input_i += (np.expand_dims(item[i], axis=0),) | |||
gt_boxes_i, gt_labels_i = gt_boxes[i], gt_labels[i] | |||
gt_boxes_i, gt_labels_i = np.expand_dims(gt_boxes[i], axis=0), np.expand_dims(gt_labels[i], axis=0) | |||
inputs_i = (images[i],) + auxiliary_input_i | |||
confi_ori, gt_object_num = self._detection_scores(inputs_i, gt_boxes_i, gt_labels_i, model=self._model) | |||
LOGGER.info(TAG, 'The number of ground-truth objects is %s', gt_object_num[0]) | |||
@@ -50,7 +50,7 @@ class PSOAttack(Attack): | |||
than zero. Default: 6. | |||
t_max (int): The maximum round of iteration for each adversarial example, | |||
which should be greater than zero. Default: 1000. | |||
pm (Union[int, float]): The probability of mutations. Default: 0.5. | |||
pm (Union[int, float]): The probability of mutations, which should be in the range of (0, 1). Default: 0.5. | |||
bounds (Union[list, tuple, None]): Upper and lower bounds of data. In form of (clip_min, | |||
clip_max). Default: None. | |||
targeted (bool): If True, turns on the targeted attack. If False, | |||
@@ -61,7 +61,7 @@ class PSOAttack(Attack): | |||
model_type (str): The type of targeted model. 'classification' and 'detection' are supported now. | |||
default: 'classification'. | |||
reserve_ratio (Union[int, float]): The percentage of objects that can be detected after attacks, | |||
specifically for model_type='detection'. Default: 0.3. | |||
specifically for model_type='detection'. Reserve_ratio should be in the range of (0, 1). Default: 0.3. | |||
Examples: | |||
>>> attack = PSOAttack(model) | |||
@@ -77,7 +77,11 @@ class PSOAttack(Attack): | |||
self._c2 = check_value_positive('c2', c2) | |||
self._c = check_value_positive('c', c) | |||
self._pop_size = check_int_positive('pop_size', pop_size) | |||
self._pm = check_value_positive('pm', pm) | |||
self._pm = check_value_non_negative('pm', pm) | |||
if self._pm > 1: | |||
msg = "pm should not be greater than 1.0, but got {}.".format(self._pm) | |||
LOGGER.error(TAG, msg) | |||
raise ValueError(msg) | |||
self._bounds = bounds | |||
if self._bounds is not None: | |||
self._bounds = check_param_multi_types('bounds', bounds, [list, tuple]) | |||
@@ -93,7 +97,7 @@ class PSOAttack(Attack): | |||
raise ValueError(msg) | |||
self._reserve_ratio = check_value_non_negative('reserve_ratio', reserve_ratio) | |||
if self._reserve_ratio > 1: | |||
msg = "reserve_ratio should be less than 1.0, but got {}.".format(self._reserve_ratio) | |||
msg = "reserve_ratio should not be greater than 1.0, but got {}.".format(self._reserve_ratio) | |||
LOGGER.error(TAG, msg) | |||
raise ValueError(msg) | |||
@@ -200,7 +204,7 @@ class PSOAttack(Attack): | |||
msg = "The parameter 'sparse' of PSOAttack is True, but the input labels is not sparse style and " \ | |||
"got its shape as {}.".format(labels.shape) | |||
LOGGER.error(TAG, msg) | |||
raise ValueError | |||
raise ValueError(msg) | |||
else: | |||
labels = np.argmax(labels, axis=1) | |||
images = inputs | |||
@@ -227,7 +231,7 @@ class PSOAttack(Attack): | |||
auxiliary_input_i = tuple() | |||
for item in auxiliary_inputs: | |||
auxiliary_input_i += (np.expand_dims(item[i], axis=0),) | |||
gt_boxes_i, gt_labels_i = gt_boxes[i], gt_labels[i] | |||
gt_boxes_i, gt_labels_i = np.expand_dims(gt_boxes[i], axis=0), np.expand_dims(gt_labels[i], axis=0) | |||
inputs_i = (images[i],) + auxiliary_input_i | |||
confi_ori, gt_object_num = self._detection_scores(inputs_i, gt_boxes_i, gt_labels_i, self._model) | |||
LOGGER.info(TAG, 'The number of ground-truth objects is %s', gt_object_num[0]) | |||