复现华为2020年的论文AdderNet,在编码过程中涉及到了pytorch
中张量的扩展机制,这里记录一下踩到的坑。
张量扩展机制
Pytorch
中的大部分算术操作都是支持维度扩展的:即使两个张量的维度不相等,但只要两个张量的维度满足一定的条件,在进行运算时python
会自动对这两个张量的数据进行扩展,使它们的维度相等,扩展后再进行加减操作。例如:
python
a=torch.tensor([[1.0,2.0,3.0],[4.0,5.0,6.0]]) # size= 1 x 2 x3
b=torch.tensor([[1.0,2.0,3.0]]) # size= 1 x 3
a - b
得出的结果是
python
tensor([[[0., 0., 0.],
[3., 3., 3.]]])
# size= 1 x 2 x 3
两个张量需要满足的条件为:
- 每个张量至少含有一个维度
- 在对张量进行迭代运算时,会从最末尾的维度对齐后开始迭代,迭代到某一个维度时,两个张量此时的维度必须以下的三个条件之一:
- 相等
- 有一个维度为1
- 有一个张量此时的维度不存在
例如:
python
x=torch.randn(5,3,4,1)
y=torch.randn( 3,1,1)
# 1 => 1 满足条件
# 4 => 1 满足条件
# 3 => 3 满足条件
# 5 => None 满足条件
# 此时就可以执行
z = x - y
# 反例
x=torch.empty(5,2,4,1)
y=torch.empty( 3,1,1)
# 1 => 1 满足条件
# 4 => 1 满足条件
# 2 => 3 不满足条件
# 5 => None 满足条件
# 此时执行下面的代码就会报错
z = x - y
张量扩展后的运算规则
如果两个张量满足了维度扩展的条件(broadcastable),通过运算得到的结果的尺寸为
- 如果x和y的维数不相等,在维数较少的张量的维数上预加1,使其长度相等 (对应第三种情况)
- 对于每个维度的大小,所产生的维度大小是沿该维度的x和y的大小的最大值。