part-0_4.pdf
https://zh-v2.d2l.ai/chapter_preliminaries/ndarray.html
https://courses.d2l.ai/zh-v2/assets/notebooks/chapter_preliminaries/ndarray.slides.html
N维数组样例
N维数组是机器学习和神经网络的主要数据结构


创建数组
需要
- 形状
- 每个元素的数据类型
- 每个元素的值

访问元素

数据操作
导入torch
张量表示由一个数值组成的数组,这个数组可能有多个维度
>>> import torch>>> x = torch.arange(12)>>> xtensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
放入一个array
可以通过张量的shape属性来访问张量(沿每个轴的长度)的形状 和张量中元素的总数
>>> x.shapetorch.Size([12])>>> x.numel()12
要想改变一个张量的形状而不改变元素数量和元素值,可以调用reshape函数
>>> x = x.reshape(3, 4)>>> xtensor([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]])
使用全0、全1、其他常量,或者从特定分布中随机采样的数字
>>> torch.zeros((2, 3, 4))tensor([[[0., 0., 0., 0.],[0., 0., 0., 0.],[0., 0., 0., 0.]],[[0., 0., 0., 0.],[0., 0., 0., 0.],[0., 0., 0., 0.]]])>>> torch.ones((2, 3, 4));tensor([[[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.]],[[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.]]])>>> torch.randn(3, 4);tensor([[ 0.0500, -0.3205, 1.1392, -0.1057],[ 1.6262, 0.9511, -0.3953, 1.1746],[-0.0074, -0.2217, -0.1776, -1.1396]])
通过提供包含数值的Python列表(或嵌套列表),来为所需张量中的每个元素赋予确定值
>>> torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])tensor([[2, 1, 4, 3],[1, 2, 3, 4],[4, 3, 2, 1]])
常见的标准算术运算符(+、-、、/和*)都可以被升级为按元素运算
>>> 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(tensor([ 3., 4., 6., 10.]), tensor([-1., 0., 2., 6.]), tensor([ 2., 4., 8., 16.]), tensor([0.5000, 1.0000, 2.0000, 4.0000]), tensor([ 1., 4., 16., 64.]))
“按元素”方式可以应用更多的计算
>>> torch.exp(x)tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])
我们也可以把多个张量连结(concatenate)在一起
>>> 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)(tensor([[ 0., 1., 2., 3.],[ 4., 5., 6., 7.],[ 8., 9., 10., 11.],[ 2., 1., 4., 3.],[ 1., 2., 3., 4.],[ 4., 3., 2., 1.]]),tensor([[ 0., 1., 2., 3., 2., 1., 4., 3.],[ 4., 5., 6., 7., 1., 2., 3., 4.],[ 8., 9., 10., 11., 4., 3., 2., 1.]]))
dim=0: 按第0行合并dim=1: 按第1列合并
通过逻辑运算符构建二元张量
>>> X == Ytensor([[False, True, False, True],[False, False, False, False],[False, False, False, False]])
对张量中的所有元素进行求和,会产生一个单元素张量
>>> X.sum()tensor(66.)
即使形状不同,我们仍然可以通过调用 广播机制(broadcasting mechanism)来执行按元素操作
>>> a = torch.arange(3).reshape((3, 1))>>> b = torch.arange(2).reshape((1, 2))>>> a, b(tensor([[0],[1],[2]]),tensor([[0, 1]]))>>> a + btensor([[0, 1],[1, 2],[2, 3]])
张量和数组虽然数学概念不同, 但有时会混用. 对张量进行”扩展”为矩阵
可以用[-1]选择最后一个元素,可以用[1:3]选择第二个和第三个元素
>>> X[-1], X[1:3](tensor([ 8., 9., 10., 11.]),tensor([[ 4., 5., 6., 7.],[ 8., 9., 10., 11.]]))
除读取外,我们还可以通过指定索引来将元素写入矩阵
>>> Xtensor([[ 0., 1., 2., 3.],[ 4., 5., 6., 7.],[ 8., 9., 10., 11.]])>>> X[1, 2] = 9>>> Xtensor([[ 0., 1., 2., 3.],[ 4., 5., 9., 7.],[ 8., 9., 10., 11.]])
为多个元素赋值相同的值,我们只需要索引所有元素,然后为它们赋值
>>> X[0:2, :] = 12>>> Xtensor([[12., 12., 12., 12.],[12., 12., 12., 12.],[ 8., 9., 10., 11.]])
运行一些操作可能会导致为新结果分配内存
>>> before = id(Y)>>> Y = Y + X>>> id(Y) == beforeFalse
执行原地操作
>>> Z = torch.zeros_like(Y)>>> print('id(Z):', id(Z))id(Z): 140482931687568>>> Z[:] = X + Y>>> print('id(Z):', id(Z))id(Z): 140482931687568
如果在后续计算中没有重复使用X, 我们也可以使用X[:] = X + Y或X += Y来减少操作的内存开销
>>> before = id(X)>>> print('id(X):', id(X))id(X): 140482931691248>>> X += Y>>> print('id(X):', id(X))id(X): 140482931691248>>> X = X + Y>>> print('id(X):', id(X))id(X): 140482931716160
转换为NumPy张量(ndarray)
>>> A = X.numpy()>>> B = torch.tensor(A)>>> type(A), type(B)(<class 'numpy.ndarray'>, <class 'torch.Tensor'>)
将大小为1的张量转换为Python标量
>>> a = torch.tensor([3.5])>>> a, a.item(), float(a), int(a)(tensor([3.5000]), 3.5, 3.5, 3)
