<jupyter_start><jupyter_text>Migrating scripts from Framework Mode to Script ModeThis notebook focus on how to migrate scripts using Framework Mode to Script Mode. The original notebook using Framework Mode can be find here https://github.com/awslabs/amazon-sagemaker-examples/blob/4c2a93114104e0b9555d7c10aaab018cac3d7c04/sagemaker-python-sdk/tensorflow_distributed_mnist/tensorflow_local_mode_mnist.ipynb  Set up the environment<jupyter_code>import os
import subprocess
import sagemaker
from sagemaker import get_execution_role

sagemaker_session = sagemaker.Session()

role = get_execution_role()<jupyter_output><empty_output><jupyter_text>Download the MNIST dataset<jupyter_code>import utils
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf

data_sets = input_data.read_data_sets('data', dtype=tf.uint8, reshape=False, validation_size=5000)

utils.convert_to(data_sets.train, 'train', 'data')
utils.convert_to(data_sets.validation, 'validation', 'data')
utils.convert_to(data_sets.test, 'test', 'data')<jupyter_output><empty_output><jupyter_text>Upload the dataWe use the ```sagemaker.Session.upload_data``` function to upload our datasets to an S3 location. The return value inputs identifies the location -- we will use this later when we start the training job.<jupyter_code>inputs = sagemaker_session.upload_data(path='data', key_prefix='data/mnist')<jupyter_output><empty_output><jupyter_text>Construct an entry point script for training On this example, we assume that you aready have a Framework Mode training script named `mnist.py`:<jupyter_code>!pygmentize 'mnist.py'<jupyter_output><empty_output><jupyter_text>The training script `mnist.py` include the Framework Mode functions ```model_fn```, ```train_input_fn```, ```eval_input_fn```, and ```serving_input_fn```. We need to create a entrypoint script that uses the functions above to create a ```tf.estimator```:<jupyter_code>%%writefile train.py

import argparse
# import original framework mode script
import mnist

import tensorflow as tf

if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    # read hyperparameters as script arguments
    parser.add_argument('--training_steps', type=int)
    parser.add_argument('--evaluation_steps', type=int)

    args, _ = parser.parse_known_args()

    # creates a tf.Estimator using `model_fn` that saves models to /opt/ml/model
    estimator = tf.estimator.Estimator(model_fn=mnist.model_fn, model_dir='/opt/ml/model')


    # creates parameterless input_fn function required by the estimator
    def input_fn():
        return mnist.train_input_fn(training_dir='/opt/ml/input/data/training', params=None)


    train_spec = tf.estimator.TrainSpec(input_fn, max_steps=args.training_steps)


    # creates parameterless serving_input_receiver_fn function required by the exporter
    def serving_input_receiver_fn():
        return mnist.serving_input_fn(params=None)


    exporter = tf.estimator.LatestExporter('Servo',
                                           serving_input_receiver_fn=serving_input_receiver_fn)


    # creates parameterless input_fn function required by the evaluation
    def input_fn():
        return mnist.eval_input_fn(training_dir='/opt/ml/input/data/training', params=None)


    eval_spec = tf.estimator.EvalSpec(input_fn, steps=args.evaluation_steps, exporters=exporter)
    
    # start training and evaluation
    tf.estimator.train_and_evaluate(estimator=estimator, train_spec=train_spec, eval_spec=eval_spec)<jupyter_output><empty_output><jupyter_text>Changes in the SageMaker TensorFlow estimatorWe need to create a TensorFlow estimator pointing to ```train.py``` as the entrypoint:<jupyter_code>from sagemaker.tensorflow import TensorFlow

mnist_estimator = TensorFlow(entry_point='train.py',
                             dependencies=['mnist.py'],
                             role='SageMakerRole',
                             framework_version='1.13',
                             hyperparameters={'training_steps':10, 'evaluation_steps':10},
                             py_version='py3',
                             train_instance_count=1,
                             train_instance_type='local')

mnist_estimator.fit(inputs)<jupyter_output><empty_output><jupyter_text>Deploy the trained model to prepare for predictionsThe deploy() method creates an endpoint (in this case locally) which serves prediction requests in real-time.<jupyter_code>mnist_predictor = mnist_estimator.deploy(initial_instance_count=1, instance_type='local')<jupyter_output><empty_output><jupyter_text>Invoking the endpoint<jupyter_code>import numpy as np
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)

for i in range(10):
    data = mnist.test.images[i].tolist()

    predict_response = mnist_predictor.predict(data)
    
    print("========================================")
    label = np.argmax(mnist.test.labels[i])
    print("label is {}".format(label))
    print("prediction is {}".format(predict_response))<jupyter_output><empty_output><jupyter_text>Clean-upDeleting the local endpoint when you're finished is important since you can only run one local endpoint at a time.<jupyter_code>mnist_estimator.delete_endpoint()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09952963311382879, 'fraction_numerical': 0.008090310442144873, 'mean_word_length': 4.887043189368771, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '1713', 'license': 'Apache-2.0', 'n_tokens_mistral': 1666, 'n_tokens_neox': 1598, 'n_words': 362, 'path': 'sagemaker-python-sdk/tensorflow_moving_from_framework_mode_to_script_mode/tensorflow_moving_from_framework_mode_to_script_mode.ipynb', 'repo_name': 'dleen/amazon-sagemaker-examples', 'size': '5315'}