大规模 MLOps 工程(二)(5)

本文涉及的产品
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 大规模 MLOps 工程(二)

大规模 MLOps 工程(二)(4)https://developer.aliyun.com/article/1517768

使用 PyTorch 自动微分进行线性回归

本节在介绍了第 6.1 节中自动微分算法的基础上,引入了 PyTorch 中的自动微分支持。作为一个激励性的例子,本节将带领你通过使用 PyTorch 自动微分和基本的梯度下降法解决单变量线性回归问题的过程。在这个过程中,你将学习如何使用 PyTorch 自动微分 API,实践可微模型的前向和反向传播,并为在接下来的章节深入应用 PyTorch 做好准备。

为了说明 PyTorch 中的自动微分特性,让我们结合梯度下降算法解决经典的线性回归问题。为了建立问题,让我们生成一些样本数据,

X = pt.linspace(-5, 5, 100)

所以变量 X 包含 100 个值,均匀分布在范围从-5 到 5。在这个例子中,假设 y = 2x + ε,其中 ε 是从标准正态分布中抽样的随机数(ε ~ N (0,1)),以便 y 可以用 PyTorch 实现为:

y = 2.0 * X + pt.randn(len(X))

向 y 函数添加 randn 噪声的目的是说明算法正确估计线的斜率的能力,换句话说,仅使用训练数据张量 y、X 即可恢复值为 2.0。

此时,如果您将 X 的值沿水平轴和 y 的值沿垂直轴绘制成图表,您应该期望看到一个类似于图 6.1 的图。当然,如果您使用了不同的随机种子,您的具体值可能会有所不同。


图 6.1 用于解释 PyTorch 张量 API 基础知识的示例回归问题

下一步,为了为梯度下降算法建立可微分模型,您需要指定模型参数以及参数值的初始猜测。对于这种简化的线性回归情况,没有偏差,您需要指定的唯一模型参数是线的斜率。为了初始化参数,您可以使用 randn 函数从标准正态分布中抽样:

w = pt.randn(1, requires_grad = True)

到目前为止,在本章中您还没有看到 requires_grad 参数在此处被 randn 张量工厂方法用于实例化 w 值。在第 6.1 节中,我介绍了自动微分算法的内部工作原理,您看到计算梯度需要为张量中的每个数据值额外的内存和计算开销。例如,对于每个 Scalar 实例,自动微分需要一个额外的 grad 属性以及一个递归反向函数的定义。

对于机器学习模型,支持自动微分可能会使张量所需的内存量增加一倍以上。因此,当使用工厂方法实例化张量时,PyTorch 默认禁用张量自动微分,需要您使用 requires_grad 参数显式启用支持。但是,如果一个张量是从启用 requires_grad 的张量派生的,那么派生张量(称为非叶张量)的 requires_grad 将自动设置为 True。

一旦模型参数 w 初始化完成,算法的前向传递就准备好了。在这种情况下,前向传递是简单地使用 w 参数猜测(预测)y 值。前向传递是作为一个返回预测的均方误差值的 forward 方法实现的:

def forward(X):
  y_pred = X * w
  mse_loss = pt.mean((y_pred - y) ** 2)
  return mse_loss

仔细查看前向方法的实现,去计算 PyTorch 在计算均方误差公式过程中实例化的所有张量的数量。第一个张量 y_pred 包含基于给定 w 值的 y 的预测值。第二个张量是 y_pred - y,包含了预测值的个体误差,而第三个张量包含了平方误差(y_pred - y) ** 2。最后,使用 mean 函数计算第四个张量,返回一个标量,其值为预测值的均方误差。

前向方法中实例化的四个张量均无需手动指定 requires_grad = True,因为 PyTorch 会自动推断:为了支持对 w 张量的梯度计算,还需要启用来自 w 的非叶张量的 requires_grad。一般来说,对于任意的 PyTorch 张量,你可以检查其 requires_grad 属性的值,以确定它是否可以用于梯度计算。例如,在前向方法的代码块中,y_pred.requires_grad 返回 True。

在本章中,你还没有使用过 PyTorch 张量聚合函数,比如 mean。在前向方法中,mean 函数简单地计算张量值的算术平均值(即平方误差的平均值),并将聚合结果返回为标量。在接下来的章节中,你将学习更多关于 mean 和其他 PyTorch 张量聚合函数的内容。

有了前向传播代码,就可以完成使用 PyTorch 自动微分来实现梯度下降的工作。回想一下,代码中的 y 和 X 的值基于方程y = 2x + ε。以下代码执行 25 次梯度下降迭代来估算 2.0 的值,该值用作方程中的斜率。

列表 6.3 使用梯度下降的 PyTorch 自动微分进行线性回归

LEARNING_RATE = 0.03
for _ in range(25):
  mse_loss = forward(X)
  w.grad = None                ❶
  mse_loss.backward()
  w.data -= LEARNING_RATE * w.grad
print("MSE ", mse_loss.data, " W ", w.data)

❶ 清空 w 的梯度(置零)。

你应该期望代码打印出接近以下数字的结果:

MSE  tensor(0.7207)  W  tensor([1.9876])

在梯度下降的实现中,将学习率任意设为 0.03,并将梯度下降迭代次数设置为 25。在接下来的章节中,你将学习更多关于超参数调整和更严格的方法来选择学习率、梯度下降迭代次数以及其他机器学习超参数的值。

正如你从第 6.1 节已经了解的那样,在使用自动微分时,重要的是在使用 backward 函数累积更新的梯度值之前将梯度归零。请注意,在 PyTorch 张量的情况下,grad 属性是通过将其设置为 None ❶ 而不是 0 的值来归零的。一旦 mse_loss 张量由 forward 方法返回,就会通过调用 backward 函数来更新梯度。梯度下降步骤等同于使用学习率和更新后梯度的负乘积来更新 w 参数数据 w.data -= LEARNING_RATE * w.grad。

请注意,由于 y 值的噪声,不应期望梯度下降或线性回归的解析解能恢复用于生成数据的精确值 2.0。为了确认这一点,你可以使用 PyTorch 张量 API 根据公式 (X^T X)(-1)*XTy* 计算解析的最小二乘解,

pt.pow(X.T @ X, -1) * (X.T @ y)

应该返回大约 tensor(1.9876) 的值。

6.3 迁移到 PyTorch 优化器进行梯度下降

本节介绍了 PyTorch 的 torch.optim 包和 Optimizer 类,包括 Adam 和 SGD(随机梯度下降),你可以在基于 PyTorch 的机器学习模型中重新使用它们,以改进模型参数的训练方式。

除了 torch.autograd 的自动微分框架外,PyTorch 还包括了 torch.optim 包,其中包含了一系列优化器,这些优化器是根据损失函数的梯度实现的替代优化启发式算法,用于更新机器学习模型参数。优化器算法的实现细节超出了本书的范围,但你应该知道,PyTorch 开发团队一直在努力维护 PyTorch torch.optim 包文档中与相应算法实现相关的研究论文的链接。³

优化器类被设计成易于交换,确保你可以在不必更改机器学习模型训练代码的情况下尝试替代优化器。回想一下,在列表 6.3 中,你实现了一个简单的线性回归版本,使用了自己简单的规则来根据梯度和学习率更新模型参数值:

w.data -= LEARNING_RATE * w.grad

不要自己硬编码这个规则,你可以通过重新实现以下代码,来重用 torch.optim.SGD 优化器中的等价更新规则。

列表 6.4 使用 torch.optim 优化器进行线性回归

import torch as pt
pt.manual_seed(0)
X = pt.linspace(-5, 5, 100)
y = 2 * X + pt.randn(len(X))
w = pt.randn(1, requires_grad = True)
def forward(X):
  y_pred = X * w
  return y_pred
def loss(y_pred, y):
  mse_loss = pt.mean((y_pred - y) ** 2)
  return mse_loss
LEARNING_RATE = 0.03
optimizer = pt.optim.SGD([w], lr = LEARNING_RATE)   ❶
EPOCHS = 25                                         ❷
for _ in range(EPOCHS):
  y_pred = forward(X)
  mse = loss(y_pred, y)
  mse.backward()
  optimizer.step()                                  ❸
  optimizer.zero_grad()                             ❹
print(w.item())

❶ 使用模型参数的可迭代对象 [w] 来实例化 SGD 优化器。

❷ 假设进行 25 个周期的梯度下降。

❸ 使用 backward 计算的梯度执行梯度更新步骤。

❹ 将模型参数的梯度归零,以备下一次迭代。

这应该输出模型对线性斜率 w 的估计值大约为 2.0812765834924307。使用 PyTorch 优化器所需的更改已经标注了❶、❸和❹。请注意,当实例化优化器❶时,您正在提供一个 Python 可迭代对象(在本例中是 Python 列表),用于模型参数。梯度下降计算出梯度后(即 backward()方法返回后),对优化器的 step()方法❸的调用基于梯度更新模型参数。优化器的 zero_grad()方法❹的调用清除(清空)梯度,以准备下一次 for 循环迭代中 backward()方法的调用。

如果您有训练机器学习模型的先验经验,可能已经遇到过 Adam 优化器。使用 PyTorch 优化器库,将 SGD 优化器❶替换为 Adam 很容易:

optimizer = pt.optim.Adam([w], lr = LEARNING_RATE)

通常,要使用 torch.optim 包中的任何 PyTorch 优化器,您需要首先使用构造函数实例化一个,

torch.optim.Optimizer(params, defaults)

其中 params 是模型参数的可迭代对象,defaults 是特定于优化器的命名参数的默认值。⁴

SGD 和 Adam 优化器都可以使用除模型参数和学习率之外的其他配置设置来实例化。然而,这些设置将在第十一章中的超参数调整中详细介绍。在那之前,示例将使用 SGD 优化器,因为它更容易理解和解释。

当你逐渐进入使用梯度下降进行更复杂的训练场景时,清晰而全面的术语是很有用的。从列表 6.4 中可以看到,通过梯度下降训练机器学习模型包括多个迭代,每个迭代包括以下操作:

  • 前向传递,其中使用特征值和模型参数返回预测输出,例如来自列表 6.4 的 y_pred = forward(X)。
  • 损失计算,其中使用预测输出和实际输出来确定损失函数的值,例如来自列表 6.4 的 mse = loss(y_pred, y)。
  • 反向传递,其中反向模式自动微分算法基于损失函数的计算计算模型参数的梯度,例如来自列表 6.4 的 mse.backward()。
  • 参数权重更新,其中使用从反向传递中计算得到的梯度值更新模型参数,如果您使用的是 torch.optim 包中的优化器,应该是 optimizer.step()。
  • 清除梯度,其中将模型参数 PyTorch 张量中的梯度值设置为 None,以防止自动微分在多次梯度下降迭代中累积梯度值;如果您使用的是 torch.optim 包中的优化器,则应使用 optimizer.zero_grad()进行此操作。

在行业中,术语迭代梯度下降的步骤通常互换使用。令人困惑的是,单词“步骤”有时也用来描述作为梯度下降的一部分执行的具体操作,例如向后步骤向前步骤。由于 PyTorch 使用步骤来特指根据损失函数的梯度来更新模型参数的操作,本书将坚持使用 PyTorch 的术语。请记住,一些 PyTorch 的框架,如 PyTorch Lightning,使用步骤来表示迭代

在过渡到使用批次进行梯度下降的模型训练之前,还有必要明确术语周期的定义。在机器学习中,一个周期描述了使用每个数据集示例恰好一次来训练(更新)机器学习模型参数所需的一个或多个梯度下降迭代。例如,列表 6.4❷指定了应该进行 25 个周期的梯度下降。使用词“周期”也对应于迭代,简单地原因是对于梯度下降的每次迭代,都会使用数据集中的所有示例来计算梯度和更新模型的权重。然而,正如您将在接下来关于批次的部分中了解到的,执行一个周期的训练可能需要多次梯度下降迭代。

6.4 开始使用数据集批次进行梯度下降

本节将向您介绍数据集批次(batches),以便您可以为使用 PyTorch 进行梯度下降做准备。梯度下降中数据集批次的概念看起来很简单。批次只是从数据集中随机抽样的一组非空示例(或在数学术语中,一个多重集)。尽管如此,使用批次的梯度下降是微妙而复杂的:数学家们甚至专门研究了这个领域,称为随机优化。训练数据集批次不仅仅是训练数据集的一个样本:在梯度下降的单个迭代中,训练数据集批次中的所有数据示例都用于更新模型的梯度。

虽然您不需要拥有数学优化的博士学位来使用 PyTorch 中的批量梯度下降,但具备与批次和梯度下降相关的精确术语能够更好地理解该主题的复杂性。

批处理大小 是一个正整数(大于零),指定了批处理中的示例数。许多机器学习研究论文和在线课程使用 mini-batch 梯度下降 这个短语来描述批处理大小大于一的梯度下降。然而,在 PyTorch 中,SGD(torch.optim.SGD)优化器以及 torch.optim 包中的其他优化器可以使用从 1 到整个数据集示例数的任何批处理大小。要记住这一点,因为在机器学习文献中,随机梯度下降 这个短语通常用来描述批处理大小恰好为一的梯度下降。

批处理大小的选择与您机器学习计算节点中的内存有关,也与梯度下降算法的机器学习性能有关。这意味着批处理大小的上限应考虑您机器学习平台节点的可用内存量。关于批处理大小的确切值的选择在第十一章的超参数调整中有更详细的介绍,但首先您应该知道您的机器学习平台节点内存中可以容纳的最大批处理大小。

对 PyTorch 中批处理的应用存在很多混淆,根源在于没有意识到批处理应该被视为数据集大小的一部分,即数据集中的示例数。将批处理解释为分数就是简单的 ,因此可以将批处理大小的选择归类为生成完整或不完整批次,其中 完整批次 的批处理大小是数据集大小的整数因子,或者更准确地说


对于某个表示数据集中批次数的正整数 batch_count。

6.5 使用 PyTorch Dataset 和 DataLoader 的数据集批处理

这一部分教你如何开始使用 PyTorch 中的数据集批处理,并使用 PyTorch 实用程序类来帮助你管理和加载数据集作为批处理。

PyTorch 框架提供了一组数据实用程序类,组织在 torch.utils.data 包中,并实现了支持使用梯度下降的数据批处理。该包中的类,包括 DataLoader、Dataset、IterableDataset 和 TensorDataset,旨在共同简化可扩展的机器学习模型训练过程的开发,包括数据集不适合单个节点内存的情况,以及数据集由分布式计算集群中的多个节点使用的情况。虽然这些类提供了可扩展的实现,但这并不意味着它们仅对大型数据集或大型计算集群有用。正如您将在本节中看到的,这些类可以很好地工作(除了可忽略的开销)与小型、内存中的数据集。

Dataset 是一个高度可重用的类,并且可以支持基于映射样式和可迭代样式的数据集子类的各种机器学习用例。映射样式数据集是 PyTorch 框架中的原始数据集类,最适合在内存中,可以通过索引进行寻址的数据集。例如,如果您要通过将 PyTorch 的数据集子类化为 MapStyleDataset 来实现自己的映射样式数据集,那么您必须实现所需的 getitemlen 方法。

列表 6.5 设计为子类的 PyTorch 映射样式数据集

import torch.utils.data.Dataset
class MapStyleDataset(Dataset):
    def __getitem__(self, index):    ❶
      ...
    def __len__(self):               ❷
      ...

❶ 映射样式接口方法,用于从数据集中检索特定项。. . .

❷ . . . 并返回整个数据集中项目的总数。

请注意,作为接口的一部分,映射样式数据集做出了两个假设:预计可以通过索引值❶访问数据集中的每个示例(项),并且随时可以了解和获取数据集的大小❷。

在大多数情况下,如果您使用的是内存数据集,您可以避免实现自己的映射样式数据集子类,而是重用 TensorDataset 类。TensorDataset 也是 torch.utils.data 包的一部分,并通过包装张量或 NumPy n 维数组来实现所需的数据集方法。例如,要为张量 X 和 y 中的示例数据值创建映射样式的训练数据集,可以直接将数据张量传递给 TensorDataset❶。

列表 6.6 简化批处理 PyTorch 张量的 TensorDataset

import torch as pt
from torch.utils.data import TensorDataset
pt.manual_seed(0)
X = pt.linspace(-5, 5, 100)
y = 2 * X + pt.randn(len(X))
train_ds = TensorDataset(y, X)   ❶

这使您可以使用 Python [0]语法从数据集中获取索引为 0 的示例,使用 getitem 方法,

print(train_ds[0])

输出为

(tensor(-11.1258), tensor(-5.))

并使用 train_ds 数据集上的 len 方法验证数据集的长度为 100,

assert
 len(train_ds) == 100

其中断言中的布尔表达式的结果为 True。

在使用数据集的实例时,实现梯度下降迭代的 PyTorch 代码不应直接访问数据集,而是使用 DataLoader 的实例作为与数据交互的接口。您将在使用 PyTorch 和 GPU 的即将到来的部分中了解更多有关使用 DataLoader 的理由。

DataLoader 本质上是对数据集的包装器,因此通过包装前面描述的 train_ds 实例,可以创建 train_dl 使用

from torch.utils.data import DataLoader
train_dl = DataLoader(train_ds)

注意,默认情况下,当 DataLoader 与映射样式的数据集一起使用时,DataLoader 实例返回的每个批次的大小为 1,这意味着以下表达式的结果为 True:

len(next(iter(train_dl))) == 1

可以通过在实例化 DataLoader 时指定 batch_size 命名参数来轻松修改此默认行为,以便该表达式

train_dl = DataLoader(train_ds, batch_size = 25)
len(next(iter(train_dl)))

评估结果为 25。

批量大小的两个值,1 和 25,都会生成完整的批次。尽管所有完整的批次的批量大小相同,但不完整的批次包含的示例数少于批量大小。具体来说,根据批量大小和数据集,不完整的批次可以包含至少

dataset_size mod batch_size

示例,或者在 Python 中,dataset_size % batch_size。

例如,当使用 batch_size 为 33 时,在 for 循环的第四次迭代过程中,以下代码生成一个批次大小为 1 的不完整批次:

train_dl = DataLoader(train_ds, batch_size = 33)
for idx, (y_batch, X_batch) in enumerate(train_dl):
  print(idx, len(X_batch))

这将打印以下内容:

0 33
1 33
2 33
3 1

处理不完整的批次没有普遍接受的技术。虽然有可能尝试防止不完整批次的问题,但在实践中可能没有太多价值:因为批次是在处理足够大卷的数据时使用的,以致于数据集太大而无法放入内存中,因此如果不完整的批次对机器学习模型的整体性能没有负面和可衡量的影响,那么可以选择忽略或删除它们。例如,DataLoader 类提供了一个 drop_last 选项,这样您就可以忽略较小的、不完整的批次:

train_dl = DataLoader(train_ds, batch_size = 33, drop_last=True)
for idx, (y_batch, X_batch) in enumerate(train_dl):
  print(idx, len(X_batch))

这将输出以下内容:

0 33
1 33
2 33

尽管在指定批大小时应谨慎使用不完整批次的 drop_last 选项,特别是在使用占数据集的大比例的批次大小时。例如,假设批次大小不慎设置为。由于此批次大小的选择产生两个批次,当使用 drop_last=True 选项时,两个中的单个不完整批次,批次大小为,被丢弃,导致将近一半的数据集浪费!

可以通过训练多个周期并将数据集与自身连接起来,使用 batch_size 窗口作为滚动窗口在数据集上滑动,从而防止不完整的批次。采用这种技术时,训练周期的数量应该基于批次大小和数据集大小的最小公倍数(lcm):


为了说明这种方法,假设仅为例子而工作的批次大小为 12,数据集大小为 33,则

import math
def lcm(a, b):
    return a * b / math.gcd(a, b)
lcm(12, 33) / 33

输出 4.0,这表示训练数据集需要与自身连接四次,以实现所需的四个训练周期,以避免不完整的批次。

从数据集中选择批次是如何进行的?由于批次旨在统计代表数据集,批次中的示例应尽可能相互独立。这意味着确保批次中的出租车票价示例是从整个数据集中随机采样(无替换)的。在实践中,实现对数据集进行随机洗牌最直接的方法是使用 PySpark DataFrame API 的 shuffle()方法。

由于批次需要统计代表数据集,您可能会倾向于重新使用基于第四章中发现的测试数据集大小的批次大小。尽管测试数据集大小指标作为批次大小的 下限,但重新使用其值并不是正确的决定,因为测试数据集大小是尽可能小而又统计代表开发数据集的。第十一章详细描述了如何使用在本章介绍的下限和上限值来选择正确的批量大小的原则性超参数调整方法。

6.6 用于批量梯度下降的 Dataset 和 DataLoader 类

本节说明了如何使用最小化示例应用 Dataset 和 DataLoader 类来教授这些概念,这些概念也适用于使用数据集批次的更复杂和更现实的机器学习问题。要使用 Dataset 和 DataLoader 执行使用批量的梯度下降的线性回归,您需要修改第 6.3 节的解决方案。

列表 6.7 使用批量数据集的基本线性回归

import torch as pt
from torch.utils.data import TensorDataset, DataLoader
pt.manual_seed(0)
X = pt.linspace(-5, 5, 100)
y = 2 * X + pt.randn(len(X))
train_ds = TensorDataset(y, X)                  ❶
train_dl = DataLoader(train_ds, batch_size=1)   ❷
w = pt.empty(1, requires_grad = True)
def forward(X):
  y_pred =  X * w
  return y_pred
def loss(y_pred, y):
  mse_loss = pt.mean((y_pred - y) ** 2)
  return mse_loss
LEARNING_RATE = 0.003
optimizer = pt.optim.SGD([w], lr = LEARNING_RATE)
EPOCHS = 25
for _ in range(EPOCHS):
  for y_batch, X_batch in train_dl:             ❸
    y_pred = forward(X_batch)                   ❹
    mse = loss(y_pred, y_batch)                 ❺
    mse.backward()
    optimizer.step()
    optimizer.zero_grad()
print(w.item())

❶ 使用 TensorDataset 提供 y 和 X 的数据集接口。

❷ 使用批量大小为 1(默认)为数据集创建一个 DataLoader。

❸ 在迭代 DataLoader 时解压数据批次中的每个元组。

❹ 对特征批次执行前向步骤以生成预测。

❺ 使用批次标签和预测计算损失。

这应该输出估计的 w 大约为 2.0812765834924307。一旦原始张量 y 和 X 被打包成映射样式的 TensorDataset 数据集 ❶,则产生的 train_ds 实例进一步包装使用 DataLoader 以生成 train_dl。

要使用梯度下降的批次,对于每个周期,代码使用在 train_dl 中由 for 循环返回的单个批次执行 100 次梯度下降迭代 ❸。由于原始数据集包含 100 个示例,并且 DataLoader 的默认批量大小等于 1。由于批量大小为 1 会产生完整的批次(回想一下批次的定义为数据集的一部分),


或者,如果您使用批次大小为 25 的批次

train_dl = DataLoader(train_ds, batch_size=25),

那么


列表 6.7 中的更改 ❹ 和 ❺ 很简单:代码不再使用原始数据集,而是使用 train_dl 实例返回的批次。

如果您将批量大小修改为生成不完整批次的值,例如通过指定批量大小为 51,

train_dl = DataLoader(train_ds, batch_size=51)

内部 for 循环的第二次迭代将生成具有 49 个示例的批次,因为 DataLoader 默认允许不完整的批次。在这种特定情况下,这不是一个问题,因为具有 torch.Size([]) 形状的模型参数可以与形状为 torch.Size([49]) 的不完整批次进行广播。然而,通常情况下,您必须注意将模型参数的形状与批次的形状对齐。在第七章中,您将从对齐模型参数与 DC 出租车数据集批次形状的示例中学习。

总结

  • 自动微分是简化复杂链式规则应用的基本算法。
  • 可以使用 python 原生数据结构来演示如何为张量实现自动微分的基础知识。
  • PyTorch 张量提供了全面的支持,用于对张量梯度进行自动微分。
  • torch.optim 中的优化器是一系列用于使用梯度下降优化机器学习模型中参数的算法。
  • PyTorch 张量的自动微分和优化器 API 在使用 PyTorch 进行机器学习时是核心内容。
  • Dataset 和 DataLoader 接口类简化了在 PyTorch 代码中使用批处理的过程。
  • TensorDataset 提供了一个可以直接使用的内存中数据集的实现。

^(1.)自动微分和反向传播的故事在这里有详细描述:people.idsia.ch/~juergen/who-invented-backpropagation.html

^(2.)在有关自动微分的复杂数学论文中,标量类被称为双重数,grad 被称为伴随数。

^(3.)例如,SGD 的文档可以从mng.bz/zEpB获取,并包含指向相关研究论文和 SGD 实现详细信息的链接。

^(4.)基础的 Optimizer 类和它的构造函数在这里有文档说明:pytorch.org/docs/stable/optim.html#torch.optim.Optimizer

^(5.)更精确地说,通过使用无替换的随机抽样,或者等效地对数据集中的示例顺序进行随机洗牌。

^(6.)根据批处理大小和数据集大小的最小公倍数增加纪元数,可以产生足够的训练纪元,以避免不完整的批次。也可以训练任意 lcm(batch_size, data set_size) 的倍数,以避免不完整批次。

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
6月前
|
机器学习/深度学习 存储 算法
大规模 MLOps 工程(四)(3)
大规模 MLOps 工程(四)
49 1
|
6月前
|
机器学习/深度学习 PyTorch API
大规模 MLOps 工程(四)(1)
大规模 MLOps 工程(四)
44 1
|
6月前
|
机器学习/深度学习 存储 PyTorch
大规模 MLOps 工程(二)(4)
大规模 MLOps 工程(二)
53 0
|
6月前
|
机器学习/深度学习 存储 PyTorch
大规模 MLOps 工程(三)(2)
大规模 MLOps 工程(三)
47 0
|
6月前
|
机器学习/深度学习 PyTorch 算法框架/工具
大规模 MLOps 工程(二)(2)
大规模 MLOps 工程(二)
60 0
|
6月前
|
机器学习/深度学习 存储 资源调度
大规模 MLOps 工程(二)(1)
大规模 MLOps 工程(二)
62 0
|
6月前
|
机器学习/深度学习 PyTorch API
大规模 MLOps 工程(三)(5)
大规模 MLOps 工程(三)
59 0
|
6月前
|
存储 算法 PyTorch
大规模 MLOps 工程(三)(3)
大规模 MLOps 工程(三)
52 0
|
6月前
|
机器学习/深度学习 存储 自然语言处理
大规模 MLOps 工程(三)(4)
大规模 MLOps 工程(三)
66 0
|
6月前
|
机器学习/深度学习 数据可视化 PyTorch
大规模 MLOps 工程(四)(2)
大规模 MLOps 工程(四)
64 0