如何通过 AWS Lambda 函数推断托管在 AWS SageMaker 上的 keras 模型?

How to make inference to a keras model hosted on AWS SageMaker via AWS Lambda function?

我有一个预训练的 keras 模型,我使用 AWS SageMakerAWS 上托管了该模型。我有一个 endpoint 并且我可以使用 Amazon SageMaker Notebook instance.

成功 predictions

我在那里做的是像下面这样提供 .PNG image,模型给出正确的预测。

file= s3.Bucket(bucketname).download_file(filename_1, 'normal.png')
file_name_1='normal.png'


import sagemaker
from sagemaker.tensorflow.model import TensorFlowModel

endpoint = 'tensorflow-inference-0000-11-22-33-44-55-666' #endpoint

predictor=sagemaker.tensorflow.model.TensorFlowPredictor(endpoint, sagemaker_session)
data = np.array([resize(imread(file_name), (137, 310, 3))])
predictor.predict(data)

现在我想使用 mobile application 进行预测。为此,我必须在 python 中写一个 Lambda function 并在其上附加一个 API gateway。我的Lambda function如下。

import os
import sys

CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, os.path.join(CWD, "lib"))

import json
import base64
import boto3
import numpy as np
from scipy import signal
from scipy.signal import butter, lfilter
from scipy.io import wavfile
import scipy.signal as sps
import io
from io import BytesIO
import matplotlib.pylab as plt
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
from datetime import datetime
from skimage.io import imread
from skimage.transform import resize
from PIL import Image

ENDPOINT_NAME = 'tensorflow-inference-0000-11-22-33-44-55-666'
runtime= boto3.client('runtime.sagemaker')

def lambda_handler(event, context):
    s3 = boto3.client("s3")
    
    # retrieving data from event.
    get_file_content_from_postman = event["content"]
    
    # decoding data.
    decoded_file_name = base64.b64decode(get_file_content_from_postman)
    
    image = Image.open(io.BytesIO(decoded_file_name))

    data = np.array([resize(imread(image), (137, 310, 3))])
    
    response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='text/csv', Body=data)
        
    result = json.loads(response['Body'].read().decode())
    
    return result

倒数第三行给我错误 'PngImageFile' object has no attribute 'read'。 知道我在这里缺少什么吗?

如果 io.BytesIO(decoded_file_name) 正确表示您的图像数据(尽管名称 decoded_file_name 表明它只是文件名,而不是实际的图像数据),那么您不需要使用 PIL。直接用就可以了:

data = np.array([resize(imread(io.BytesIO(decoded_file_name)), (137, 310, 3))])

我遗漏了导致此错误的一件事。收到图像数据后,我使用了 python 列表,然后 json.dump 该列表(列表)。下面是代码供参考。

import os
import sys

CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, os.path.join(CWD, "lib"))

import json
import base64
import boto3
import numpy as np
import io
from io import BytesIO
from skimage.io import imread
from skimage.transform import resize

# grab environment variable of Lambda Function
ENDPOINT_NAME = os.environ['ENDPOINT_NAME']
runtime= boto3.client('runtime.sagemaker')

def lambda_handler(event, context):
    s3 = boto3.client("s3")
    
    # retrieving data from event.
    get_file_content_from_postman = event["content"]
    
    # decoding data.
    decoded_file_name = base64.b64decode(get_file_content_from_postman)
    
    data = np.array([resize(imread(io.BytesIO(decoded_file_name)), (137, 310, 3))])
    
    payload = json.dumps(data.tolist())
    
    response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload)
        
    result = json.loads(response['Body'].read().decode())
    
    return result