azure - Score.py 用于图像的 AzureML

标签 azure keras deployment

我已经使用 Azure ML 服务部署了一个模型(文档很糟糕)。我的项目是围绕计算机视觉的,我想测试 Web 服务,但它返回 Unauthorized, no Authorization header。但是,当我发布到 URL 时,它会返回 200 响应(没关系),但不会返回图像属于哪个类以及模型的准确度。

我已经构建了模型的 REST API,我将分享代码。这是独立(本地)工作的 REST API。当我使用 Postman 时,我会收到包含预测和准确度分数的返回结果。

# import the necessary packages
from keras.models import load_model
import tensorflow as tf
from keras.preprocessing.image import img_to_array
from PIL import Image
from PIL import ImageFile
import numpy as np
from keras import backend as K

from flask import Flask
import flask

#Azure stuff I don't know but are needed.
from azureml.contrib.services.aml_request import AMLRequest, rawhttp
from azureml.contrib.services.aml_response import AMLResponse

# manipulate files
import io
import os 
import json
import requests

# AzureML stuff to consider, checks for the registered models.
from azureml.core.model import Model 

app = Flask(__name__)
def init():
    global model
    #Get the path where the deployed model can be found.
    #load models
    model = Model.get_model_path(model_name='large_models_1')
    global graph
    graph = tf.get_default_graph()
    print("* Model Loaded *, this is the init() * ")

# prepares image for prediction
def prepare_image(image, target):
  #  if the image mode is not RGB, convert it
    if image.mode != "RGB":
        image = image.convert("RGB")

    # resize the input image and preprocess it
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    image = image.resize(target)
    image = img_to_array(image)/255.
    image = np.expand_dims(image, axis=0)
    image = np.vstack([image])
    return image


@app.route("/predict", methods=["POST"])
def run():

    print("This is run () ")
    K.clear_session() # making new predictions.
    # wanna see the error.
    try:
        if flask.request.method  == 'POST':
            if flask.request.files.get("image"):
                image = flask.request.files["image"].read()
                image = Image.open(io.BytesIO(image))      
                image_files = prepare_image(image, target=(160,160)) # prepares the images to be loaded to the model.

                with graph.as_default():
                    prediction = model.predict(image_files).tolist()
                    print(prediction)
                    response = {
                         "prediction":{
                                "anomaly": prediction[0][0],
                                "normal": prediction[0][1],
                        
                                    } # JSON response 
                            } #end response
                    return json.dumps(response, indent=4)

        else:
            print("Error 500, bad request dumb ass !.")
    

    # Let's see the error.
    except Exception as e:
        result = str(e)
        return json.dumps(result, indent=4)

问题是,我使用 AKS(Azure Kubernetes 服务)进行部署,并且必须更改 Score.py 以匹配二进制数据(图像),这是来自此链接“https://”上的教程/learn.microsoft.com/en-us/azure/machine-learning/service/how-to-deploy-and-where"

from azureml.contrib.services.aml_request import AMLRequest, rawhttp
from azureml.contrib.services.aml_response import AMLResponse


def init():
    print("This is init()")


@rawhttp
def run(request):
    print("This is run()")
    print("Request: [{0}]".format(request))
    if request.method == 'GET':
        # For this example, just return the URL for GETs.
        respBody = str.encode(request.full_path)
        return AMLResponse(respBody, 200)
    elif request.method == 'POST':
        reqBody = request.get_data(False)
        # For a real-world solution, you would load the data from reqBody
        # and send it to the model. Then return the response.

        # For demonstration purposes, this example just returns the posted data as the response.
        return AMLResponse(reqBody, 200)
    else:
        return AMLResponse("bad request", 500)

我的问题是,当我将图像发布到 URL 时,如何执行正确的测试?我尝试过使用该教程,但似乎没有帮助,而且我不明白。顺便说一句,我感觉这涉及到 Score.py 和 run() 函数。

最佳答案

我从同一个教程开始,这正在工作 init() 和 run() (至少对我来说): 请注意,我不使用 AKS,但使用 Azure 容器实例。我相当确定它不会改变任何东西(除了测试部分中提到的授权 header (见下文))

%%writefile scorebinary.py
import json
import numpy as np
import os
from tensorflow.keras.models import load_model
import PIL
from io import BytesIO
from azureml.contrib.services.aml_request import AMLRequest, rawhttp
from azureml.contrib.services.aml_response import AMLResponse

def DataPrepImage(rawimage):
    Def=200
    img = rawimage.resize((Def,Def), resample=PIL.Image.BILINEAR)
    img = (np.array(img)/255).reshape(-1,Def,Def,1)
    return img

def init():
    global network    

    # AZUREML_MODEL_DIR is an environment variable created during deployment.
    # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION)
    # For multiple models, it points to the folder containing all deployed models (./azureml-models)
    folder = os.getenv('AZUREML_MODEL_DIR')
    if (folder==None): #Test hors docker
        folder = "."

    model_path = os.path.join(folder, 'Reseau_Siamois_3_36.h5')

    #On charge le model Keras
    network = load_model(model_path)

@rawhttp
def run(request):
    if request.method == 'POST':
        reqBody = request.get_data(False)
        myImage = PIL.Image.open(BytesIO(reqBody))
        myImage = myImage.convert('L')

        #Dataprep de l'image
        imgprepped = DataPrepImage(myImage)

        # make prediction  
        embed = network.predict(imgprepped)

        return {'emb':embed.tolist(),'imgpreped':imgprepped.tolist()}
    else:
        return AMLResponse("bad request, use POST", 500)

为了测试它,我使用它。现在对于 AKS 看看评论(不是我的,它们来自 Azure 教程),它可能会解决您的 4xx 错误问题

import requests
import PIL
import json
import matplotlib.pyplot as plt
%matplotlib inline

img = open('cat.jpg', 'rb').read()
headers = {'Content-Type':'application/json'}

# for AKS deployment you'd need to the service key in the header as well
# api_key = service.get_key()
# headers = {'Content-Type':'application/json',  'Authorization':('Bearer '+ api_key)} 

resp = requests.post(service.scoring_uri,data=img, headers=headers)

#print("POST to url", service.scoring_uri)
responsedata = json.loads(resp.text)
emb = responsedata['emb']

print("prediction:", emb)
img = np.array(responsedata['imgpreped'])
plt.axis("off")
plt.imshow(img[0,:,:,0],vmin=0, vmax=1,cmap='Greys')

最后不要忘记加载必要的包:

from azureml.core.conda_dependencies import CondaDependencies 

myenv = CondaDependencies()
myenv.add_conda_package("tensorflow")
myenv.add_conda_package("pillow")
myenv.add_pip_package("azureml-contrib-services")


with open("myenv.yml","w") as f:
    f.write(myenv.serialize_to_string())
with open("myenv.yml","r") as f:
    print(f.read())

关于azure - Score.py 用于图像的 AzureML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59175701/

相关文章:

c# - 可以使一个 Hello World exe 在所有版本的 .NET 中工作吗? (2.0 和 4.5)

azure - Microsoft.IdentityModel dll 在哪里

c# - CosmosDB - DocumentDB - 批量插入,无需饱和集合 RU

azure - 如何在Terraform中自动配置Azure容器实例和Azure MySql之间的防火墙?

azure - 在 Azure 数据工厂中将 JSON 转换为 CSV

python - Keras 2 fit_generator 用户警告 : `steps_per_epoch` is not the same as the Keras 1 argument `samples_per_epoch`

c# - 使用 Visual Studio 的 Windows 窗体应用程序的安装项目中的输出文件允许的最大数据大小

按最后一个轴的 Keras 点积层

python - Keras 中的顺序模型是什么意思

Node.js 生产部署