0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PyTorch教程-3.3. 综合回归数据

jf_pJlTbmA9 来源:PyTorch 作者:PyTorch 2023-06-05 15:38 次阅读

机器学习就是从数据中提取信息。所以你可能想知道,我们可以从合成数据中学到什么?虽然我们本质上可能并不关心我们自己融入人工数据生成模型的模式,但此类数据集仍然可用于教学目的,帮助我们评估学习算法的属性并确认我们的实现是否按预期工作。例如,如果我们创建的数据的正确参数是先验已知的,那么我们可以验证我们的模型实际上可以恢复它们。

%matplotlib inline
import random
import torch
from d2l import torch as d2l

%matplotlib inline
import random
from mxnet import gluon, np, npx
from d2l import mxnet as d2l

npx.set_np()

%matplotlib inline
import random
import jax
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
from jax import numpy as jnp
from d2l import jax as d2l

No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)

%matplotlib inline
import random
import tensorflow as tf
from d2l import tensorflow as d2l

3.3.1. 生成数据集

对于这个例子,我们将使用低维来简洁。以下代码片段生成 1000 个示例,这些示例具有从标准正态分布中提取的二维特征。生成的设计矩阵X属于R1000×2. 我们通过应用地面真值线性函数生成每个标签,通过加性噪声破坏它们ϵ,为每个示例独立且相同地绘制:

(3.3.1)y=Xw+b+ϵ.

为了方便起见,我们假设ϵ取自均值为正态分布μ=0和标准差 σ=0.01. 请注意,对于面向对象的设计,我们将代码添加到__init__子类的方法中d2l.DataModule (在3.2.3 节中介绍)。允许设置任何额外的超参数是一种很好的做法。我们用 save_hyperparameters(). batch_size稍后将确定。

class SyntheticRegressionData(d2l.DataModule): #@save
  """Synthetic data for linear regression."""
  def __init__(self, w, b, noise=0.01, num_train=1000, num_val=1000,
         batch_size=32):
    super().__init__()
    self.save_hyperparameters()
    n = num_train + num_val
    self.X = torch.randn(n, len(w))
    noise = torch.randn(n, 1) * noise
    self.y = torch.matmul(self.X, w.reshape((-1, 1))) + b + noise

class SyntheticRegressionData(d2l.DataModule): #@save
  """Synthetic data for linear regression."""
  def __init__(self, w, b, noise=0.01, num_train=1000, num_val=1000,
         batch_size=32):
    super().__init__()
    self.save_hyperparameters()
    n = num_train + num_val
    self.X = np.random.randn(n, len(w))
    noise = np.random.randn(n, 1) * noise
    self.y = np.dot(self.X, w.reshape((-1, 1))) + b + noise

class SyntheticRegressionData(d2l.DataModule): #@save
  """Synthetic data for linear regression."""
  def __init__(self, w, b, noise=0.01, num_train=1000, num_val=1000,
         batch_size=32):
    super().__init__()
    self.save_hyperparameters()
    n = num_train + num_val
    key = jax.random.PRNGKey(0)
    key1, key2 = jax.random.split(key)
    self.X = jax.random.normal(key1, (n, w.shape[0]))
    noise = jax.random.normal(key2, (n, 1)) * noise
    self.y = jnp.matmul(self.X, w.reshape((-1, 1))) + b + noise

class SyntheticRegressionData(d2l.DataModule): #@save
  """Synthetic data for linear regression."""
  def __init__(self, w, b, noise=0.01, num_train=1000, num_val=1000,
         batch_size=32):
    super().__init__()
    self.save_hyperparameters()
    n = num_train + num_val
    self.X = tf.random.normal((n, w.shape[0]))
    noise = tf.random.normal((n, 1)) * noise
    self.y = tf.matmul(self.X, tf.reshape(w, (-1, 1))) + b + noise

下面,我们将真实参数设置为w=[2,−3.4]⊤ 和b=4.2. 稍后,我们可以根据这些真实值检查我们估计的参数。

data = SyntheticRegressionData(w=torch.tensor([2, -3.4]), b=4.2)

data = SyntheticRegressionData(w=np.array([2, -3.4]), b=4.2)

data = SyntheticRegressionData(w=jnp.array([2, -3.4]), b=4.2)

data = SyntheticRegressionData(w=tf.constant([2, -3.4]), b=4.2)

每行由features一个向量组成R2 每一行labels都是一个标量。让我们看一下第一个条目。

print('features:', data.X[0],'nlabel:', data.y[0])

features: tensor([-0.0499, -0.2817])
label: tensor([5.0533])

print('features:', data.X[0],'nlabel:', data.y[0])

features: [2.2122064 1.1630787]
label: [4.684836]

print('features:', data.X[0],'nlabel:', data.y[0])

features: [-0.86997527 -3.2320356 ]
label: [13.438176]

print('features:', data.X[0],'nlabel:', data.y[0])

features: tf.Tensor([-0.8617247 0.9828964], shape=(2,), dtype=float32)
label: tf.Tensor([-0.86415064], shape=(1,), dtype=float32)

3.3.2. 读取数据集

训练机器学习模型通常需要多次遍历数据集,一次获取一小批示例。然后使用此数据更新模型。为了说明这是如何工作的,我们实现了该 方法,通过(在第 3.2.1 节中介绍 )get_dataloader将其注册到类中 。它采用批量大小、特征矩阵和标签向量,并生成大小为 的小批量 。因此,每个小批量包含一个特征和标签的元组。请注意,我们需要注意我们是处于训练模式还是验证模式:在前者中,我们希望以随机顺序读取数据,而对于后者,能够以预定义的顺序读取数据可能对于调试目的很重要。SyntheticRegressionDataadd_to_classbatch_size

@d2l.add_to_class(SyntheticRegressionData)
def get_dataloader(self, train):
  if train:
    indices = list(range(0, self.num_train))
    # The examples are read in random order
    random.shuffle(indices)
  else:
    indices = list(range(self.num_train, self.num_train+self.num_val))
  for i in range(0, len(indices), self.batch_size):
    batch_indices = torch.tensor(indices[i: i+self.batch_size])
    yield self.X[batch_indices], self.y[batch_indices]

@d2l.add_to_class(SyntheticRegressionData)
def get_dataloader(self, train):
  if train:
    indices = list(range(0, self.num_train))
    # The examples are read in random order
    random.shuffle(indices)
  else:
    indices = list(range(self.num_train, self.num_train+self.num_val))
  for i in range(0, len(indices), self.batch_size):
    batch_indices = np.array(indices[i: i+self.batch_size])
    yield self.X[batch_indices], self.y[batch_indices]

@d2l.add_to_class(SyntheticRegressionData)
def get_dataloader(self, train):
  if train:
    indices = list(range(0, self.num_train))
    # The examples are read in random order
    random.shuffle(indices)
  else:
    indices = list(range(self.num_train, self.num_train+self.num_val))
  for i in range(0, len(indices), self.batch_size):
    batch_indices = jnp.array(indices[i: i+self.batch_size])
    yield self.X[batch_indices], self.y[batch_indices]

@d2l.add_to_class(SyntheticRegressionData)
def get_dataloader(self, train):
  if train:
    indices = list(range(0, self.num_train))
    # The examples are read in random order
    random.shuffle(indices)
  else:
    indices = list(range(self.num_train, self.num_train+self.num_val))
  for i in range(0, len(indices), self.batch_size):
    j = tf.constant(indices[i : i+self.batch_size])
    yield tf.gather(self.X, j), tf.gather(self.y, j)

为了建立一些直觉,让我们检查第一个小批量数据。每个小批量特征都为我们提供了它的大小和输入特征的维度。同样,我们的小批量标签将具有由 给出的匹配形状batch_size。

X, y = next(iter(data.train_dataloader()))
print('X shape:', X.shape, 'ny shape:', y.shape)

X shape: torch.Size([32, 2])
y shape: torch.Size([32, 1])

X, y = next(iter(data.train_dataloader()))
print('X shape:', X.shape, 'ny shape:', y.shape)

X shape: (32, 2)
y shape: (32, 1)

X, y = next(iter(data.train_dataloader()))
print('X shape:', X.shape, 'ny shape:', y.shape)

X shape: (32, 2)
y shape: (32, 1)

X, y = next(iter(data.train_dataloader()))
print('X shape:', X.shape, 'ny shape:', y.shape)

X shape: (32, 2)
y shape: (32, 1)

虽然看似无害,但调用 iter(data.train_dataloader())说明了 Python 面向对象设计的强大功能。请注意,我们 在创建对象后SyntheticRegressionData向类添加了一个方法。尽管如此,该对象受益于事后向类添加功能。data

在整个迭代过程中,我们获得不同的小批量,直到整个数据集都用完(试试这个)。虽然上面实现的迭代有利于教学目的,但它的效率低下,可能会让我们在实际问题上遇到麻烦。例如,它要求我们将所有数据加载到内存中,并执行大量随机内存访问。在深度学习框架中实现的内置迭代器效率要高得多,它们可以处理诸如存储在文件中的数据、通过流接收的数据以及动态生成或处理的数据等来源。接下来让我们尝试使用内置迭代器实现相同的方法。

3.3.3. 数据加载器的简洁实现

我们可以调用框架中现有的 API 来加载数据,而不是编写我们自己的迭代器。和以前一样,我们需要一个具有特征X 和标签的数据集y。除此之外,我们设置了batch_size内置的数据加载器,让它有效地处理混洗示例。

@d2l.add_to_class(d2l.DataModule) #@save
def get_tensorloader(self, tensors, train, indices=slice(0, None)):
  tensors = tuple(a[indices] for a in tensors)
  dataset = torch.utils.data.TensorDataset(*tensors)
  return torch.utils.data.DataLoader(dataset, self.batch_size,
                    shuffle=train)

@d2l.add_to_class(SyntheticRegressionData) #@save
def get_dataloader(self, train):
  i = slice(0, self.num_train) if train else slice(self.num_train, None)
  return self.get_tensorloader((self.X, self.y), train, i)

@d2l.add_to_class(d2l.DataModule) #@save
def get_tensorloader(self, tensors, train, indices=slice(0, None)):
  tensors = tuple(a[indices] for a in tensors)
  dataset = gluon.data.ArrayDataset(*tensors)
  return gluon.data.DataLoader(dataset, self.batch_size,
                 shuffle=train)

@d2l.add_to_class(SyntheticRegressionData) #@save
def get_dataloader(self, train):
  i = slice(0, self.num_train) if train else slice(self.num_train, None)
  return self.get_tensorloader((self.X, self.y), train, i)

JAX is all about NumPy like API with device acceleration and the functional transformations, so at least the current version doesn’t include data loading methods. With other libraries we already have great data loaders out there, and JAX suggests using them instead. Here we will grab TensorFlow’s data loader, and modify it slightly to make it work with JAX.

@d2l.add_to_class(d2l.DataModule) #@save
def get_tensorloader(self, tensors, train, indices=slice(0, None)):
  tensors = tuple(a[indices] for a in tensors)
  # Use Tensorflow Datasets & Dataloader. JAX or Flax do not provide
  # any dataloading functionality
  shuffle_buffer = tensors[0].shape[0] if train else 1
  return tfds.as_numpy(
    tf.data.Dataset.from_tensor_slices(tensors).shuffle(
      buffer_size=shuffle_buffer).batch(self.batch_size))

@d2l.add_to_class(SyntheticRegressionData) #@save
def get_dataloader(self, train):
  i = slice(0, self.num_train) if train else slice(self.num_train, None)
  return self.get_tensorloader((self.X, self.y), train, i)

@d2l.add_to_class(d2l.DataModule) #@save
def get_tensorloader(self, tensors, train, indices=slice(0, None)):
  tensors = tuple(a[indices] for a in tensors)
  shuffle_buffer = tensors[0].shape[0] if train else 1
  return tf.data.Dataset.from_tensor_slices(tensors).shuffle(
    buffer_size=shuffle_buffer).batch(self.batch_size)

@d2l.add_to_class(SyntheticRegressionData) #@save
def get_dataloader(self, train):
  i = slice(0, self.num_train) if train else slice(self.num_train, None)
  return self.get_tensorloader((self.X, self.y), train, i)

新数据加载器的行为与之前的数据加载器一样,只是它更高效并且增加了一些功能。

X, y = next(iter(data.train_dataloader()))
print('X shape:', X.shape, 'ny shape:', y.shape)

X shape: torch.Size([32, 2])
y shape: torch.Size([32, 1])

X, y = next(iter(data.train_dataloader()))
print('X shape:', X.shape, 'ny shape:', y.shape)

X shape: (32, 2)
y shape: (32, 1)

X, y = next(iter(data.train_dataloader()))
print('X shape:', X.shape, 'ny shape:', y.shape)

X shape: (32, 2)
y shape: (32, 1)

X, y = next(iter(data.train_dataloader()))
print('X shape:', X.shape, 'ny shape:', y.shape)

X shape: (32, 2)
y shape: (32, 1)

例如,框架API提供的数据加载器支持内置__len__方法,所以我们可以查询它的长度,即批次数。

len(data.train_dataloader())

32

len(data.train_dataloader())

32

len(data.train_dataloader())

32

len(data.train_dataloader())

32

3.3.4. 概括

数据加载器是一种抽象加载和操作数据过程的便捷方式。这样,相同的机器学习 算法无需修改即可处理许多不同类型和来源的数据。数据加载器的优点之一是它们可以组合。例如,我们可能正在加载图像,然后有一个后期处理过滤器来裁剪或修改它们。因此,数据加载器可用于描述整个数据处理管道。

至于模型本身,二维线性模型是我们可能遇到的最简单的模型。它使我们能够测试回归模型的准确性,而不必担心数据量不足或方程组未定。我们将在下一节中充分利用它。

3.3.5. 练习

如果样本数量不能除以批量大小,将会发生什么。如何通过使用框架的 API 指定不同的参数来更改此行为?

如果我们想要生成一个巨大的数据集,其中参数向量的大小w和示例的数量 num_examples都很大怎么办?

如果我们不能将所有数据保存在内存中会怎样?

如果数据保存在磁盘上,您将如何打乱数据?您的任务是设计一种不需要太多随机读取或写入的高效算法。提示:伪随机排列生成器 允许您设计重新洗牌而不需要显式存储排列表(Naor 和 Reingold,1999)。

实现一个数据生成器,在每次调用迭代器时动态生成新数据。

您将如何设计一个随机数据生成器,使其在每次调用时生成相同的数据?

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据加载器
    +关注

    关注

    0

    文章

    2

    浏览量

    5746
  • pytorch
    +关注

    关注

    2

    文章

    803

    浏览量

    13148
收藏 人收藏

    评论

    相关推荐

    Pytorch模型训练实用PDF教程【中文】

    PyTorch 提供的数据增强方法(22 个)、权值初始化方法(10 个)、损失函数(17 个)、优化器(6 个)及 tensorboardX 的方法(13 个)进行了详细介绍。本教程分为四章
    发表于 12-21 09:18

    回归算法有哪些,常用回归算法(3种)详解

    回归是数学建模、分类和预测中最古老但功能非常强大的工具之一。回归在工程、物理学、生物学、金融、社会科学等各个领域都有应用,是数据科学家常用的基本工具。回归通常是机器学习中使用的第一个算
    发表于 07-28 14:36

    为什么学习深度学习需要使用PyTorch和TensorFlow框架

    如果你需要深度学习模型,那么 PyTorch 和 TensorFlow 都是不错的选择。 并非每个回归或分类问题都需要通过深度学习来解决。甚至可以说,并非每个回归或分类问题都需要通过机器学习来解决。毕竟,许多
    的头像 发表于 09-14 10:57 3415次阅读

    基于PyTorch的深度学习入门教程之PyTorch重点综合实践

    前言 PyTorch提供了两个主要特性: (1) 一个n维的Tensor,与numpy相似但是支持GPU运算。 (2) 搭建和训练神经网络的自动微分功能。 我们将会使用一个全连接的ReLU网络作为
    的头像 发表于 02-15 10:01 1739次阅读

    PyTorch教程之数据预处理

    电子发烧友网站提供《PyTorch教程之数据预处理.pdf》资料免费下载
    发表于 06-02 14:11 0次下载
    <b class='flag-5'>PyTorch</b>教程之<b class='flag-5'>数据</b>预处理

    PyTorch教程3.1之线性回归

    电子发烧友网站提供《PyTorch教程3.1之线性回归.pdf》资料免费下载
    发表于 06-05 11:30 0次下载
    <b class='flag-5'>PyTorch</b>教程3.1之线性<b class='flag-5'>回归</b>

    PyTorch教程3.3综合回归数据

    电子发烧友网站提供《PyTorch教程3.3综合回归数据.pdf》资料免费下载
    发表于 06-05 15:48 0次下载
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>3.3</b>之<b class='flag-5'>综合</b><b class='flag-5'>回归</b><b class='flag-5'>数据</b>

    PyTorch教程3.4之从头开始执行线性回归

    电子发烧友网站提供《PyTorch教程3.4之从头开始执行线性回归.pdf》资料免费下载
    发表于 06-05 11:25 0次下载
    <b class='flag-5'>PyTorch</b>教程3.4之从头开始执行线性<b class='flag-5'>回归</b>

    PyTorch教程3.5之线性回归的简洁实现

    电子发烧友网站提供《PyTorch教程3.5之线性回归的简洁实现.pdf》资料免费下载
    发表于 06-05 11:28 0次下载
    <b class='flag-5'>PyTorch</b>教程3.5之线性<b class='flag-5'>回归</b>的简洁实现

    PyTorch教程4.1之Softmax回归

    电子发烧友网站提供《PyTorch教程4.1之Softmax回归.pdf》资料免费下载
    发表于 06-05 15:46 0次下载
    <b class='flag-5'>PyTorch</b>教程4.1之Softmax<b class='flag-5'>回归</b>

    PyTorch教程4.4之从头开始实现Softmax回归

    电子发烧友网站提供《PyTorch教程4.4之从头开始实现Softmax回归.pdf》资料免费下载
    发表于 06-05 15:37 0次下载
    <b class='flag-5'>PyTorch</b>教程4.4之从头开始实现Softmax<b class='flag-5'>回归</b>

    PyTorch教程-3.1. 线性回归

    3.1. 线性回归¶ Colab [火炬]在 Colab 中打开笔记本 Colab [mxnet] Open the notebook in Colab Colab [jax
    的头像 发表于 06-05 15:38 496次阅读
    <b class='flag-5'>PyTorch</b>教程-3.1. 线性<b class='flag-5'>回归</b>

    PyTorch教程-4.1. Softmax 回归

    4.1. Softmax 回归¶ Colab [火炬]在 Colab 中打开笔记本 Colab [mxnet] Open the notebook in Colab Colab [jax
    的头像 发表于 06-05 15:38 604次阅读
    <b class='flag-5'>PyTorch</b>教程-4.1. Softmax <b class='flag-5'>回归</b>

    pytorch如何训练自己的数据

    本文将详细介绍如何使用PyTorch框架来训练自己的数据。我们将从数据准备、模型构建、训练过程、评估和测试等方面进行讲解。 环境搭建 首先,我们需要安装PyTorch。可以通过访问
    的头像 发表于 07-11 10:04 446次阅读

    PyTorch 数据加载与处理方法

    PyTorch 是一个流行的开源机器学习库,它提供了强大的工具来构建和训练深度学习模型。在构建模型之前,一个重要的步骤是加载和处理数据。 1. PyTorch 数据加载基础 在
    的头像 发表于 11-05 17:37 304次阅读