如何通过 AWS Lambda 函数对托管在 AWS SageMaker 上的 keras 模型进行推理?



我有一个预先训练好的keras模型,我使用AWS SageMaker托管在AWS上。我有一个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

最新更新