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.

servable_config.py 4.8 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. # Copyright 2020 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. """Resnet50 ImageNet config python file"""
  16. import os
  17. import ast
  18. import numpy as np
  19. import mindspore.dataset as ds
  20. import mindspore.dataset.transforms.c_transforms as TC
  21. import mindspore.dataset.vision.c_transforms as VC
  22. from mindspore_serving.worker import register
  23. cur_dir = os.path.abspath(os.path.dirname(__file__))
  24. print("current dir:", cur_dir)
  25. with open(os.path.join(cur_dir, "imagenet1000_clsidx_to_labels.txt"), "r") as fp:
  26. idx_2_label = ast.literal_eval(fp.read())
  27. idx_2_label[1000] = "empty"
  28. def preprocess_eager(image):
  29. """
  30. Define preprocess, input is image numpy, return preprocess result.
  31. Return type can be numpy, str, bytes, int, float, or bool.
  32. Use MindData Eager, this image processing can also use other image processing library, likes numpy, PIL or cv2 etc.
  33. """
  34. image_size = 224
  35. mean = [0.485 * 255, 0.456 * 255, 0.406 * 255]
  36. std = [0.229 * 255, 0.224 * 255, 0.225 * 255]
  37. decode = VC.Decode()
  38. resize = VC.Resize([image_size, image_size])
  39. normalize = VC.Normalize(mean=mean, std=std)
  40. hwc2chw = VC.HWC2CHW()
  41. image = decode(image)
  42. image = resize(image)
  43. image = normalize(image)
  44. image = hwc2chw(image)
  45. return image
  46. def preprocess_pipeline(instances):
  47. """
  48. Define preprocess pipeline, the function arg is multi instances, every instance is tuple of inputs.
  49. This example has one input and one output.
  50. Use MindData Pipeline.
  51. """
  52. def generator_func():
  53. for instance in instances:
  54. image = instance[0]
  55. yield (image,)
  56. resnet_ds = ds.GeneratorDataset(generator_func, ["image"], shuffle=False)
  57. image_size = 224
  58. mean = [0.485 * 255, 0.456 * 255, 0.406 * 255]
  59. std = [0.229 * 255, 0.224 * 255, 0.225 * 255]
  60. resnet_ds = resnet_ds.map(operations=VC.Decode(), input_columns="image", num_parallel_workers=8)
  61. trans = [
  62. VC.Resize([image_size, image_size]),
  63. VC.Normalize(mean=mean, std=std),
  64. VC.HWC2CHW()
  65. ]
  66. resnet_ds = resnet_ds.map(operations=TC.Compose(trans), input_columns="image", num_parallel_workers=2)
  67. for data in resnet_ds.create_dict_iterator():
  68. image_result = data["image"]
  69. yield (image_result,)
  70. def postprocess_top1(score):
  71. """
  72. Define postprocess. This example has one input and one output.
  73. The input is the numpy tensor of the score, and the output is the label str of top one.
  74. """
  75. max_idx = np.argmax(score)
  76. return idx_2_label[max_idx]
  77. def postprocess_top5(score):
  78. """
  79. Define postprocess. This example has one input and two outputs.
  80. The input is the numpy tensor of the score. The first output is the str joined by labels of top five,
  81. and the second output is the score tensor of the top five.
  82. """
  83. idx = np.argsort(score)[::-1][:5] # top 5
  84. ret_label = [idx_2_label[i] for i in idx]
  85. ret_score = score[idx]
  86. return ";".join(ret_label), ret_score
  87. register.declare_servable(servable_file="resnet50_1b_imagenet.mindir", model_format="MindIR")
  88. @register.register_method(output_names=["label"])
  89. def classify_top1(image):
  90. """Define method `classify_top1` for servable `resnet50`.
  91. The input is `image` and the output is `lable`."""
  92. x = register.call_preprocess_pipeline(preprocess_pipeline, image)
  93. x = register.call_servable(x)
  94. x = register.call_postprocess(postprocess_top1, x)
  95. return x
  96. @register.register_method(output_names=["label"])
  97. def classify_top1_v1(image):
  98. """Define method `classify_top1_v1` for servable `resnet50`.
  99. The input is `image` and the output is `label`. """
  100. x = register.call_preprocess(preprocess_eager, image)
  101. x = register.call_servable(x)
  102. x = register.call_postprocess(postprocess_top1, x)
  103. return x
  104. @register.register_method(output_names=["label", "score"])
  105. def classify_top5(image):
  106. """Define method `classify_top5` for servable `resnet50`.
  107. The input is `image` and the output is `label` and `score`. """
  108. x = register.call_preprocess_pipeline(preprocess_pipeline, image)
  109. x = register.call_servable(x)
  110. label, score = register.call_postprocess(postprocess_top5, x)
  111. return label, score

A lightweight and high-performance service module that helps MindSpore developers efficiently deploy online inference services in the production environment.