Torch中的张量tensor和Numpy中的数组array的区别(详细)

一、Torch中的tensor和Tensor的区别

在 Torch 中,tensorTensor 它们在使用时有一些细微的区别:

  1. torch.tensor()(函数):这是一个工厂函数,用于创建一个新的张量。torch.tensor() 可以从各种数据类型(如列表、数组)创建新的张量,并且你可以指定数据类型(如 dtype)。最重要的是,torch.tensor() 总是会复制其输入数据,所以原始数据和新创建的张量是完全独立的。
    简单来说torch.tensor()中的数据类型决定生成张量的类型
    可以通过torch.set_default_tensor_type(t)设置默认的tensor类型

  2. torch.Tensor(类):这实际上是 torch.FloatTensor 的别名,是一个张量类的构造函数。使用 torch.Tensor() 时,如果没有提供具体的数据类型,它默认创建一个浮点数类型的张量(torch.FloatTensor)。它可以从现有数据创建张量,但其行为(比如是否复制数据)取决于输入数据的类型。

  3. 共享和非共享内存:如前所述,torch.tensor() 总是复制数据,而 torch.Tensor() 可能不复制数据,尤其是当输入是一个 NumPy 数组时。如果你使用 torch.Tensor() 来自 NumPy 数组创建张量,那么原始数组和新张量将共享相同的内存(除非显式地请求复制)。

  4. 用法:在实际使用中,torch.tensor() 通常是首选,因为它在创建张量时提供了更多的灵活性和明确性。它允许用户更清晰地控制数据类型和数据是否被复制。torch.Tensor() 通常在需要默认数据类型(浮点数)的情况下使用。

总结来说,虽然 tensorTensor 在 PyTorch 中都用于表示多维数据数组,但它们在创建张量时的行为和用途有所不同。选择使用哪一个取决于你的具体需求,比如是否需要复制数据,以及你希望张量的数据类型是什么。

二、Tensor和Numpy区别

  1. 数据类型和打印方式

    • 在 NumPy 中,数组的类型是 numpy.ndarray。要获取数组的类型,通常会使用 type(x),其中 x 是数组。
    • 在 PyTorch 中,一个张量的类型是 torch.Tensor 或其派生类型(如 torch.FloatTensor)。要获取张量的数据类型(如 float32, int64 等),可以使用 x.dtype,而 x.type() 可以用来获取完整的类型信息(包括其属于哪个类,如 torch.FloatTensor)。
  2. 计算位置(CPU vs GPU)

    • NumPy 数组默认只能在 CPU 上进行操作和计算。NumPy 本身不支持 GPU 加速。
    • PyTorch 张量可以在 CPU 或 GPU 上进行操作和计算。这是 PyTorch 特别适合于深度学习和高性能计算的原因之一。通过使用 .to() 方法或 .cuda() 方法,可以将张量移动到 GPU 上(如果有可用的 GPU),这可以显著加速某些类型的计算。

这些区别反映了 NumPy 和 PyTorch 在设计和应用方面的不同。NumPy 主要用于通用的数值计算,而 PyTorch 专注于支持深度学习,包括对 GPU 加速的支持。在实际应用中,这些差异使得 PyTorch 在处理大规模、需要高性能计算的深度学习任务时更为有效和灵活。

三、Tensor和Numpy相互转化

  1. 从 NumPy ndarray 转换为 PyTorch Tensor

    • 使用 torch.from_numpy() 方法。这个方法创建了一个不复制数据的张量。这意味着原始的 NumPy 数组和新创建的张量共享相同的内存。如果修改其中一个,另一个也会被修改。
      import numpy as np
      import torch
      
      a = np.array([1, 2, 3])
      tensor = torch.from_numpy(a)
      
  2. 从 PyTorch Tensor 转换为 NumPy ndarray

    • 使用 .numpy() 方法。如果张量存储在 CPU 上,并且没有需要渐变的计算,这个方法会返回一个共享相同内存的 NumPy 数组。这意味着修改张量或数组中的一个会影响另一个。
      tensor = torch.tensor([1, 2, 3])
      ndarray = tensor.numpy()
      

需要注意的是,如果张量存储在 GPU 上(即使用了 CUDA),则在转换为 NumPy 数组之前,需要先将其移动到 CPU。这可以通过 .to('cpu') 方法实现:

tensor = torch.tensor([1, 2, 3], device='cuda')
ndarray = tensor.to('cpu').numpy()

同样的,如果你想将一个 NumPy 数组转换为在 GPU 上的张量,可以使用 .to() 方法:

a = np.array([1, 2, 3])
tensor = torch.from_numpy(a).to('cuda')

这些方法在数据科学和机器学习中非常有用,尤其是在需要将数据在不同的库和计算资源之间移动时。

疑问(torch.tensor()torch.Tensor()进行转换有什么区别):

torch.tensor()torch.Tensor() 都可以用来从 NumPy 数组创建 PyTorch 张量(tensor),但它们之间存在一些重要区别:

  1. 默认数据类型和设备torch.tensor() 创建的张量继承了原始数据的数据类型和设备属性。这意味着如果你的 NumPy 数组是一个特定的数据类型(比如 float32),使用 torch.tensor() 会保留这个数据类型。另一方面,torch.Tensor() 默认会创建一个 torch.FloatTensor,不管原始数据的类型是什么。

  2. 数据复制torch.tensor() 会复制其输入数据,因此原始数据和新创建的张量在内存中是独立的。这意味着修改原始数据不会影响到新创建的张量,反之亦然。而 torch.Tensor() 在某些情况下可能不会复制数据。当输入是 NumPy 数组时,torch.Tensor() 实际上就是 torch.from_numpy() 的别名,它不会复制数据,而是在原始数据上创建张量。这意味着原始数据和新张量共享相同的内存,修改其中一个会影响另一个。

  3. 明确和直观torch.tensor() 是一个工厂函数,它更加直观地显示你正在从一些数据创建一个新的张量。另一方面,torch.Tensor() 更像是一个构造函数,其行为可能因输入类型而异。

总的来说,torch.tensor() 通常是首选方法,因为它在数据类型和内存行为方面提供更多的一致性和预测性。如果你需要确保创建的张量与原始数据在内存中是分离的,并且保持原始数据的类型,那么使用 torch.tensor() 是更好的选择。