| @@ -9,6 +9,7 @@ | |||
| 操作系统:Linux-x86_64 | |||
| 软件环境: | |||
| 1. python 3.7.5或python 3.9.0 | |||
| 2. 安装MindSpore 1.5.0可以参考[MindSpore安装页面](https://www.mindspore.cn/install) | |||
| @@ -20,35 +21,34 @@ | |||
| - 从Gitee下载源码 | |||
| `git clone https://gitee.com/mindspore/mindarmour.git` | |||
| - 在源码根目录下,切换到serving分支 | |||
| `cd mindarmour` | |||
| `git checkout -b serving origin/serving` | |||
| - 编译并安装MindArmour | |||
| `python setup.py install` | |||
| 5. 安装Perlin-numpy: | |||
| `pip3 install git+https://github.com/pvigier/perlin-numpy` | |||
| ### 文件结构说明 | |||
| ```bash | |||
| serving | |||
| ├── server | |||
| │ ├── serving_server.py # 启动serving服务脚本 | |||
| │ ├── serving_server.py # 启动serving服务脚本 | |||
| │ ├── export_model | |||
| │ │ └── add_model.py # 生成模型文件脚本 | |||
| │ │ └── add_model.py # 生成模型文件脚本 | |||
| │ └── perturbation | |||
| │ └── serverable_config.py # 服务端接收客户端数据后的处理脚本 | |||
| │ └── serverable_config.py # 服务端接收客户端数据后的处理脚本 | |||
| └── client | |||
| ├── serving_client.py # 启动客户端脚本 | |||
| └── perturb_config.py # 扰动方法配置文件 | |||
| ├── serving_client.py # 启动客户端脚本 | |||
| └── perturb_config.py # 扰动方法配置文件 | |||
| ``` | |||
| ## 脚本说明及使用 | |||
| @@ -71,17 +71,17 @@ python add_model.py | |||
| ```python | |||
| ··· | |||
| # Path of template images | |||
| TEMPLATE_LEAF_PATH = '/root/mindarmour/example/test_data/template/leaf' | |||
| TEMPLATE_WINDOW_PATH = '/root/mindarmour/example/test_data/template/window' | |||
| TEMPLATE_PERSON_PATH = '/root/mindarmour/example/test_data/template/person' | |||
| TEMPLATE_BACKGROUND_PATH = '/root/mindarmour/example/test_data/template/dirt_background' | |||
| ··· | |||
| # 客户端可以请求的方法,包含3个返回值:"results", "file_names", "file_length" | |||
| @register.register_method(output_names=["results", "file_names", "file_length"]) | |||
| def natural_perturbation(img, perturb_config, methods_number, outputs_number): | |||
| """method natural_perturbation data flow definition, only preprocessing and call model""" | |||
| @@ -110,24 +110,24 @@ python add_model.py | |||
| ```python | |||
| ··· | |||
| def start(): | |||
| servable_dir = os.path.dirname(os.path.realpath(sys.argv[0])) | |||
| # 服务配置 | |||
| # 服务配置 | |||
| servable_config = server.ServableStartConfig(servable_directory=servable_dir, servable_name="perturbation", device_ids=(0, 1), num_parallel_workers=4) | |||
| # 启动服务 | |||
| server.start_servables(servable_configs=servable_config) | |||
| # 启动启动gRPC服务,用于客户端和服务端之间通信 | |||
| server.start_grpc_server(address="0.0.0.0:5500", max_msg_mb_size=200) # ip和最大的传输数据量,单位MB | |||
| server.start_grpc_server(address="0.0.0.0:5500", max_msg_mb_size=200) # ip和最大的传输数据量,单位MB | |||
| # 启动启动Restful服务,用于客户端和服务端之间通信 | |||
| server.start_restful_server(address="0.0.0.0:5500") | |||
| server.start_restful_server(address="0.0.0.0:5500") | |||
| ``` | |||
| gRPC传输性能更好,Restful更适合用于web服务,根据需要选择。 | |||
| 执行命令`python serverong_server.py`启动服务。 | |||
| 当服务端打印日志`Serving RESTful server start success, listening on 0.0.0.0:5500`时,表示Serving RESTful服务启动成功,推理模型已成功加载。 | |||
| ### 客户端进行推理 | |||
| @@ -136,59 +136,62 @@ python add_model.py | |||
| ```python | |||
| PerturbConfig = [{"method": "Contrast", "params": {"alpha": 1.5, "beta": 0}}, | |||
| {"method": "GaussianBlur", "params": {"ksize": [5, 5]}}, | |||
| {"method": "SaltAndPepperNoise", "params": {"factor": 0.05}}, | |||
| {"method": "Translate", "params": {"x_bias": 0.1, "y_bias": -0.2}}, | |||
| {"method": "Scale", "params": {"factor_x": 0.7, "factor_y": 0.7}}, | |||
| {"method": "Shear", "params": {"factor": 2, "director": "horizonal"}}, | |||
| {"method": "Rotate", "params": {"angle": 40}}, | |||
| {"method": "MotionBlur", "params": {"degree": 5, "angle": 45}}, | |||
| {"method": "GradientBlur", "params": {"point": [50, 100], "kernel_num": 3, "center": True}}, | |||
| {"method": "GradientLuminance", | |||
| "params": {"color_start": [255, 255, 255], | |||
| "color_end": [0, 0, 0], | |||
| "start_point": [100, 150], "scope": 0.3, | |||
| "bright_rate": 0.3, "pattern": "light", | |||
| "mode": "circle"}}, | |||
| {"method": "Perlin", "params": {"ratio": 0.5, "shade": 0.1}}, | |||
| {"method": "Curve", "params": {"curves": 10, "depth": 10, | |||
| {"method": "GaussianBlur", "params": {"ksize": 5}}, | |||
| {"method": "SaltAndPepperNoise", "params": {"factor": 0.05}}, | |||
| {"method": "Translate", "params": {"x_bias": 0.1, "y_bias": -0.2}}, | |||
| {"method": "Scale", "params": {"factor_x": 0.7, "factor_y": 0.7}}, | |||
| {"method": "Shear", "params": {"factor": 2, "director": "horizontal"}}, | |||
| {"method": "Rotate", "params": {"angle": 40}}, | |||
| {"method": "MotionBlur", "params": {"degree": 5, "angle": 45}}, | |||
| {"method": "GradientBlur", "params": {"point": [50, 100], "kernel_num": 3, "center": True}}, | |||
| {"method": "GradientLuminance", | |||
| "params": {"color_start": [255, 255, 255], | |||
| "color_end": [0, 0, 0], | |||
| "start_point": [100, 150], "scope": 0.3, | |||
| "bright_rate": 0.3, "pattern": "light", | |||
| "mode": "circle"}}, | |||
| {"method": "Perlin", "params": {"ratio": 0.5, "shade": 0.1}}, | |||
| {"method": "Curve", "params": {"curves": 10, "depth": 10, | |||
| "mode": "vertical"}}, | |||
| {"method": "BackgroundWord", "params": {"shade": 0.1}}, | |||
| {"method": "Perspective", | |||
| "params": {"ori_pos": [[0, 0], [0, 800], [800, 0], [800, 800]], | |||
| "dst_pos": [[50, 0], [0, 800], [780, 0], [800, 800]]}}, | |||
| {"method": "BackShadow", | |||
| "params": {"back_type": 'leaf', "shade": 0.2}}, | |||
| ] | |||
| {"method": "BackgroundWord", "params": {"shade": 0.1}}, | |||
| {"method": "Perspective", | |||
| "params": {"ori_pos": [[0, 0], [0, 800], [800, 0], [800, 800]], | |||
| "dst_pos": [[50, 0], [0, 800], [780, 0], [800, 800]]}}, | |||
| {"method": "BackShadow", | |||
| "params": {"back_type": 'leaf', "shade": 0.2}}, | |||
| ] | |||
| ``` | |||
| 其中`method`为扰动方法名,`params`为对应方法的参数。可用的扰动方法及对应参数可在`mindarmour/natural_robustness/natural_noise.py`中查询。 | |||
| 其中,`BackShadow`方法的参数较为特别,在`natural_noise.py`中的参数为template_path,但是这里配置时需改为back_type,参数值取值范围:'leaf'、'window'、'person'、'background'。 | |||
| 2. 在`serving_client.py`中写客户端的处理脚本,包含输入输出的处理、服务端的调用,可以参考下面的例子。 | |||
| ```python | |||
| ··· | |||
| def perturb(perturb_config): | |||
| """invoke servable perturbation method natural_perturbation""" | |||
| # 请求的服务端ip及端口、请求的服务名、请求的方法名 | |||
| client = Client("10.175.122.87:5500", "perturbation", "natural_perturbation") | |||
| client = Client("10.175.122.87:5500", "perturbation", "natural_perturbation") | |||
| # 输入数据 | |||
| instances = [] | |||
| img_path = '/root/liuzhidan/serving/example/adversarial/test_data/1.png' | |||
| result_path = '/root/liuzhidan/perturb-serving/example/adv/result/' | |||
| img_path = '/root/mindarmour/example/adversarial/test_data/1.png' | |||
| result_path = '/root/mindarmour/example/adv/result/' | |||
| methods_number = 2 | |||
| outputs_number = 3 | |||
| img = cv2.imread(img_path) | |||
| img = cv2.imencode('.png', img)[1].tobytes() # 图片传输用bytes格式,不支持numpy.ndarray格式 | |||
| img = cv2.imencode('.png', img)[1].tobytes() # 图片传输用bytes格式,不支持numpy.ndarray格式 | |||
| perturb_config = json.dumps(perturb_config) # 配置方法转成json格式 | |||
| instances.append({"img": img, 'perturb_config': perturb_config}) # instances中可添加多个输入 | |||
| instances.append({"img": img, 'perturb_config': perturb_config, "methods_number": methods_number, | |||
| "outputs_number": outputs_number}) # instances中可添加多个输入 | |||
| # 请求服务,返回结果 | |||
| result = client.infer(instances) | |||
| # 对服务请求得到的结果进行处理,将返回的图片字节流存成图片 | |||
| file_names = result[0]['file_names'].split(';') | |||
| length = result[0]['file_length'].tolist() | |||
| @@ -209,10 +212,5 @@ python add_model.py | |||
| 输入命令`python serving_client.py`开启客户端,如果对应目录下生成扰动样本图片则说明serving服务正确执行。 | |||
| ### 其他 | |||
| 在`serving_logs`目录下可以查看运行日志,辅助debug。 | |||
| 在`serving_logs`目录下可以查看运行日志,辅助debug。 | |||