目录
先决条件
设置Azure机器学习工作区
准备Azure ML Notebook
下载MNIST数据集
探索MNIST数据集
定义模型
训练模型
评估和注册模型
使用保存的模型进行预测
清理Azure资源
概括
本文展示了使用TensorFlow创建和训练模型,然后在Azure ML上运行模型训练的代码。随后将进行简短的演示,以表明经过训练的模型可以按预期工作。
在本系列中,我们将通过几种方法在Azure上的Python中创建和使用机器学习模型。在第一篇文章中,我们使用带有ML扩展的Visual Studio Code在Azure上训练XGBoost模型。然后,我们使用GitHub Codespaces和GitHub Actions在每次将更改推送到存储库后自动训练PyTorch模型。
在大多数现实生活中的机器学习项目中,最终模型的实际训练需要一个漫长的实验阶段。这个阶段是高度交互的,因此单独使用常规Python代码并不常见。最初,您将主要使用JupyterLab上的Jupyter notebook。本文介绍如何使用TensorFlow模型在Azure机器学习工作区中进行训练。
您可以在GitHub上找到本文的示例代码。
先决条件要遵循本文中的示例,您需要一个Web浏览器并访问Azure订阅。如果您没有订阅,可以注册一个免费的Azure帐户。
设置Azure机器学习工作区如果您已按照前两篇文章中的示例进行操作,则您应该已经创建了Azure:机器学习工作区。如果没有,您可以像任何其他Azure资源一样快速构建它。一种方法是登录Azure门户,单击创建资源,然后在搜索框中键入“机器学习”。
从列表中选择机器学习并单击创建后,您需要输入工作区的详细信息。
您可以输入您喜欢的任何值,但在以下示例中,我们将azureml-rg称为资源组,将demo-ws称为工作区名称。满意后,单击查看 + 创建,然后单击最终向导屏幕上的创建。几分钟后,您可以访问新资源。
剩下的时间我们花在Azure机器学习工作室。要到达那里,请单击Azure门户中的Launch studio或在浏览器中手动输入ml.azure.com。然后,选择您的工作区。
准备Azure ML Notebook创建笔记本的最简单方法是单击Azure机器学习工作室的笔记本磁贴中的立即开始按钮:
在此之前,我们需要添加一个计算。没有它,我们仍然可以创建和编辑笔记本,但不能运行其代码。
要继续,请单击左侧菜单上的计算选项。
在这里,我们有四个选项可供选择:
- 计算实例
- 计算集群
- 推理集群
- 连接的计算机
计算实例是使用笔记本的最佳选择。
创建新的计算实例时,我们需要提供其名称和虚拟机(VM)参数。您可能需要在这里有点创意,因为它在您的Azure区域中必须是独一无二的。如果您预计计算量很大,您可以考虑使用带有GPU的VM。
与用于后台处理的计算集群不同,在需要时提供计算实例并在不使用时将其删除不是自动的。最初,您大部分时间都在编写代码,而不是运行它。因此,GPU无论如何都会处于空闲状态。
当计算运行时,您会在计算实例选项卡上看到其状态:
从这里,我们可以启动JupyterLab或Jupyter。选择您喜欢的任何选项。这对我们的目的无关紧要,所以我们继续使用Jupyter。不过,对于更严肃的开发,JupyterLab提供了许多有用的功能。
当Jupyter启动时,应该只需要一点时间,我们选择New,然后选择Python 3.8 - Tensorflow内核。我们最终得到一个新的空笔记本。
让我们为它命名(例如,“aml-demo-tf-notebook”)。现在我们准备开始了。
下载MNIST数据集与本系列的前两篇文章一样,我们首先下载MNIST手写数字数据集。我们使用Microsoft的Azure Open Datasets 作为来源:
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'))
执行此单元后,数据集文件就可以使用了。
探索MNIST数据集将数据集下载到我们的ML工作区后,我们可以对其进行探索。首先,我们需要加载它。这部分代码是特定于数据集的,在我们的例子中,是从Azure开放数据集示例中借用的。如果您想使用您的数据,则需要相应地更新或替换它。
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
除了简单地加载数据外,该load_dataset方法还对像素值(范围从0-255到0-1)进行归一化,并将输出整形为TensorFlow框架所期望的尺寸。
要加载我们的数据集,我们运行:
X_train, y_train, X_test, y_test = load_dataset(DATA_FOLDER)
我们可以确认,我们预计训练集中有60,000张单色图像(每张28 x 28像素):
让我们看看里面有什么:
def show_images(images, labels):
images_cnt = len(images)
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])
运行此单元格将向我们展示训练集中的前十张标记图像:
我们有数据,所以现在我们可以开始研究模型了。为了使事情符合目的,我们将创建一个简单的卷积神经网络(CNN),它接受28 x 28矩阵,并返回10位数字中的每一个的概率分数。
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"])
现在,我们可以开始训练了。如果我们想在Azure ML实验中保留我们的训练历史,我们需要首先处理它:
from azureml.core import Workspace, Experiment
import mlflow, mlflow.tensorflow
SUBSCRIPTION=""
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()
使用上面的代码,我们创建新的实验(aml-demo-tf-notebook-training),通知MLflow框架使用Azure ML工作区进行跟踪,开始新的运行,最后让MLflow自动记录TensorFlow训练进度。这种自动记录功能可确保模型参数和训练进度跟踪,而无需额外的手动步骤。
有了所有这些部分,我们终于可以开始训练了。为了确保运行之间的可重复结果,我们使用恒定的随机馈送:
tf.random.set_seed(101)
model.fit(X_train, y_train, epochs=5)
mlflow.end_run()
无论所选计算实例VM的大小如何,我们的简单模型和相对简单的数据集都不会花费很长时间。
由于我们的跟踪配置,我们可以使用机器学习工作室中的“实验”选项卡检查其进度和指标(在训练期间和之后):
如果训练您的模型花费的时间太长,则可能是重新考虑计算VM大小的时候了。您可以随时返回机器学习工作室的计算部分创建更强大的VM实例,然后重新运行笔记本。或者,您可以将训练代码保存在单独的文件中,然后在计算集群上运行训练。后者使用Visual Studio Code稍微容易一些,如前两篇文章所示。
评估和注册模型训练结束后,我们可以检查我们的模型如何在以前看不见的测试数据上工作。最简单的方法是使用模型的评估方法:
我们有98%的准确率。如果模型对我们来说足够好,我们可以保存它并注册以备将来使用。保存TensorFlow模型有多种选择。我们使用单文件HDF5格式的便携性。最后,保存模型后,我们可以将其注册到Azure:机器学习工作区:
from azureml.core.model import Model
model.save(‘mnist-tf-model.h5')
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__)
训练后的模型现在可供将来使用。
要加载在Azure:机器学习工作区中注册的模型,我们使用以下代码:
aml_model = Model(workspace=ws, name='mnist-tf-model', version=registered_model.version)
downloaded_model_filename = aml_model.download(exist_ok=True)
downloaded_model = tf.keras.models.load_model(downloaded_model_filename)
如果您在与训练不同的笔记本会话中运行此代码,请确保提供正确的版本参数值。
让我们检查一下我们加载的内容:
现在我们可以使用该模型进行预测。
preds = downloaded_model.predict(X_test).argmax(axis=1)
我们可以快速检查它与我们的真实情况的比较:
正如我们所见,前三个预测值和后三个预测值都是正确的。
如果我们仍然对我们的模型没有信心,我们可以使用与之前相同的方法来查看为测试图像预测的标签:
show_images(X_test[:10], preds[:10])
现在,让我们使用完整的测试数据集来评估预测。我们可以再次使用该downloaded_model.evaluate方法,但为了避免重新运行预测,我们还可以依赖该scikit-learn方法:
from sklearn.metrics import accuracy_score
accuracy_score(y_test, preds)
我们应该得到与训练后直接相同的值,0.9864。
清理Azure资源使用笔记本完成工作后,请记住停止并删除不再需要的资源。这样做的一个极端方法是删除整个资源组azureml-rg。如果您想保留您的数据,您应该做的最低限度是停止所有计算实例:
与我们在前几篇文章中使用的计算集群不同,计算实例在配置的不活动时间段后不会自动停止。
概括在整个系列中,你已经了解了我们如何以多种不同的方式使用Python来使用Azure机器学习创建和训练模型。这三部分系列的最后一篇文章展示了如何使用Azure ML笔记本训练TensorFlow模型。
在本文中,您体验了如何不费吹灰之力地调整示例代码来处理您自己的图像的任何图像分类任务。很可能,您有不同数量的通道(MNIST 图像是单色的)和类别。在这种情况下,您必须适当地更改型号代码和load_dataset方法。
若要了解开始使用Azure机器学习所需的一切,请查看快速入门:创建工作区资源。
https://www.codeproject.com/Articles/5321728/Python-Machine-Learning-on-Azure-Part-3-Creating-a