训练深度神经网络时调参经验

训练深度神经网络时调参经验

1.如果损失一直比较大,且降不下去,就是说模型在训练集和测试集上的结果都比较差

可以尝试从以下三个方面入手:

(1)损失函数

如果是回归任务的损失函数有:

优先选择SmoothL1Loss函数

下面公式中的N可以看做是batch size一般是传入数据的第一个纬度,n可以看做是一个batch size中的元素个数,可以看下面的代码更为清晰

SmoothL1损失函数
torch.nn.SmoothL1Loss(size_average=None, reduce=None, reduction='mean', beta=1.0) 在某些情况下可以防止梯度爆炸
image-20220402201344135
L1Loss损失函数
image-20220402200500404
MSELoss损失函数
二范数的平方
image-20220402200641563

关于损失函数中的reduction参数有三个选择:

import torch.nn as nn
loss1 = nn.MSELoss(reduction='sum')
loss2 = nn.L1Loss(reduction='none')
loss3 = nn.SmoothL1Loss() # 默认是mean
input = torch.ones(2, 2, 2)*2
input.requires_grad = True
target = torch.zeros(2, 2, 2)
output1 = loss1(input, target)
output2 = loss2(input, target)
output3 = loss3(input, target)
print('sum:{}\nnone:{}\nmean:{}'.format(output1, output2, output3))
"""
sum:32.0
none:tensor([[[2., 2.],
[2., 2.]],
[[2., 2.],
[2., 2.]]], grad_fn=<L1LossBackward>)
mean:1.5 ## 由于2-0大于1,所以计算结果是|2-0|-0.5*1=1.5,一共8个元素,均值也是1.5
"""

(2)优化器 optimizer

优化器是用来更新传入的网络参数的(根据计算出来的参数梯度),注意如果参数需要放在GPU上,应该在构建优化器前,就将参数放到GPU

一般选择Adam优化器,有时候会比SGD好很多

Adam
torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False, *, foreach=None, maximize=False)
image-20220402214446963
SGD
torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False, *, maximize=False, foreach=None)
image-20220402214901325

(3)网络模型的复杂度

有可能是欠拟合引起的,也就是说模型复杂度不够,可以增加网络深度。比如刚开始用的torchvision.models.resnet18(pretrained=True),可以增加到resnet101或者152等等,就是这样一个思路。

2.训练损失为nan

很有可能是梯度爆炸引起的网络输出值超出可控范围,导致输出值很离谱,这样损失函数计算时就为nan

可以尝试通过减小学习率来解决,这样梯度很大时,我们的参数变化也不会那么大

posted @   rain-1227  阅读(319)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示