欧意交易所资讯

uncategorized
首页 > 欧意交易所资讯 > 正文内容

pytorch 计算过程中如何节省显存并注册钩子导出中间变量

qer1231年前 (2024-11-06)欧意交易所资讯425

钩子方法有四种:

火炬..()

火炬.nn..k()

火炬.nn..ok()

torch.nn.._hook()。

1、手电筒..(挂钩)

用于导出指定张量的梯度,或者修改梯度值。

import torch
def grad_hook(grad):
    grad *= 2
x = torch.tensor([2., 2., 2., 2.], requires_grad=True)
y = torch.pow(x, 2)
z = torch.mean(y)
h = x.register_hook(grad_hook)
z.backward()
print(x.grad)
h.remove()    # removes the hook
>>> tensor([2., 2., 2., 2.])

注意:(1)上面的代码是有效的,但是如果写成grad = grad * 2就会无效,因为此时没有对grad进行本地操作,新的grad值并没有传递给指定的梯度。为了安全起见,最好在 def 语句中指定 grad。现在:

def grad_hook(grad):
    grad = grad * 2
    return grad

(2) 可以使用()方法取消钩子。注意,()必须在()之后,因为梯度计算只有在执行()语句时才开始,而在x.()处它只“注册”了一个grad hook。此时没有计算,而是执行 取消这个钩子就行了,然后()这个钩子就不起作用了。

(3)如果类中定义了钩子函数,则必须先在输入参数中添加self,即

def grad_hook(self, grad):
    ...

2、torch.nn..k(,输入,输出)

用于导出指定子模块(可以是layer、等nn.type)的输入输出张量,但只能修改输出。它常用于导出或修改卷积特征图。

inps, outs = [],[]
def layer_hook(module, inp, out):
    inps.append(inp[0].data.cpu().numpy())
    outs.append(out.data.cpu().numpy())
hook = net.layer1.register_forward_hook(layer_hook)
output = net(input)
hook.remove()

注意:(1)由于模块可以有多个输入,因此输入是元组类型,需要先提取出来再进行操作;输出是元组类型,可以直接使用。

(2)导出后不要放到显存上,除非你有A100。

(3)只能修改输出out的值,不能修改输入inp的值(不能返回,本地修改无效)。修改时最好以表单形式返回,如:

def layer_hook(self, module, inp, out):
    out = self.lam * out + (1 - self.lam) * out[self.indices]
    return out

这段代码在mixup中使用,混合中间层特征,实现数据增强,其中self.lam是[0,1]概率值,self.lam是[0,1]概率值。是最后一个序列号。

3、torch.nn.._hook(, in)

用于导出或修改指定子模块的输入张量。

def pre_hook(module, inp):
    inp0 = inp[0]
    inp0 = inp0 * 2
    inp = tuple([inp0])
    return inp
hook = net.layer1.register_forward_pre_hook(pre_hook)
output = net(input)
hook.remove()

注意:(1)inp值是tuple类型,所以需要先提取张量,然后进行其他操作,然后将其转换为tuple并返回。

(2)这句话只有在执行=net(input)时才会被调用。 ()可以放在调用后取消钩子。

4、torch.nn..ok(, , )

用于导出指定子模块的输入和输出张量的梯度,但只能修改输入张量的梯度(即只能返回gin),不能修改输出张量的梯度。

gouts = []
def backward_hook(module, gin, gout):
    print(len(gin),len(gout))
    gouts.append(gout[0].data.cpu().numpy())
    gin0,gin1,gin2 = gin
    gin1 = gin1*2
    gin2 = gin2*3
    gin = tuple([gin0,gin1,gin2])
    return gin
hook = net.layer1.register_backward_hook(backward_hook)
loss.backward()
hook.remove()

注意:

(1) 和都是元组,必须先展开。修改的时候,执行操作然后再把tuple放回去。

(2) 该钩子函数是在()语句中调用的,因此()应放在()之后,以取消钩子。

扫描二维码推送至手机访问。

版权声明:本文由本站发布,如需转载请注明出处。

转载请注明出处https://www.juxingsy.com/post/1568.html

标签: hook
分享给朋友:

相关文章

AICOIN数字货币行情软件:实时行情、价格提醒与币种排名功能详解

是一款知名的数字货币行情软件,它为众多投资者提供了强大且实用的功能。接下来我将从几个关键方面为你详细剖析它。 多样行情 交易市场较为复杂, 收集了很多主流交易平台的数据。你可以便捷地查看比特币、以太...

挖矿挣钱:与算力、区块链关联的虚拟货币奖励获取方式

挖矿挣钱这件事,简单而言是借助计算机运算去获取虚拟货币的奖励。就如同一场在数字领域探寻宝藏的旅程,此过程中包含诸多专业的计算以及网络技术。 算力竞争 算力指的是计算机的计算能力。在挖矿时,需要强大的计...

EcMarkets客户投诉激增,评分降至3.17分,虚假交易平台指控频发

EcMarkets客户投诉激增,评分降至3.17分,虚假交易平台指控频发

最近,我们注意到客户投诉数量有所增加,其评分已降至 3.17,这是一个相当低的分数。尽管如此,它仍然拥有英国监管许可证。让我们仔细看看客户的评价。 从客户投诉中我们可以看到一些问题,包括被指为虚假外...

OKEx 官方网站:探索数字货币领域的奇妙之旅

各位尊敬的朋友们,您们好!今次,我愿带领诸位去探寻一处神秘且极具魅力的领域—OKEx官方网站。请各位做好准备,与我携手共赴这场数字货币的奇妙之旅,体验它带来的惊喜吧! OKEx官网的第一印象 初次访问...

以太坊价格走势如过山车,经济学家深度解析

以太坊,其在加密货币领域宛如激荡起伏的过山车,日复一日上演激动人心的剧情。身为一名对以太坊市场有长期深度研究的经济学家,在此,我将与诸位探讨这既令人兴奋又备感挑战的以太坊价格走势。 心跳加速的涨势 首...

警惕!盘古社区衰落,元灵社区又起,Defi 金融骗局何时休?

警惕!盘古社区衰落,元灵社区又起,Defi 金融骗局何时休?

该车型领先的是保时捷,其次是盘古社区FIST和OSK,均暴跌90%以上。在315接到通知之前,这些都是血淋淋的悲剧。交易员在发币之前就已经提前分配了筹码。当市场崩溃时,你根本没有机会。跑步的地方。...

加入欧意交易所,探索元宇宙世界!

探索DeFi,DApps, NFTs 和GameFi的世界,和OKX一起创造未来!