Tensor 张量

神经网络中的数据,都存放在 Tensor 中,Tensor 类似多维数组或者数学上的矩阵。OneFlow 提供了很多用于操作 Tensor 的算子,Tensor 与算子一起构成神经网络。

Tensor 有别于普通的多维数组的地方是:除了可以运行在 CPU 上外,它还可以运行在 其它 AI 芯片(如 NVIDIA GPU)上,因此可以提高运算速度。此外,OneFlow 还为张量提供了 自动求导 的功能。

  1. import oneflow as flow
  2. import numpy as np

创建 Tensor

有多种方法创建 Tensor,包括:

  • 直接从数据创建
  • 通过 Numpy 数组创建
  • 使用算子创建

直接从数据创建

可以直接从数据创建 Tensor:

  1. x1 = flow.tensor([[1, 2], [3, 4]])
  2. x2 = flow.tensor([[1.0, 2.0], [3.0, 4.0]])
  3. print(x1)
  4. print(x2)

可以看到创建的 x1x2 Tensor,它们的类型分别是 int64float32

  1. tensor([[1, 2],
  2. [3, 4]], dtype=oneflow.int64)
  3. tensor([[1., 2.],
  4. [3., 4.]], dtype=oneflow.float32)

通过 Numpy 数组创建

Tensor 可以通过 Numpy 数组创建,只需要在创建 Tensor 对象时,将 Numpy 数组作为参数传递即可。

  1. x3 = flow.tensor(np.ones((2,3)))
  2. x4 = flow.tensor(np.random.rand(2,3))
  3. print(x3)
  4. print(x4)
  1. tensor([[1., 1., 1.],
  2. [1., 1., 1.]], dtype=oneflow.float64)
  3. tensor([[0.6213, 0.6142, 0.1592],
  4. [0.5539, 0.8453, 0.8576]], dtype=oneflow.float64)

通过算子创建

OneFlow 中还提供了一些算子,可以通过它们创建 Tensor。比如 oneszeros,、eye,它们分别创建全为1的张量、全为0的张量和单位张量。

  1. x5 = flow.ones(2, 3)
  2. x6 = flow.zeros(2, 3)
  3. x7 = flow.eye(3)
  4. print(x5)
  5. print(x6)
  6. print(x7)
  1. tensor([[1., 1., 1.],
  2. [1., 1., 1.]], dtype=oneflow.float32)
  3. tensor([[0., 0., 0.],
  4. [0., 0., 0.]], dtype=oneflow.float32)
  5. tensor([[1., 0., 0.],
  6. [0., 1., 0.],
  7. [0., 0., 1.]], dtype=oneflow.float32)

randn 方法可以创建随机化的张量:

  1. x8 = flow.randn(2,3)

Tensortensor 的区别

细心的用户会发现,OneFlow 中有 oneflow.Tensoroneflow.tensor 两个接口,它们都能用来创建张量。那么它们有什么区别呢?

简单而言,大写的 Tensor 数据类型默认限定为 float32,而小写的 tensor 的数据类型可以随着创建时的数据改变。以下代码展示了两者这方面的区别:

  1. print(flow.Tensor([1, 2, 3]))
  2. print(flow.tensor([1, 2, 3]))
  3. print(flow.tensor([1.0, 2.0, 3.0]))

数据结果为:

  1. tensor([1., 2., 3.], dtype=oneflow.float32)
  2. tensor([1, 2, 3], dtype=oneflow.int64)
  3. tensor([1., 2., 3.], dtype=oneflow.float32)

此外,大写的 Tensor 可以在创建时不指定具体数据:

  1. x9 = flow.Tensor(2, 3)
  2. print(x9.shape)
  1. flow.Size([2, 3])

因此,如果在创建张量的同时不想指定数据,那么常常用 oneflow.Tensor,否则,应该使用 oneflow.tensor

Tensor 的属性

Tensor 的 shapedtypedevice 属性分别描述了 Tensor 的形状、数据类型和所在的设备类型。

  1. x9 = flow.randn(1,4)
  2. print(x9.shape)
  3. print(x9.dtype)
  4. print(x9.device)

输出结果分别展示了张量的形状、数据类型和所处的设备(第0号 CPU 上,之所以有编号,是因为 OneFlow 很方便自然地支持分布式,可参考 Consistent Tensor

  1. flow.Size([1, 4])
  2. oneflow.float32
  3. cpu:0

可以通过 reshape 方法改变 Tensor 的形状,用 to 方法改变 Tensor 的数据类型和所处设备:

  1. x10 = x9.reshape(2, 2)
  2. x11 = x10.to(dtype=flow.int32, device=flow.device("cuda"))
  3. print(x10.shape)
  4. print(x11.dtype, x11.device)
  1. flow.Size([2, 2])
  2. oneflow.int32 cuda:0

操作 Tensor 的常见算子

OneFlow 中提供了大量的算子,对 Tensor 进行操作,它们大多在 oneflowoneflow.Tensoroneflow.nnoneflow.nn.functional这几个名称空间下。

OneFlow 中的 Tensor,与 Numpy 数组一样易用。比如,支持与 Numpy 类似的切片操作:

  1. tensor = flow.ones(4, 4)
  2. print('First row: ',tensor[0])
  3. print('First column: ', tensor[:, 0])
  4. print('Last column:', tensor[..., -1])
  5. tensor[:,1] = 0
  6. print(tensor)
  1. First row: tensor([1., 1., 1., 1.], dtype=oneflow.float32)
  2. First column: tensor([1., 1., 1., 1.], dtype=oneflow.float32)
  3. Last column: tensor([1., 1., 1., 1.], dtype=oneflow.float32)
  4. tensor([[1., 0., 1., 1.],
  5. [1., 0., 1., 1.],
  6. [1., 0., 1., 1.],
  7. [1., 0., 1., 1.]], dtype=oneflow.float32)

此外,OneFlow 中还有很多其它操作,如算数相关操作的 addsubmuldiv等;位置相关操作的 scattergathergather_nd等;以及激活函数、卷积等(reluconv2d),点击它们的链接可以查看更详细的 API 说明,并找到更多的其它算子。

为正常使用来必力评论功能请激活JavaScript