数据操作

https://zh.d2l.ai/chapter_preliminaries/ndarray.html

1 Like
  1. 开头第二段 “感觉怼本部分很熟悉” typo: 怼 -> 对
  2. 2.1.2. 运算 第二段 u_i$ 前面少 $
  3. 2.1.2. 运算,有句话重复了?——“我们也可以把多个张量连结在一起,把它们端对端地叠起来形成一个更大的张量。 我们也可以 连结 (concatenate) 多个张量在一起,将它们端到端堆叠以形成更大的张量。”
  4. 2.1.6. 转换为其他 Python 对象 “当你在 CPU 或 GPU 上执行操作的时候,此时Python的NumPy包也希望使用相同的内存块执行其他操作时,你不希望停止计算。” 这句话或许可以将原文的等待(waiting to see whether) 也翻译出来?(可能只是我看中文版的这句话没怎么看懂 :wink:
2 Likes

Thanks @thebesttv ! 如果哪些语句可以改进,请发 PR 做 d2l 的 contributor!

前面y = x.reshape(3, 4)
后面
a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
没闹明白,为啥有的时候用reshape(),有时候用reshape(()),运行结果也没看出区别

6 Likes

torch文档里:torch.reshape`( input, shape) → Tensor
input的数据是Tensor类型.
shape是期望新的shape.
我是这么理解的:
y = x.reshape(3, 4)是torch下的tensor实例对象x的方法,a = torch.arange(3).reshape((3, 1))里面用的是torch文档里的方法。
两个方法只是形式看起来不一样:对于对象x的实例方法,当在python类里每次定义方法时都需要绑定这个实例self,就是reshape(self, shape),因为实例方法的调用离不开实例,我们需要把实例自己传给函数,调用的时候是这样的x.reshape(),其实就相当于是reshape(x, shape)

1 Like

My answer: 第二章

2 Likes

您好,
用pytorch的时候,您的书里面说:
“转换为 NumPy 张量很容易,反之也很容易。转换后的结果不共享内存“
但pytorch documentation说:
“Tensors on the CPU and NumPy arrays can share their underlying memory locations, and changing one will change the other.”
似乎最新版pytorch里的numpy()和from_numpy()会共享内存。英文版的书里也有这个问题。

6 Likes

you are right,they share same 内存

.numpy.from_numpy方法是可以共享内存的,但如果使用torch.tensor(ndarray)由numpy数组生成tensor,就不会共享内存。

1 Like

有时我们想从某个概率分布中随机采样来得到张量中每个元素的值。例如,当我们构造数组来作为神经网络中的参数时,我们通常会随机初始化参数的值。以下代码创建一个形状为 (3, 4) 的张量。其中的每个元素都从均值为0、标准差为1的标准高斯(正态)分布中随机采样。

torch.randn(3, 4)

tensor([[ 2.1173, -0.3256, -0.9538, -0.6639], [ 0.3116, -0.2538, -0.8779, 0.1701], [ 0.8984, -0.1042, -0.7746, 0.3877]])

这里生成的是随机数据,不是正态数据

torch.randn returns a tensor filled with random numbers from a normal distribution with mean 0 and variance 1 (also called the standard normal distribution).

https://pytorch.org/docs/stable/generated/torch.randn.html?highlight=randn#torch.randn

兄弟别搞错了,标准正态分布,不是说数据只能在-1, 0,1之间,数据是有可能落到大于1,小于-1的地方的

2 Likes

然inplace 操作更加符合性能需求,python为何不直接默认了呢?而是搞出一些 X +=Y 和 Z[:] =X + Y 这样的需要甄别的骚操作?在大规模的计算过程中,将矩阵修改为原地操作会是提升性能的一个小trick吗?

默认还得了。。。。原地修改只是一种策略罢了,又不是所有操作都要求原地修改?语言层面的东西因为你一个计算就称为骚操作?

“首先,可以使用 arange 创建一个行向量 x 。这个行向量包含从0开始的前12个整数,它们被默认创建为浮点数。” 不是默认创建为64int吗?

1 Like

可能是作者疏忽了吧,其他创建张量方法一般都是float32,已经写习惯了。

应该是函数的重载吧,主要就是为了方便实用来的,你可以 help(torch.reshape)查看文档,和这个用法差不多

感谢你的回答,我再次总结了一下。看下面的代码

X = torch.tensor([1.0, 2, 4, 8])
print(id(X))
A = X.numpy()
print(id(A))
X.add_(1), A

输出

140487850431104 140487850554928
 (tensor([2., 3., 5., 9.]), array([2., 3., 5., 9.], dtype=float32))

虽然,X和A的地址不一样,但共享内存更新X会改变A。而要把一个numpy转为tensor
a = numpy.ones(5),
方法一 b = torch.tensor(a) 相当于创建一个新tensor,不会共享内存
方法二 b = torch.from_numpy(a) 相当于从获取numpy中的值,会共享内存

故.numpy和from_numpy会共享内存,torch.tensor不会共享内存

4 Likes

2.1.6这一句话,确实没怎么懂,到底我们训练模型时,需要使用同一块内存,还是不使用同一块内存呢? 我理解的是相同的数据不使用同一块内存效率更高,不晓得对不对? 同一数据numpy中array格式转化为torch中tensor格式,内存地址确实变了的。

torch.reshape(input, shape)函数中两个参数的类型:
Args:
input (Tensor): the tensor to be reshaped
shape (tuple of ints): the new shape
shape是整数的元组,而元组可以写为(a,b)也可以写为a,b,并且input.reshape(shape)这种形式实际上调用的是torch.reshape(input,shape)。这样应该就可以理解了。