d2l之部分数据操作
一、广播机制
两个张量进行运算(加减乘除幂等)
如果两个张量形状相同则很容易进行运算,如果两个张量不同的时候该如何进行运算呢?
1、a张量竖为1,b张量横为1 比如:a = torch.arange(3).reshape((3, 1)), b = torch.arange(2).reshape((1, 2))
a+b的计算过程为:先将a张量竖复制为跟b一样多的列[[0,1,2], [0,1,2]], b张量按行复制为跟a一样多行[[0, 0, 0], [1,1,1]]
将两个张量转换成形状相同的张量之后再进行计算
2、a和b中有一个的横或者竖为1且不唯1的行或者列要跟另外的张量大小一致,否则没法执行广播机制。
比如:a = torch.arange(4).reshape(4,1), b = torch.arange(4).reshape(2,2) ; a + b 会报错
a = torch.arange(4).reshape(4,1), b = torch.arange(8).reshape(4,2); a会先将形状转换为跟b一样大小,按列复制
二、节省内存之指针
python大部分运算情况下都是值复制,如果内存是几百兆情况下则会导致巨大的内存波动。
1、首先,我们不想总是不必要地分配内存。在机器学习中,我们可能有数百兆的参数,并且在一秒内多次更新所有参数。通常情况下,我们希望原地执行这些更新;
2、如果我们不原地更新,其他引用仍然会指向旧的内存位置,这样我们的某些代码可能会无意中引用旧的参数。
原地修改的几种方式:
1、直接使用整个Z的内存:Z[:] = X + Y
2、修改Z中的某个元素:Z[0, 0] = 10
3、修改Z中的某一列:Z[0] = torch.arange(5)
4、如果是自加: X = X + Y 则X会使用新的地址;此时如果改为: X += Y 那么X依旧是原来的地址
三、有时候需要ndarry和tensor相互之间进行转换,则可以用如下进行
A = X.numpy() # 将tensor转换为ndarry类型的张量
B = torch.tensor(A) # 因为A已经是ndarry, 这里通过torch.tensor()转换为tensor张量
对应的学习链接是:https://zh-v2.d2l.ai/chapter_preliminaries/ndarray.html