数据操作

对于广播机制中两个张量按元素相加,要满足以下两个条件:
1、两个张量维度相同
2、每个张量的size里面要有一个维度为1
然后各自按照那个维度复制再按元素相加。

  1. 运行X >Y和X<Y后会返回一个全为bool的张量
    返回结果分别为:
    tensor([[False, False, False, False],
    [ True, True, True, True],
    [ True, True, True, True]])

    tensor([[ True, False, True, False],
    [False, False, False, False],
    [False, False, False, False]])
    2.使用3维张量运行
    // 使用三维向量
    a = torch.arange(3).reshape(3,1,1)
    b = torch.arange(6).reshape(1,3,2)
    a+b
    如下为广播机制的分析:

import torch
import numpy as np

x = torch.rand(3,3)
xr1 = x.reshape(1,9)
xr9 = x.reshape(9,1)
print(id(x) == id(xr1))
print(id(x) == id(xr9))
print(id(x.storage()) == id(xr1.storage()))
print(id(x.storage()) == id(xr9.storage()))

results :
False
False
True
True
2.1.5 节省内存小节似乎可以提一下张量(tensor)的存储结构,这样可以更底层知道其是否共享存储。

除了1那个维度之外的维度必须相等。。。。。。。。。。。。

哦,我明白了,共享内存的意思不是说地址一样,而是说一个改变会引起另一个改变?

 满足广播的条件:需要两个张量的每个维度满足以下条件:

  a.这两个维度的大小相等
  b. 某个维度 一个张量有,一个张量没有
  c.某个维度 一个张量有,一个张量也有但大小是1

个人见解:我看了一下两个reshape()的API说明,reshape提供两种参数接收方式,也就是说有重载。一种是直接接收数据 reshape(self, *shape: _int),也就是以reshape(3,4)的形式,一种是sequence的形式reshape(self, shape: Sequence[Union[_int, SymInt]]),这种就是((3,4))

这里torch.arange(3)生成的不也是tensor对象吗,两者有什么区别吗,还是不明白x.reshape(3,4)和x.reshape((3,4))有什么区别 :eyes:

三峡刘战来也[quote=“goldpiggy, post:1, topic:1747, full:true”]
https://zh.d2l.ai/chapter_preliminaries/ndarray.html
[/quote]

:stuck_out_tongue:

可以参考 :grinning:
广播机制规则:

  • 如果遵守以下规则,则两个tensor是“可广播的”:
    • 每个tensor至少有一个维度;
    • 遍历tensor所有维度时,从末尾随开始遍历,两个tensor存在下列情况:
      • tensor维度相等。
      • tensor维度不等且其中一个维度为1。
      • tensor维度不等且其中一个维度不存在。
  • 如果两个tensor是“可广播的”,则计算过程遵循下列规则:
    • 如果两个tensor的维度不同,则在维度较小的tensor的前面增加维度,使它们维度相等。
    • 对于每个维度,计算结果的维度值取两个tensor中较大的那个值。
    • 两个tensor扩展维度的过程是将数值进行复制。
2 Likes

我之前找到的形式上的规律是: 两个张量总是在两轴间成对出现x,1和1,x形式,然后对1的轴做广播;其他轴若不能配对则应该保持大小相同。 :smiling_face_with_three_hearts: 还是你这个规则全面。

  1. 运行本节中的代码。将本节中的条件语句X == Y更改为X < YX > Y,然后看看你可以得到什么样的张量。

    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]])
    X > Y

​ 输出:

tensor([[False, False, False, False],
        [ True,  True,  True,  True],
        [ True,  True,  True,  True]])
        
  1. 用其他形状(例如三维张量)替换广播机制中按元素操作的两个张量。结果是否与预期相同?
a = torch.arange(20).reshape((5,1,4))
b = torch.arange(48).reshape((6,2,4))
(a+b).shape
RuntimeError: The size of tensor a (5) must match the size of tensor b (6) at non-singleton dimension 0
a = torch.arange(30).reshape((2,3,1,5))
b = torch.arange(60).reshape((3,4,5))
(a+b).shape
torch.Size([2, 3, 4, 5])

广播机制条件:

1)每个张靓至少为1维

2)从后往前比张量形状,维度大小要么相等,要么其中一个等于1,要么其中一个不存在

例: 2 3 1 5 3 4 5 5比5,1比4,3比3 可以广播

我对广播机制的理解是
1.每个张量至少具有一个维度;
2.广播时,从尾部,也可以说是右边开始比对维度,需要满足尺寸大小相等或其中一个为1或其中一个不存在
例如
a = torch.arange(36).reshape((1,9,4))
b = torch.arange(9).reshape((9,1))
a + b就能运行
参考

第一题
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]])

X数据如下所示

0. 1. 2. 3.
4. 5. 6. 7.
8. 9. 10. 11.

Y数据如下所示

2. 1. 4. 3.
1. 2. 3. 4.
4. 3. 2. 1.

X == Y的结果为

False True False True
False False False False
False False False False
X<Y的结果为
True False True False
False False False False
False False False False
X>Y的结果为
False False False False
True True True True
True True True True

得到了一些由比较的布尔值组成的张量

第二题

a = torch.arange(3).reshape((3, 1))

b = torch.arange(2).reshape((1, 2))
a,b

输出框

(tensor([[0],
         [1],
         [2]]),
 tensor([[0, 1]]))
a = torch.arange(3).reshape((1,3, 1))
a

输出框

tensor([[[0],
         [1],
         [2]]])
a+b

输出框

tensor([[[0, 1],
         [1, 2],
         [2, 3]]])

可以看出a,b都被复制为shape=(1, 3, 2)形状,然后相加,结果仍然为(1, 3, 2)形状,说明广播机制对张量仍然生效

动手代码写了一下,一个括号完全可以的,所以应该是按照正常方法传参就可以。

注意:

  • .add().add_()都能把两个张量加起来,但.add_in-place 操作,也就是结果会存储到原来的x中。
  • Q:共享内存的意思不是说地址一样,而是说一个改变会引起另一个改变?
    A :如果你对其中一个对象进行了修改,那么另一个对象也会反映出这些更改,因为它们实际上是在操作同一块内存区域,即同一地址。