我们使用Numpy也是可以手动去编写神经网络进行反向传播深度学习的,就是有两个问题,
1.Numpy手动去编写神经网络很繁琐,代码量较大,不利于大规模开发;2.Numpy无法直接使用GPU加速计算
看到网上有很多人说PyTorch很好用,比TensorFlow优雅便捷。个人认为其中一个很主要的原因PyTorch很类似与Numpy,对数据操作处理很简单。并且PyTorch是支持使用GPU加速的,所以有人比喻PyTorch是GPU版本的Numpy。
PyTorch为了实现GPU加速功能,引入了Tensor,为了实现自动求导功能引入了Variable。但是由于引入了这些新的概念,会让一些不理解初学者在使用的时候遇到一些问题。
我们现在已经知道了PyTorch为了实现GPU加速功能,引入了Tensor,为了实现自动求导功能引入了Variable。我们一般读取的数据都是以Numpy Array方式的。在TensorFlow,Numpy的数据会在输入网络后自动转换为Tensor,一般不需要我们进行显性操作,当然偶尔也会有例外,可以参考 [开发技巧]·TensorFlow中numpy与tensor数据相互转化。但是在PyTorch,需要我们自己进行显性操作才可以的。
下面我以一个网络训练的过程来讲解它们之间如何进行相互的转换。
总结一下,真正和我们开发人员直接接触的是Numpy数据,需要送入网络时进行Numpy2Tensor,如果一些Tensor作为参数需要求解梯度信息时进行Tensor2Variable。需要从Variable取数据时,使用Variable2Tensor。对Tensor进行读取操作时需要Tensor2Numpy。
注意一点,Numpy与Variable无法直接转换,需要经过Tensor作为中介。
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)