日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pytorch forward_pytorch使用hook打印中间特征图、计算网络算力等

發布時間:2023/12/13 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pytorch forward_pytorch使用hook打印中间特征图、计算网络算力等 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0、參考

https://oldpan.me/archives/pytorch-autograd-hook

https://pytorch.org/docs/stable/search.html?q=hook&check_keywords=yes&area=default

https://github.com/pytorch/pytorch/issues/598

https://github.com/sksq96/pytorch-summary

https://github.com/allensll/test/blob/591c7ce3671dbd9687b3e84e1628492f24116dd9/net_analysis/viz_lenet.py

1、背景

在神經網絡的反向傳播當中個,流程只保存葉子節點的梯度,對于中間變量的梯度沒有進行保存。

import torch x = torch.tensor([1,2],dtype=torch.float32,requires_grad=True) y = x+2 z = torch.mean(torch.pow(y, 2)) lr = 1e-3 z.backward() x.data -= lr*x.grad.data print(y.grad)

此時輸出就是:None,這個時候hook的作用就派上,hook可以通過自定義一些函數,從而完成中間變量的輸出,比如中間特征圖、中間層梯度修正等。

? 在pytorch docs搜索hook,可以發現有四個hook相關的函數,分別為register_hook,register_backward_hook,register_forward_hook,register_forward_pre_hook。其中register_hook屬于tensor類,而后面三個屬于moudule類。

  • register_hook函數屬于torch.tensor類,函數在tensor梯度計算的時候就會執行,這個函數主要處理梯度相關的數據,表現形式$hook(grad) rightarrow Tensor or None$.
import torch x = torch.tensor([1,2],dtype=torch.float32,requires_grad=True) y = x * 2 y.register_hook(print) <torch.utils.hooks.RemovableHandle at 0x7f765e876f60> z = torch.mean(y) z.backward() tensor([ 0.5000, 0.5000])
  • Register_backward_hook等三個屬于torch.nn,屬于moudule中的方法。
hook(module, grad_input, grad_output) -> Tensor or None

寫個demo,參考:

下面的計算為

import torch import torch.nn as nn device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")def print_hook(grad):print ("register hook:", grad)return gradclass TestNet(nn.Module):def __init__(self):super(TestNet, self).__init__()self.f1 = nn.Linear(4, 1, bias=True)self.weights_init()def weights_init(self):self.f1.weight.data.fill_(4)self.f1.bias.data.fill_(0.1)def forward(self, input):self.input = inputout = input * 0.75out = self.f1(out)out = out / 4return outdef back_hook(self, moudle, grad_input, grad_output):print ("back hook in:", grad_input)print ("back hook out:", grad_output)# 修改梯度# grad_input = list(grad_input)# grad_input[0] = grad_input[0] * 100# print (grad_input)return tuple(grad_input)if __name__ == '__main__':input = torch.tensor([1, 2, 3, 4], dtype=torch.float32, requires_grad=True).to(device)net = TestNet()net.to(device)net.register_backward_hook(net.back_hook)ret = net(input)print ("result", ret)ret.backward()print('input.grad:', input.grad)for param in net.parameters():print('{}:grad->{}'.format(param, param.grad))

輸出:

result tensor([7.5250], grad_fn=<DivBackward0>) back hook in: (tensor([0.2500]), None) back hook out: (tensor([1.]),) input.grad: tensor([0.7500, 0.7500, 0.7500, 0.7500]) Parameter containing: tensor([[4., 4., 4., 4.]], requires_grad=True):grad->tensor([[0.1875, 0.3750, 0.5625, 0.7500]]) Parameter containing: tensor([0.1000], requires_grad=True):grad->tensor([0.2500])

輸出結果以及梯度都很明顯,簡單分析一下w權重的梯度,

另外,hook中有個bug,假設我們bug,假設我們注釋掉out = out / 4這行,可以發現輸出變成back hook in: (tensor([1.]), tensor([1.]))。這種情況就不符合上面我們的梯度計算公式,是因為這個時候:

則此時的偏導只是對

和 進行計算,所以都是1,1。這是pytorch的設計缺陷

  • register_forward_hook跟Register_backward_hook差不多,就不過多復述。
  • register_forward_pre_hook,可以發現其輸入只有hook(module, input) -> None
    其主要是針對推理時的hook.

2、應用

2.1 特征圖打印

? 直接利用pytorch已有的resnet18進行特征圖打印,只打印卷積層的特征圖,

import torch from torchvision.models import resnet18 import torch.nn as nn from torchvision import transformsimport matplotlib.pyplot as pltdef viz(module, input):x = input[0][0]#最多顯示4張圖min_num = np.minimum(4, x.size()[0])for i in range(min_num):plt.subplot(1, 4, i+1)plt.imshow(x[i].cpu())plt.show()import cv2 import numpy as np def main():t = transforms.Compose([transforms.ToPILImage(),transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])])device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")model = resnet18(pretrained=True).to(device)for name, m in model.named_modules():# if not isinstance(m, torch.nn.ModuleList) and # not isinstance(m, torch.nn.Sequential) and # type(m) in torch.nn.__dict__.values():# 這里只對卷積層的feature map進行顯示if isinstance(m, torch.nn.Conv2d):m.register_forward_pre_hook(viz)img = cv2.imread('./cat.jpeg')img = t(img).unsqueeze(0).to(device)with torch.no_grad():model(img)if __name__ == '__main__':main()

直接放幾張中間層的圖

圖1 第一層卷積層輸入

圖2 第四層卷積層的輸入

2.2 模型大小,算力計算

同樣的用法,可以直接參考pytorch-summary這個項目。

總結

以上是生活随笔為你收集整理的pytorch forward_pytorch使用hook打印中间特征图、计算网络算力等的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 精品人妻一区二区三区久久夜夜嗨 | www.激情| 少妇被躁爽到高潮无码人狍大战 | 91av官网| 久热国产精品 | 伊人超碰| 91激情| h网站免费在线观看 | 午夜精品久久久久久久99老熟妇 | 色综合99久久久无码国产精品 | 国产精品国产三级国产传播 | 欧美老女人性视频 | 人人超碰在线 | 狠狠五月天 | av网址网站 | 人妻少妇偷人精品久久久任期 | 手机电影在线观看 | 日本三级一区二区三区 | 成人网站免费观看入口 | 国产91绿帽单男绿奴 | 日本特黄网站 | 秋霞福利网 | 日韩精品视频在线播放 | 国产对白视频 | 国产主播一区二区三区 | 国产美女永久免费无遮挡 | 天海翼av| 亚洲热在线观看 | 日本熟妇人妻中出 | 在线观看网址你懂的 | 黄页网站免费在线观看 | 97国产成人无码精品久久久 | 国产伦乱 | jizz免费在线观看 | 久久久综合视频 | 久操欧美| 欧美一级大黄 | 久久精品99久久久久久 | 国产一级黄色大片 | 日本三级午夜理伦三级三 | 熟女人妻一区二区三区免费看 | 性色欲网站人妻丰满中文久久不卡 | 日韩在线观看视频免费 | 久久精品视频无码 | 亚洲国产精品综合久久久 | 日日干,夜夜操 | 亚洲成a人在线观看 | 国产欧美精品一区二区色综合朱莉 | www.com黄色片| 久操视频在线观看 | 国产丰满大乳奶水在线视频 | 三年中国片在线高清观看 | 欧美日韩高清一区二区三区 | 中文字幕亚洲高清 | 在线播放一级片 | 久久久久国产精品一区二区 | 色一五月 | 日韩三级一区 | 欧美视频第一页 | 黄色a级片在线观看 | 国产一区二区三区黄 | 日韩和欧美的一区二区 | 粗大黑人巨茎大战欧美成人免费看 | 日韩av日韩 | 亚洲精品欧洲 | 亚洲无码一区二区三区 | 年下总裁被打光屁股sp | 精品久草 | 久久香蕉影视 | 国产美女精品人人做人人爽 | 日韩免费小视频 | 中文字幕第三页 | 狂野欧美性猛交xxxxhd | a级片免费视频 | www.黄在线 | 人人妻人人澡人人爽欧美一区双 | 西比尔在线观看完整视频高清 | 李丽珍裸体午夜理伦片 | 精品无码一区二区三区的天堂 | 久久久久免费精品 | 成人免费公开视频 | 久久人人爽人人爽人人片 | 诱惑av| 九九精品免费视频 | 久草网在线视频 | 日本阿v视频在线观看 | 丁香婷婷深情五月亚洲 | 天天做天天看 | 亚洲深夜视频 | 黑人巨大精品欧美黑白配亚洲 | 欧美日一区二区三区 | 欧美不卡在线视频 | 久久久久国色av免费观看性色 | 国产老头户外野战xxxxx | 久久久久国产精品一区二区 | 香蕉久热 | h无码动漫在线观看 | 四虎国产 | 亚洲日本视频在线观看 |