mindarmour.adv_robustness.evaluations.neuron_metrics 源代码

# Copyright 2023 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Neuron sensitivity metrics.
"""

import mindspore as ms
from mindspore import ops

from mindarmour.utils.logger import LogUtil

# pylint: disable=redefined-builtin, unused-argument

LOGGER = LogUtil.get_instance()
TAG = "NeuronMetric"


[文档]class NeuronMetric: """ Neuron sensitivity of models towards adversarial examples. Args: model (mindspore.nn.Cell): The victim model. inputs (mindspore.Tensor): Original samples. adv_inputs (mindspore.Tensor): Adversarial samples generated from original samples. hook_names (List[str]): The name of the evaluated layers. Raises: ValueError: If `output` is no more than 1 dimension. Examples: >>> from mindarmour.adv_robustness.evaluations import NeuronMetric >>> from mindspore import ops >>> # Refer to https://gitee.com/mindspore/docs/blob/master/docs/mindspore/code/lenet.py >>> model = LeNet() >>> x = ops.randn((10, 3, 32, 32)) >>> adv_x = ops.randn((10, 3, 32, 32)) >>> layers = ["conv1", "conv2", "fc1", "fc2"] >>> neuron_metric = NeuronMetric(model, x, adv_x, layers) >>> nsense = neuron_metric.neuron_sensitivity() """ def __init__(self, model, inputs, adv_inputs, hook_names): self._model = model self._inputs = inputs self._adv_inputs = adv_inputs self._hook_names = hook_names hooks = [] self._features = [] def forward_hook(model, input, output): if len(output.shape) <= 1: msg = 'The output tensor should have more than 1 dimension, \ but got shape {}'.format(output.shape) LOGGER.error(msg) raise ValueError(msg) self._features.append( output.reshape(output.shape[0], output.shape[1], -1).mean(axis=-1) ) for name in self._hook_names: hook = self._model.__getattr__(name).register_forward_hook(forward_hook) hooks.append(hook) self._model(ms.Tensor(self._inputs)) self._model(ms.Tensor(self._adv_inputs)) for hook in hooks: hook.remove()
[文档] def neuron_sensitivity(self): """ Calculate neuron sensitivity (NS). Returns: A dictionary, whose key is the layer name in hook_name, and the value is a numpy.ndarray of neuron sensitivity of each neuron. """ nsense = {} n = len(self._hook_names) for i in range(n): nsense[self._hook_names[i]] = ops.norm( self._features[i] - self._features[i + n], axis=[0], p=1 ).asnumpy() return nsense