【Pytorch】提取模型中间层输出(hook, .register_forward_hook(hook=hook))

这篇具有很好参考价值的文章主要介绍了【Pytorch】提取模型中间层输出(hook, .register_forward_hook(hook=hook))。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 提取模型中间层输出(hook, .register_forward_hook(hook=hook))

1.1 定义模型

import torch
import torch.nn as nn
class StudentModel(nn.Module):
    def __init__(self, input=25, output=2):
        super().__init__()
        self.l1 = nn.Linear(input, 16)
        self.l2 = nn.Linear(16, 32)
        self.l3 = nn.Linear(32, 2)
        self.relu = nn.ReLU()
        self.softmax = nn.Softmax(dim=1)
    
    def forward(self, X):
        x = X.reshape(-1, 25)
        x = self.relu(self.l1(x))
        x = self.relu(self.l2(x))
        x = self.relu(self.l3(x))

        x = self.softmax(x)
        res = x.max(1).indices
        return torch.tensor(res, dtype=float)

sm = StudentModel()
'''
StudentModel(
  (l1): Linear(in_features=25, out_features=16, bias=True)
  (l2): Linear(in_features=16, out_features=32, bias=True)
  (l3): Linear(in_features=32, out_features=2, bias=True)
  (relu): ReLU()
  (softmax): Softmax(dim=1)
)
'''

1.2 定义hook函数 调用.register_forward_hook(hook=hook)

features_in_hook = []
features_out_hook = []

def hook(module, fea_in, fea_out):
    features_in_hook.append(fea_in)
    features_out_hook.append(fea_out)
    return None

layer = sm.l1
layer.register_forward_hook(hook=hook)
'''
<torch.utils.hooks.RemovableHandle at 0x11b18a5b0>
'''

1.3 模型跑数据

sm(Xtrain)
'''
tensor([0., 1., 1., 1., 1., 1., 1., 1., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
        1., 1., 1., 0., 1., 1., 1., 1., 0., 1., 1., 1., 1., 1., 1., 1., 1., 0.,
        1., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0., 1., 1., 1., 1., 1., 1.,
        1., 1., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
        1., 1., 1., 1., 0., 1., 1., 1., 1., 1., 0., 1., 1., 1., 1., 1., 0., 1.,
        1., 1., 1., 0., 1., 1., 1., 1., 1., 1.], dtype=torch.float64)
'''

1.4 获取中间层输出

features_in_hook[0][0].shape
'''
torch.Size([100, 25])
'''
features_in _hook
'''
[(tensor([[0.4921, 0.8465, 0.3133,  ..., 0.8547, 0.0275, 0.0872],
          [0.1217, 0.5101, 0.9094,  ..., 0.0517, 0.5217, 0.8201],
          [0.3493, 0.6255, 0.7081,  ..., 0.6097, 0.3401, 0.0455],
          ...,
          [0.6717, 0.0128, 0.2326,  ..., 0.1152, 0.5885, 0.9372],
          [0.8665, 0.8432, 0.3781,  ..., 0.3370, 0.8750, 0.4666],
          [0.7063, 0.1330, 0.3501,  ..., 0.5658, 0.2588, 0.3254]],
         grad_fn=<ReshapeAliasBackward0>),)]
'''
features_out_hook[0].shape
'''
torch.Size([100, 16])
'''
features_out_hook
'''
tensor([[ 0.1448, -0.0800, -0.1307,  ..., -0.1472,  0.6660, -0.0465],
        [ 0.4460,  0.2587, -0.1345,  ..., -0.4809,  0.8669, -0.2805],
        [ 0.2118,  0.0445, -0.1910,  ..., -0.5179,  0.9163, -0.0972],
        ...,
        [ 0.1761, -0.0178, -0.4799,  ..., -0.3769,  0.6353, -0.3738],
        [ 0.1534, -0.0314, -0.2041,  ..., -0.3669,  1.0264, -0.1857],
        [-0.0438,  0.0639, -0.2547,  ..., -0.4396,  0.7633, -0.2492]],
       grad_fn=<AddmmBackward0>)
'''

2. 插值处理 上下采样 torch.nn.functional.interpolate()

import torch.nn.functional as F

'''
mode 
	"nearest" 复制最近的一个元素实现插值,输入必须4维
	"linear" 线性插值
	...
'''

x = torch.rand(1, 1, 3, 4)
F.interpolate(x, (5, 5), mode="nearest").shape
'''
torch.Size([1, 1, 5, 5])
'''
x = torch.rand(1, 3, 3)
F.interpolate(x, 5, mode="linear").shape
'''
torch.Size([1, 3, 5])
'''

3. 指定维度求最大值索引 torch.max(x, dim=).indices

x = torch.rand(3, 2)
'''
tensor([[0.5832, 0.0757],
        [0.4064, 0.4217],
        [0.1081, 0.5463]])
'''
torch.max(x, dim=1) 
'''
每行的最大值及其索引
torch.return_types.max(
values=tensor([0.5832, 0.4217, 0.5463]),
indices=tensor([0, 1, 1]))
'''
torch.max(x, dim=1).indices
'''
适合二分类
tensor([0, 1, 1]))
'''

4. 模型转GPU计算

需要转换的对象

  • 模型
  • 损失函数
  • 数据(特征数据、标签)

4.1 .cuda()

'''
.cuda(0) 指定第0块GPU
'''
if torch.cuda.is_available():
    model = model.cuda()
    loss_fn = loss_fn.cuda()
    X = X.cuda()
    y = y.cuda()
    

4.2 .to(device)

# 第二种方法
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
device0 = torch.device('cuda:0')

model.to(device)
loss_fn.to(device)
X = X.to(device)
y = y.to(device)

4.3 多GPU并行计算

4.3.1 单进程多GPU训练(DP)模式 torch.nn.DataParallel

  • 并行的多卡都是由一个进程进行控制,在进行梯度的传播时,是在主GPU上进行的。
  1. 将模型布置到多个指定GPU上
    model = torch.nn.DataParallel(model,device_ids=device_list)
  2. 指定模型布置的主GPU
    main_dev = 0
    model.to(main_dev)
  3. 优化器放到主GPU
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    optimizer.to(device)
  4. 数据放到主GPU
    data.to(main_dev)
device_list = [0, 1, 2, 3]
main_dev = device_list[0]  #主GPU,也就是分发任务和结果回收的GPU,也是梯度传播更新的GPU
model = torch.nn.DataParallel(model,device_ids=device_list)
model.to(main_dev)
 
for data in train_dataloaders: 
   model.train(True)
   inputs, labels = data
   inputs = Variable(inputs.to(main_dev))  #将数据放到主要GPU
   labels = Variable(labels.to(main_dev)) 

4.4 限定GPU可用

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "1,2"

# 从可用GPU中搜索第0和1的GPU
Model = nn.DataParallel(Model, device_ids=[0,1])

5. 模型更改、添加和删除层

5.1 model.add_module()

m = Treelinears()
m
'''
TreeLinears(
  (l1): Linear(in_features=8, out_features=4, bias=True)
  (l2): Linear(in_features=4, out_features=2, bias=True)
  (l3): Linear(in_features=2, out_features=1, bias=True)
)
'''
m.add_module('add_l4', nn.Linear(1, 1))
m
'''
TreeLinears(
  (l1): Linear(in_features=8, out_features=4, bias=True)
  (l2): Linear(in_features=4, out_features=2, bias=True)
  (l3): Linear(in_features=2, out_features=1, bias=True)
  (add_l4): Linear(in_features=1, out_features=1, bias=True)
)
'''

5.2 Sequential().add_module()

sq = nn.Sequential()
sq.add_module('add_l1', nn.Linear(1, 1))
sq.add_module('add_l2', nn.Linear(1, 1))
'''
Sequential(
  (add_l1): Linear(in_features=1, out_features=1, bias=True)
  (add_l2): Linear(in_features=1, out_features=1, bias=True)
)
'''

5.3 del model.layer

del sq.add_l1
'''
Sequential(
  (add_l2): Linear(in_features=1, out_features=1, bias=True)
)
'''

6. 获取模型参数量、FLOPs

6.1 thop.profile

import torch
from thop import profile

def get_flops_params_idx4(model, input_shape=[256, 1, 28, 28]):
    """
    :param model: 传入模型
    :param inshape: 模型的输入shape
    :return : (flops, params)
    """
    tensor = (torch.rand(*inpust_shape), )
    flops, params = profile(model, tensor) # 更改源码 不print

    return flops, params

6.2 torch 自带接口计算参数量

# 参数量
sum([param.nelement() for param in model.parameters()])

7. 损失函数

7.1 均方误差 torch.nn.MSELoss()

import torch
import torch.nn as nn

# 预测是[0,1,2]的概率
X = [[0.1, 0.8, 0.3],
     [0.2, 0.9, 0.1]]
X = torch.tensor(X)
# 真实标签
y = [[0], [0]]
y = torch.tensor(y)
'''
均方误差,多用于回归
X输入维度必须为(N, C),N样本数,C类别数
y输入维度必须为(N, 1), N样本数,第二维度1填写真实标签值
'''
nn.MSELoss()(X, y)
'''
tensor(0.2667)
'''

7.2 交叉熵损失 torch.nn.CrossEntropyLoss()

nn.CrossEntropyLoss 在内部执行了 softmax 操作,不需要显式地在模型的最后一层添加 softmax 激活函数。

import torch
import torch.nn as nn

X = torch.rand(10, 8)
y = torch.randint(0, 2, (10, ))
'''
交叉熵损失,多用于多分类
X输入维度必须为(N, C),N样本数,C类别数, dtype=float
y输入维度必须为(N, ), 第一维度N为样本数,填写真实标签值, dtype=long
'''
nn.CrossEntropyLoss()(X, y)
'''
tensor(1.0546)
'''

7.3 torch.nn.NULLLoss()

  • 输入输出与nn.CrossEntropyLoss()一样,

  • 区别在于: 内部没有softmax操作,需要显示调用torch.log_softmax(x, dim=1), 再输入nn.NULLLoss()

7.4 torch.nn.BCELoss()/BCEWithLogitsLoss()

解决二分类问题,模型输出层设置为nn.Linear(n, 1)

  1. BCELoss()(input, target) 解决二分类问题,模型输出层应接nn.sigmoid()
    input 维度不定,target维度与input维度相同,值为0or1

  2. BCEWithLogitsLoss() >>> nn.sigmoid + nn.BCELoss

8. 二分类 概率->索引

x = torch.tensor([[1, 2],
                  [3, 2]])

torch.max(x, 0)
'''
torch.return_types.max(
values=tensor([3, 2]),
indices=tensor([1, 0]))
'''
torch.max(x, 0).indices
'''
tensor([1, 0])
'''

9. pickle 保存读取数据/模型

import pickle

dic = {'a': [1, 2], 
       'b':[1, 2, 3]}

with open('dic.pkl', 'wb') as fp:
    pickle.dump(dic, fp)

with open('dic.pkl', 'rb') as fp:
    d = pickle.load(fp)

文章来源地址https://www.toymoban.com/news/detail-648416.html

import pickle

fp = open('dic.pkl', 'wb')
pickle.dump(cols, fp)
fp.close()

fp = open('dic.pkl', 'rb')
data = pickle.load(fp)
fp.close()

到了这里,关于【Pytorch】提取模型中间层输出(hook, .register_forward_hook(hook=hook))的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 没有“中间商赚差价”, OpenVINO™ 直接支持 PyTorch 模型对象

    点击蓝字 关注我们,让开发变得更有趣 作者 | 杨亦诚 排版 | 李擎 没有“中间商赚差价”,  OpenVINO™  直接支持 PyTorch 模型对象 背景 作为最热门的开源深度学习框架之一,PyTorch 的易用性和灵活性使其深受学术和研究界的喜爱。之前 OpenVINO™ 对于 PyTorch 模型的支持也仅仅停

    2024年02月10日
    浏览(26)
  • Pytorch模型如何查看每层输入维度输出维度

    在 PyTorch 中,可以使用 torchsummary 库来实现对 PyTorch 模型的结构及参数统计的输出,其可以方便我们查看每层输入、输出的维度以及参数数量等信息。 安装 torchsummary 库: 使用方法如下: 其中, model 是需要查看的模型, (3, 32, 32) 表示模型的输入维度,即 C = 3,H = 32,W = 32。

    2024年02月16日
    浏览(34)
  • 【pytorch】同一个模型model.train()和model.eval()模式下的输出完全不同

    测试时为什么要使用model.eval() - 小筱痕 - 博客园 (cnblogs.com) 输出不同的原因是由于student模型中的某些层的行为不同。一些层,如dropout和batch normalization,在训练和评估过程中的行为是不同的。 在训练过程中,dropout层会随机将一部分输入置为零,这有助于防止过拟合。dropou

    2024年02月12日
    浏览(40)
  • avue中增删改功能hook提取

    再avue使用中,我们会进场用到表格的增删改功能,我们写一个公共的hooks,然后只需要对请求的方法,参数的前后处理,就可以统一生成

    2024年04月17日
    浏览(36)
  • 【pytorch】使用训练好后的模型权重,在验证集上输出分类的混淆矩阵并保存错误图片

    在机器学习领域,混淆矩阵是一个非常有用的指标,它可以帮助我们更好地理解模型在验证集上的表现。本文介绍了如何使用pytorch框架,利用训练好后的模型权重,在验证集上输出分类的混淆矩阵,并保存错误图片的方法。 首先,我们需要准备一个pytorch框架的模型,并将模

    2024年02月13日
    浏览(28)
  • APP攻防--安卓逆向&JEB动态调试&LSPosed模块&算法提取&Hook技术

    安装java环境变量(最好jdk11) 安装adb环境变量 设置adb环境变量最好以Android命名 启动开发者模式 设置--关于平板电脑--版本号(单机五次) 开启USB调试 设置--系统--高级--开发者选项--USB调试 开启USB调试目的是为了后续让JEB能够获取模拟器上的进程 安装激活JEB 软件安装包和破解参

    2024年02月05日
    浏览(37)
  • arcpy批量提取面状水系中间线

    由于面状水系可能存在多条中间线,因此批量提取时需要使用 ArcGIS 中的 Feature To Line 工具结合 Python 循环和游标来完成。 以下是代码: import arcpy import os # 设置输入输出路径和文件名 input_folder = r\\\"C:datariver_polygons\\\" output_folder = r\\\"C:datariver_midlines\\\" # 创建输出文件夹 if not os.pa

    2024年02月10日
    浏览(31)
  • 神经网络输出中间特征图

    在进行神经网络的训练过程中,会生成不同的特征图信息,这些特征图中包含大量图像信息,如轮廓信息,细节信息等,然而,我们一般只获取最终的输出结果,至于中间的特征图则很少关注。 前两天师弟突然问起了这个问题,但我也没有头绪,后来和师弟研究了一下,大概

    2024年02月09日
    浏览(30)
  • VS2022配置工程的编译路径(输出目录和中间目录)

    TIPS:以下使用visual C++中Windows桌面向导生成的解决方案为例。且演示的visual studio的版本为2022,即visual studio 2022。  注意:不勾选放在同一目录下     我们在解决方案内新建两个项目  其中,两个项目project1和project2的编译路径,即输出目录和中间目录均是默认配置。 ( 项目

    2024年02月08日
    浏览(48)
  • pytorch对中间特征层可视化方案

    本文主要介绍如何使用pytorch获得已经训练好的网络的中间特征层,并将其转化为热力图的简单方法 效果图 1、在原本的test代码上进行修改 2、随便写一个钩子函数(具体了解可以搜索“pytorch中的钩子(Hook)有何作用?”) 3、然后注册一下钩子函数(在你需要保存的卷积层进行

    2024年02月13日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包