使用AWS Lambda加载Keras模型

5

我正在尝试使用Keras在本地训练的NN模型进行部署。我在本地使用以下方式使用我的模型:

from keras.models import load_model
model = load_model("/path/to/model/model.h5")
prediction = model.predict(x)

现在,我需要在我的Lambda函数中使用相同的模型。我将模型上传到了一个s3存储桶中。然后,我尝试访问文件:

model = load_model("https://s3-eu-west-1.amazonaws.com/my-bucket/models/model.h5")

但是它告诉我文件不存在。我猜是权限问题。我也尝试过像这样(类似于我从s3读取JSON文件的方式):

client_s3 = boto3.client("s3")
result = client_s3.get_object(Bucket="my-bucket", Key='models/model.h5')
model = load_model(result["Body"].read())

但是我遇到了这个错误:
"stackTrace": [
[
  "/var/task/lambda_function.py",
  322,
  "lambda_handler",
  "model = load_model(result[\"Body\"].read())"
],
[
  "/var/task/keras/models.py",
  227,
  "load_model",
  "with h5py.File(filepath, mode='r') as f:"
],
[
  "/var/task/h5py/_hl/files.py",
  269,
  "__init__",
  "fid = make_fid(name, mode, userblock_size, fapl, swmr=swmr)"
],
[
  "/var/task/h5py/_hl/files.py",
  99,
  "make_fid",
  "fid = h5f.open(name, flags, fapl=fapl)"
],
[
  "h5py/_objects.pyx",
  54,
  "h5py._objects.with_phil.wrapper",
  null
],
[
  "h5py/_objects.pyx",
  55,
  "h5py._objects.with_phil.wrapper",
  null
],
[
  "h5py/h5f.pyx",
  78,
  "h5py.h5f.open",
  null
],
[
  "h5py/defs.pyx",
  621,
  "h5py.defs.H5Fopen",
  null
],
[
  "h5py/_errors.pyx",
  123,
  "h5py._errors.set_exception",
  null
]
],
"errorType": "UnicodeDecodeError",
"errorMessage": "'utf8' codec can't decode byte 0x89 in position 29: invalid start byte"
}

我怀疑result["Body"].read()函数不能与h5py对象一起使用。如何最好地从s3加载h5py模型? 解决方案: 解决方案是将文件下载到/tmp/文件夹中:
result = client_s3.download_file("my-bucket",'model.h5', "/tmp/model.h5")
model = load_model("/tmp/day/model.h5")

模型文件 model.h5 是否在存储桶中公开访问?如果没有,使用 AWS SDK for S3 下载该文件并保存到 /tmp 目录中,然后加载模型。 - Ashan
这不是公开的,我通过下载解决了。我已经更新了问题并附上了解决方案。 - Titus Pullo
4个回答

4

问题

boto3.client("s3")..get_object(...)["Body"].read() 返回一个字节串,但是keras.models.load_model需要一个文件路径 (来源)。

解决方案

将文件存储在某个地方。可以使用tempfile


1

在@Raji发布的链接中,我发现keras 最近实现 了从google云存储加载模型文件和/或权重文件的功能。

首先,在google云上设置一个新项目,并创建一个google云存储桶,然后将模型文件上传到其中。或者像我一样,将权重文件上传到那里(例如地址为“gs://my-bucket/my_weights.hdf5”)。生成新的服务账户凭据,将相应的json文件下载到您的repo中,并记录绝对文件路径(如“/path/to/repo/my_credentials.json”)。

设置环境变量:

# .env
GOOGLE_APPLICATION_CREDENTIALS="/path/to/repo/my_credentials.json" 
MODEL_WEIGHTS_FILEPATH="gs://my-bucket/my_weights.hdf5"

FYI:我遇到了类似“所有获取谷歌身份验证令牌的尝试均失败”的错误,直到我设置了“GOOGLE_APPLICATION_CREDENTIALS”环境变量以满足对凭据的隐式检查。
从Google云存储加载权重:

import os
from dotenv import load_dotenv

load_dotenv()

MODEL_WEIGHTS_FILEPATH = os.getenv("MODEL_WEIGHTS_FILEPATH")

print(MODEL_WEIGHTS_FILEPATH)

# an optional check
import tensorflow as tf
tf.io.gfile.exists(MODEL_WEIGHTS_FILEPATH)

model = unweighted_model() # your keras model
weighted_model = model.load_weights(MODEL_WEIGHTS_FILEPATH)
weighted_model.predict("zyx") # predict or do whatever with your model

0
这对我有用:
s3_client = boto3.client('s3')
s3_client.download_file('bucket_name','file_name','model') #downloading the model to temporary file named "model"
with h5py.File('model','r') as f:
    model = load_model(f)

0

这对我有用 https://github.com/keras-team/keras/issues/9343#issuecomment-440903847

s3 = boto3.resource('s3')
obj = s3.Object(bucket_name, model_file_name) #.h5 file
body = obj.get()['Body'].read()

file_access_property_list = h5py.h5p.create(h5py.h5p.FILE_ACCESS)
file_access_property_list.set_fapl_core(backing_store=False)
file_access_property_list.set_file_image(body)  

file_id_args = {
    'fapl': file_access_property_list,
    'flags': h5py.h5f.ACC_RDONLY,
    'name': b'this should never matter',
}

h5_file_args = {
    'backing_store': False,
    'driver': 'core',
    'mode': 'r',
}

with contextlib.closing(h5py.h5f.open(**file_id_args)) as file_id:
    with h5py.File(file_id, **h5_file_args) as h5_file:
        loaded_model = load_model(h5_file)    #from keras.models

现在,loaded_model 可以用来进行预测。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接