其他
【他山之石】pytorch使用hook打印中间特征图、计算网络算力等
“他山之石,可以攻玉”,站在巨人的肩膀才能看得更高,走得更远。在科研的道路上,更需借助东风才能更快前行。为此,我们特别搜集整理了一些实用的代码链接,数据集,软件,编程技巧等,开辟“他山之石”专栏,助你乘风破浪,一路奋勇向前,敬请关注。
地址:https://www.zhihu.com/people/se-zui
01
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)
register_hook函数属于torch.tensor类,函数在tensor梯度计算的时候就会执行,这个函数主要处理梯度相关的数据,表现形式 .
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
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 grad
class 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 = input
out = input * 0.75
out = self.f1(out)
out = out / 4
return out
def 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])
register_forward_hook跟Register_backward_hook差不多,就不过多复述。 register_forward_pre_hook,可以发现其输入只有
hook(module, input) -> None
其主要是针对推理时的hook.
02
2.1 特征图打印
import torch
from torchvision.models import resnet18
import torch.nn as nn
from torchvision import transforms
import matplotlib.pyplot as plt
def 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()
2.2 模型大小,算力计算
03
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
“他山之石”历史文章
Ray和Pytorch Lightning 使用指北
如何在科研论文中画出漂亮的插图?
PyTorch 源码解读之 torch.optim:优化算法接口详解
AI框架基础技术之深度学习中的通信优化
SimCLR:用于视觉表征的对比学习框架
Pytorch Autograd与计算图
tensorflow2.4性能调优最佳实践
PyTorch | DDP系列:入门教程、实现原理与源代码解析、实战与技巧
教你用PyTorch玩转Transformer英译中翻译模型!
深度学习工程技巧之网格调参
PyTorch使用预训练模型进行模型加载
深度学习调参经验总结
PyTorch实现断点继续训练
Pytorch/Tensorflow-gpu训练并行加速trick(含代码)
从NumPy开始实现一个支持Auto-grad的CNN框架
更多他山之石专栏文章,
请点击文章底部“阅读原文”查看
分享、点赞、在看,给个三连击呗!