应用篇#3:MMPretrain的使用2
摘要:本文记录了深度学习模型训练过程中的问题解决与结果分析。首先解决了工作目录路径问题,将相对路径改为绝对路径后成功输出训练数据。随后尝试了多种结果读取方法:日志文件仅显示训练数据,TensorBoard因访问问题失败,JSON文件同样缺少评估指标。更换为ResNet18模型后成功获取训练损失和验证准确率等指标。文章还介绍了自定义模型改进方法,通过深度可分离卷积替换标准卷积层,并成功运行。最后说明
一、昨日问题解决与结果读取
1、昨日问题解决
昨天遇到work_dir中没有checkpoint输出!!!的问题
该设置由配置文件最后一行决定,原始为相对路径,如下:
work_dir = '.work_dirs/1'
后修改为绝对路径:
work_dir = '/root/mmpretrain/work_dirs/1'
此后便在指定的文件夹中出现了训练过程数据
2、结果读取
(1)××以时间戳命名的日志文件××
mmpretrain/work_dirs/1/20251126_091311/20251126_091311.log
# 查看最新的日志文件 ls -la /root/mmpretrain/work_dirs/1/20251126_091311/20251126_091311.log # 查看日志内容 cat /root/mmpretrain/work_dirs/1/20251126_091311/20251126_091311.log # 或者 tail -f /root/mmpretrain/work_dirs/1/20251126_091311/20251126_091311.log
运行完后发现,只输出了所有训练过程的数据,并不包含评价指标
2025/11/26 09:23:22 - mmengine - INFO - Epoch(train) [23][2800/3125] lr: 1.0000e-01 eta: 1:11:21 time: 0.0080 data_time: 0.0008 memory: 18 loss: 2.3116
(2)××使用 TensorBoard 可视化××
# 启动 TensorBoard tensorboard --logdir=/root/mmpretrain/work_dirs/1 # 然后在浏览器中访问 http://localhost:6006
由于无法访问http://localhost:6006,失败
(3)××查看 JSON 格式的评估结果××
# 查看评估结果文件 ls -la /root/mmpretrain/work_dirs/1/20251126_091311/vis_data/ # 查看评估结果 cat /root/mmpretrain/work_dirs/1/20251126_091311/vis_data/20251126_091311.json
依然只输出
{"lr": 0.1, "data_time": 0.0007235050201416015, "loss": 2.3024168252944945, "time": 0.007788324356079101, "epoch": 23, "iter": 70350, "memory": 18, "step": 70350}
(4)××使用 MMPreTrain 工具分析××
# 分析训练日志 python /root/mmpretrain/tools/analysis_tools/analyze_logs.py /root/mmpretrain/work_dirs/1/20251126_091311/20251126_091311.log --keys accuracy --legend train val # 绘制损失曲线 python tools/analysis_tools/analyze_logs.py /root/mmpretrain/work_dirs/1/时间戳.log --keys loss --legend train val --out loss_curve.png
同样没法输出,有可能是这个模型不输出准确度。但是,即便是一个十分简单的网络,训练用的数据集明显是图像,不要评价指标怎么确定训练效果呢?
我们换一个模型,重新尝试一下
python mmpretrain/tools/train.py mmpretrain/configs/resnet/resnet18_8xb16_cifar10.py #进行训练 python mmpretrain/readresult.py #读取结果
换模型后成功运行readresult.py输出了结果
解析结果统计: epochs 数量: 190 train_losses 数量: 190 val_accuracies 数量: 6 最终训练损失: 0.5704 最终验证准确率: 80.33 数据已保存到 CSV 文件
(5)除了默认的Accuracy以外其他指标的读取
MMPretrain的默认评价指标只有accuracy,需要注册并在配置文件中调用不同的其他评价指标,例如:
# 在您的配置文件中修改 val_evaluator 和 test_evaluator
val_evaluator = [ dict(type='Accuracy', topk=(1, 5)), # Top-1 和 Top-5 准确率
dict(type='SingleLabelMetric', items=['precision', 'recall', 'f1-score'], average='macro'), # 精确率、召回率、F1分数
dict(type='ConfusionMatrix') # 混淆矩阵
]
test_evaluator = [ dict(type='Accuracy', topk=(1, 5)), dict(type='SingleLabelMetric', items=['precision', 'recall', 'f1-score'], average='macro'), dict(type='ConfusionMatrix') ]
python mmpretrain/tools/train.py mmpretrain/work_dirs/resnet18_8xb16_cifar10/resnet18_8xb16_cifar10.py #训练 python mmpretrain/readresult.py #读取结果
运行过程如下,成功输出
(base) root@autodl-container-35c04cbe2d-10eebea8:~# python mmpretrain/readresult.py 解析结果统计: epochs 数量: 68 train_losses 数量: 68 accuracy/top1 数量: 2 最终 accuracy/top1: 68.0000 precision 数量: 2 最终 precision: 72.2313 recall 数量: 2 最终 recall: 68.0000 f1-score 数量: 2 最终 f1-score: 68.5939 最终训练损失: 0.8946 已保存: /root/mmpretrain/work_dirs/resnet18_8xb16_cifar10/accuracy_top1_results.csv 已保存: /root/mmpretrain/work_dirs/resnet18_8xb16_cifar10/precision_results.csv 已保存: /root/mmpretrain/work_dirs/resnet18_8xb16_cifar10/recall_results.csv 已保存: /root/mmpretrain/work_dirs/resnet18_8xb16_cifar10/f1-score_results.csv 数据已保存到 CSV 文件 === 最终评估结果摘要 === accuracy/top1: 68.0000 precision: 72.2313 recall: 68.0000 f1-score: 68.5939
二、自定义模型+现有数据集思路二实践
1、深度可分离卷积
深度可分离卷积是轻量化模型的常用工具,在我做YOLO改进的时候用到过,详情可以参考
https://blog.csdn.net/hjs314159/article/details/146367861?spm=1001.2014.3001.5501
我们尝试用这个简单的模块来替换原来的Conv2d模块
其定义代码如下:
class Conv(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):
super(Conv, self).__init__()
self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size, stride, padding, groups=in_channels)
self.pointwise = nn.Conv2d(in_channels, out_channels, 1)
def forward(self, x):
out = self.depthwise(x)
out = self.pointwise(out)
return out
2、实践
(1)resnet_cifar代码解读
def __init__(self, depth, deep_stem=False, **kwargs):
super(ResNet_CIFAR, self).__init__(
depth, deep_stem=deep_stem, **kwargs) # 调用父类初始化
assert not self.deep_stem, 'ResNet_CIFAR do not support deep_stem' # 检查不支持deep_stem
def _make_stem_layer(self, in_channels, base_channels):
self.conv1 = build_conv_layer( # 创建初始卷积层
self.conv_cfg, # 卷积配置
in_channels, # 输入通道数
base_channels, # 输出通道数
kernel_size=3, # 3x3卷积核(CIFAR优化)
stride=1, # 步长1(CIFAR优化)
padding=1, # 填充1保持尺寸
bias=False) # 无偏置(配合BN使用)
self.norm1_name, norm1 = build_norm_layer( # 创建归一化层
self.norm_cfg, base_channels, postfix=1) # 归一化配置,后缀为1
self.add_module(self.norm1_name, norm1) # 添加归一化层到模型
self.relu = nn.ReLU(inplace=True) # 创建ReLU激活函数
def forward(self, x):
x = self.conv1(x) # 通过初始卷积层
x = self.norm1(x) # 通过归一化层
x = self.relu(x) # 通过激活函数
outs = [] # 初始化输出列表
for i, layer_name in enumerate(self.res_layers): # 遍历残差层
res_layer = getattr(self, layer_name) # 获取残差层对象
x = res_layer(x) # 通过当前残差层
if i in self.out_indices: # 检查是否在输出索引中
outs.append(x) # 添加到输出列表
return tuple(outs) # 返回多尺度特征图元组
(2)修改
①在前面把spdconv的定义照搬,并实现内部调用(无需注册);
②修改第6-14行如下,按照SPDConv所需的参数来填写:
def _make_stem_layer(self, in_channels, base_channels): self.conv1 = Conv( in_channels, base_channels, kernel_size=3, stride=1, padding=1)
成功运行!!
3、注意事项
-
虽然MMPretrain把模型拆分成了不同的组件,但是组件之间并不是可以任意组合的,需要在大小、参数等方面对齐
-
每个组件的输出不一定是Tensor,也有可能是Tuple
Tensor(张量)
-
Tensor是PyTorch中的核心数据结构,可以看作是一个多维数组。
-
它包含统一类型的数据(例如浮点数、整数等),并支持在GPU上进行加速计算。
-
Tensor有形状(shape)、数据类型(dtype)和设备(device)等属性。
-
在神经网络中,输入、输出、参数等通常都是Tensor。
Tuple(元组)
-
Tuple是Python中的内置数据结构,属于序列类型。
-
它可以包含任意类型的元素(包括Tensor和其他Tuple),并且是不可变的(创建后不能修改)。
-
Tuple使用圆括号
()定义,元素之间用逗号分隔。
-
并不是每个组件都是必须的,例如可以没有Neck部分
-
loss是和Head绑定的,拆解模型的时候要注意
三、现有模型+自定义数据集
“现有模型+自定义数据集”是大多数企业所需要的模式,有时,企业会对现有模型进行微调或者改进,以此提高模型的准确度,并形成竞争优势。因此,这是所有模式中最关键的一个。
1、准备照片数据集
按照有无监督准备数据集,以无监督学习为例,准备一个文件夹,文件夹中放分类文件夹,再放各类别的照片即可
2、修改配置文件
train_dataloader = dict( batch_size=16, collate_fn=dict(type='default_collate'), dataset=dict( data_root='data/cifar10', pipeline=[ …………
在dataset=dict(后面要加上自定义数据集的类别:
type='CostomDataset'
注意!!!
-
要跟着修改地址目录,删除或增加不必要的设置
-
train、test和val的dataloader中都要进行修改
更多推荐

所有评论(0)