将预训练的 Keras 加载到 Sagemaker - 本地分类有效但 sagemaker 分类发生变化
Loading Pretrained Keras to Sagemaker - local classification works but sagemaker classification changes
编辑:找到解决方案,请参阅 post 的底部。
我有一个预训练的 keras 模型 (model.h5),它是一个用于图像分类的 CNN。我的目标是在 sagemaker 上部署模型并使用 lambda 函数与 sagemaker 端点交互并进行预测。当我使用以下代码在我的本地机器上使用模型进行预测时,我得到了我期望的结果:
model = load_model(r'model.h5')
photo_fp = r'/path/to/photo.jpg'
img = Image.open(photo_fp).resize((128,128))
image_array = np.array(img) / 255.
img_batch = np.expand_dims(image_array, axis=0)
print(model.predict(img_batch))
# [[9.9984562e-01 1.5430539e-04 2.2775747e-14 9.5851349e-16]]
但是,当我将模型部署为 sagemaker 上的端点时,我得到了不同的结果。下面是我将模型部署为端点的代码:
model = load_model(r'model.h5')
import tensorflow as tf
from tensorflow import keras
import sagemaker
import boto3, re
from sagemaker import get_execution_role
def convert_h5_to_aws(loaded_model):
# Interpreted from 'Data Liam'
from tensorflow.python.saved_model import builder
from tensorflow.python.saved_model.signature_def_utils import predict_signature_def
from tensorflow.python.saved_model import tag_constants
model_version = '1'
export_dir = 'export/Servo/' + model_version
# Build the Protocol Buffer SavedModel at 'export_dir'
builder = builder.SavedModelBuilder(export_dir)
# Create prediction signature to be used by TensorFlow Serving Predict API
signature = predict_signature_def(
inputs={"inputs": loaded_model.input}, outputs={"score": loaded_model.output})
with tf.compat.v1.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
# Save the meta graph and variables
builder.add_meta_graph_and_variables(
sess=sess, tags=[tag_constants.SERVING], signature_def_map={"serving_default": signature})
builder.save()
#create a tarball/tar file and zip it
import tarfile
with tarfile.open('model.tar.gz', mode='w:gz') as archive:
archive.add('export', recursive=True)
convert_h5_to_aws(model)
sagemaker_session = sagemaker.Session()
inputs = sagemaker_session.upload_data(path='model.tar.gz', key_prefix='model')
!touch train.py # from notebook
# the (default) IAM role
role = get_execution_role()
framework_version = tf.__version__
# Create Sagemaker model
from sagemaker.tensorflow.model import TensorFlowModel
sagemaker_model = TensorFlowModel(model_data = 's3://' + sagemaker_session.default_bucket() + '/model/model.tar.gz',
role = role,
framework_version = framework_version,
entry_point = 'train.py')
predictor = sagemaker_model.deploy(initial_instance_count=1,
instance_type='ml.m4.xlarge')
这可以很好地部署并保存为端点。然后,我调用端点:
runtime = boto3.client('runtime.sagemaker')
endpoint_name = 'endpoint-name-for-Whosebug'
img = Image.open(photo_fp).resize((128,128))
image_array = np.array(img) / 255.
img_batch = np.expand_dims(image_array, axis=0)
predictor = TensorFlowPredictor(endpoint_name)
result = predictor.predict(data=img_batch)
print(result)
# {'predictions': [[0.199595317, 0.322404563, 0.209394112, 0.268606]]}
如您所见,分类器将所有输出预测为几乎相等的概率,这不是在本地机器上预测的结果。这让我相信我的部署出了问题。
我尝试将模型权重和 json 模型结构加载到 sagemaker 而不是整个 h5 模型,但产生了相同的结果。我还使用以下代码调用端点而不是预测器 API:
payload = json.dumps(img_batch.tolist())
response = runtime.invoke_endpoint(EndpointName=endpoint_name,
ContentType='application/json',
Body=payload)
result = json.loads(response['Body'].read().decode())
print(result)
# {'predictions': [[0.199595317, 0.322404563, 0.209394112, 0.268606]]}
但同样的结果。
知道为什么我在 sagemaker 上得到的结果与在本地机器上使用相同型号的结果不同吗?
谢谢!
编辑:找到解决方案。问题出在 TensorflowModel 框架版本参数上。我将 framework_version 更改为“1.12”并在 Sagemaker Jupyter 实例中安装了版本 1.12,并使用 TF 1.12 在本地重新训练了我的模型。我不完全确定为什么会这样,但我发现的所有博客(例如 this one)都使用 1.12。希望这有帮助。
为了社区的利益在回答部分提供解决方案
The problem was with the TensorflowModel
framework version argument. After
changing the framework_version
to 1.12
and installed version TF 1.12
in
the Sagemaker Jupyter
instance and retrained model locally using TF 1.12
got same results. (paraphrased from Peter Van Katwyk)
编辑:找到解决方案,请参阅 post 的底部。
我有一个预训练的 keras 模型 (model.h5),它是一个用于图像分类的 CNN。我的目标是在 sagemaker 上部署模型并使用 lambda 函数与 sagemaker 端点交互并进行预测。当我使用以下代码在我的本地机器上使用模型进行预测时,我得到了我期望的结果:
model = load_model(r'model.h5')
photo_fp = r'/path/to/photo.jpg'
img = Image.open(photo_fp).resize((128,128))
image_array = np.array(img) / 255.
img_batch = np.expand_dims(image_array, axis=0)
print(model.predict(img_batch))
# [[9.9984562e-01 1.5430539e-04 2.2775747e-14 9.5851349e-16]]
但是,当我将模型部署为 sagemaker 上的端点时,我得到了不同的结果。下面是我将模型部署为端点的代码:
model = load_model(r'model.h5')
import tensorflow as tf
from tensorflow import keras
import sagemaker
import boto3, re
from sagemaker import get_execution_role
def convert_h5_to_aws(loaded_model):
# Interpreted from 'Data Liam'
from tensorflow.python.saved_model import builder
from tensorflow.python.saved_model.signature_def_utils import predict_signature_def
from tensorflow.python.saved_model import tag_constants
model_version = '1'
export_dir = 'export/Servo/' + model_version
# Build the Protocol Buffer SavedModel at 'export_dir'
builder = builder.SavedModelBuilder(export_dir)
# Create prediction signature to be used by TensorFlow Serving Predict API
signature = predict_signature_def(
inputs={"inputs": loaded_model.input}, outputs={"score": loaded_model.output})
with tf.compat.v1.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
# Save the meta graph and variables
builder.add_meta_graph_and_variables(
sess=sess, tags=[tag_constants.SERVING], signature_def_map={"serving_default": signature})
builder.save()
#create a tarball/tar file and zip it
import tarfile
with tarfile.open('model.tar.gz', mode='w:gz') as archive:
archive.add('export', recursive=True)
convert_h5_to_aws(model)
sagemaker_session = sagemaker.Session()
inputs = sagemaker_session.upload_data(path='model.tar.gz', key_prefix='model')
!touch train.py # from notebook
# the (default) IAM role
role = get_execution_role()
framework_version = tf.__version__
# Create Sagemaker model
from sagemaker.tensorflow.model import TensorFlowModel
sagemaker_model = TensorFlowModel(model_data = 's3://' + sagemaker_session.default_bucket() + '/model/model.tar.gz',
role = role,
framework_version = framework_version,
entry_point = 'train.py')
predictor = sagemaker_model.deploy(initial_instance_count=1,
instance_type='ml.m4.xlarge')
这可以很好地部署并保存为端点。然后,我调用端点:
runtime = boto3.client('runtime.sagemaker')
endpoint_name = 'endpoint-name-for-Whosebug'
img = Image.open(photo_fp).resize((128,128))
image_array = np.array(img) / 255.
img_batch = np.expand_dims(image_array, axis=0)
predictor = TensorFlowPredictor(endpoint_name)
result = predictor.predict(data=img_batch)
print(result)
# {'predictions': [[0.199595317, 0.322404563, 0.209394112, 0.268606]]}
如您所见,分类器将所有输出预测为几乎相等的概率,这不是在本地机器上预测的结果。这让我相信我的部署出了问题。
我尝试将模型权重和 json 模型结构加载到 sagemaker 而不是整个 h5 模型,但产生了相同的结果。我还使用以下代码调用端点而不是预测器 API:
payload = json.dumps(img_batch.tolist())
response = runtime.invoke_endpoint(EndpointName=endpoint_name,
ContentType='application/json',
Body=payload)
result = json.loads(response['Body'].read().decode())
print(result)
# {'predictions': [[0.199595317, 0.322404563, 0.209394112, 0.268606]]}
但同样的结果。
知道为什么我在 sagemaker 上得到的结果与在本地机器上使用相同型号的结果不同吗? 谢谢!
编辑:找到解决方案。问题出在 TensorflowModel 框架版本参数上。我将 framework_version 更改为“1.12”并在 Sagemaker Jupyter 实例中安装了版本 1.12,并使用 TF 1.12 在本地重新训练了我的模型。我不完全确定为什么会这样,但我发现的所有博客(例如 this one)都使用 1.12。希望这有帮助。
为了社区的利益在回答部分提供解决方案
The problem was with the
TensorflowModel
framework version argument. After changing theframework_version
to1.12
and installed versionTF 1.12
in theSagemaker Jupyter
instance and retrained model locally usingTF 1.12
got same results. (paraphrased from Peter Van Katwyk)