这几天写模型遇到的一点知识点的总结
文档地址:load_state_dict(state_dict, strict=True)
para_in_last_net = torch.load('./resnet_ckp.txt') # 把之前网络的参数下载到para_in_last_net中
model.load_state_dict(para_in_last_net) # 把para_in_last_net加载到model中
model = myNet(opts)
model.load_state_dict(torch.load('./resnet_ckp.txt''))
# 这两步可以合并写
model.named_parameters()、model.paramenters() 和model.state_dict() 这三个是Pytorch用于查看网络参数的方法。
model.named_parameters() : 返回模块参数上的迭代器,同时产生参数名称和参数本身
model.paramenters(): 返回模块参数上的迭代器,常传递给优化器 tensor格式
相当于少返回了named
>>> for param in model.parameters():
>>> print(type(param), param.size())
<class 'torch.Tensor'> (20L,)
<class 'torch.Tensor'> (20L, 1L, 5L, 5L)
state_dict(destination=None, prefix=’’, keep_vars=False)
返回包含module所有状态的字典。包括参数和持久缓冲区(例如运行平均值)。 键是相应的参数和缓冲区名称。
示例:
>>> module.state_dict().keys()
['bias', 'weight']
自己能力不够写不出来,这里有两个很好的学习材料
花书讲解参考,有关于AdaGrad, RMSProp和Adam。但是书上的东西笔记难理解
这个B站的视频讲的很清楚关于各种优化算法的讲解
b站视频深度学习优化
这一部分参考花书,我摘抄下来:
当计算图变的很深时,神经网络优化算法会面临长期依赖问题----------由于变深的结构使模型丧失了学习到向前信息的能力,让优化变得极其困难.
例如,假设某个计算图中包含一条反复与矩阵 W W W相乘的路径。那么 t t t步后,相当于乘以 W t W^t Wt。假设 W W W有特征分解
W = V d i a g ( λ ) V − 1 W=Vdiag(λ)V^{-1} W=Vdiag(λ)V−1在这种情况下
W t = ( V d i a g ( λ ) V − 1 ) t = V d i a g ( λ ) t V − 1 W^t= (V diag(λ) V^{-1})^t = V diag(λ)^t V^{-1} Wt=(Vdiag(λ)V−1)t=Vdiag(λ)tV−1
当特征值 λ i λ_i λi不在1附近时:若量级大于1则会爆炸, 若梯度小于1则会消失。
梯度爆炸使得学习不稳定。(很少,但是对优化过程影响很大)
梯度消失使得我们难以知道参数朝那个方向移动能够改进代价函数。(大部分情况)
关于梯度消失和梯度爆炸的细节可以进一步看花书8.2.5节和10.7节
这个不是很理解,是在花书的后面两节,这里有一个优化算法的博客写的很好
优化算法——截断梯度法(TG)
这里贴一个torch.nn.utils.clip_grad_norm的源码解析,因为我也不熟悉,所有这个仅供参考。
def clip_grad_norm_(parameters: _tensor_or_tensors, max_norm: float, norm_type: float = 2.0) -> torch.Tensor:
"""Clips gradient norm of an iterable of parameters. 截断梯度范数的一个迭代参数
The norm is computed over all gradients together, as if they were
concatenated into a single vector. Gradients are modified in-place.
这个范数是对所有的梯度值一起计算,它们连接成一个向量,梯度是就地修改
Args:
parameters (Iterable[Tensor] or Tensor): an iterable of Tensors or a
single Tensor that will have gradients normalized
一个可迭代的Tensors或者单个Tensor,它将会归一化梯度
max_norm (float or int): max norm of the gradients 梯度的最大范数
norm_type (float or int): type of the used p-norm. Can be ``'inf'`` for
infinity norm. 规定范数的类型,默认L2
Returns:
Total norm of the parameters (viewed as a single vector).
参数的总体范数(作为单个向量来看)
"""
if isinstance(parameters, torch.Tensor):
parameters = [parameters] # 要求Tensor
parameters = [p for p in parameters if p.grad is not None] # 传入和求梯度的参数
max_norm = float(max_norm)
norm_type = float(norm_type)
if len(parameters) == 0:
return torch.tensor(0.)
device = parameters[0].grad.device # GPU或CPU运算
if norm_type == inf:
total_norm = max(p.grad.detach().abs().max().to(device) for p in parameters)
# 当梯度的最大范数是无穷大,参数中的p先取梯度(tensor),从计算图中脱离,按位求绝对值,取最大的
else:
total_norm = torch.norm(torch.stack([torch.norm(p.grad.detach(), norm_type).to(device) for p in parameters]), norm_type)
# 先对p求2范数,将所有结果放到一个列表,用torch.stack 拼接,再求2范数。返回所给tensor的矩阵范数或向量范数
clip_coef = max_norm / (total_norm + 1e-6) # 裁剪系数,我设置max_norm为10, 也就是说total_norm>10时, clip_coef < 1
if clip_coef < 1:
for p in parameters:
p.grad.detach().mul_(clip_coef.to(p.grad.device)) # p*clip_coef,对p进行剪裁
return total_norm
这里的torch.norm,只举一个例子, 详解可以看文档
c = torch.tensor([[ 1, 2, 3],[-1, 1, 4]] , dtype= torch.float)
>>> torch.norm(c, dim=0)
---
tensor([1.4142, 2.2361, 5.0000])
未完待续