oneflow icon indicating copy to clipboard operation
oneflow copied to clipboard

numpy type 和 tensor type 二元运算类型转换问题

Open lixiang007666 opened this issue 3 years ago • 5 comments

问题来源:

https://github.com/Oneflow-Inc/OneCloud/issues/141#issuecomment-1203781305 https://github.com/Oneflow-Inc/OneCloud/issues/141#issuecomment-1203912725

最小复现代码:

import oneflow as flow
import numpy as np
a=np.array([1,2]).astype(np.double)[0]
b=flow.randn(10)
c= a + b
print(type(c))

import torch
a=np.array([1,2]).astype(np.double)[0]
b=torch.randn(10)
c= a + b
print(type(c))

上面代码的输出结果: image

从上面来看,在 oneflow 里, numpy.float64 和 tensor 做二元运算,类型会被强转为 numpy.ndarray,而 torch 转为 tensor。

lixiang007666 avatar Aug 04 '22 02:08 lixiang007666

np.array([1,2]).astype(np.double)[0] 是 numpy.float64 类型,所以没有调用 ScalarAdd2Functor。

lixiang007666 avatar Aug 04 '22 04:08 lixiang007666

是的,其他numpy类型是可以被转换为Tensor

shaoshitong avatar Aug 04 '22 07:08 shaoshitong

是的,其他numpy类型是可以被转换为Tensor

也不是这样的,总结了下:

oneflow 当前与 torch 没对齐的地方有下面两点:

  • 我们以 c = a + b 为例,假设 a 为 numpy.xx 类型(实际上必须一个 “scalar”,如果一个 numpy 数组和 tensor 二元运算,在 torch 上是不支持的,oneflow 支持),b 为 oneflow.tensor,那么在 oneflow 上,计算结果的 type 是 numpy.ndarray,在 torch 上则是一个 tensor。
  • c = b + a 的情况,b 还是 oneflow.tensor,a 还是 numpy.xx 类型,在常规情况下(这里调用 scalaradd 算子,上面那种情况调用 ScalarAdd2)。这种情况下 torch 支持 a 为各种类型,比如 numpy.int,而 oneflow 则会报下面的已知问题: image。因为 oneflow 只能把 numpy.float64 、long 和 bool 转换为 scalar。

lixiang007666 avatar Aug 04 '22 08:08 lixiang007666

好的学到了

shaoshitong avatar Aug 04 '22 09:08 shaoshitong

这里分 case 详细讨论一下这个问题:

  • 第一种:a 是 numpy.xx type,b 是 tensor,做 b+a。
import oneflow as flow
import numpy as np
a=np.array([1]).astype(np.double)[0]
print(type(a))
b=flow.randn(1)
c= b + a
print(type(c))

import torch
import numpy as np
a=np.array([1]).astype(np.double)[0]
print(type(a))
b=torch.randn(1)
c= b + a
print(type(c))

这时 oneflow 和 torch 是对齐的。

  • 第二种:a 是 numpy.float64 type,b 是 tensor,做 a+b。
import oneflow as flow
import numpy as np
a=np.array([1]).astype(np.double)[0]
print(type(a))
b=flow.randn(1)
c= a + b
print(type(c))

import torch
import numpy as np
a=np.array([1]).astype(np.double)[0]
print(type(a))
b=torch.randn(1)
c= a + b
print(type(c))

这时 print(type(c)),oneflow 的输出为 numpy.ndarray,而 torch 是个 tensor,也就是这个 issue 的来源。

  • 第三种:a 是 numpy.int type,b 是 tensor,做 b+a。
import oneflow as flow
import numpy as np
a=np.array([1]).astype(np.int)[0]
print(type(a))
b=flow.randn(1)
c= b + a
print(type(c))

import torch
import numpy as np
a=np.array([1]).astype(np.int)[0]
print(type(a))
b=torch.randn(1)
c= b + a
print(type(c))

这时,oneflow 不支持这种情况,torch 输出还为 tensor。

  • 第四种:a 是 scalar,b 是 tensor,做 a+b。
import oneflow as flow
import numpy as np
a=1.0
print(type(a))
b=flow.randn(1)
c= a + b
print(type(c))

import torch
import numpy as np
a=1.0
print(type(a))
b=torch.randn(1)
c= a + b
print(type(c))

这种情况两者是对齐的。

  • 第五种:a 是 numpy.ndarray type,b 是 tensor,做 a+b 运算。
import oneflow as flow
import numpy as np
a=np.array([1]).astype(np.double)
print(type(a))
b=flow.randn(1)
c= a + b
print(type(c))

import torch
import numpy as np
a=np.array([1]).astype(np.double)
print(type(a))
b=torch.randn(1)
c= a + b
print(type(c))

这时,oneflow 是支持这种运算的,输出为 numpy type,而 torch 则不支持,既:TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and 'Tensor'

lixiang007666 avatar Aug 08 '22 02:08 lixiang007666