Skip to main content

Azure机器学习一天教程 - 在云平台上训练您的第一个机器学习模型

分类:  Azure机器学习 标签:  #Azure #人工智能 #Python #机器学习 发布于: 2023-06-11 21:33:30

我们前面学习了如何设置云开发环境和本地的开发环境,同时我们也演示一个在云平台上的一个Hello, World, 如果大家需要再回去看看这两篇的话,可以使用文章末尾的链接查看就可以了,我们本章学习如何真正在云平台上训练你的第一个机器学习模型。

先决条件

  • 已经有了Azure订阅,并且创建了Azure Machine Learning的资源。
  • 设置了开发环境。

安装用于本地测试的包

提示
如果你不计划在本地测试训练脚本的话,无需准备本地包,Azure上用于计算的机器,默认都已经预置安装了必要的软件包,并且经过测试。

启动Anaconda的命令行之后,激活用于测试的Python环境:

conda activate myl
//安装必要的包:
conda install pytorch torchvision torchaudio cudatoolkit=10.2 -c pytorch

由于我们这个实例是基于pytorch的,所以需要安装必要的包。

安装好,请一次使用Azure cli设定云平台,登录,选定默认的订阅。

编写脚本

训练脚本

创建一个新的项目目录:

mkdir firstmodel
cd firstmodel
mkdir src

在目录src里创建一个model.py的文件,用于定义神经网络

import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)
    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

保存该文件之后,再在该目录下创建一个训练脚本,该训练脚本使用PyTorchtorchvision.datasetCIFAR10数据集, 在目录src里创建一个训练脚本train.py:

import torch
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms

from model import Net

# download CIFAR 10 data
trainset = torchvision.datasets.CIFAR10(
   root="../data",
   train=True,
   download=True,
   transform=torchvision.transforms.ToTensor(),
)
trainloader = torch.utils.data.DataLoader(
   trainset, batch_size=4, shuffle=True, num_workers=2
)

if __name__ == "__main__":

   # define convolutional network
   net = Net()

   # set up pytorch loss /  optimizer
   criterion = torch.nn.CrossEntropyLoss()
   optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

   # train the network
   for epoch in range(2):

       running_loss = 0.0
       for i, data in enumerate(trainloader, 0):
           # unpack the data
           inputs, labels = data

           # zero the parameter gradients
           optimizer.zero_grad()

           # forward + backward + optimize
           outputs = net(inputs)
           loss = criterion(outputs, labels)
           loss.backward()
           optimizer.step()

           # print statistics
           running_loss += loss.item()
           if i % 2000 == 1999:
               loss = running_loss / 2000
               print(f"epoch={epoch + 1}, batch={i + 1:5}: loss {loss:.2f}")
               running_loss = 0.0

   print("Finished Training")

你可以在本地的conda环境里运行一下这个训练脚本,看看该脚本是否有问题,如果有问题就在本地调试,本地调试成功后,我们在使用控制脚本将该训练脚本上传到云平台,这也是我们一直在讲的一个基本理念:由本地扩展到云平台, 这也是一个基本的原则。

通过本地运行,可以看到运行成功了,接下来我们需要将该训练脚本提交到云平台上。

编写控制脚本

在根目录创建一个run-pytorch.py的脚本,脚本内容如下。
需要注意的是我们已经将Azure Machine Learning的配置文件config.js放在了根目录,同时也使用Azure Cli设置了环境。

# run-pytorch.py
from azureml.core import Workspace
from azureml.core import Experiment
from azureml.core import Environment
from azureml.core import ScriptRunConfig

if __name__ == "__main__":
    ws = Workspace.from_config()
    experiment = Experiment(workspace=ws, name='day1-experiment-train')
    config = ScriptRunConfig(source_directory='./src',
                             script='train.py',
                             compute_target='cpu-cluster')

    # 需要注意的是,这里直接使用了预置的环境。
    env = ws.environments['AzureML-PyTorch-1.6-CPU']
    config.run_config.environment = env

    run = experiment.submit(config)

    aml_url = run.get_portal_url()
    print(aml_url)

在根目录里运行该控制脚本之后,该控制脚本即会将训练脚本提交到Azure云平台。通过输出你即可以观察到云平台的训练结果。

好了,你的第一个通过云平台训练出来的机器学习模型就完成了。

给训练脚本添加集成到Azure机器学习平台的日志和指标

为了在训练脚本中和Azure云平台进行交互,例如输出日志到云平台,添加监控指标等等,我们只需要更改一下训练脚本,就可以达到这个目的:

修改后的train.py

import torch
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from model import Net
from azureml.core import Run
# ADDITIONAL CODE: get run from the current context
# 添加第一处,引用运行的实例
run = Run.get_context()
# download CIFAR 10 data
trainset = torchvision.datasets.CIFAR10(
    root='./data',
    train=True,
    download=True,
    transform=torchvision.transforms.ToTensor()
)
trainloader = torch.utils.data.DataLoader(
    trainset,
    batch_size=4,
    shuffle=True,
    num_workers=2
)
if __name__ == "__main__":
    # define convolutional network
    net = Net()
    # set up pytorch loss /  optimizer
    criterion = torch.nn.CrossEntropyLoss()
    optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
    # train the network
    for epoch in range(2):
        running_loss = 0.0
        for i, data in enumerate(trainloader, 0):
            # unpack the data
            inputs, labels = data
            # zero the parameter gradients
            optimizer.zero_grad()
            # forward + backward + optimize
            outputs = net(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
            # print statistics
            running_loss += loss.item()
            if i % 2000 == 1999:
                loss = running_loss / 2000
                # ADDITIONAL CODE: log loss metric to AML
		# 添加的第二处,记录指标到云平台
                run.log('loss', loss)
                print(f'epoch={epoch + 1}, batch={i + 1:5}: loss {loss:.2f}')
                running_loss = 0.0
    print('Finished Training')

这个脚本中简单的添加了两处:

# ADDITIONAL CODE: get run from the current context
run = Run.get_context()

# ADDITIONAL CODE: log loss metric to AML
run.log('loss', loss)

到这里全部完成了,下一篇我们继续学习如何处理自己的数据来训练模型。