动手学机器学习v2-04-1数据操作

数据操作

1. N维数组(张量)

  • 张量类
    • 在MXNet中为ndarray
    • 在PyTorch和TensorFlow中为Tensor
  • 无论使用哪个深度学习框架,它的张量类都与Numpy的ndarray类似,但要多一些重要功能:
    • GPU很好地支持加速计算,而NumPy仅支持CPU计算;
    • 张量类支持自动微分。这些功能使得张量类更适合深度学习。

2. 创建数组

2.1 入门

  • 导入torch
import torch
  • 使用arange创建一个行向量x

它们被默认创建为浮点数。张量中的每个值都称为张量的元素(element)

x = torch.arange(12)
x

  • 通过张量的shape属性来访问张量的形状 (沿每个轴的长度)
x.shape

  • 如果只想知道张量中元素的总数,即形状的所有元素乘积,可以检查它的大小(size)。 因为这里在处理的是一个向量,所以它的shape与它的size相同。
x.numel()

  • 改变张量的形状

注意,通过改变张量的形状,张量的大小不会改变。

X = x.reshape(3, 4)
X

  • 初始化全0矩阵
torch.zeros((2, 3, 4))

  • 初始化全1矩阵
torch.ones((2, 3, 4))

  • 随机初始化,数值符合正态分布(均值为0,标准差为1)
torch.randn(3, 4)

  • 通过提供包含数值的Python列表(或嵌套列表)来为所需张量中的每个元素赋予确定值

最外层的列表对应于轴0,内层的列表对应于轴1。

torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])

2.2 运算

  • 基本运算符
x = torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2, 2, 2, 2])
x + y, x - y, x * y, x / y, x ** y  # **运算符是求幂运算

  • e的幂次
torch.exp(x)

  • 多个张量连结(上下合并、左右合并)

当我们沿行(轴-0,形状的第一个元素)和按列(轴-1,形状的第二个元素)

X = torch.arange(12, dtype=torch.float32).reshape((3,4))
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)

  • 逻辑运算符判断两个张量在对应的位置上是否相等
X == Y

  • 对张量中的所有元素进行求和会产生一个只有一个元素的张量
X.sum()

2.3 广播机制

机制的工作方式如下:首先,通过适当复制元素来扩展一个或两个数组,以便在转换之后,两个张量具有相同的形状。其次,对生成的数组执行按元素操作。

  • 创建数组
a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
a, b

  • 广播式加法:矩阵a将复制列,矩阵b将复制行,然后再按元素相加。
a + b

2.4 索引和切片

  • [-1]选择最后一个元素,可以用[1:3]选择第二个和第三个元素
X[-1], X[1:3]

  • 指定索引来将元素写入矩阵
X[1, 2] = 9
X

X[0:2, :] = 12
X

2.5 节省内存

用Python的id()函数演示了这一点,它给我们提供了内存中引用对象的确切地址

  • Python首先计算Y + X,为结果分配新的内存,然后使Y指向内存中的这个新位置
before = id(Y)
Y = Y + X
id(Y) == before

  • 为了不分配新的地址,那么执行原地操作

使用切片表示法将操作的结果分配给先前分配的数组,例如Y[:] = 。我们首先创建一个新的矩阵Z,其形状与另一个Y相同,使用zeros_like来分配一个全0的块。

Z = torch.zeros_like(Y)
print('id(Z):', id(Z))
Z[:] = X + Y
print('id(Z):', id(Z))

  • 在后续计算中没有重复使用X,我们也可以使用X[:] = X + Y或X += Y来减少操作的内存开销
before = id(X)
X += Y
id(X) == before

2.6 转换为其他Python对象

  • 转换为NumPy张量很容易,反之也很容易。转换后的结果不共享内存
A = X.numpy()
B = torch.tensor(A)
type(A), type(B)

  • 要将大小为1的张量转换为Python标量,可以调用item函数或Python的内置函数。
a = torch.tensor([3.5])
a, a.item(), float(a), int(a)

posted @ 2021-10-02 23:52  Trouvaille_fighting  阅读(105)  评论(0)    收藏  举报