准备编译模型 - Amazon SageMaker
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

准备编译模型

SageMaker Neo 要求机器学习模型满足特定的输入数据形状。编译所需的输入形状取决于您使用的深度学习框架。正确设置了模型输入形状格式后,请根据以下要求保存模型。保存模型后,压缩模型伪影。

SageMaker Neo 需要什么输入数据形状?

在编译模型之前,请确保模型格式正确。Neo 需要已训练模型的预期数据输入(JSON 格式或列表格式)的名称和形状。预期的投入是针对具体框架的。

以下是 SageMaker Neo 期望的输入形状:

使用已训练模型的字典格式,指定预期数据输入的名称和形状(NCHW 格式)。请注意,虽然 Keras 模型构件应以 NHWC (channel-last) 格式上传,但 DataInputConfig 应以 NCHW (channel-last) 格式指定。所需的字典格式如下所示:

  • 对于一个输入:{'input_1':[1,3,224,224]}

  • 对于两个输入:{'input_1': [1,3,224,224], 'input_2':[1,3,224,224]}

使用已训练模型的字典格式,指定预期数据输入的名称和形状(NCHW 格式)。所需的字典格式如下所示:

  • 对于一个输入:{'data':[1,3,1024,1024]}

  • 对于两个输入:{'var1': [1,1,28,28], 'var2':[1,1,28,28]}

使用已训练模型的字典格式,指定预期数据输入的名称和形状(NCHW 格式)。或者,您可以仅使用列表格式指定形状。所需的字典格式如下所示:

  • 对于字典格式的一个输入:{'input0':[1,3,224,224]}

  • 对于列表格式的一个输入:[[1,3,224,224]]

  • 对于字典格式的两个输入:{'input0':[1,3,224,224], 'input1':[1,3,224,224]}

  • 对于列表格式的两个输入:[[1,3,224,224], [1,3,224,224]]

使用已训练模型的字典格式,指定预期数据输入的名称和形状(NHWC 格式)。所需的字典格式如下所示:

  • 对于一个输入:{'input':[1,1024,1024,3]}

  • 对于两个输入:{'data1': [1,28,28,1], 'data2':[1,28,28,1]}

使用已训练模型的字典格式,指定预期数据输入的名称和形状(NHWC 格式)。所需的字典格式如下所示:

  • 对于一个输入:{'input':[1,224,224,3]}

不需要输入数据名称和形状。

SageMaker 新的保存模型

以下代码示例演示了如何保存模型以使其与 Neo 兼容。模型必须打包为压缩 tar 文件(*.tar.gz)。

Keras 模型需要一个模型定义文件(.h5)。

有两个选项可用于保存 Keras 模型,以使其与 SageMaker Neo 兼容:

  1. 将导出到.h5使用的格式model.save("<model-name>", save_format="h5")

  2. 冻结SavedModel导出后。

下面是如何将tf.keras模型作为冻结图(选项二):

import os import tensorflow as tf from tensorflow.keras.applications.resnet50 import ResNet50 from tensorflow.keras import backend tf.keras.backend.set_learning_phase(0) model = tf.keras.applications.ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3), pooling='avg') model.summary() # Save as a SavedModel export_dir = 'saved_model/' model.save(export_dir, save_format='tf') # Freeze saved model input_node_names = [inp.name.split(":")[0] for inp in model.inputs] output_node_names = [output.name.split(":")[0] for output in model.outputs] print("Input names: ", input_node_names) with tf.Session() as sess: loaded = tf.saved_model.load(sess, export_dir=export_dir, tags=["serve"]) frozen_graph = tf.graph_util.convert_variables_to_constants(sess, sess.graph.as_graph_def(), output_node_names) tf.io.write_graph(graph_or_graph_def=frozen_graph, logdir=".", name="frozen_graph.pb", as_text=False)
警告

不要将模型导出为SavedModel类使用model.save(<path>, save_format='tf')。这种格式适用于训练,但不适合推断。

MxNet 模型必须保存为单个符号文件*-symbol.json和单个参数*.params files

Gluon Models

定义神经网络,使用HybridSequential类。这将以符号编程的风格运行代码(而不是命令式编程)。

from mxnet import nd, sym from mxnet.gluon import nn def get_net(): net = nn.HybridSequential() # Here we use the class HybridSequential. net.add(nn.Dense(256, activation='relu'), nn.Dense(128, activation='relu'), nn.Dense(2)) net.initialize() return net # Define an input to compute a forward calculation. x = nd.random.normal(shape=(1, 512)) net = get_net() # During the forward calculation, the neural network will automatically infer # the shape of the weight parameters of all the layers based on the shape of # the input. net(x) # hybridize model net.hybridize() # export model net.export('<model_name>') # this will create model-symbol.json and model-0000.params files for name in ["<model_name>-0000.params", "<model_name>-symbol.json"]: tar.add(name) tar.close()

有关混合模型的更多信息,请参阅MXNet 杂交文档

Gluon Model Zoo (GluonCV)

GluonCV 模型动物园模型预先混合。所以你可以导出它们。

import numpy as np import mxnet as mx import gluoncv as gcv net = gcv.model_zoo.get_model('<model_name>', pretrained=True) net.export('<model_name>') tar = tarfile.open("<model_name>.tar.gz", "w:gz") >>>>>>> ngl_neo_framework_model_saving_how_to for name in ["<model_name>-0000.params", "<model_name>-symbol.json"]: tar.add(name) tar.close()
Non Gluon Models

保存到磁盘时,所有非粘合型号都使用*-symbol*.params文件。因此,它们已经是 Neo 的正确格式了。

# Pass the following 3 parameters: sym, args, aux mx.model.save_checkpoint('<model_name>',0,sym,args,aux) # this will create <model_name>-symbol.json and <model_name>-0000.params files tar = tarfile.open("<model_name>.tar.gz", "w:gz") for name in ["<model_name>-0000.params", "<model_name>-symbol.json"]: tar.add(name) tar.close()

PyTorch 模型必须保存为定义文件 (.pt或者.pth),输入数据类型为float32

要保存模型,请使用torch.jit.trace其次是torch.save。这会将对象保存到磁盘文件中,默认情况下使用 python 酸菜(pickle_module=pickle)来保存对象和一些元数据。接下来,将保存的模型转换为压缩 tar 文件。

import torchvision import torch model = torchvision.models.resnet18(pretrained=True) model.eval() inp = torch.rand(1, 3, 224, 224) model_trace = torch.jit.trace(model, inp) # Save your model. The following code saves it with the .pth file extension model_trace.save('model.pth') # Save as a compressed tar file with tarfile.open('model.tar.gz', 'w:gz') as f: f.add('model.pth') f.close()

TensorFlow 需要一个.pb或者一个.pbtxt文件和包含变量的变量目录。对于冻结模型,只有一个.pb或者.pbtxt文件是必需的。

Pre-Trained Model

以下代码示例演示如何使用 tar Linux 命令来压缩模型。在终端或 Jupyter 笔记本中运行以下命令(如果您使用 Jupyter 笔记本,请插入!在语句开头处的魔术命令):

import os import tensorflow as tf # Download SSD_Mobilenet trained model wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v2_coco_2018_03_29.tar.gz # unzip the compressed tar file tar xvf ssd_mobilenet_v2_coco_2018_03_29.tar.gz # Change into the directory where the model is stored cd ssd_mobilenet_v2_coco_2018_03_29 # Compress the tar file and save it in a directory called 'saved model' tar czvf panorama-model.tar.gz saved_model

本示例中使用的命令标志可完成以下操作:

  • c:创建存档

  • z:使用 gzip 压缩归档文件

  • v:显示存档进度

  • f:指定档案的文件名

内置估计器可以由特定于框架的容器或特定于算法的容器进行。内置算法和框架特定估计器的估计器对象将模型保存为正确的格式,当您使用内置.fit方法。

例如,您可以使用sagemaker.TensorFlow来定义一个 TensorFlow 估计器:

from sagemaker.tensorflow import TensorFlow estimator = TensorFlow(entry_point='mnist.py', role=role, framework_version='1.15.3', py_version='py3', training_steps=1000, evaluation_steps=100, instance_count=2, instance_type='ml.c4.xlarge')

然后使用.fit内置方法:

estimator.fit(inputs)

在最终使用构建编译模型之前compile_model方法:

# Specify output path of the compiled model output_path = '/'.join(estimator.output_path.split('/')[:-1]) # Compile model optimized_estimator = estimator.compile_model(target_instance_family='ml_c5', input_shape={'data':[1, 784]}, # Batch size 1, 3 channels, 224x224 Images. output_path=output_path, framework='tensorflow', framework_version='1.15.3')

您也可以使用sagemaker.estimator.Estimator用于初始化估计器对象以进行训练和编译内置算法的类compile_modelSageMaker 法:

from sagemaker.image_uris import retrieve aws_region = sagemaker_session.boto_region_name # Specify built-in algorithm training image training_image = retrieve(framework='image-classification', region=aws_region, image_scope='training') training_image = retrieve(framework='image-classification', region=aws_region, image_scope='training') # Create estimator object for training estimator = sagemaker.estimator.Estimator(image_uri=training_image, role=role, instance_count=1, instance_type='ml.p3.8xlarge', volume_size = 50, max_run = 360000, input_mode= 'File', output_path=s3_training_output_location, base_job_name='image-classification-training' ) # Setup the input data_channels to be used later for training. train_data = sagemaker.inputs.TrainingInput(s3_training_data_location, content_type='application/x-recordio', s3_data_type='S3Prefix') validation_data = sagemaker.inputs.TrainingInput(s3_validation_data_location, content_type='application/x-recordio', s3_data_type='S3Prefix') data_channels = {'train': train_data, 'validation': validation_data} # Train model estimator.fit(inputs=data_channels, logs=True) # Compile model with Neo optimized_estimator = estimator.compile_model(target_instance_family='ml_c5', input_shape={'data':[1, 3, 224, 224], 'softmax_label':[1]}, output_path=s3_compilation_output_location, framework='mxnet', framework_version='1.7')

有关使用 SageMaker Python 开发工具包编译模型的更多信息,请参阅编译模型(Amazon SageMaker 开发工具包)