ValueError: не найдено пакетов SavedModel! при попытке развернуть модель TF2.0 в SageMaker - PullRequest
0 голосов
/ 23 января 2020

Я пытаюсь развернуть модель TF2.0 в SageMaker. До сих пор мне удалось обучить модель и сохранить ее в корзину S3, но когда я вызываю метод .deploy(), я получаю следующую ошибку из облачного хранилища

ValueError: no SavedModel bundles found!

Вот мой учебный скрипт:

### Code to add in a tensorflow_estimator.py file

import argparse
import os
import pathlib
import tensorflow as tf


if __name__ == '__main__':


    parser = argparse.ArgumentParser()

    # hyperparameters sent by the client are passed as command-line arguments to the script.
    parser.add_argument('--epochs', type=int, default=10)
    parser.add_argument('--batch_size', type=int, default=100)
    parser.add_argument('--learning_rate', type=float, default=0.1)

    # Data, model, and output directories
    parser.add_argument('--output-data-dir', type=str, default=os.environ.get('SM_OUTPUT_DATA_DIR'))
    parser.add_argument('--model-dir', type=str, default=os.environ.get('SM_MODEL_DIR'))
    parser.add_argument('--train', type=str, default=os.environ.get('SM_CHANNEL_TRAIN'))
    parser.add_argument('--test', type=str, default=os.environ.get('SM_CHANNEL_TEST'))

    args, _ = parser.parse_known_args()

    print("##### ARGS ##### \n{}".format(args))

    # Get files 
    path = pathlib.Path(args.train)

    # Print out folder content 
    for item in path.iterdir():
        print("##### DIRECTORIES ##### \n{}".format(item))

    # Get all images 
    all_images = list(path.glob("*/*"))
    all_image_paths = [str(path) for path in list(path.glob("*/*"))]

    # Transform images into tensors
    def preprocess_and_load_images(path):
        image = tf.io.read_file(path)
        image = tf.image.decode_jpeg(image, channels=3)
        image = tf.image.resize(image, [192, 192])
        return image

    # Apply preprocessing function
    ds_paths = tf.data.Dataset.from_tensor_slices(all_image_paths)
    ds_images = ds_paths.map(preprocess_and_load_images)

    # Map Labels
    labels = []
    for data in path.iterdir():  
        if data.is_dir():               
            labels += [data.name]    

    labels_index = {}
    for i,label in enumerate(labels):
        labels_index[label]=i

    print("##### Label Index ##### \n{}".format(labels_index))

    all_image_labels = [labels_index[path.parent.name] for path in list(path.glob("*/*"))]

    # Create a tf Dataset
    labels_ds = tf.data.Dataset.from_tensor_slices(all_image_labels)

    # Zip train and labeled dataset
    full_ds = tf.data.Dataset.zip((ds_images, labels_ds))

    # Shuffle Dataset and batch it 
    full_ds = full_ds.shuffle(len(all_images)).batch(args.batch_size)

    # Create a pre-trained model 
    base_model = tf.keras.applications.InceptionV3(input_shape=(192,192,3), 
                                               include_top=False,
                                               weights = "imagenet"
                                               )

    base_model.trainable = False
    model = tf.keras.Sequential([
                base_model,
                tf.keras.layers.GlobalAveragePooling2D(),
                tf.keras.layers.Dense(len(labels), activation="softmax")
            ])

    initial_learning_rate = args.learning_rate

    lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
        initial_learning_rate,
        decay_steps=1000,
        decay_rate=0.96,
        staircase=True) 

    model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate = lr_schedule),
              loss = tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics = [tf.keras.metrics.SparseCategoricalAccuracy()])

    # Train the model
    model.fit(full_ds, epochs=args.epochs)

    # Save the model 
    model.save(os.path.join(args.model_dir, "tf_model"), save_format="tf")

def model_fn(model_dir):
    classifier = tf.keras.models.load_model(os.path.join(model_dir, "tf_model"))
    return classifier

А вот код, который я написал в Colab

from sagemaker.tensorflow import TensorFlow

tf_estimator = TensorFlow(entry_point='tensorflow_estimator.py', 
                          role=role,
                          train_instance_count=1, 
                          train_instance_type='ml.m5.large',
                          framework_version='2.0.0', 
                          sagemaker_session=sagemaker_session,
                          output_path=s3_output_location,
                          hyperparameters={'epochs': 1,
                                           'batch_size': 30,
                                           'learning_rate': 0.001},
                          py_version='py3')


tf_estimator.fit({"train":train_data})

from sagemaker.tensorflow.serving import Model

model = Model(model_data='s3://path/to/model.tar.gz', 
              role=role,
              framework_version="2.0.0",
              sagemaker_session=sagemaker_session)

predictor = model.deploy(initial_instance_count=1, instance_type='ml.m5.large')

Я уже пытался посмотреть эту ветку , но На самом деле у меня нет проблем с версиями в моем файле tar.gz, поскольку структура выглядит следующим образом:

├── assets
├── saved_model.pb
└── variables
    ├── variables.data-00000-of-00001
    └── variables.index

Я чувствую, что могу ошибаться при определении model_fn() в моем учебном скрипте, но определенно не не то, что заменить это. Ребята, у вас есть идея?

Большое спасибо за вашу помощь!

1 Ответ

0 голосов
/ 23 января 2020

Я на самом деле пытался изменить свой учебный скрипт следующим образом:

### Code to add in a tensorflow_estimator.py file

import argparse
import os
import pathlib
import tensorflow as tf


if __name__ == '__main__':


    parser = argparse.ArgumentParser()

    # hyperparameters sent by the client are passed as command-line arguments to the script.
    parser.add_argument('--epochs', type=int, default=10)
    parser.add_argument('--batch_size', type=int, default=100)
    parser.add_argument('--learning_rate', type=float, default=0.1)

    # Data, model, and output directories
    parser.add_argument('--output-data-dir', type=str, default=os.environ.get('SM_OUTPUT_DATA_DIR'))
    parser.add_argument('--model-dir', type=str, default=os.environ.get('SM_MODEL_DIR'))
    parser.add_argument('--train', type=str, default=os.environ.get('SM_CHANNEL_TRAIN'))
    parser.add_argument('--test', type=str, default=os.environ.get('SM_CHANNEL_TEST'))

    args, _ = parser.parse_known_args()

    print("##### ARGS ##### \n{}".format(args))

    # Get files 
    path = pathlib.Path(args.train)

    # Print out folder content 
    for item in path.iterdir():
        print("##### DIRECTORIES ##### \n{}".format(item))

    # Get all images 
    all_images = list(path.glob("*/*"))
    all_image_paths = [str(path) for path in list(path.glob("*/*"))]

    # Transform images into tensors
    def preprocess_and_load_images(path):
        image = tf.io.read_file(path)
        image = tf.image.decode_jpeg(image, channels=3)
        image = tf.image.resize(image, [192, 192])
        return image

    # Apply preprocessing function
    ds_paths = tf.data.Dataset.from_tensor_slices(all_image_paths)
    ds_images = ds_paths.map(preprocess_and_load_images)

    # Map Labels
    labels = []
    for data in path.iterdir():  
        if data.is_dir():               
            labels += [data.name]    

    labels_index = {}
    for i,label in enumerate(labels):
        labels_index[label]=i

    print("##### Label Index ##### \n{}".format(labels_index))

    all_image_labels = [labels_index[path.parent.name] for path in list(path.glob("*/*"))]

    # Create a tf Dataset
    labels_ds = tf.data.Dataset.from_tensor_slices(all_image_labels)

    # Zip train and labeled dataset
    full_ds = tf.data.Dataset.zip((ds_images, labels_ds))

    # Shuffle Dataset and batch it 
    full_ds = full_ds.shuffle(len(all_images)).batch(args.batch_size)

    # Create a pre-trained model 
    base_model = tf.keras.applications.InceptionV3(input_shape=(192,192,3), 
                                               include_top=False,
                                               weights = "imagenet"
                                               )

    base_model.trainable = False
    model = tf.keras.Sequential([
                base_model,
                tf.keras.layers.GlobalAveragePooling2D(),
                tf.keras.layers.Dense(len(labels), activation="softmax")
            ])

    initial_learning_rate = args.learning_rate

    lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
        initial_learning_rate,
        decay_steps=1000,
        decay_rate=0.96,
        staircase=True) 

    model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate = lr_schedule),
              loss = tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics = [tf.keras.metrics.SparseCategoricalAccuracy()])

    # Train the model
    model.fit(full_ds, epochs=args.epochs)

    # Save the model 
    model.save(os.path.join(args.model_dir, "tensorflow_model/1"), save_format="tf")

Кажется, важно иметь числовое имя для вашей папки.

...