简介这是一份面向计算机视觉初学者与深度学习实践者的天气图像分类数据集适用于图像识别、CNN模型训练及多类别分类任务教学与科研。数据集共9000个样本涵盖14类典型天气现象如cloudy、rain、snow、sunrise、fogsmog等已按标准划分训练集7180张与测试集808张目录结构清晰data/train_data / data/test_data开箱即用。压缩包含2000个文件主体为7987张JPG格式天气实拍图命名规范含类别前缀辅以1个Python训练脚本和1张说明PNG图总大小676.81MB便于本地加载与迁移学习。已有1118人下载学习配套CNN模型在该数据集上可达96.3%准确率提供可复现的基线性能参考读者可直接用于模型微调、数据增强实验、混淆矩阵分析及14细粒度天气场景识别系统开发。 天气分类数据集这件事我算是被逼着才动手做的。当时接了一个户外场景识别的项目需要先判断天气再走后续逻辑翻遍了公开渠道要么是几千张的小规模demo要么类别只有晴天、多云、雨、雪四类雾天和阴天基本是混在一起的。后来一咬牙自己攒了一个9000样本的天气分类数据集从采集、清洗到训练、部署走完了一遍全流程。这篇文章就把整个过程中的关键决策、踩过的坑、以及最终沉淀下来的方法完整记录下来给正在做或打算做类似视觉分类任务的朋友一个可以直接参考的样本。1. 天气分类这件事为什么比想象中难很多人一听“天气分类”就觉得简单不就是给图打个标签吗。真正做了之后才发现这是典型的“看起来容易、做起来处处是坑”的视觉任务。1.1 天气不是一个实体而是一组视觉特征的综合表现先想一个本质问题人在看到一张户外照片时是怎么判断“今天是晴天”的靠的是天空区域的比例和亮度、阴影是否存在且锐利、光线照射角度、地面和建筑表面的反射特性、空气中颗粒物的能见度等等。这些线索聚合在一起才形成一个“晴天”的认知。这就导致天气分类和猫狗分类有本质区别。猫有眼睛、耳朵、胡须这些明确的语义部件深度学习模型可以通过提取局部纹理特征来识别但天气没有固定的“部件”它是一整张图的全局视觉状态。晴天和阴天的差异可能只是天空区域亮度的梯度变化雨天和雾天都具备低能见度特征但前者是雨丝造成的动态模糊后者是气溶胶散射造成的均匀灰蒙。这种全局性、模糊性的特征对数据集构建提出了很高要求。如果采集样本时不考虑场景多样性、光照方向、拍摄设备差异、画面中是否有人为前景遮挡等因素模型很容易学到“天空在画面顶部有多亮”这种粗暴的捷径特征换一批真实场景就崩。1.2 9000个样本的规模是拍脑袋定的吗先从需求反推。六分类任务每类如果期望达到90%以上准确率常规经验是每类样本量不少于数据维度承载能力的一个下限。我在实践中发现对于ImageNet预训练模型做微调每类1200到1500张图基本能收敛出稳定的决策边界少于800张时雨天和雾天这类边界模糊的类别很容易出现振荡。9000这个数字其实是“每类1500张 × 6类”算出来的理想值。但真实采集过程中会发现有些类别很容易凑晴天、阴天有些类别极难凑到均衡雷暴、雪天所以最终每个类别的数量并不完全一致整体规模定格在9000。这个数量级的另一个好处是训练时间可控单卡环境下用ResNet50微调20个epoch大概在一个多小时跑完可以快速迭代验证清洗效果和数据增强策略是否有效。2. 数据采集渠道与清洗策略9000张图是怎么攒出来的数据来源和清洗过程是整条流水线里最耗时、最乏味、也最容易被低估的环节。这里直接把我的渠道配比和踩坑经历摊开讲。2.1 三个主要采集源头与配比我最终用的是三路来源的混合方案不是单一渠道原因是单一渠道会导致严重的数据偏置。比如全用网络图片搜索模型会学到搜索引擎结果特点——大量高清、构图标准、带后期调色的图片部署到真实监控画面时直接水土不服。来源渠道及大致占比来源渠道占比说明公开天气数据集约35%整合了多个公开数据集中的天气相关子集但只取其中场景相对真实、不包含水印和标注框的图片网络图片搜索引擎约40%按“晴天、阴天、雨天、雪天、雾天、雷暴”等多组关键词组合检索覆盖不同地域和季节实拍与街景截帧约25%用行车记录仪和手机在城市、郊区、山区、高速等场景拍摄再从视频中截帧为什么坚持保留实拍和街景截帧这一路因为这是唯一能保证“设备真实感”的数据来源。网络图片大多是摄影作品构图考究天气特征被艺术化放大而模型最终要部署在监控探头、车载摄像头这类常规设备上画面可能存在偏色、噪点、镜头畸变甚至遮挡。没有真实设备画面兜底验证集指标再高也心虚。2.2 清洗过程中最耗费时间的细分类目清洗是数据集中间最容易出问题的一环。9000张原始图里能直接用的可能只有一半稍多。我逐类过了一遍总结出几类高频废弃样本多天气混杂画面下半部分是雪地上半部分却是晴空蓝天。这种样本无法给出唯一标签直接删除。低质量强噪声严重过曝、完全黑场、运动模糊到看不清任何场景结构。这类图连人类都无从判断就不该进入训练集。天气特征被遮蔽画面被大面积广告牌、建筑物墙体占满天空占比不足5%即使知道当天天气也无从判断。搜索引擎带水印和文字叠加尤其是带新闻台标的画面模型会学到“台标位置有文字”这种无关特征。清洗是一件需要耐心但不需要太多技术含量的事情。效率最高的做法是先用一个粗筛脚本按文件大小和基本亮度直方图剔除明显垃圾样本再做人工逐图检查。9000张原图我用两个晚上完成了第一轮粗筛又用一周碎片时间做了逐类细筛。3. 类别体系设计分几类、边界画在哪类别体系的设计直接决定了任务难度上限。分得太粗模型自然容易收敛但落地时价值低分得太细类别之间重叠严重标注一致性迟早出问题。3.1 六分类体系的判定标准我最终采用的是“晴天、阴天、雨天、雪天、雾天、雷暴”六分类方案。这个方案参考了气象学中天气现象的基本分类同时兼顾了视觉可分辨性。关键在于每个类别必须有明确的视觉判定标准而不是模糊的日常感受晴天天空区域存在明显亮度梯度日照产生清晰阴影或高光反射整体色温偏暖。阴天天空亮度均匀且偏低云层厚实无明确阴影边界光线方向不可辨识。雨天画面中存在雨丝、雨滴或地面积水反光能见度低于晴天但高于雾天的均匀灰蒙。雪天地面、屋顶或植被存在积雪覆盖区域通常伴随灰白色天空。雾天能见度显著降低远近物体对比度差异明显天空区域与地面建筑边界模糊。雷暴云层极厚且低垂画面整体偏暗可能包含闪电亮斑、暴雨或冰雹特征。这个判定标准不仅是给标注者用的也是给模型划定的决策边界。比如一张图里地面湿漉漉但天空灰亮没有明显雨丝这种我归入阴天而不是雨天——因为从视觉特征上讲它不具备“雨”的直接证据宁可让模型在阴天和雨天边界处犯一点错也不要让内部标签自相矛盾。3.2 容易混淆的边界样本怎么处理最让人头疼的类别组合有两对阴天与雨天、雾天与阴天。阴天和雨天的混淆点很好理解雨后地面积水反光但天空已经亮开此时残留的“湿”特征和“阴”特征同时存在。我的处理策略是引入“当前天气状态”的概念即标签反映的是拍摄时刻画面呈现的最显著天气现象而不是过去几小时发生过什么。地面有积水但无雨滴、天空泛亮就应该标阴天。雾天和阴天的混淆则更隐蔽。浓雾天气的天空本身也是灰白色和阴天天空视觉差异极小。两者的判别关键在“中低空物体的清晰度”雾天中远处楼宇、树木轮廓被大幅度模糊且边缘弥散阴天只是光线暗物体轮廓依然是锐利的。清洗时我会放大局部区域逐张确认这一对类别的耗时基本上是其他类别的好几倍。4. 预处理与数据增强把每个样本的价值榨干数据集的“质”来自清洗和类别设计“量”的价值则需要预处理和数据增强来充分释放。9000张图说多不多说少也不少关键是让模型从有限样本里学到真正的泛化特征。4.1 尺寸统一与归一化细节所有图片在送入模型前统一处理为224×224分辨率这是ResNet系列和EfficientNet系列的标准输入尺寸。处理方式上不是简单缩放而是在缩放前先做短边对齐裁剪避免画面比例被强行压扁导致天空区域的形态失真。归一化参数我沿用ImageNet统计值均值[0.485, 0.456, 0.406]标准差[0.229, 0.224, 0.225]。很多新手会忽略一个细节如果数据集本身有明显色偏比如监控画面偏绿偏蓝可以在归一化之前加一个自适应白平衡或直方图均衡化步骤但这可能同时削弱季节特征的表现力。天气分类里色温本身就是一种天气特征所以我强烈建议不要做重度的色彩归一化保留原始色偏让模型自己去利用这些线索。数据划分上我采用85%训练、5%验证、10%测试的比例。因为是按类别分别切分的每个类别内部都按这个比例抽避免出现某一类在测试集中缺失的极端情况。最终训练集约7650张验证集450张测试集900张。4.2 数据增强策略的取舍数据增强不是越多越好每一项增强都会对特征分布产生特定影响。我实际启用的增强管线如下随机水平翻转概率0.5对所有类别都安全天空区域水平翻转不会改变天气含义。随机旋转±10度超过这个范围会造成地平线明显倾斜破坏场景常识。随机亮度/对比度调整幅度±20%可以增强模型对曝光差异的鲁棒性但幅度不能过大否则晴天可能被调成阴天的亮度分布。随机色彩抖动亮度、对比度、饱和度、色相的小幅组合扰动帮助模型不依赖特定色温。随机裁剪缩放0.8到1.0倍缩放后再裁剪到224×224模拟不同拍摄距离下天气特征呈现的比例差异。有两个增强我故意没有加一是高斯噪声二是随机擦除。原因是天气分类对纹理细节敏感雨丝、雪片、闪电亮斑这些关键线索都是局部细节加噪声或擦除会直接破坏这些微小却强判别力的特征。实际验证下来这套增强策略在验证集上带来了约3个百分点的提升更重要的是增强了模型对实拍画面的适应性。测试集里我特意混入了一批没有参与训练的不同地区街景截图准确率下降幅度在可以接受的范围内。5. 模型选型与训练配置为什么迁移学习是捷径9000张图对深度学习模型来说说多不多。如果从零训练一个ResNet50这个数据量远不足以让底层卷积核学到足够丰富的通用视觉特征。迁移学习几乎是唯一合理的选择。5.1 从零训练还是微调算一笔账从零训练的代价不仅体现在时间和算力上更体现在收敛效果上。ImageNet预训练模型的底层特征边缘、纹理、颜色块组合是来自千万级图片的通用知识这些特征和天气分类所需的基本视觉单元高度重合。微调时只需要将高层特征重新组合形成适应天气语义的决策结构。具体选型上我对比过ResNet50和EfficientNet-B0。ResNet50训练稳定、生态成熟、推理速度快在1080Ti上单卡训练毫无压力EfficientNet-B0理论精度更高但对学习率和正则化参数更敏感调参成本高。最终选用ResNet50但把最后一层全连接替换为6输出的分类头同时将分类头初始学习率设置为其他层的10倍。5.2 超参数配置与训练结果解读训练配置如下优化器AdamW初始学习率1e-3分类头主干部分1e-4批次大小32训练轮数30个epoch学习率调度余弦退火衰减最低降到初始学习率的1%权重衰减1e-4损失函数交叉熵损失类别不平衡不明显时不需要加权训练过程中我记录了每个epoch的训练损失、验证损失和验证准确率。一个值得注意的现象是第3到第5个epoch验证准确率会快速增长到88%左右之后进入缓慢提升期到第18个epoch稳定在93%附近后续几乎不再有波动。如果看到验证损失在后期不再下降甚至反弹就该及时早停不必盲目跑满30个epoch。最终测试集上的分类报告显示晴天、阴天、雪天的F1分数都超过了94%雨天和雾天在91%左右表现最差的是雷暴F1约87%。雷暴的短板在于数据量本身最少且闪电亮斑在缩放到224×224后变得不显著这是特征尺度导致的固有限制目前靠数据规模本身难以完全解决。6. 训练中踩过的坑类别不均衡与样本噪声没有哪一次训练是顺利到底的。这里把我在反复迭代中真正踩过、也真正解决了的问题记录下来。6.1 噪声样本对收敛的影响第一版数据集的清洗不够彻底尤其是雪天和雷暴类混入了一些“夜晚灯光下的雨雪反光”画面。训练出来的模型在验证集上准确率尚可但测试集误判率偏高。把误判样本拉出来逐张看发现好几个晴天图被模型判成雪天。原因很快定位上部分夜间灯光画面在缩略图中呈现出白色点状高光和雪片的视觉特征高度相似。模型学到了“大量离散白色亮点”这个特征而这个特征在夜间城市灯光画面中同样存在。这就是典型的样本噪声引入错误偏置。修复方式不是简单删除而是重新审视“雪天”类别的判定标准明确加入“环境光照充足、积雪覆盖连续区域”这一条件。夜间灯光下的动态雨雪、夜景灯光反光一律排除能明确识别的夜晚画面在雨天、阴天类中也做了逐一排查。6.2 混淆矩阵暴露的真实问题训练中期我对验证集做了一次详细的混淆矩阵分析发现两个顽固的混淆对一是雷暴被误判为阴天二是雨天被误判为雾天。雷暴被误判为阴天根因是雷暴样本中很大一部分画面只有厚重暗云层没有出现闪电亮斑。人眼知道这是雷暴来临前的气象但视觉特征上它和阴天的差异确实有限。这个问题的解决思路是在类别标准上做了细化雷暴类仅保留那些有闪电亮斑、明显强降雨、或云层结构极端低垂压迫感的样本避免把“即将雷暴”的阴天画面硬塞进雷暴类。雨天和雾天的混淆则是物理层面的困难雨滴在静态帧上可能并不清晰而雨天的低能见度和雾天在特定角度下确实视觉相近。我尝试了添加“地面湿润反射”这一人工规则在后期处理时仍保留了一部分边界样本允许模型对这类模糊输入给出51%对49%级别的置信度而不是强行要求每一个测试样本都给出确定答案。对工程落地来说知道“不确定”比知道“错答案”更有价值。7. 评估指标与部署经验不只是个准确率模型训练完成只是第一步真正让它产生价值的是评估和落地部署。这个环节的一些做法和单纯跑模型是有明显区别的。7.1 为什么准确率够用还不够准确率是全局指标但天气分类在落地时通常不是孤立模型而是下游逻辑链中的一环。比如识别到雨天就启动雨刷、识别到雾天就提醒降低车速这意味着不同类别的误判代价完全不同雾天误判为晴天代价远高于晴天误判为阴天。因此评估时我重点看每一类的精确率和召回率而不只盯着总体准确率。精确率低意味着模型频繁把其他天气误判成当前类召回率低则意味着当前类大量被漏检。以雷暴为例模型虽然整体F1只有87%但精确率达到91%说明“报警为雷暴”时绝大多数情况下是真的雷暴这对安全告警场景非常关键。另一个实用指标是置信度校准。部署时如果设定“置信度低于0.7就进入人工确认流程”那么模型的置信度分数必须真实可靠。我测试发现ResNet50的softmax输出存在轻微过自信倾向实际修正方法是在验证集上统计每个置信度区间内的真实准确率然后做一个阈值映射表。这个操作耗时短但直接提升了人机协同场景下的体验。7.2 落地部署时的一个经验模型最终部署时我选择导出为ONNX格式用ONNX Runtime做推理。相比直接用PyTorch推理ONNX导出后推理速度提升约20%并且可以脱离Python环境运行方便嵌入到C边缘设备里。部署时有一个细节输入图片的预处理必须和训练时保持一致。这个要求说起来简单实际调试中很容易翻车。比如调用摄像头帧时图片默认是BGR通道顺序如果不做RGB转换直接送入模型模型对颜色的理解会完全错乱晴天和阴天这类主要靠色温和亮度区分的类别准确率会大幅跳水。我当时在这个问题上排查了小半天最后发现就是一行通道顺序的代码写反了。7.2.1 一个小技巧把预处理封装成独立函数建议把“读取图片、缩放、归一化、通道转换、维度拓展”完整封装成一个独立函数并且用一张已知类别的图片做端到端验证。保证训练脚本和部署脚本调用同一个预处理函数避免两份逻辑不一致。7.2.2 关于后续扩展这套流程跑通之后后续遇到其他细粒度图像分类任务比如路面状态识别、植被类型判断、建筑风格分类基本可以直接复用。数据采集、清洗流程、类别边界定义、迁移学习微调、混淆矩阵分析、模型导出部署这一条流水线是通用的。不同的任务只是在类别判定标准和数据来源上有所调整核心方法论完全一致。我实际做下来最大的体会是9000张图的数据集规模并不大真正决定模型效果的不是GPU型号和数据总量而是数据质量的控制力和对类别语义的深入理解。把这些基础工作做到位一个不到一百行的训练脚本也能训练出可部署的实用模型。本文还有配套的精品资源点击获取