PyTorch中Numpy,Tensor与Variable深入理解与转换技巧

tech2025-08-12  14

1.问题描述

我们使用Numpy也是可以手动去编写神经网络进行反向传播深度学习的,就是有两个问题,

1.Numpy手动去编写神经网络很繁琐,代码量较大,不利于大规模开发;2.Numpy无法直接使用GPU加速计算

看到网上有很多人说PyTorch很好用,比TensorFlow优雅便捷。个人认为其中一个很主要的原因PyTorch很类似与Numpy,对数据操作处理很简单。并且PyTorch是支持使用GPU加速的,所以有人比喻PyTorch是GPU版本的Numpy。

PyTorch为了实现GPU加速功能,引入了Tensor,为了实现自动求导功能引入了Variable。但是由于引入了这些新的概念,会让一些不理解初学者在使用的时候遇到一些问题。

2.问题剖析

我们现在已经知道了PyTorch为了实现GPU加速功能,引入了Tensor,为了实现自动求导功能引入了Variable。我们一般读取的数据都是以Numpy Array方式的。在TensorFlow,Numpy的数据会在输入网络后自动转换为Tensor,一般不需要我们进行显性操作,当然偶尔也会有例外,可以参考 [开发技巧]·TensorFlow中numpy与tensor数据相互转化。但是在PyTorch,需要我们自己进行显性操作才可以的。

下面我以一个网络训练的过程来讲解它们之间如何进行相互的转换。

首先我们会读取Numpy的数据,我们为了能够送入网络,使用GPU计算加速,所以要进行Numpy2Tensor操作,由于网络输入输出都是Variable,我们还需要Tensor2Variable。在训练的过程中,我们需要取出loss的值,由于loss参与了backward(),所以此时的loss已经变成了Variable,我们取出loss时需要取出的是Tensor。同样的,如果我想取出网络输出的结果时,由于网络输入输出都是Variable,也需要执行Variable2Tensor,如果进一步我们想把loss显示出来,就需要Tensor2Numpy。

总结一下,真正和我们开发人员直接接触的是Numpy数据,需要送入网络时进行Numpy2Tensor,如果一些Tensor作为参数需要求解梯度信息时进行Tensor2Variable。需要从Variable取数据时,使用Variable2Tensor。对Tensor进行读取操作时需要Tensor2Numpy。

3.转换方法

Numpy2Tensor:1. torch.from_numpy(Numpy_data) 2. torch.tensor(Numpy_data)Tensor2Variable: 1. Variable(Tensor_data)Variable2Tensor: 1. Variable_data.data()Tensor2Numpy : 1.Tensor_data.numpy()

注意一点,Numpy与Variable无法直接转换,需要经过Tensor作为中介。

4 实际测试

import numpy as np import torch from torch.autograd import Variable a=np.random.randint(0,4,(2,2)) print(a) b=torch.from_numpy(a) print(b) c=Variable(torch.from_numpy(a)) print(c) d=c.data.numpy() print(d)

输出:

[[2 0]  [2 3]] tensor([[2, 0],         [2, 3]], dtype=torch.int32) tensor([[2, 0],         [2, 3]], dtype=torch.int32) [[2 0]  [2 3]]  

关于网络输入为tensor还是Variable,传入参数可以为tensor也可以为variable,但尽量传variable吧,反正input在测试的时候都要包装成variable,做参数更新,如下;

import torch from torch.autograd import Variable tensor = torch.FloatTensor([[1,2],[3,4]]) variable = Variable(tensor,requires_grad=True) print(tensor) print(variable) t_out = torch.mean(tensor * tensor) v_out = torch.mean(variable * variable) v_out.backward() print('反向传播之后',variable) #反向传播的时候variable 是受影响的,因为反向传播了 print('变量的data是tensor类型--',variable.data) print('variable转为numpy--',variable.data.numpy())# 必须借助于tensor转换为numpy

参考一幅图

numpy_tensor=np.random.randint(0,4,(2,2)) # numpy转为tensor pytorch_tensor1=torch.from_numpy(numpy_tensor) pytorch_tensor2=torch.tensor(numpy_tensor) gpu_tensor=pytorch_tensor1.cuda() print(pytorch_tensor1) print(pytorch_tensor2) print(gpu_tensor) # pytorch_tensor转为numpy numpy_array=pytorch_tensor1.numpy() # 如果tensor在gp上 numpy_array=pytorch_tensor1.cpu().numpy()

 

 输出:

tensor([[0, 3], [0, 0]], dtype=torch.int32) tensor([[0, 3], [0, 0]], dtype=torch.int32) tensor([[0, 3], [0, 0]], device='cuda:0', dtype=torch.int32)

 

最新回复(0)