Pytorch中numpy() ,detach(),clone(),copy_(),deepcopy(),from_numpy(),array(),FloatTensor()详解

numpy():

Tensor.numpy():将Tensor转化为ndarray,这里的Tensor可以是标量或者向量(与item()不同)转换前后的dtype不会改变

代码:

import torch
import torch.nn as nn

x = torch.Tensor([1,2])
print(x)
print(x.type())
y = x.numpy()
print(y)

结果:

tensor([1., 2.])
torch.FloatTensor
[1. 2.]

detach():

返回一个新的Variable,从当前计算图中分离下来的,但是仍指向原变量的存放位置,不同之处只是requires_grad为false,得到的这个Variable永远不需要计算其梯度,不具有grad。

即使之后重新将它的requires_grad置为true,它也不会具有梯度grad,这样我们就会继续使用这个新的Variable进行计算,后面当我们进行反向传播时,到该调用detach()的Variable就会停止,不能再继续向前进行传播

detach()操作后的tensor与原始tensor共享数据内存,当原始tensor在计算图中数值发生反向传播等更新之后,detach()的tensor值也发生了改变。

源码为:

def detach(self):
    """Returns a new Variable, detached from the current graph.
    Result will never require gradient. If the input is volatile, the output
    will be volatile too.
    .. note::
     Returned Variable uses the same data tensor, as the original one, and
     in-place modifications on either of them will be seen, and may trigger
     errors in correctness checks.
    """
    result = NoGrad()(self) # this is needed, because it merges version counters
    result._grad_fn = None
     return result

推荐博客:

https://www.jb51.net/article/259928.html


clone():
表示clone后的返回值是个中间变量,因此支持梯度的回溯。clone操作在一定程度上可以视为是一个identity-mapping函数

 检测:

import torch

a = torch.tensor(1.0, requires_grad=True)
b = a.clone()
c = a.detach()
a.data *= 3
b += 1
print(a)  # tensor(3., requires_grad=True)
print(b)
print(c)

结果:

tensor(3., requires_grad=True)
tensor(2., grad_fn=<AddBackward0>)
tensor(3.)

 

Copy_():

 比如x4.copy_(x2), 将x2的数据复制到x4,并且会修改计算图,使得反向传播自动计算梯度时,计算出x4的梯度后再继续前向计算x2的梯度. 注意,复制完成之后,两者的值的改变互不影响,
因为他们并不共享内存.
copy_()同样将源张量中的数据复制到目标张量(数据不共享),其device,dtype和requires_grad一般都保留目标张量的设定,仅仅进行数据复制,同时其支持broadcast操作。
import torch                                                  
a = torch.tensor([[1,2,3], [4,5,6]], device="cuda")           
b = torch.tensor([7.0,8.0,9.0], requires_grad=True)           
a.copy_(b)                                                    
print(a)   # tensor([[7, 8, 9], [7, 8, 9]], device='cuda:0')  

输出:

tensor([[7, 8, 9],
        [7, 8, 9]], device='cuda:0')

 

copy.deepcopy()

copy.deepcopy()函数是一个深复制函数。

所谓深复制,就是从输入变量完全复制可以相同的变量,无论怎么改变新变量,原有变量的值都不会受到影响。

与等号赋值不同,等号复制类似于贴标签,两者实质上是同一段内存。

像列表这样的变量,可以用深复制复刻,从而建立一个完全的新变量,如果用等号给列表复制,则新变量的改变将会引起原变量的随之改变。

 

from_numpy():
函数torch.from_numpy()提供支持将numpy数组转换为Pytorch中的张量。它期望输入为numpy数组(numpy.ndarray)。输出类型为张量。返回的张量和ndarray共享相同的内存。返回的张量不可调整大小。

当前它接受具有numpy.float64,numpy.float32,numpy.float16,numpy.int64,numpy.int32,numpy.int16,numpy.int8,numpy.uint8和numpy.bool的dtypes的ndarray。

import torch
import numpy

# A numpy array of size 6
a = numpy.array([1.0, -0.5, 3.4, -2.1, 0.0, -6.5])
print(a)
# Applying the from_numpy function and
# storing the resulting tensor in 't'
t = torch.from_numpy(a)
print(t)

结果:

[ 1.  -0.5  3.4 -2.1  0.  -6.5]
tensor([ 1.0000, -0.5000,  3.4000, -2.1000,  0.0000, -6.5000],
       dtype=torch.float64)

 np.array()

np.array函数的作用为可以把列表中的数据转换为矩阵或者向量,用于创建一个组。

np.array()这个方法,在括号中填写参数,注意这个参数的类型是列表list,可以直接填写方括号,

也可以把列表存在一个数组变量中,然后通过np.array方法赋值给数组变量即可。

 

torch.FloatTensor():

类型转换,将list,numpy转化为tensor。以list->tensor为例:

print(torch.FloatTensor([1.0]))   

输出

tensor([1.])

 

posted @ 2023-03-04 11:52  sqsq  阅读(401)  评论(0编辑  收藏  举报