训练深度神经网络时调参经验
训练深度神经网络时调参经验
1.如果损失一直比较大,且降不下去,就是说模型在训练集和测试集上的结果都比较差
可以尝试从以下三个方面入手:
(1)损失函数
如果是回归任务的损失函数有:
优先选择SmoothL1Loss
函数
下面公式中的N
可以看做是batch size
一般是传入数据的第一个纬度,n
可以看做是一个batch size
中的元素个数,可以看下面的代码更为清晰
SmoothL1 损失函数 |
---|
torch.nn.SmoothL1Loss (size_average=None, reduce=None, reduction='mean', beta=1.0) 在某些情况下可以防止梯度爆炸 |
![]() |
L1Loss 损失函数 |
![]() |
MSELoss 损失函数 |
二范数的平方 |
![]() |
关于损失函数中的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) |
![]() |
SGD |
torch.optim.SGD (params, lr= |
![]() |
(3)网络模型的复杂度
有可能是欠拟合引起的,也就是说模型复杂度不够,可以增加网络深度。比如刚开始用的torchvision.models.resnet18(pretrained=True)
,可以增加到resnet101
或者152
等等,就是这样一个思路。
2.训练损失为nan
很有可能是梯度爆炸引起的网络输出值超出可控范围,导致输出值很离谱,这样损失函数计算时就为nan
可以尝试通过减小学习率来解决,这样梯度很大时,我们的参数变化也不会那么大
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!