使用FastAI训练车型分类模型时准确率极低的问题求助
使用FastAI训练车型分类模型时准确率极低的问题求助
我现在正在搭建一个模型,用来分类数千个不同车企的车型。我参考了fastbook的一些章节来构建代码结构和模型,但遇到了大问题——训练完成后模型的准确率惨不忍睹,预测结果非常糟糕(我用error_rate作为评估指标)。以下是我目前使用的代码:
#!/usr/bin/env python # coding: utf-8 # In[ ]: #Affiche les class d'images peu fourni pour permettre de les enrichir import os import re def count_files(directory, n_occurrences): files_count = {} for subdir, dirs, files in os.walk(directory): for file in files: filename = file.split("_", 3)[0:3] # prends les 3 premières parties du nom de fichier filename = "_".join(filename) if filename in files_count: files_count[filename] += 1 else: files_count[filename] = 1 filtered_files = [(file, count) for file, count in files_count.items() if count < n_occurrences] filtered_files.sort(key=lambda tup: tup[1], reverse=True) print(filtered_files) count_files('images/archive', 5) # In[ ]: #Nomme les classes pour le datablock import re def get_name(string): matches = re.findall(r"_", string) if len(matches) >= 3: index = string.index("_", string.index("_", string.index("_")+1)+1) return string[:index] return string # In[ ]: from fastai.vision.all import * cars = DataBlock(blocks = (ImageBlock, CategoryBlock), get_items=get_image_files, splitter=RandomSplitter(valid_pct=0.3, seed=44), get_y=using_attr(get_name, 'name'), item_tfms=Resize(128), batch_tfms=aug_transforms(size=128)) # In[ ]: dls = cars.dataloaders('images/archive', bs=16) # In[ ]: dls.show_batch(nrows=3, ncols=3) # In[ ]: model = xresnet34(n_out=dls.c) learn = Learner(dls, model, loss_func=LabelSmoothingCrossEntropy(), metrics=accuracy) learn.fine_tune(3) # In[ ]: #width 600 interp = ClassificationInterpretation.from_learner(learn) #Matrice de confusion #interp.plot_confusion_matrix(figsize=(12,12), dpi=60) interp.most_confused(min_val=50) # In[ ]: lr_min,lr_steep = learn.lr_find(suggest_funcs=(minimum, steep)) print(f"Minimum/10: {lr_min:.2e}, steepest point: {lr_steep:.2e}") # In[ ]: #MinimumLR/10 learn.fit_one_cycle(3, 1e-8) # In[ ]: learn.unfreeze() # In[ ]: learn.lr_find() # In[ ]: #Lr_find[0] learn.fit_one_cycle(6, lr_max=6e-5) # In[ ]: learn.fit_one_cycle(3, 6e-5) learn.unfreeze() learn.fit_one_cycle(12, lr_max=slice(1e-6,1e-4)) # In[ ]: learn.recorder.plot_loss() # In[ ]: learn.predict('test/porsche.jpg')
我来帮你分析可能的问题点和对应的解决方案:
数据层面的核心问题
- 类别极端不平衡:你已经注意到了样本量少的类别,但数千个车型的场景下,大量类别可能只有寥寥几个样本,模型根本无法学到有效特征。建议先统计所有类别的样本数量,把样本数少于10-20的类别暂时合并(比如按品牌合并)或者移除,先让模型能学好样本充足的类别,之后再逐步处理小众类别;同时可以对小众类别做针对性的数据增强(比如旋转、翻转、亮度调整等)来扩充样本。
- 标签提取逻辑验证:你的
get_name函数通过下划线分割提取车型名称,这个逻辑是否100%准确?建议随机抽取几十张图片,手动核对get_y生成的标签和实际车型是否一致——如果标签经常出错,模型肯定学不好。 - 数据集划分不合理:
RandomSplitter在类别极多时,很容易出现某些类别在验证集里没有样本,或者样本极少的情况,导致评估结果失真。建议换成StratifiedSplitter,保证训练集和验证集的类别分布一致。
模型与训练策略优化
- 提升模型容量:xresnet34对于数千个类别的分类任务来说,容量可能不够。可以尝试换成xresnet50、xresnet101,或者试试FastAI支持的视觉Transformer(ViT)这类更大的预训练模型,预训练模型的特征提取能力更强,更适合复杂的分类任务。
- 调整学习率与训练轮数:你之前用了1e-8这种极低的学习率,这会导致模型参数几乎不更新,完全起不到训练效果。建议先冻结模型(只训练最后一层分类头),用
lr_find找到合适的学习率后,先训练10-20轮,再解冻整个模型,用slice(1e-6, 1e-4)这样的学习率范围进行微调,同时观察训练损失和验证损失的变化,一旦验证损失开始上升就停止训练,避免过拟合。 - 提升图像分辨率与增强策略:128x128的分辨率太低了,车型的很多关键特征(比如车标、车身线条)会被压缩丢失。建议把分辨率提高到224x224甚至256x256;同时可以增强数据增强的强度,比如在
aug_transforms里加入RandomResizedCrop、RandomFlip、Brightness、Contrast等参数,让模型见过更多不同角度、不同光照的车辆图片,提升泛化能力。 - 尝试更适合的损失函数:
LabelSmoothingCrossEntropy不错,但对于类别极多且不平衡的任务,可以试试FocalLoss,它能降低易分类样本的权重,让模型更关注难分类的小众类别。
训练流程监控与迭代
- 仔细分析混淆矩阵:用
interp.plot_confusion_matrix看看哪些类别最容易混淆,分析这些类别是本身外观相似,还是标签错误,针对性地优化数据(比如补充相似类别的样本、修正错误标签)。 - 监控损失变化:通过
learn.recorder.plot_loss()观察训练损失和验证损失的趋势,如果训练损失一直在下降但验证损失上升,说明过拟合,需要增加正则化(比如在Learner里加入wd=1e-4的权重衰减)或者减少训练轮数;如果两者都不下降,说明学习率太低或者模型容量不足。
- 仔细分析混淆矩阵:用
希望这些建议能帮你解决问题,提升模型的准确率!
备注:内容来源于stack exchange,提问作者N7Legend
相关产品推荐
相关产品推荐

