From 4a16ca2fa23dcd94c4dbe9e2e16b9e58e23b381d Mon Sep 17 00:00:00 2001 From: ZhidanLiu Date: Tue, 9 Nov 2021 15:22:30 +0800 Subject: [PATCH] reconstruct output of natural_robustness serving --- examples/natural_robustness/serving/README.md | 26 ++++++++++--- .../serving/client/serving_client.py | 3 ++ .../serving/server/perturbation/servable_config.py | 43 ++++++++++++---------- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/examples/natural_robustness/serving/README.md b/examples/natural_robustness/serving/README.md index 32eeab8..ee1f82d 100644 --- a/examples/natural_robustness/serving/README.md +++ b/examples/natural_robustness/serving/README.md @@ -80,12 +80,12 @@ python add_model.py ··· - # 客户端可以请求的方法,包含3个返回值:"results", "file_names", "file_length" + # 客户端可以请求的方法,包含4个返回值:"results", "file_names", "file_length", "names_dict" - @register.register_method(output_names=["results", "file_names", "file_length"]) + @register.register_method(output_names=["results", "file_names", "file_length", "names_dict"]) def natural_perturbation(img, perturb_config, methods_number, outputs_number): """method natural_perturbation data flow definition, only preprocessing and call model""" - res = register.add_stage(perturb, img, perturb_config, methods_number, outputs_number, outputs_count=3) + res = register.add_stage(perturb, img, perturb_config, methods_number, outputs_number, outputs_count=4) return res ``` @@ -98,12 +98,24 @@ python add_model.py - methods_number:每次扰动随机从配置项中选择方法的个数。 - outputs_number:对于每张图片,生成的扰动图片数量。 - **输出**res中包含3个参数: + **输出**res中包含4个参数: - results:拼接后的图像bytes; - - file_names:图像名,格式为`method1_param1_value1_param2_value2_#···method2_param1_value1_param2_value2_#···.png`,方法之间用`#`分割,方法名、参数名、参数值之间用`_` 分割。 + + - file_names:图像名,格式为`xxx.png`,其中‘xxx’为A-Za-z中随机选择20个字符构成的字符串。 + - file_length:每张图片的bytes长度。 + - names_dict: 图片名和图片使用扰动方法构成的字典。格式为: + + ```bash + { + picture1.png: [[method1, parameters of method1], [method2, parameters of method2], ...]], + picture2.png: [[method3, parameters of method3], [method4, parameters of method4], ...]], + ... + } + ``` + 启动server服务前请将TEMPLATE_LEAF_PATH、TEMPLATE_WINDOW_PATH、TEMPLATE_PERSON_PATH、TEMPLATE_BACKGROUND_PATH的路径换成用户本地模板图片路径。 2. #### 启动server。 @@ -203,6 +215,10 @@ python add_model.py print('name: ', name) image = Image.open(BytesIO(res_img)) image.save(os.path.join(result_path, name)) + + names_dict = result[0]['names_dict'] + with open('names_dict.json', 'w') as file: + file.write(names_dict) ``` 启动client前,需将服务端的IP地址改成部署server的IP地址,图片路径、结果存储路基替换成用户数据路径。 diff --git a/examples/natural_robustness/serving/client/serving_client.py b/examples/natural_robustness/serving/client/serving_client.py index e74db58..83f2851 100644 --- a/examples/natural_robustness/serving/client/serving_client.py +++ b/examples/natural_robustness/serving/client/serving_client.py @@ -50,6 +50,9 @@ def perturb(perturb_config): print('name: ', name) image = Image.open(BytesIO(res_img)) image.save(os.path.join(result_path, name)) + names_dict = result[0]['names_dict'] + with open('names_dict.json', 'w') as file: + file.write(names_dict) if __name__ == '__main__': diff --git a/examples/natural_robustness/serving/server/perturbation/servable_config.py b/examples/natural_robustness/serving/server/perturbation/servable_config.py index a7f57c2..43e9fdb 100644 --- a/examples/natural_robustness/serving/server/perturbation/servable_config.py +++ b/examples/natural_robustness/serving/server/perturbation/servable_config.py @@ -15,10 +15,10 @@ """perturbation servable config""" import json import copy +import random from io import BytesIO import cv2 from PIL import Image -import numpy as np from mindspore_serving.server import register from mindarmour.natural_robustness.natural_noise import * @@ -28,6 +28,8 @@ TEMPLATE_WINDOW_PATH = '/root/mindarmour/example/adv/test_data/template/window' TEMPLATE_PERSON_PATH = '/root/mindarmour/example/adv/test_data/template/person' TEMPLATE_BACKGROUND_PATH = '/root/mindarmour/example/adv/test_data//template/dirt_background' +CHARACTERS = [chr(i) for i in range(65, 91)]+[chr(j) for j in range(97, 123)] + path_dict = {'leaf': TEMPLATE_LEAF_PATH, 'window': TEMPLATE_WINDOW_PATH, 'person': TEMPLATE_PERSON_PATH, @@ -79,13 +81,15 @@ def check_inputs(img, perturb_config, methods_number, outputs_number): def perturb(img, perturb_config, methods_number, outputs_number): + """Perturb given image.""" img, config, methods_number, outputs_number = check_inputs(img, perturb_config, methods_number, outputs_number) res_img_bytes = b'' file_names = [] file_length = [] + names_dict = {} for _ in range(outputs_number): - file_name = '' dst = copy.deepcopy(img) + used_methods = [] for _ in range(methods_number): item = np.random.choice(config) method_name = item['method'] @@ -93,34 +97,33 @@ def perturb(img, perturb_config, methods_number, outputs_number): params = item['params'] dst = method(**params)(img) - file_name = file_name + method_name + '_' - for key in params: - if key == 'template_path': - file_name += 'back_type_' - file_name += params[key].split('/')[-1] - file_name += '_' - continue - file_name += key - file_name += '_' - file_name += str(params[key]) - file_name += '_' - file_name += '#' - - file_name += '.png' - file_names.append(file_name) + if method_name == 'BackShadow': + method_params = copy.deepcopy(params) + method_params['back_type'] = method_params['template_path'].split('/')[-1] + del method_params['template_path'] + else: + method_params = params + + used_methods.append([method_name, method_params]) + name = ''.join(random.sample(CHARACTERS, 20)) + name += '.png' + file_names.append(name) + names_dict[name] = used_methods res_img = cv2.imencode('.png', dst)[1].tobytes() res_img_bytes += res_img file_length.append(len(res_img)) - return res_img_bytes, ';'.join(file_names), file_length + names_dict = json.dumps(names_dict) + + return res_img_bytes, ';'.join(file_names), file_length, names_dict model = register.declare_model(model_file="tensor_add.mindir", model_format="MindIR", with_batch_dim=False) -@register.register_method(output_names=["results", "file_names", "file_length"]) +@register.register_method(output_names=["results", "file_names", "file_length", "names_dict"]) def natural_perturbation(img, perturb_config, methods_number, outputs_number): """method natural_perturbation data flow definition, only preprocessing and call model""" - res = register.add_stage(perturb, img, perturb_config, methods_number, outputs_number, outputs_count=3) + res = register.add_stage(perturb, img, perturb_config, methods_number, outputs_number, outputs_count=4) return res