pytorch 权重weight 与 梯度grad 可视化
查看特定layer的权重以及相应的梯度信息
打印模型
观察到model下面有module的key,module下面有features的key, features下面有(0)的key,这样就可以直接打印出weight了
在pdb debug界面输入p model.module.features[0].weight,就可以看到weight,输入 p model.module.features[0].weight.grad 就可以查看梯度信息。
中间变量的梯度 : .register_hook
pytorch 为了节省显存,在反向传播的过程中只针对计算图中的叶子结点(leaf variable)保留了梯度值(gradient)。但对于开发者来说,有时我们希望探测某些中间变量(intermediate variable) 的梯度来验证我们的实现是否有误,这个过程就需要用到 tensor的register_hook接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | grads = {} def save_grad(name): def hook(grad): grads[name] = grad return hook x = torch.randn( 1 , requires_grad = True ) y = 3 * x z = y * y # 为中间变量注册梯度保存接口,存储梯度时名字为 y。 y.register_hook(save_grad( 'y' )) # 反向传播 z.backward() # 查看 y 的梯度值 print (grads[ 'y' ]) |
打印网络回传梯度
net.named_parameters()
parms.requires_grad 表示该参数是否可学习,是不是frozen的;
parm.grad 打印该参数的梯度值。
1 2 3 4 5 6 7 8 9 | net = your_network().cuda() def train(): ... outputs = net(inputs) loss = criterion(outputs, targets) loss.backward() for name, parms in net.named_parameters(): print ( '-->name:' , name, '-->grad_requirs:' ,parms.requires_grad, \ ' -->grad_value:' ,parms.grad) |
查看pytorch产生的梯度
1 | [x.grad for x in self .optimizer.param_groups[ 0 ][ 'params' ]] |
pytorch模型可视化及参数计算
我们在设计完程序以后希望能对我们的模型进行可视化,pytorch这里似乎没有提供相应的包直接进行调用,下面把代码贴出来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import torch from torch.autograd import Variable import torch.nn as nn from graphviz import Digraph def make_dot(var, params = None ): if params is not None : assert isinstance(params.values()[ 0 ], Variable) param_map = {id(v): k for k, v in params.items()} node_attr = dict(style = 'filled' , shape = 'box' , align = 'left' , fontsize = '12' , ranksep = '0.1' , height = '0.2' ) dot = Digraph(node_attr = node_attr, graph_attr = dict(size = "12,12" )) seen = set() def size_to_str(size): return '(' + ( ', ' ).join([ '%d' % v for v in size]) + ')' def add_nodes(var): if var not in seen: if torch.is_tensor(var): dot.node(str(id(var)), size_to_str(var.size()), fillcolor = 'orange' ) elif hasattr(var, 'variable' ): u = var.variable name = param_map[id(u)] if params is not None else '' node_name = '%s\n %s' % (name, size_to_str(u.size())) dot.node(str(id(var)), node_name, fillcolor = 'lightblue' ) else : dot.node(str(id(var)), str(type(var).__name__)) seen.add(var) if hasattr(var, 'next_functions' ): for u in var.next_functions: if u[ 0 ] is not None : dot.edge(str(id(u[ 0 ])), str(id(var))) add_nodes(u[ 0 ]) if hasattr(var, 'saved_tensors' ): for t in var.saved_tensors: dot.edge(str(id(t)), str(id(var))) add_nodes(t) add_nodes(var.grad_fn) return dot |
我们在我们的模型下面直接进行调用就可以了,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | if __name__ = = "__main__" : model = DeepLab(backbone = 'resnet' , output_stride = 16 ) input = torch.rand( 1 , 3 , 53 , 53 ) output = model(input) g = make_dot(output) g.view() params = list(net.parameters()) k = 0 for i in params: l = 1 print ( "该层的结构:" + str(list(i.size()))) for j in i.size(): l * = j print ( "该层参数和:" + str(l)) k = k + l print ( "总参数数量和:" + str(k)) |
模型部分可视化结果:
参数计算:
以上为个人经验,希望能给大家一个参考,也希望大家多多支持自学编程网。
- 本文固定链接: https://zxbcw.cn/post/214223/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)