易学好用的 Pytorch — Tensor、tensor、as_tensor 和 from_numpy

这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战

最近每天都谈一谈自己感想,可能是随着年龄增长,经历的也多了,有的时候总想啰嗦两句。这些年一直 focus 前端,也就是和顾客最接近层面,现在前端技术可以是日新月异,所以得紧跟其脚步,新的技术其绚丽 demo,通常会紧紧将我吸引住,让我夜不能寐,将其搞到手,还没等到应用,下一个又来了。

今天深度学习paper 也是如此,一路追赶,多少披星戴月。不过感觉自己还是停留在应用,也是处于整个体系前端,希望自己能够停下浮躁,跟风心里。也停下疲惫脚步。打打基础,毕竟先来看底层东西,虽然耗时,不过这些年看过来,变化不大,比较保值。

tensor 和 Tensor

data = np.array([1,2,3])
复制代码
  • torch.tensor 是一个工厂方法,返回一个 Tensor 类的实例
  • torch.Tensor 是一个类,调用类来实例化一个 Tensor
torch.tensor(data) #tensor([1, 2, 3])
复制代码

接下来我们就用以下几种方法来解释一下如何基于 data 这个 numpy.ndarray 来创建一个 tensor

t1 = torch.Tensor(data)
t2 = torch.tensor(data)
t3 = torch.as_tensor(data)
t4 = torch.from_numpy(data)
复制代码

tensor([1., 2., 3.]) 
tensor([1, 2, 3]) 
tensor([1, 2, 3]) 
tensor([1, 2, 3])
复制代码

大家从输出结果可能已经看出了 Tensor 类型浮点型,而其他都是整型,为证实将他们类型输出一下。

print(t1.dtype)
print(t2.dtype)
print(t3.dtype)
print(t4.dtype)
复制代码
torch.float32 
torch.int64 
torch.int64 
torch.int64
复制代码

这是因为 Tensor 采用默认指定数据类型作为类型,torch.get_default_dtype()torch.float32

也可以在创建 torch.tensor 时候指定数据类型 print(torch.tensor(np.array([1.,2.,3.]),dtype=torch.float32))

tensor 类型

我们区分 tensor 主要从两个方面,一个是 tensor 的数据类型,有点编程经验,应该不难理解。tensor 作为容器,所以其类型是由其中放置数据类型所决定,在选择 tensor 数据类型,需要考虑数据精度要求,够用就好不要浪费。

t1 = torch.tensor([1,2,3])
t2 = torch.tensor([1.,2.,3.])
print(t1.dtype)
print(t2.dtype)
复制代码
torch.int64 
torch.float32
复制代码

通过下面代码可以了解到 torch.Tensor 和 torch.tensor 是对数据进行 copy 而 torch.as_tensor 和 from_numpy 是对 numpy array 的对象共享内存。

data = np.array([1,2,3])
复制代码
t1 = torch.Tensor(data)
t2 = torch.tensor(data)
t3 = torch.as_tensor(data)
t4 = torch.from_numpy(data)
复制代码
data[0] = 0
data[1] = 0
data[2] = 0
复制代码
print(t1) #tensor([1., 2., 3.])
print(t2) # tensor([1, 2, 3])
复制代码
print(t3) #tensor([0, 0, 0])
print(t4) #tensor([0, 0, 0])
复制代码
  • 由于 numpy.ndarray 对象是分配在 CPU 上,所以如果 torch 正在使用 GPU,在调用 torch.as_tensor 时,就需要将数据从 CPU 复制到 GPU。
  • as_tensor 不支持 python 内置的列表结构数据,例如 list
  • 如果想要更好的使用 as_tensor 就需要开发人员对内存,否则可能不经意之间就修改底层数据,导致可能影响多个对象。
  • 如果需要在 numpy.ndarray 对象和 tensor 对象之间来回切换,使用 as_tensor() 可以提升性能,如果只是进行一次加载,使用 as_tensor 优势就不那么明显。

还有就是 tensor 根据其运行设备(device)不同而不同,所以下面例子介绍运行在 CPU 上 tensor 和运行在 GPU 上 tensor 是无法进行计算。

t1 + t2 #tensor([2., 4., 6.])
复制代码
t1 = torch.tensor([1,2,3])
t2 = t1.cuda()
复制代码
t1 + t2
复制代码
RuntimeError                              Traceback (most recent call last)
<ipython-input-4-9ac58c83af08> in <module>()
----> 1 t1 + t2
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!
复制代码

这里还有一点需要注意就是 reference 和 copy,虽然这些方法都可以得到一个我们想要 tensor,

扫描二维码关注公众号,回复: 13676338 查看本文章
batch = next(iter(train_loader))
复制代码
len(batch) #2
复制代码
type(batch) #list
复制代码
images,labels = batch
len(images) #10
复制代码
grid = torchvision.utils.make_grid(images,row=10)
plt.figure(figsize=(15,15))
plt.imshow(np.transpose(grid,(1,2,0)))
复制代码

fashion_mnist_batch.png

猜你喜欢

转载自juejin.im/post/7060422095880224776