<jupyter_start><jupyter_text>Dataset Download<jupyter_code>import os
import urllib.request
DATA_FOLDER = os.path.join(os.getcwd(), 'datasets/mnist-data')
DATASET_BASE_URL = 'https://azureopendatastorage.blob.core.windows.net/mnist/'
os.makedirs(DATA_FOLDER, exist_ok=True)
urllib.request.urlretrieve(
    os.path.join(DATASET_BASE_URL, 'train-images-idx3-ubyte.gz'),
    filename=os.path.join(DATA_FOLDER, 'train-images.gz'))
urllib.request.urlretrieve(
    os.path.join(DATASET_BASE_URL, 'train-labels-idx1-ubyte.gz'),
    filename=os.path.join(DATA_FOLDER, 'train-labels.gz'))
urllib.request.urlretrieve(
    os.path.join(DATASET_BASE_URL, 't10k-images-idx3-ubyte.gz'),
    filename=os.path.join(DATA_FOLDER, 'test-images.gz'))
urllib.request.urlretrieve(
    os.path.join(DATASET_BASE_URL, 't10k-labels-idx1-ubyte.gz'),
    filename=os.path.join(DATA_FOLDER, 'test-labels.gz'))<jupyter_output><empty_output><jupyter_text>Dataset Load and Exploration<jupyter_code>import gzip
import struct
import numpy as np
def load_dataset(dataset_path):
    def unpack_mnist_data(filename: str, label=False):
        with gzip.open(filename) as gz:
            struct.unpack('I', gz.read(4))
            n_items = struct.unpack('>I', gz.read(4))
            if not label:
                n_rows = struct.unpack('>I', gz.read(4))[0]
                n_cols = struct.unpack('>I', gz.read(4))[0]
                res = np.frombuffer(gz.read(n_items[0] * n_rows * n_cols), dtype=np.uint8)
                res = res.reshape(n_items[0], n_rows * n_cols) / 255.0
            else:
                res = np.frombuffer(gz.read(n_items[0]), dtype=np.uint8)
                res = res.reshape(-1)
        return res
    
    X_train = unpack_mnist_data(os.path.join(dataset_path, 'train-images.gz'), False)
    y_train = unpack_mnist_data(os.path.join(dataset_path, 'train-labels.gz'), True)
    X_test = unpack_mnist_data(os.path.join(dataset_path, 'test-images.gz'), False)
    y_test = unpack_mnist_data(os.path.join(dataset_path, 'test-labels.gz'), True)

    return X_train.reshape(-1,28,28,1), y_train, X_test.reshape(-1,28,28,1), y_test
X_train, y_train, X_test, y_test = load_dataset(DATA_FOLDER)
print(X_train.shape)
import matplotlib.pyplot as plt
def show_images(images, labels):
    images_cnt = len(images)
    assert images_cnt <= 10, f"Number of images cannot exceed 10. The provided list has {images_cnt} elements."
    assert images_cnt == len(labels), f"Number of images ({images_cnt}) should be equal to number of labels ({len(labels)})"
    f, axarr = plt.subplots(nrows=1, ncols=images_cnt, figsize=(16,16))
    for idx in range(images_cnt):
        img = images[idx]
        lab = labels[idx]
        axarr[idx].imshow(img, cmap='gray_r')
        axarr[idx].title.set_text(lab)
        axarr[idx].axis('off')

    plt.show()    
show_images(X_train[:10], y_train[:10])<jupyter_output><empty_output><jupyter_text>TensorFlow Model<jupyter_code>import tensorflow as tf
def create_tf_model():
    model = tf.keras.models.Sequential(
        [
            tf.keras.layers.Conv2D(filters=10, kernel_size=5, input_shape=(28,28,1), activation='relu'),
            tf.keras.layers.MaxPool2D(pool_size=(2,2)),
            tf.keras.layers.Conv2D(filters=20, kernel_size=5, activation='relu'),
            tf.keras.layers.Dropout(rate=0.2),
            tf.keras.layers.MaxPool2D(pool_size=(2,2)),
            tf.keras.layers.Flatten(),
            tf.keras.layers.Dense(320, activation='relu'),
            tf.keras.layers.Dense(50, activation='relu'),
            tf.keras.layers.Dropout(0.2),
            tf.keras.layers.Dense(10, activation='relu')
        ]
    )
    
    return model
model = create_tf_model()
model.build()
model.summary()
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(optimizer="adam", loss=loss_fn, metrics=["accuracy"])<jupyter_output><empty_output><jupyter_text>Prepare Azure ML Experiment<jupyter_code>from azureml.core import Workspace, Experiment
import mlflow, mlflow.tensorflow
SUBSCRIPTION="<your-subscription-id>"
GROUP="azureml-rg"
WORKSPACE="demo-ws"
ws = Workspace(
    subscription_id=SUBSCRIPTION,
    resource_group=GROUP,
    workspace_name=WORKSPACE,
)
experiment = Experiment(ws, "aml-demo-tf-notebook-training")
mlflow.set_tracking_uri(ws.get_mlflow_tracking_uri())
mlflow.start_run(experiment_id=experiment.id)
mlflow.tensorflow.autolog()<jupyter_output><empty_output><jupyter_text>Start Training<jupyter_code>tf.random.set_seed(101)
model.fit(X_train, y_train, epochs=5)
mlflow.end_run()<jupyter_output><empty_output><jupyter_text>Model Evaluation and Registration in AzureML<jupyter_code>model.evaluate(X_test, y_test)
model.save('mnist-tf-model.h5')
from azureml.core.model import Model
registered_model = Model.register(
    workspace=ws,
    model_name='mnist-tf-model',
    model_path='mnist-tf-model.h5',
    model_framework=Model.Framework.TENSORFLOW,
    model_framework_version=tf.__version__)
registered_model<jupyter_output><empty_output><jupyter_text>Load Registered Model<jupyter_code>aml_model = Model(workspace=ws, name='mnist-tf-model', version=registered_model.version)
downloaded_model_filename = aml_model.download(exist_ok=True)
print(downloaded_model_filename)
downloaded_model = tf.keras.models.load_model(downloaded_model_filename)
downloaded_model.summary()<jupyter_output>Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 24, 24, 10)        260       
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 12, 12, 10)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 8, 8, 20)          5020      
_________________________________________________________________
dropout (Dropout)            (None, 8, 8, 20)          0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 4, 4, 20)          0         
_________________________________________________________________
flatten (Flatten)            (None, 320)               0         
________________________________________________________[...]<jupyter_text>Evaluate Loaded Model<jupyter_code>preds = downloaded_model.predict(X_test).argmax(axis=1)
print(preds)
print(y_test)
show_images(X_test[:10], preds[:10])
from sklearn.metrics import accuracy_score
accuracy_score(y_test, preds)
downloaded_model.evaluate(X_test, y_test)<jupyter_output>313/313 [==============================] - 1s 4ms/step - loss: 0.0451 - accuracy: 0.9864
{'fraction_non_alphanumeric': 0.13738538893818397, 'fraction_numerical': 0.023070097604259095, 'mean_word_length': 4.393141945773524, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 35, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '288665', 'license': 'MIT', 'n_tokens_mistral': 2384, 'n_tokens_neox': 2285, 'n_words': 335, 'path': '3-aml-tensorflow-samples/aml-demo-tf-notebook.ipynb', 'repo_name': 'szjarek/articles-AzureML-with-Python', 'size': '6762'}