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.

README.md 8.2 kB

4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. # 自然扰动样本生成serving服务
  2. 提供自然扰动样本生成在线服务。客户端传入图片和扰动参数,服务端返回扰动后的图片数据。
  3. ## 环境准备
  4. 硬件环境:Ascend 910,GPU
  5. 操作系统:Linux-x86_64
  6. 软件环境:
  7. 1. python 3.7.5或python 3.9.0
  8. 2. 安装MindSpore 1.6.0可以参考[MindSpore安装页面](https://www.mindspore.cn/install)
  9. 3. 安装MindSpore Serving 1.6.0可以参考[MindSpore Serving 安装页面](https://www.mindspore.cn/serving/docs/zh-CN/r1.5/serving_install.html)
  10. 4. 安装serving分支的MindArmour:
  11. - 从Gitee下载源码
  12. `git clone https://gitee.com/mindspore/mindarmour.git`
  13. - 编译并安装MindArmour
  14. `python setup.py install`
  15. ### 文件结构说明
  16. ```bash
  17. serving
  18. ├── server
  19. │ ├── serving_server.py # 启动serving服务脚本
  20. │ └── perturbation
  21. │ └── serverable_config.py # 服务端接收客户端数据后的处理脚本
  22. └── client
  23. ├── serving_client.py # 启动客户端脚本
  24. └── perturb_config.py # 扰动方法配置文件
  25. ```
  26. ## 脚本说明及使用
  27. ### 部署Serving推理服务
  28. 1. #### `servable_config.py`说明。
  29. ```python
  30. ···
  31. # 客户端可以请求的方法,包含4个返回值:"results", "file_names", "file_length", "names_dict"
  32. @register.register_method(output_names=["results", "file_names", "file_length", "names_dict"])
  33. def natural_perturbation(img, perturb_config, methods_number, outputs_number):
  34. """method natural_perturbation data flow definition, only preprocessing and call model"""
  35. res = register.add_stage(perturb, img, perturb_config, methods_number, outputs_number, outputs_count=4)
  36. return res
  37. ```
  38. 方法`natural_perturbation`为对外提供服务的接口。
  39. **输入:**
  40. - img:输入为图片,格式为bytes。
  41. - perturb_config:扰动配置项,具体配置参考`perturb_config.py`。
  42. - methods_number:每次扰动随机从配置项中选择方法的个数。
  43. - outputs_number:对于每张图片,生成的扰动图片数量。
  44. **输出**res中包含4个参数:
  45. - results:拼接后的图像bytes;
  46. - file_names:图像名,格式为`xxx.png`,其中‘xxx’为A-Za-z中随机选择20个字符构成的字符串。
  47. - file_length:每张图片的bytes长度。
  48. - names_dict: 图片名和图片使用扰动方法构成的字典。格式为:
  49. ```bash
  50. {
  51. picture1.png: [[method1, parameters of method1], [method2, parameters of method2], ...]],
  52. picture2.png: [[method3, parameters of method3], [method4, parameters of method4], ...]],
  53. ...
  54. }
  55. ```
  56. 2. #### 启动server。
  57. ```python
  58. ···
  59. def start():
  60. servable_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
  61. # 服务配置
  62. servable_config = server.ServableStartConfig(servable_directory=servable_dir, servable_name="perturbation", device_ids=(0, 1), num_parallel_workers=4)
  63. # 启动服务
  64. server.start_servables(servable_configs=servable_config)
  65. # 启动启动gRPC服务,用于客户端和服务端之间通信
  66. server.start_grpc_server(address="0.0.0.0:5500", max_msg_mb_size=200) # ip和最大的传输数据量,单位MB
  67. # 启动启动Restful服务,用于客户端和服务端之间通信
  68. server.start_restful_server(address="0.0.0.0:5500")
  69. ```
  70. gRPC传输性能更好,Restful更适合用于web服务,根据需要选择。
  71. 执行命令`python serverong_server.py`启动服务。
  72. 当服务端打印日志`Serving RESTful server start success, listening on 0.0.0.0:5500`时,表示Serving RESTful服务启动成功,推理模型已成功加载。
  73. ### 客户端进行推理
  74. 1. 在`perturb_config.py`中设置扰动方法及参数。下面是个例子:
  75. ```python
  76. PerturbConfig = [{"method": "Contrast", "params": {"alpha": 1.5, "beta": 0}},
  77. {"method": "GaussianBlur", "params": {"ksize": 5}},
  78. {"method": "SaltAndPepperNoise", "params": {"factor": 0.05}},
  79. {"method": "Translate", "params": {"x_bias": 0.1, "y_bias": -0.2}},
  80. {"method": "Scale", "params": {"factor_x": 0.7, "factor_y": 0.7}},
  81. {"method": "Shear", "params": {"factor": 2, "director": "horizontal"}},
  82. {"method": "Rotate", "params": {"angle": 40}},
  83. {"method": "MotionBlur", "params": {"degree": 5, "angle": 45}},
  84. {"method": "GradientBlur", "params": {"point": [50, 100], "kernel_num": 3, "center": True}},
  85. {"method": "GradientLuminance",
  86. "params": {"color_start": [255, 255, 255],
  87. "color_end": [0, 0, 0],
  88. "start_point": [100, 150], "scope": 0.3,
  89. "bright_rate": 0.3, "pattern": "light",
  90. "mode": "circle"}},
  91. {"method": "Curve", "params": {"curves": 5, "depth": 10,
  92. "mode": "vertical"}},
  93. {"method": "Perspective",
  94. "params": {"ori_pos": [[0, 0], [0, 800], [800, 0], [800, 800]],
  95. "dst_pos": [[50, 0], [0, 800], [780, 0], [800, 800]]}},
  96. ]
  97. ```
  98. 其中`method`为扰动方法名,`params`为对应方法的参数。可用的扰动方法及对应参数可在`mindarmour/natural_robustness/natural_noise.py`中查询。
  99. 2. 在`serving_client.py`中写客户端的处理脚本,包含输入输出的处理、服务端的调用,可以参考下面的例子。
  100. ```python
  101. ···
  102. def perturb(perturb_config):
  103. """invoke servable perturbation method natural_perturbation"""
  104. # 请求的服务端ip及端口、请求的服务名、请求的方法名
  105. ip_addr = "0.0.0.0:8800"
  106. client = Client(ip_addr, "perturbation", "natural_perturbation")
  107. # 输入数据
  108. instances = []
  109. img_path = '/root/mindarmour/example/adversarial/test_data/1.png'
  110. result_path = '/root/mindarmour/example/adv/result/'
  111. methods_number = 2
  112. outputs_number = 3
  113. img = cv2.imread(img_path)
  114. img = cv2.imencode('.png', img)[1].tobytes() # 图片传输用bytes格式,不支持numpy.ndarray格式
  115. perturb_config = json.dumps(perturb_config) # 配置方法转成json格式
  116. instances.append({"img": img, 'perturb_config': perturb_config, "methods_number": methods_number,
  117. "outputs_number": outputs_number}) # instances中可添加多个输入
  118. # 请求服务,返回结果
  119. result = client.infer(instances)
  120. # 对服务请求得到的结果进行处理,将返回的图片字节流存成图片
  121. file_names = result[0]['file_names'].split(';')
  122. length = result[0]['file_length'].tolist()
  123. before = 0
  124. for name, leng in zip(file_names, length):
  125. res_img = result[0]['results']
  126. res_img = res_img[before:before + leng]
  127. before = before + leng
  128. print('name: ', name)
  129. image = Image.open(BytesIO(res_img))
  130. image.save(os.path.join(result_path, name))
  131. names_dict = result[0]['names_dict']
  132. with open('names_dict.json', 'w') as file:
  133. file.write(names_dict)
  134. ```
  135. 启动client前,需将服务端的IP地址改成部署server的IP地址,图片路径、结果存储路基替换成用户数据路径。
  136. 目前serving数据传输支持的数据类型包括:python的int、float、bool、str、bytes,numpy number, numpy array object。
  137. 输入命令`python serving_client.py`开启客户端,如果对应目录下生成扰动样本图片则说明serving服务正确执行。
  138. ### 其他
  139. 在`serving_logs`目录下可以查看运行日志,辅助debug。

MindArmour关注AI的安全和隐私问题。致力于增强模型的安全可信、保护用户的数据隐私。主要包含3个模块:对抗样本鲁棒性模块、Fuzz Testing模块、隐私保护与评估模块。 对抗样本鲁棒性模块 对抗样本鲁棒性模块用于评估模型对于对抗样本的鲁棒性,并提供模型增强方法用于增强模型抗对抗样本攻击的能力,提升模型鲁棒性。对抗样本鲁棒性模块包含了4个子模块:对抗样本的生成、对抗样本的检测、模型防御、攻防评估。