.numpy()、.item()、.cpu()、.clone()、.detach()及.data的使用 && tensor类型的转换

2023-11-12

.numpy()、.item()、.cpu()、.clone()、.detach()及.data的使用

本文主要介绍 .numpy()、.item()、.cpu()、.clone()、.detach()及.data这些常用的类型转换的函数或者方法的区分,以及在实际训练中遇到的实际问题。

.item()
  • item() 将一个Tensor变量转换为python标量int float等单个的数值,但是不能是数组)常用于用于深度学习训练时,将loss值转换为标量并加,以及进行分类任务,计算准确值值时需要(如例一)。 item()是可以直接从gpu上转换为标量,看下面例一的loss.item() && 例二 运行结果。
# 例一  在gpu上运行 计算loss值和acc值
optimizer.zero_grad()
outputs = model(data)
loss = F.cross_entropy(outputs, label)
acc = (outputs.argmax(dim=1) == label).sum().cpu().item() / len(labels)     #这里也用到了.item(),可以先转换到cpu
loss.backward()
optimizer.step()
train_loss += loss.item()   #这里用到了.item(),也可以直接item()
train_acc += acc
# 例二
a = torch.tensor([5],requires_grad=True,dtype=torch.float64,device='cuda')
print(a)
b = a.item()
print(b)
#输出: 
# tensor([5.], device='cuda:0', dtype=torch.float64, requires_grad=True)  
# 5.0
.cpu()
  • .cpu() 将数据的处理设备从其他设备(如.cuda()拿到cpu上),不会改变变量类型,转换后仍然是Tensor变量。 为什么需要这一步? 因为gpu上的数组不能直接进行转换类型的操作
a = torch.tensor([[1,2,3],[4,5,6]],requires_grad=True,dtype=torch.float64).cuda()
# 正确做法
b = a.cpu().detach().numpy()
b    
输出: array([[1., 2., 3.],
             [4., 5., 6.]])
.numpy()
  • numpy() Tensor.numpy()将Tensor转化为ndarray,这里的Tensor可以是标量(即item()的作用)或者 向量(与item()不同,一般是矩阵),转换前后的dtype不会改变,但是要注意能直接numpy()的tensor的前提是没有梯度·(requires_grad=False)的。若有梯度(比如requires_grad=True,或者在神经网络的前向传播过程中),则需要 先.detach()再进行numpy()。 在后面还会讲解.detach()作用。
  • eg:
a = torch.tensor([[1.,2.]])
a_numpy = a.numpy() #[[1., 2.]]
a = torch.tensor(1.5)
a_numpy = a.numpy() #1.5
.clone()
  • .clone()函数可以返回一个完全相同的tensor,新的tensor开辟新的内存,但是仍然留在计算图中。**所以它复制完会保留原来的梯度,原来有梯度那么clone完也是有梯度的。**而 没有梯度 又可以直接用.numpy()转换为数组,用.clone()也不行,这个暂时感觉用的很少。
  • 下列是有梯度不能用numpy() 的一个错误案例。在前向传播过程中.clone()依旧有梯度,所以不可numpy()
    在这里插入图片描述
.detach()
  • .detach() 函数可以返回一个完全相同的tensor,新的tensor开辟与旧的tensor共享内存,新的tensor会脱离计算图不会牵扯梯度计算。也就是requires_grad=False, 因此可以 接着进行numpy() 的操作,解决了numpy()需要建立在无梯度的tensor的基础上的问题。

举例:前向传播过程中,如果在传播过程中用.detach()生成了新的变量,然后用这个新的变量继续往下传播,这样会导致梯度反向传播到这里就不能继续前面的参数也不会发生改变了

# enc_outputs : 前向传播产生的变量
# enc_outputs1 : 过程中自己生成的变量
for i in enc_outputs:
    a = i[0].cpu().detach().numpy()
    enc_outputs1.append(a)
return torch.tensor(enc_outputs1).to(device), enc_self_attns
# 进行训练的时候enc_outputs1脱离了计算,不进行反向传播了
  • .detach()就是返回一个新的tensor,并且这个tensor是从当前的计算图中分离出来的。但是返回的tensor和原来的tensor是共享内存空间的。当model不希望更新某部分的参数的时候,就可以用.detach()一下,如下例子:

如果A网络的输出被喂给B网络作为输入, 如果我们希望在梯度反传的时候只更新B中参数的值,而不更新A中的参数值,这时候就可以使用.detach()

a = A(input)
a = a.deatch() # 或者a.detach_()进行in_place操作
out = B(a)
loss = criterion(out, labels)
loss.backward()

.data
  • .data — tensor .data 返回和 x 的相同数据 tensor,而且这个新的tensor和原来的tensor是共用数据的,一者改变,另一者也会跟着改变,而且新分离得到的tensor的require s_grad = False, 即不可求导的。(这一点其实detach是一样的)
a = torch.tensor([1.0], requires_grad=True)
b = a.data
print(b, b.requires_grad)
## 输出为: tensor([1.]) False
.data和.detach()不同点

参考博客

pytorch中.numpy()、.item()、.cpu()、.detach()及.data的使用

ValueError:only one element tensors can be converted to Python scalars解决办法

torch.Tensor

Tensor类型的转换:

torch.Tensor

  • CPU和GPU的Tensor之间转换 : 多用于将数据从gpu()转到cpu(),因为gpu上的数据不能直接操作

    • data.cuda():cpu –> gpu
    • data.cpu():gpu –> cpu
  • Tensor与Numpy Array之间的转换

    • data.numpy():Tensor –> Numpy.ndarray

      • 但是要注意此时需要转换的data是否有梯度
      • data有梯度时候,如果直接numpy(),会报错,正确做法是先.detach()
      a = torch.tensor([[1,2,3],[4,5,6]],requires_grad=True,dtype=torch.float64)
      b = a.numpy()
      print(b)
      # RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.
      
      # 正确做法
      b = a.detach().numpy()
      b    
      输出: array([[1., 2., 3.],
                   [4., 5., 6.]])
      
      • data没有梯度的时候,可以直接numpy()
      a = torch.tensor([[1,2,3],[4,5,6]],dtype=torch.float64)
      b = a.numpy()
      print(b)
      # array([[1., 2., 3.],[4., 5., 6.]])
      
      • 若data在gpu上,需要先将数据移动到cpu上,具体操作如下:
      a = torch.tensor([[1,2,3],[4,5,6]],requires_grad=True,dtype=torch.float64).cuda()
      # 正确做法
      b = a.cpu().detach().numpy()
      b    
      输出: array([[1., 2., 3.],
                   [4., 5., 6.]])
      
    • torch.from_numpy(data):Numpy.ndarray –> Tensor

      • Numpy桥,将numpy.ndarray 转换为pytorch的 Tensor。 返回的张量tensor和numpy的ndarray共享同一内存空间。修改一个会导致另外一个也被修改。返回的张量不能改变大小。
      a = np.array([1, 2, 3])
      t = torch.from_numpy(a)
      t
      # torch.LongTensor([1, 2, 3])
      t[0] = -1
      a
      # array([-1,  2,  3]
      
  • Tensor的基本类型转换

    • tensor.long():
    • tensor.half():将tensor投射为半精度浮点(16位浮点)类型
    • tensor.int():
    • tensor.double():
    • tensor.float():
    • tensor.char():
    • tensor.byte():
    • tensor.short():
  • Tensor的基本数据类型转换

    • type(dtype=None, non_blocking=False, **kwargs):指定类型改变。例如data = data.type(torch.float32)
    • type_as(tensor):按照给定的tensor的类型转换类型。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.numpy()、.item()、.cpu()、.clone()、.detach()及.data的使用 && tensor类型的转换 的相关文章

随机推荐

  • 作用域和堆内存的区别

    作用域是函数执行的时候产生fn 函数执行的时候首先会开辟一个新的内存空间叫栈内存 环境或作用域 数据类型在赋值的时候会开辟一个新的内存空间叫堆内存 存放代码块的 二者都会形成一个内存地址 生成对象的单例模式 优势 每个对象都是独立的 即便属
  • @SuppressWarnings("resource")作用

    1 实例 SuppressWarnings resource public static void main String args Scanner input new Scanner System in 写代码时 input 警告加上这个
  • 若隐若现的芯片

    先看效果 再看代码
  • 【java语法基础】常量与变量、数据类型,以及数据类型的转换

    常量 就是值永远不被改变的量 声明一个常量 需要用final关键字修饰 具体格式 final 常量类型 常量标识符 常量值 例如 final int PIE 18 注 在定义一个常量标识符时 所有的字符都要大写 如果常量标识符由多个单词组成
  • 用python实现数字图片识别神经网络--实现网络训练功能

    上节我们完成了神经网络基本框架的搭建 当时剩下了最重要的一个接口train 也就是通过读取数据自我学习 进而改进网络识别效率的功能尚未实现 从本节开始 我们着手实现该功能 自我训练过程分两步走 第一步是计算输入训练数据 给出网络的计算结果
  • git查看日志

    目录 引言 git查看该项目提交记录 查看指定条数的记录 显示提交的差异 提交的简略信息 按行显示提交信息 按照指定格式显示记录 指定文件的提交记录 指定字符串或函数的提交记录 示例 引言 有时需要对之前所做的一些修改查看记录 这里是查看g
  • STM32F407ZGT6控制舵机(采用高级定时器8)

    前言 32单片机给舵机供电不足 会出现不稳定的情况 舵机鬼畜 所以要外加电源给舵机供电 利用12v锂电池 通过稳压模块降压到5 5v 提供给舵机 稳压电路的gnd一定要接上32单片机的gnd 不共地虽然能供电但数据线无法传输数据 stm32
  • 以太坊ERC-20协议详解

    区块链学习 https github com xianfeng92 Love Ethereum ERC20是以太坊定义的一个 代币标准 https github com ethereum EIPs blob master EIPS eip
  • 计算机网络综合选择题

    计算机网络综合选择题 TCP IP体系结构中的TCP和IP所提供的服务分别为 A 运输层服务和网络层服务 B 运输层服务和应用层服务 C 链路层服务和网络层服务 D 网络层服务和运输层服务 答案 A 2 对于无序接收的滑动窗口协议 若序号位
  • JAVA中的异常处理机制

    JAVA中的异常处理机制 java异常处理中的关键字 try catch finally throw throws return try 检测代码块 在此代码块中一旦检测到异常就会自动跳转到相应的catch try 检测代码块 catch
  • 21_pre_access 阶段

    文章目录 限制每个客户端的并发连接数 limit conn 指令 示例配置 限制每个客户端的每秒处理请求数 limit req 指令 限制每个客户端的并发连接数 ngx http limit conn module 生效阶段 ngx htt
  • Java实现FTP的上传和下载!

    java实现连接FTP服务器 实现文件的上传和下载 一 FTP服务器 FTP服务器 File Transfer Protocol Server 是在互联网上提供文件存储和访问服务的计算机 它们依照FTP协议提供服务 FTP协议是一种专门用来
  • 一文简单了解RPMB

    不知道大家对于RPMB有所了解吗 最近在看这些存储介质的介绍的时候 在推荐里面看到了这个东西 又因为对安全本身就有所涉及学习 所以这里来看看这个东西 学习的内容都是来自前辈们的blog 会在文末附注 1 Flash是什么 关于存储的种类有很
  • 解决mysql忘记密码无法登陆问题

    当我们忘记mysql密码的时候我们不仅无法访问数据库 也无法修改密码 这是个很头疼的问题 下面是跳过用户验证登陆数据库的小技巧 第一步 打开我们安装mysql的目录 复制 D PhpStudy PHPTutorial MySQL bin 地
  • 同一端口有2个前端应用应该如何配置nginx.conf

    需求 业务系统中有2种完全不同角色 页面没有相同模块拆分成了2个应用A和B 但后端是同一个后端 部署的时候要求A和B在同一端口下 问 如何配置nginx 首先我们将A B前端包放到 opt app jhscf deploy html下 这样
  • 电脑如何打开虚拟化设置?

    当你开启Vmware中的虚拟机时 如果出现以上提示 说明你的虚拟化没有打开 在计算机中 虚拟化 英语 Virtualization 是一种资源管理技术 是将计算机的各种实体资源 如服务器 网络 内存及存储等 予以抽象 转换后呈现出来 打破实
  • R语言-随机前沿分析法--SFA

    3 1介绍 生产函数模型 lnqi x i b vi ui 随机生产前沿函数 qi 产出变量向量 x i 投入变量向量 b 变量参数估计 vi 统计噪声的对称随机误差 ui 无效效应 3 2度量技术效率的方法 SFA 参数 DEA 非参数
  • Fortran 90学习之旅(一)Visual Fortran 6.5 的安装与第一个例子

    转载请标明是引用于 http blog csdn net chenyujing1234 源码 http www rayfile com zh cn files e5f02f0a 8799 11e1 b6a2 0015c55db73d 高尔夫
  • Java 中封装JDBC连接到JDBCUtils工具类的详解

    博主前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住也分享一下给大家 点击跳转到网站 前言 在JDBC操作中 获取连接和释放资源是经常使用到的 可以将其封装成到一个工具类JDBCUtils中 JDBCUtils中有两个方法
  • .numpy()、.item()、.cpu()、.clone()、.detach()及.data的使用 && tensor类型的转换

    文章目录 numpy item cpu clone detach 及 data的使用 item cpu numpy clone detach data data和 detach 不同点 Tensor类型的转换 numpy item cpu