梯度爆炸和运行环境保存(torch.save)

1.查找模型训练崩溃原因是否由于梯度爆炸或者梯度消失引起

方法1:参考 https://zhuanlan.zhihu.com/p/32154263,通过tensorboard检测梯度值和参数值来查找原因。该方式便于观察,不好做定量统计

方法2:使用csv文件记录网络所有层的相关梯度和网络层所有的值,通过统计分析(比如统计梯度的最大最小值),得出是否由于梯度爆炸造成网络崩溃

当由于梯度爆炸造成网络崩溃时,需要设置阈值。阈值的选择也需要通过统计获得

2.如果是梯度爆炸引起的,需要做梯度裁剪。

方法1:梯度范数裁剪:

import torch.nn as nn
import torch.optim as optim
import torch

class LinearNet(nn.Module):
    def __init__(self, features_in=5, features_out=5):
        super().__init__()
        self.linear = nn.Linear(features_in, features_out)
        self._init_weight()

    def forward(self, x):
        return self.linear(x)
    def _init_weight(self):
        nn.init.constant_(self.linear.weight, val=1)
        nn.init.constant_(self.linear.bias, val=0)
# 定义
net = LinearNet()
mse_fn = nn.L1Loss()
optimizer = optim.SGD(net.parameters(), lr=0.1)
# 网络输入和标签
x = torch.FloatTensor([120,200,0.5,-200,1])
target_value = torch.FloatTensor([2,1,5,10,40])
# loss计算
predict = net(x)
loss = mse_fn(predict, target_value)

loss.backward()
print("grad before clip:"+str(net.linear.weight.grad))
# nn.utils.clip_grad_value_(net.linear.weight, clip_value=1.1)
nn.utils.clip_grad_norm_(net.linear.weight, max_norm=2, norm_type='inf')
print("grad after clip:"+str(net.linear.weight.grad))

nn.utils.clip_grad_norm_:

源代码:https://blog.csdn.net/qq_40178291/article/details/100853237

归一化时的系数:max_norm/parameters的范数,范数类型为norm_type;如果norm_type为1,则为绝对值之和;如果norm_type为2,则为欧式距离;如果范数类型为inf,则为最大值,使用inf做归一化,如果parameters值大于max_norm,则归一化后最大值为max_norm,如果小于max_norm,则parameters不变。

nn.utils.clip_grad_value_

把参数中大于clip_value的值设置为clip_value.

这里所说的大于小于都是针对绝对值的比较,设置为也是符号不变。

 

1.为了重现运行环境,当检测到运行异常时,需要保存模型,输入等,调试时将保存的数据加载。

#保存一个tensor

torch.save(tensor,path)--->tensor=torch.load(path)

#保存多个环境:保存为一个字典,

torch.save({'exp':a,'exp2':a+2},path) -->dict_tensor=torch.load(path)  

 

2.当出现梯度问题,而且自己找不到原因解决该问题时;可以出现这种问题时,跳过本次的结果(这种方式只能处理该次输入数据有问题,比如输入数据使得梯度为nan,对模型本身无法改善)

其中:

optimizer.zero_grad()  将参数的梯度都设置为0

loss.backward():计算各个变量的梯度,并将梯度赋值给各个变量

optimizer.step():根据当前变量的梯度和学习率,对变量做梯度下降来更新变量

所以,loss.backward()后,判断梯度是否满足条件,不满足则使用optimizer.zeros_grad()来将本次的梯度都设置为0

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值