python训练模型损失值6000多_记录模型训练时loss值的变化情况

本文介绍了一种在模型训练过程中记录loss变化的新方法,通过sys.stdout.write和 实现每一步loss值在同一行显示,便于观察。此外还讨论了训练过程中可能出现的loss异常及其原因,包括数据预处理、学习率设置等问题。

记录训练过程中的每一步的loss变化

if verbose and step % verbose == 0:

sys.stdout.write('\r{} / {} : loss = {}'.format(

step, total_steps, np.mean(total_loss)))

sys.stdout.flush()

if verbose:

sys.stdout.write('\r')

sys.stdout.flush()

一般我们在训练神经网络模型的时候,都是每隔多少步,输出打印一下loss或者每一步打印一下loss,今天发现了另一种记录loss变化的方法,就是用

sys.stdout.write('\r{} / {} : loss = {}')

如图上的代码,可以记录每一个在每个epoch中记录用一行输出就可以记录每个step的loss值变化,

\r就是输出不会换行,因此如果你想同一样输出多次,在需要输出的字符串对象里面加上"\r",就可以回到行首了。

sys.stdout.flush() #一秒输出了一个数字

具体的实现就是下面的图:

这样在每个epoch中也可以观察loss变化,但是只需要打印一行,而不是每一行都输出。

补充知识:训练模型中损失(loss)异常分析

前言

训练模型过程中随时都要注意目标函数值(loss)的大小变化。一个正常的模型loss应该随训练轮数(epoch)的增加而缓慢下降,然后趋于稳定。虽然在模型训练的初始阶段,loss有可能会出现大幅度震荡变化,但是只要数据量充分,模型正确,训练的轮数足够长,模型最终会达到收敛状态,接近最优值或者找到了某个局部最优值。在模型实际训练过程中,可能会得到一些异常loss值,如loss等于nan;loss值忽大忽小,不收敛等。

下面根据自己使用Pythorh训练模型的经验,分析出一些具体原因和给出对应的解决办法。

一、输入数据

1. 数据的预处理

输入到模型的数据一般都是经过了预处理的,如用pandas先进行数据处理,尤其要注意空值,缺失值,异常值。

缺失值:数值类型(NaN),对象类型(None, NaN),时间类型(NaT)

空值:""

异常值:不再正常区间范围的值

例如对缺失值可以进行判断df.isnull()或者df.isna();丢弃df.dropna();填充df.fillna()等操作。

输入到模型中的数据一般而言都是数值类型的值,一定要保证不能出现NaN, numpy中的nan是一种特殊的float,该值数值运算的结果是不正常的,所以可能会导致loss值等于nan。可以用numpy.any(numpy.isnan(x))检查一下input和target。

2. 数据的读写

例如使用Pandas读取.csv类型的数据得到的DataFrame会添加默认的index,再写回到磁盘会多一列。如果用其他读取方式再读入,可能会导致数据有问题,读取到NaN。

import pandas as pd

Output = pd.read_csv('./data/diabetes/Output.csv')

trainOutput, testOutput = Output[:6000], Output[6000:]

trainOutput.to_csv('./data/diabetes/trainOutput.csv')

testOutput.to_csv('./data/diabetes/testOutput.csv')

3. 数据的格式

Pythorch中的 torch.utils.data.Dataset 类是一个表示数据集的抽象类。自己数据集的类应该继承自 Dataset 并且重写__len__方法和__getitem__方法:

__len__ : len(dataset) 返回数据集的大小

__getitem__ :用以支持索引操作, dataset[idx]能够返回第idx个样本数据

然后使用torch.utils.data.DataLoader 这个迭代器(iterator)来遍历所有的特征。具体可以参见这里

在构造自己Dataset类时,需要注意返回的数据格式和类型,一般不会出现NaN的情况但是可能会导致数据float, int, long这几种类型的不兼容,注意转换。

二、学习率

基于梯度下降的优化方法,当学习率太高时会导致loss值不收敛,太低则下降缓慢。需要对学习率等超参数进行调参如使用网格搜索,随机搜索等。

三、除零错

对于回归问题,可能出现了除0 的计算,加一个很小的余项可能可以解决。类似于计算概率时进行的平滑修正,下面的代码片段中loss使用交叉混合熵(CossEntropy),计算3分类问题的AUC值,为了避免概率计算出现NaN而采取了相应的平滑处理。

from sklearn.metrics import roc_auc_score

model_ft, y_true, losslists = test_model(model_ft, criterion, optimizer)

n_class = 3

y_one_hot = np.eye(n_class)[y_true.reshape(-1)]

# solve divide zero errot

eps = 0.0000001

y_scores = losslists / (losslists.sum(axis=1, keepdims=True)+eps)

#print(y_scores)

#print(np.isnan(y_scores))

"""

metrics.roc_auc_score(y_one_hot, y_pred)

"""

print("auc: ")

roc_auc_score(y_one_hot, y_scores)

四、loss函数

loss函数代码编写不正确或者已经编写好的loss函数API使用不清楚

五、某些易错代码

Pytorch在进行自动微分的时候,默认梯度是会累加的,所以需要在每个epoch的每个batch中对梯度清零,否则可能会导致loss值不收敛。不要忘记添加如下代码

optimizer.zero_grad()

以上这篇记录模型训练时loss值的变化情况就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持python博客。

<think>好的,用户遇到了YOLOv11训练box_loss、cls_loss和dfl_loss初始为零的问题。我需要先分析可能的原因,然后给出解决方法。 首先,用户提到的损失函数初始为零,可能意味着模型在初始阶段没有有效的梯度更新。常见原因包括数据问题、初始化设置、损失计算错误或学习率不当。 检查数据加载是否正确。数据路径错误或标注格式不符可能导致模型无法学习。比如COCO格式的标注是否正确,类别ID是否从0开始。用户需要确认数据路径是否正确,并检查标注文件是否存在错误。 然后是模型初始化。YOLO模型通常会预加载权重,如果用户未正确加载预训练模型,或者自定义层初始化不当,可能导致参数初始化为零。特别是检测头的偏置初始化,引用[3]提到偏置初始化为较大负以避免错误检测。如果初始化不正确,可能导致损失异常。 损失函数配置也需要检查。YOLOv11可能使用特定的损失组合,如box_loss、cls_loss和dfl_loss。如果这些损失函数的参数设置错误,或者权重为零,会导致损失值异常。需要确认配置文件中损失函数的参数是否正确,尤其是dfl_loss可能需要特定的参数设置。 学习率过高或过低也可能影响训练初期。过高的学习率可能导致梯度爆炸,损失值异常;过低则可能使模型无法有效更新。建议使用预训练模型推荐的初始学习率,并逐步调整。 另外,数据增强策略可能影响。如果应用了过强的增强,导致输入数据难以识别,模型无法学习。可以暂关闭数据增强,观察损失变化。 调试步骤建议用户逐步排查:先检查数据,再确认模型初始化是否正确,接着查看损失配置,调整学习率,最后考虑数据增强的影响。同,使用预训练模型作为起点,确保各组件正确加载。 总结下来,用户需要从数据、模型初始化、损失配置、学习率等方面逐一排查,结合引用中的信息,特别是偏置初始化和预训练模型加载,来解决问题。</think>关于YOLOv11训练$box\_loss$、$cls\_loss$、$dfl\_loss$初始为0的问题,以下是可能原因及解决方法: ### 一、原因分析 1. **数据加载异常** - 数据路径错误或标注格式不匹配(如COCO/YOLO格式混淆) - 输入图像尺寸与模型配置不匹配(如$img\_size=640$但实际输入为其他尺寸) - 类别标签未从0开始连续编号(需符合$class\_id \in [0, n-1]$) 2. **初始化问题** - 检测头未正确加载预训练权重(引用[2]中`YOLO(abs_path('./weights/yolov8n.pt'))`的加载方式需确认权重兼容性) - 偏置初始化未按规范设置(引用[3]提到需通过$bias\_init$设置合理初始) 3. **损失计算配置错误** - 损失函数权重系数设置异常(如$loss\_weights=[0,0,0]$) - DFL损失参数未正确配置(需要设置$use\_dfl=True$及相关参数) 4. **学习率异常** - 初始学习率过高(如$lr0=0.001$变成$lr0=1.0$) - 预热阶段设置过短(如$warmup\_epochs=0$) ### 二、解决方法 1. **数据验证** ```python from PIL import Image import yaml # 检查标注文件 with open('data.yaml') as f: data_cfg = yaml.safe_load(f) print(f"类别数: {data_cfg['nc']}, 类别列表: {data_cfg['names']}") # 验证图像读取 img = Image.open('train/images/0001.jpg') print(f"图像尺寸: {img.size}, 模式: {img.mode}") ``` 2. **模型初始化修正** ```python # 正确加载预训练模型(引用[2]) model = YOLO('yolov11.pt').load('yolov11_base.pt') # 检测头偏置初始化(引用[3]) for m in model.model.modules(): if isinstance(m, nn.Conv2d): b = m.bias.view(4, -1) b.data[:, 0] += math.log(8/(640/4)**2) # 调整检测层偏置 ``` 3. **损失配置检查** ```yaml # loss配置示例 loss: name: YOLOv11Loss box: 7.5 # 坐标损失系数 cls: 0.5 # 分类损失系数 dfl: 1.5 # DFL损失系数 use_dfl: True reg_max: 16 # DFL关键参数 ``` 4. **训练参数调整** ```python # 推荐训练配置 results = model.train( data='data.yaml', epochs=300, lr0=0.01, # 初始学习率 warmup_epochs=3, # 学习率预热 label_smoothing=0.1, momentum=0.9, weight_decay=0.0005 ) ``` ### 三、调试建议 1. 先使用$batch\_size=1$进行快速验证 2. 可视化初始预测结果: ```python from ultralytics.utils.plotting import plot_results plot_results('results.csv') # 损失曲线分析 ``` 3. 检查梯度传播: ```python for name, param in model.named_parameters(): if param.grad is None: print(f"No gradient: {name}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值