You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

mechanisms.py 9.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. # Copyright 2019 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. """
  15. Noise Mechanisms.
  16. """
  17. from mindspore import Tensor
  18. from mindspore.nn import Cell
  19. from mindspore.ops import operations as P
  20. from mindspore.common.parameter import Parameter
  21. from mindspore.common import dtype as mstype
  22. from mindarmour.utils._check_param import check_param_type
  23. from mindarmour.utils._check_param import check_value_positive
  24. from mindarmour.utils._check_param import check_value_non_negative
  25. from mindarmour.utils._check_param import check_param_in_range
  26. class MechanismsFactory:
  27. """ Factory class of mechanisms"""
  28. def __init__(self):
  29. pass
  30. @staticmethod
  31. def create(policy, *args, **kwargs):
  32. """
  33. Args:
  34. policy(str): Noise generated strategy, could be 'Gaussian' or
  35. 'AdaGaussian'. Noise would be decayed with 'AdaGaussian' mechanism while
  36. be constant with 'Gaussian' mechanism. Default: 'AdaGaussian'.
  37. args(Union[float, str]): Parameters used for creating noise
  38. mechanisms.
  39. kwargs(Union[float, str]): Parameters used for creating noise
  40. mechanisms.
  41. Raises:
  42. NameError: `policy` must be in ['Gaussian', 'AdaGaussian'].
  43. Returns:
  44. Mechanisms, class of noise generated Mechanism.
  45. """
  46. if policy == 'Gaussian':
  47. return GaussianRandom(*args, **kwargs)
  48. if policy == 'AdaGaussian':
  49. return AdaGaussianRandom(*args, **kwargs)
  50. raise NameError("The {} is not implement, please choose "
  51. "['Gaussian', 'AdaGaussian']".format(policy))
  52. class Mechanisms(Cell):
  53. """
  54. Basic class of noise generated mechanism.
  55. """
  56. def construct(self, gradients):
  57. """
  58. Construct function.
  59. """
  60. class GaussianRandom(Mechanisms):
  61. """
  62. Gaussian noise generated mechanism.
  63. Args:
  64. norm_bound(float): Clipping bound for the l2 norm of the gradients.
  65. Default: 1.0.
  66. initial_noise_multiplier(float): Ratio of the standard deviation of
  67. Gaussian noise divided by the norm_bound, which will be used to
  68. calculate privacy spent. Default: 1.5.
  69. mean(float): Average value of random noise. Default: 0.0.
  70. seed(int): Original random seed. Default: 0.
  71. Returns:
  72. Tensor, generated noise with shape like given gradients.
  73. Examples:
  74. >>> gradients = Tensor([0.2, 0.9], mstype.float32)
  75. >>> norm_bound = 1.0
  76. >>> initial_noise_multiplier = 0.1
  77. >>> net = GaussianRandom(norm_bound, initial_noise_multiplier)
  78. >>> res = net(gradients)
  79. >>> print(res)
  80. """
  81. def __init__(self, norm_bound=1.0, initial_noise_multiplier=1.5, mean=0.0, seed=0):
  82. super(GaussianRandom, self).__init__()
  83. self._norm_bound = check_value_positive('norm_bound', norm_bound)
  84. self._norm_bound = Tensor(norm_bound, mstype.float32)
  85. self._initial_noise_multiplier = check_value_positive('initial_noise_multiplier',
  86. initial_noise_multiplier)
  87. self._initial_noise_multiplier = Tensor(initial_noise_multiplier, mstype.float32)
  88. mean = check_param_type('mean', mean, float)
  89. mean = check_value_non_negative('mean', mean)
  90. self._mean = Tensor(mean, mstype.float32)
  91. self._normal = P.Normal(seed=seed)
  92. def construct(self, gradients):
  93. """
  94. Generated Gaussian noise.
  95. Args:
  96. gradients(Tensor): The gradients.
  97. Returns:
  98. Tensor, generated noise with shape like given gradients.
  99. """
  100. shape = P.Shape()(gradients)
  101. stddev = P.Mul()(self._norm_bound, self._initial_noise_multiplier)
  102. noise = self._normal(shape, self._mean, stddev)
  103. return noise
  104. class AdaGaussianRandom(Mechanisms):
  105. """
  106. Adaptive Gaussian noise generated mechanism. Noise would be decayed with training. Decay mode could be 'Time'
  107. mode or 'Step' mode.
  108. Args:
  109. norm_bound(float): Clipping bound for the l2 norm of the gradients.
  110. Default: 1.5.
  111. initial_noise_multiplier(float): Ratio of the standard deviation of
  112. Gaussian noise divided by the norm_bound, which will be used to
  113. calculate privacy spent. Default: 5.0.
  114. mean(float): Average value of random noise. Default: 0.0
  115. noise_decay_rate(float): Hyper parameter for controlling the noise decay.
  116. Default: 6e-4.
  117. decay_policy(str): Noise decay strategy include 'Step' and 'Time'.
  118. Default: 'Time'.
  119. seed(int): Original random seed. Default: 0.
  120. Returns:
  121. Tensor, generated noise with shape like given gradients.
  122. Examples:
  123. >>> gradients = Tensor([0.2, 0.9], mstype.float32)
  124. >>> norm_bound = 1.0
  125. >>> initial_noise_multiplier = 5.0
  126. >>> mean = 0.0
  127. >>> noise_decay_rate = 6e-4
  128. >>> decay_policy = "Time"
  129. >>> net = AdaGaussianRandom(norm_bound, initial_noise_multiplier, mean
  130. >>> noise_decay_rate, decay_policy)
  131. >>> res = net(gradients)
  132. >>> print(res)
  133. """
  134. def __init__(self, norm_bound=1.5, initial_noise_multiplier=5.0, mean=0.0,
  135. noise_decay_rate=6e-4, decay_policy='Time', seed=0):
  136. super(AdaGaussianRandom, self).__init__()
  137. norm_bound = check_value_positive('norm_bound', norm_bound)
  138. initial_noise_multiplier = check_value_positive('initial_noise_multiplier',
  139. initial_noise_multiplier)
  140. self._norm_bound = Tensor(norm_bound, mstype.float32)
  141. initial_noise_multiplier = Tensor(initial_noise_multiplier, mstype.float32)
  142. self._initial_noise_multiplier = Parameter(initial_noise_multiplier,
  143. name='initial_noise_multiplier')
  144. self._stddev = P.Mul()(self._norm_bound, self._initial_noise_multiplier)
  145. self._noise_multiplier = Parameter(initial_noise_multiplier,
  146. name='noise_multiplier')
  147. mean = check_param_type('mean', mean, float)
  148. mean = check_value_non_negative('mean', mean)
  149. self._mean = Tensor(mean, mstype.float32)
  150. noise_decay_rate = check_param_type('noise_decay_rate', noise_decay_rate, float)
  151. check_param_in_range('noise_decay_rate', noise_decay_rate, 0.0, 1.0)
  152. self._noise_decay_rate = Tensor(noise_decay_rate, mstype.float32)
  153. if decay_policy not in ['Time', 'Step']:
  154. raise NameError("The decay_policy must be in ['Time', 'Step'], but "
  155. "get {}".format(decay_policy))
  156. self._decay_policy = decay_policy
  157. self._sub = P.Sub()
  158. self._mul = P.Mul()
  159. self._add = P.TensorAdd()
  160. self._div = P.Div()
  161. self._dtype = mstype.float32
  162. self._normal = P.Normal(seed=seed)
  163. self._assign = P.Assign()
  164. def _update_multiplier(self):
  165. """ Update multiplier. """
  166. if self._decay_policy == 'Time':
  167. temp = self._div(self._initial_noise_multiplier,
  168. self._noise_multiplier)
  169. temp = self._add(temp, self._noise_decay_rate)
  170. self._noise_multiplier = self._assign(self._noise_multiplier,
  171. self._div(self._initial_noise_multiplier, temp))
  172. else:
  173. one = Tensor(1, self._dtype)
  174. temp = self._sub(one, self._noise_decay_rate)
  175. self._noise_multiplier = self._assign(self._noise_multiplier, self._mul(temp, self._noise_multiplier))
  176. return self._noise_multiplier
  177. def _update_stddev(self):
  178. self._stddev = self._assign(self._stddev, self._mul(self._noise_multiplier, self._norm_bound))
  179. return self._stddev
  180. def construct(self, gradients):
  181. """
  182. Generate adaptive Gaussian noise.
  183. Args:
  184. gradients(Tensor): The gradients.
  185. Returns:
  186. Tensor, generated noise with shape like given gradients.
  187. """
  188. shape = P.Shape()(gradients)
  189. noise = self._normal(shape, self._mean, self._stddev)
  190. # pylint: disable=unused-variable
  191. mt = self._update_multiplier()
  192. # pylint: disable=unused-variable
  193. std = self._update_stddev()
  194. return noise

MindArmour关注AI的安全和隐私问题。致力于增强模型的安全可信、保护用户的数据隐私。主要包含3个模块:对抗样本鲁棒性模块、Fuzz Testing模块、隐私保护与评估模块。