

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Preparación del modelo para compilación
<a name="neo-compilation-preparing-model"></a>

SageMaker Neo requiere que los modelos de aprendizaje automático se adapten a formas de datos de entrada específicas. La forma de entrada necesaria para la compilación depende del marco de aprendizaje profundo que utilice. Una vez que la forma de entrada del modelo tenga el formato correcto, guarde el modelo de acuerdo con los requisitos que se indican a continuación. Una vez que haya guardado el modelo, comprima los artefactos del modelo.

**Topics**
+ [¿Qué formas de datos de entrada espera SageMaker Neo?](#neo-job-compilation-expected-inputs)
+ [Guardar modelos para SageMaker Neo](#neo-job-compilation-how-to-save-model)

## ¿Qué formas de datos de entrada espera SageMaker Neo?
<a name="neo-job-compilation-expected-inputs"></a>

Antes de compilar el modelo, asegúrese de que tiene el formato correcto. Neo espera el nombre y la forma de las entradas de datos previstas para su modelo formado con formato de diccionario JSON o formato de lista. Las entradas de datos previstas son específicas del marco. 

A continuación se muestran las formas de entrada que SageMaker Neo espera:

### Keras
<a name="collapsible-section-1"></a>

Especifique el nombre y la forma (formato NCHW) de las entradas de datos previstas usando un formato de diccionario para su modelo entrenado. Tenga en cuenta que, si bien los artefactos del modelo Keras deben cargarse en formato NHWC (último canal), DataInputConfig deben especificarse en formato NCHW (canal primero). Los formatos de diccionario necesarios son los siguientes: 
+ Para una entrada: `{'input_1':[1,3,224,224]}`
+ Para dos entradas: `{'input_1': [1,3,224,224], 'input_2':[1,3,224,224]}`

### MXNet/ONNX
<a name="collapsible-section-2"></a>

Especifique el nombre y la forma (formato NCHW) de las entradas de datos previstas usando un formato de diccionario para su modelo entrenado. Los formatos de diccionario necesarios son los siguientes:
+ Para una entrada: `{'data':[1,3,1024,1024]}`
+ Para dos entradas: `{'var1': [1,1,28,28], 'var2':[1,1,28,28]}`

### PyTorch
<a name="collapsible-section-3"></a>

En el caso de un PyTorch modelo, no es necesario proporcionar el nombre y la forma de las entradas de datos esperadas si se cumplen las dos condiciones siguientes:
+ Creó el archivo de definición del modelo con la PyTorch versión 2.0 o una versión posterior. Para obtener más información sobre cómo crear el archivo de definición, consulte la [PyTorch](#how-to-save-pytorch) sección sobre cómo *guardar modelos para SageMaker Neo*.
+ Está compilando el modelo para una instancia en la nube. Para obtener más información sobre los tipos de instancias compatibles con SageMaker Neo, consulte[Tipos de instancias y marcos compatibles](neo-supported-cloud.md).

Si cumples estas condiciones, SageMaker Neo obtiene la configuración de entrada del archivo de definición del modelo (.pt o .pth) con el que hayas creado. PyTorch

De lo contrario, tendrá que hacer lo siguiente:

Especifique el nombre y la forma (formato NCHW) de las entradas de datos previstas usando un formato de diccionario para su modelo entrenado. Como alternativa, puede especificar la forma únicamente mediante un formato de lista. Los formatos de diccionario necesarios son los siguientes:
+ Para una entrada en formato de diccionario: `{'input0':[1,3,224,224]}`
+ Para una entrada en formato de lista: `[[1,3,224,224]]`
+ Para dos entradas en formato de diccionario: `{'input0':[1,3,224,224], 'input1':[1,3,224,224]}`
+ Para dos entradas en formato de lista: `[[1,3,224,224], [1,3,224,224]]`

### TensorFlow
<a name="collapsible-section-4"></a>

Especifique el nombre y la forma (formato NHWC) de las entradas de datos previstas usando un formato de diccionario para su modelo entrenado. Los formatos de diccionario necesarios son los siguientes:
+ Para una entrada: `{'input':[1,1024,1024,3]}`
+ Para dos entradas: `{'data1': [1,28,28,1], 'data2':[1,28,28,1]}`

### TFLite
<a name="collapsible-section-5"></a>

Especifique el nombre y la forma (formato NHWC) de las entradas de datos previstas usando un formato de diccionario para su modelo entrenado. Los formatos de diccionario necesarios son los siguientes:
+ Para una entrada: `{'input':[1,224,224,3]}`

**nota**  
SageMaker Neo solo es compatible con TensorFlow Lite para dispositivos periféricos. Para obtener una lista de los dispositivos SageMaker Neo edge compatibles, consulta la [dispositivos](neo-supported-devices-edge-devices.md#neo-supported-edge-devices) página de SageMaker Neo. Para ver una lista de los destinos de instancias en la nube de SageMaker Neo compatibles, consulta la [Tipos de instancias y marcos compatibles](neo-supported-cloud.md) página de SageMaker Neo.

### XGBoost
<a name="collapsible-section-6"></a>

No son necesarios el nombre y la forma de los datos de entrada.

## Guardar modelos para SageMaker Neo
<a name="neo-job-compilation-how-to-save-model"></a>

En los siguientes ejemplos de código se muestra cómo guardar el modelo para que sea compatible con Neo. Los modelos deben empaquetarse como archivos tar comprimidos (`*.tar.gz`).

### Keras
<a name="how-to-save-tf-keras"></a>

Los modelos de Keras requieren un archivo de definición de modelo (`.h5`).

Hay dos opciones para guardar tu modelo Keras y hacerlo compatible con SageMaker Neo:

1. Exporte a formato `.h5` con `model.save("<model-name>", save_format="h5")`.

1. Congele el archivo `SavedModel` después de exportarlo.

A continuación se muestra un ejemplo de cómo exportar un modelo `tf.keras` como un gráfico congelado (segunda opción):

```
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)

import tarfile
tar = tarfile.open("frozen_graph.tar.gz", "w:gz")
tar.add("frozen_graph.pb")
tar.close()
```

**aviso**  
No exporte su modelo con clase `SavedModel` utilizando `model.save(<path>, save_format='tf')`. Este formato es adecuado para el entrenamiento, pero no para la inferencia.

### MXNet
<a name="how-to-save-mxnet"></a>

MXNet los modelos se deben guardar como un único archivo de símbolos `*-symbol.json` y un único parámetro`*.params files`.

------
#### [ Gluon Models ]

Defina la red neuronal mediante la Clase `HybridSequential`. Esto ejecutará el código al estilo de programación simbólica (a diferencia de programación imperativa).

```
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()
net(x)

# export model
net.export('<model_name>') # this will create model-symbol.json and model-0000.params files

import tarfile
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()
```

Para obtener más información sobre la hibridación de modelos, consulte la documentación sobre la [MXNet hibridación](https://mxnet.apache.org/versions/1.7.0/api/python/docs/tutorials/packages/gluon/blocks/hybridize.html).

------
#### [ Gluon Model Zoo (GluonCV) ]

Los modelos de zoológico modelo GluonCV vienen prehibridados. Así que puede simplemente exportarlos.

```
import numpy as np
import mxnet as mx
import gluoncv as gcv
from gluoncv.utils import export_block
import tarfile

net = gcv.model_zoo.get_model('<model_name>', pretrained=True) # For example, choose <model_name> as resnet18_v1
export_block('<model_name>', net, preprocess=True, layout='HWC')

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()
```

------
#### [ Non Gluon Models ]

Todos los modelos que no son Gluon cuando se guardan en disco utilizan archivos `*-symbol` y `*.params`. Por lo tanto, ya están en el formato correcto para 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

import tarfile
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
<a name="how-to-save-pytorch"></a>

PyTorch los modelos deben guardarse como un archivo de definición (`.pt`o`.pth`) con un tipo de datos de entrada de. `float32`

Para guardar el modelo, utilice el método `torch.jit.trace` seguido del método `torch.save`. Este proceso guarda un objeto en un archivo de disco y, de forma predeterminada, usa python pickle (`pickle_module=pickle`) para guardar los objetos y algunos metadatos. A continuación, convierte el modelo guardado en un archivo tar comprimido.

```
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
import tarfile
with tarfile.open('model.tar.gz', 'w:gz') as f:
    f.add('model.pth')
f.close()
```

Si guarda el modelo con la PyTorch versión 2.0 o posterior, SageMaker Neo obtiene la configuración de entrada del modelo (el nombre y la forma de su entrada) del archivo de definición. En ese caso, no es necesario especificar la configuración de entrada de datos para SageMaker AI al compilar el modelo.

Si quieres evitar que SageMaker Neo obtenga la configuración de entrada, puedes establecer el `_store_inputs` parámetro en. `torch.jit.trace` `False` Si lo hace, debe especificar la configuración de entrada de datos para SageMaker AI al compilar el modelo.

Para obtener más información sobre el `torch.jit.trace` método, consulte [TORCH.JIT.TRACE](https://pytorch.org/docs/stable/generated/torch.jit.trace.html#torch.jit.trace) en la documentación. PyTorch 

### TensorFlow
<a name="how-to-save-tf"></a>

TensorFlow requiere uno `.pb` o un `.pbtxt` archivo y un directorio de variables que contenga variables. Para modelos congelados, solo se necesita un archivo `.pb` o `.pbtxt`.

En el siguiente ejemplo de código se muestra cómo utilizar el comando tar de Linux para comprimir el modelo. Ejecute lo siguiente en su terminal o en un cuaderno de Jupyter (si utiliza un cuaderno de Jupyter, inserte el comando mágico `!` al principio de la instrucción):

```
# 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

# Compress the tar file and save it in a directory called 'model.tar.gz'
!tar czvf model.tar.gz ssd_mobilenet_v2_coco_2018_03_29/frozen_inference_graph.pb
```

Los indicadores de comando utilizados en este ejemplo permiten lo siguiente:
+ `c`: crear un archivo
+ `z`: comprimir el archivo con gzip
+ `v`: mostrar el avance del archivo
+ `f`: especificar el nombre del archivo

### Estimadores integrados
<a name="how-to-save-built-in"></a>

Los estimadores integrados se crean mediante contenedores específicos del marco o contenedores específicos de un algoritmo. Los objetos del estimador, tanto para el algoritmo integrado como para el estimador específico del marco, guardan el modelo en el formato correcto cuando se entrena el modelo con el método integrado `.fit`.

Por ejemplo, puede usar `sagemaker.TensorFlow` a para definir un TensorFlow estimador:

```
from sagemaker.tensorflow import TensorFlow

estimator = TensorFlow(entry_point='mnist.py',
                        role=role,  #param role can be arn of a sagemaker execution role
                        framework_version='1.15.3',
                        py_version='py3',
                        training_steps=1000, 
                        evaluation_steps=100,
                        instance_count=2,
                        instance_type='ml.c4.xlarge')
```

Luego forme al modelo con el método incorporado `.fit`:

```
estimator.fit(inputs)
```

Antes de compilar por último el modelo con el método incorporado `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')
```

También puedes usar la `sagemaker.estimator.Estimator` clase para inicializar un objeto estimador para entrenar y compilar un algoritmo integrado con el método del SDK `compile_model` de Python: SageMaker 

```
import sagemaker
from sagemaker.image_uris import retrieve
sagemaker_session = sagemaker.Session()
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,  #param role can be arn of a sagemaker execution 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')
```

Para obtener más información sobre la compilación de modelos con el SDK de SageMaker Python, consulte[Compilar un modelo (Amazon SageMaker AI SDK)](neo-job-compilation-sagemaker-sdk.md).