使用 Python SDK 记录和上传数据
本教程介绍如何使用 Python SDK 进行创建、加载、上传 Run 和 Artifact,设定超参数,记录指标等操作。
创建 Run
基本方法
在模型的训练脚本中,你需要首先创建一个 Run,通过调用 t9k.em.create_run()
函数。其返回的 Run
实例即代表了一次训练的运行。此方法调用后,Run 将被创建,具有状态“Running”,其本地文件默认保存在相对路径 .em/runs
下,每个 Run 拥有一个独立的名为 <run_name>_<date>_<time>_<random_suffix>
(称为该 Run 的备用名称)的子目录。
最基本的初始化方法只需要提供名称作为参数。
from t9k import em
run = em.create_run(name='mnist_torch') # 返回Run实例
自动上传
如果想要自动异步上传 Run 的更新,可以设定 auto_upload=True
,并提供文件夹路径,以及设定是否创建不存在的各级文件夹。在这种情况下,你在创建 Run 之前需要先登录到 AIStore 服务器。
run = em.create_run(name='mnist_torch',
auto_upload=True, # 启用自动上传
folder='new-folder', # 文件夹路径
make_folder=True) # 创建不存在的各级文件夹
如果目标文件夹已经存在同名的 Run,则需要指定 conflict_strategy
参数以处理冲突,参数接受以下值:
'skip'
:跳过上传。'error'
:错误退出。'new'
:以 Run 的备用名称上传。'replace'
:替换同名的 Run。
例如,运行以下代码两次,第二次创建的 Run 会以类似 mnist_torch_231231_235959_61p5jc
的名称被上传到 new-folder
文件夹下。
run = em.create_run(name='mnist_torch',
auto_upload=True,
folder='new-folder',
make_folder=True,
conflict_strategy='new')
提供标签和描述
你可以为创建的 Run 提供用于分类或介绍的标签或描述。
run = em.create_run(
name='mnist_torch',
labels=['torch', 'CNN'], # 标签
description= # 描述
'Train a simple CNN model that classifies images of handwritten digits.')
提供配置文件
你可以将上面的所有配置(以及下面将要提到的超参数)都写进一个 YAML 文件里,然后传入该配置文件的路径即可。
run = em.create_run(config_path='./run_config.yaml') # 提供配置文件
其中 run_config.yaml
的内容如下:
name: mnist_torch
auto_upload: true
folder: new-folder
make_folder: true
conflict_strategy: new
labels:
- torch
- CNN
description: Train a simple CNN model that classifies images of handwritten digits.
设定超参数
基本方法
超参数是影响模型训练效果的重要因素,记录训练的超参数十分必要,尤其是当你聚焦于某几个特定的超参数时。Run
实例的 hparams
属性是一个容器对象,用于保存你想要记录的所有超参数,你可以像操作 Python 字典一样操作它。一种推荐的设定超参数的方法是调用一次该容器对象的 update()
方法完成所有超参数的设定。
run.hparams.update({
'batch_size': 32,
'epochs': 10,
'learning_rate': 0.001,
'conv_channels': 32,
'conv_kernel_size': 3,
'maxpool_size': 2,
'linear_features': 64,
})
hparams = run.hparams # 便于之后访问
另一种推荐的方法是在创建 Run 的时候就传入所有超参数,此时可以将超参数也写进配置文件。
run = em.create_run(
name='mnist_torch',
hparams={
'batch_size': 32,
'epochs': 10,
'learning_rate': 0.001,
'conv_channels': 32,
'conv_kernel_size': 3,
'maxpool_size': 2,
'linear_features': 64,
})
# 或
run = em.create_run(config_path='./run_config.yaml')
其中 run_config.yaml
的内容如下:
name: mnist_torch
hparams:
batch_size: 32
epochs: 10
learning_rate: 0.001
conv_channels: 32
conv_kernel_size: 3
maxpool_size: 2
linear_features: 64
当然,你也可以多次调用 update()
方法,或者使用类似 Python 字典的键值对赋值方法设定单个超参数。
run.hparams['batch_size'] = 32
设定完成之后,使用这些超参数配置模型,同样使用类似 Python 字典的键值对访问方法。
from tensorflow.keras import layers, models, optimizers
model = models.Sequential()
model.add(layers.Conv2D(hparams['conv_channels'], # 使用超参数配置模型
hparams['conv_kernel_size'],
input_shape=(28, 28, 1)))
...
optimizer = optimizers.Adam(learning_rate=hparams['learning_rate'])
model.compile(
optimizer=optimizer,
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
...
model.fit(train_images,
train_labels,
batch_size=hparams['batch_size'],
epochs=hparams['epochs'])
设定作为标记的超参数
在上面的示例中,所有超参数都是直接传入各函数以配置模型。你也可以设定一些作为标记的超参数,例如网络类型、优化器类型、损失函数类型、激活函数类型等,以便日后快速回顾重要信息。
run.hparams.update({
'network_structure': 'CNN',
'optimizer': 'Adam',
'loss': 'sparse categorical crossentropy',
'linear_acti': 'relu',
})
配合 argparse 模块使用
许多训练脚本的超参数都是从命令行传入,由 argparse
模块解析。这些超参数可以方便地转换为字典对象并传入 update()
方法。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(...)
args = parser.parse_args()
run.hparams.update(args.__dict__)
记录指标
手动记录
Run
实例的 log()
方法用于记录模型在训练、验证或测试过程中产生的指标。被传入的字典对象会被作为指标记录,与此同时还需要提供指标的类型、当前的全局训练步数以及(可选的)当前的回合数。
# PyTorch模型
for epoch in range(1, epochs + 1):
model.train()
for step, (data, target) in enumerate(train_loader, 1):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
if step % 500 == 0:
train_loss = loss.item()
logging.info(
'epoch {:d}/{:d}, batch {:5d}/{:d} with loss: {:.4f}'.
format(epoch, epochs, step, steps_per_epoch, train_loss))
global_step = (epoch - 1) * steps_per_epoch + step
run.log(
type='train', # 指标类型
metrics={'loss': train_loss}, # 指标名称及相应值
step=global_step, # 当前全局步数
epoch=epoch) # 当前回合数
自动记录
对于建立在 Keras API 上的模型,更简单的方法是在模型的训练和测试方法中分别添加回调 t9k.em.keras.EMFitCallback
和 t9k.em.keras.EMEvalCallback
的实例。回调会相应地调用 log()
方法以自动记录各指标并同步到服务器。
# Keras模型
# 训练/验证过程和测试过程分别使用不同的回调
from t9k.em.keras import EMFitCallback, EMEvalCallback
model.fit(train_images,
train_labels,
epochs=10,
validation_split=0.2,
callbacks=EMFitCallback(run))
model.evaluate(test_images,
test_labels,
callbacks=EMEvalCallback(run))
结束 Run
模型的训练与测试全部完成后,你需要结束 Run,通过调用 Run
实例的 finish()
方法。此方法调用后,Run 的状态将更新为“Complete”。
run.finish()
创建 Artifact
基本方法
如要记录和保存与训练过程有关的文件,你需要创建一个 Artifact,通过调用 t9k.em.create_artifact()
函数。此方法调用后,Artifact 将被创建,其本地文件默认保存在相对路径 .em/artifacts
下。与 Run 相同,每个 Artifact 拥有一个独立的名为 <artifact_name>
最基本的初始化方法只需要提供名称作为参数。
dateset_artifact = em.create_artifact(name='mnist_dataset')
提供标签和描述
你可以为创建的 Artifact 提供用于分类或介绍的标签或描述。
dateset_artifact = em.create_artifact(
name='mnist_dataset',
labels=['dataset', 'MNIST'], # 标签
description='Image dataset of handwritten digits.') # 描述
为 Artifact 添加文件
与训练过程有关的文件通过 Artifact
实例的 add_file()
和 add_dir()
方法添加到 Artifact 中。
dateset_artifact.add_file(file_path='./mnist.npz') # 添加单个文件
dateset_artifact.add_dir(dir_path='./mnist/') # 添加目录
Artifact 中的文件对象具有层次结构,你可以指定文件或目录位于 Artifact 的何路径下。
dateset_artifact.add_file(file_path='./mnist.npz', obj_path='dataset/')
dateset_artifact.add_dir(dir_path='./mnist/', obj_path='dataset/')
还可以通过 add_reference()
方法为 Artifact 添加一个网络文件的引用。
dateset_artifact.add_reference(uri='https://storage.googleapis.com/cvdf-datasets/mnist/train-images-idx3-ubyte.gz', obj_path='dataset/')
标记 Artifact 为 Run 的输入输出
为了构成 Run 与 Artifact 之间的数据流,需要调用 Run
实例的 mark_input()
和 mark_output()
方法以标记 Artifact
实例为其输入或输出。
run.mark_input(dateset_artifact)
run.mark_output(model_artifact)
上传数据
基本方法
上传数据之前,你需要先登录到 AIStore 服务器,通过调用 t9k.em.login()
函数。
em.login(ais_host='<your-server-host>', api_key='<your-api-key>')
然后调用 Run
或 Artifact
实例的 upload()
方法。
run.upload()
artifact.upload()
上传本地保存的数据
你也可以在训练结束之后将本地保存的数据上传到 AIStore 服务器,以应对训练时无网络连接、最初未打算上传、误删服务器中的数据等情形。
首先登录到 AIStore 服务器,然后加载保存在本地的 Run 或 Artifact,调用其 upload()
方法。
run = em.load_run(path='.em/runs/mnist_torch_231222_141932_61p5jc')
run.upload(folder='default', make_folder=True)
artifact = em.load_artifact(path='.em/runs/mnist_torch_saved_model_230908_165433_tou3ai')
artifact.upload(folder='default', make_folder=True)
下一步
- 进一步学习如何在单设备训练场景下追踪模型训练