简介这是一份面向计算机相关专业学生与项目实战学习者的道路坑洼检测课程设计资源基于计算机视觉技术实现核心价值在于提供AlexNet、LeNet-5及LeNet-5 2.0三种算法模型的对比实验方案适合正在做毕设、课设或期末大作业的同学直接参考与二次开发。压缩包共14个文件包含11个Python源码文件、2个h5模型权重文件以及1份README说明文档整体约10.49MB源码覆盖模型定义、训练、预测与测试等完整流程h5文件为已训练好的模型可直接加载验证。该资源经导师指导并通过评审答辩平均分达96.5分代码均测试运行成功后才上传已有155人学习下载。读者可从中获得多模型对比的完整实现思路、可复用的训练与推理脚本以及清晰的工程目录结构便于快速理解道路坑洼检测的算法流程并在此基础上修改扩展功能。1. 道路坑洼检测这套 Python 源码为什么值得先跑通再谈改进路面巡检这件事真正做过的人都知道痛点不在“拍不到”而在“拍回来一堆图没人看得完”。一段两公里的城市支路行车记录仪随手就是几千帧人工逐帧找坑洼眼睛先报废。这套基于计算机视觉的道路坑洼检测 Python 源码解决的就是把这件事从人工筛图变成模型推理——输入路面图像输出是否坑洼的分类结果。资源里打包了 AlexNet、LeNet-5、LeNet-5 2.0 三种网络实现外加训练、预测、测试、Excel 导出等脚本是一份结构完整、能直接跑起来的课程设计级项目。它适合正在做计算机视觉大作业、毕设或课程设计的学生也适合想拿一个真实小数据集练手模型对比的入门者。下面我按“先跑通、再拆结构、最后调参”的顺序把这份源码拆开讲。2. 先看清目录结构每个 .py 文件到底管什么拿到一个压缩包最忌讳的就是双击 main.py 直接跑。这份资源的文件命名有点随意main.py和mainz.py、Predictor.py和Predictorz.py成对出现不先理清关系很容易改错文件。我一般会先把所有脚本按职责分成四类数据与训练、模型定义、推理预测、结果导出。分完类再动手能省掉大量“改了没反应”的时间。2.1 按职责给脚本分类从文件名和常见课程设计结构推断这套代码大致是这样分工的文件职责说明AlexNet.py模型定义AlexNet 网络结构实现LeNet-5.py/LeNet-5 2.0.py模型定义两个版本的 LeNet-52.0 通常是改进版main.py/mainz.py训练入口加载数据、编译模型、保存权重Predictor.py/Predictorz.py推理封装加载模型对单张或批量图片预测pre.py预处理图像读取、缩放、归一化test.py/testmodel.py测试评估在测试集上算准确率、混淆矩阵excel.py结果导出把预测结果写进 ExcelsampleLenet.h5/sampleLeNet-5.h5已训练权重直接可用的模型文件这里要注意.h5是 Keras/TensorFlow 的权重格式说明整套代码跑在 TensorFlow Keras 上不是 PyTorch。这一点决定了你的环境怎么配后面会细说。main.py和mainz.py大概率是同一份训练逻辑的两个版本可能一个是原始版、一个是调参版跑之前先 diff 一下别两个都跑浪费时间。2.2 环境依赖与版本选择既然是 Keras 的.h5权重环境就得围绕 TensorFlow 来配。我一般会单独建一个虚拟环境避免和系统里的其他包打架# 建虚拟环境Python 版本建议 3.8~3.10太新反而容易踩 TF 的坑 python -m venv pothole_env # Windows 激活 pothole_env\Scripts\activate # Linux / macOS 激活 source pothole_env/bin/activate # 装核心依赖TF 2.x 自带 Keras pip install tensorflow2.10.0 pip install numpy pandas openpyxl matplotlib pillow opencv-python参数说明tensorflow2.10.0是我在 Windows 上跑.h5权重比较稳的一个版本2.10 之后 Keras 独立成包老代码里from keras.models import load_model的写法可能报错。openpyxl是excel.py导出 xlsx 必需的缺了会直接抛ModuleNotFoundError。opencv-python对应热词里常搜的python下载cv2pre.py里大概率用到了cv2.imread和cv2.resize。提示如果你机器上已经装了 TF 2.15 以上先别急着降级可以先跑一次test.py看报错是不是keras导入问题。是的话再决定降版本还是改导入语句别一上来就重装环境。2.3 先跑推理再碰训练新手最容易犯的错是先跑main.py训练。训练要数据、要时间、要显存一旦数据路径不对报错信息还特别长。正确顺序是先跑推理用现成的.h5权重验证环境通不通# 推理验证的最小脚本确认环境和权重都能用 import numpy as np from tensorflow.keras.models import load_model from tensorflow.keras.preprocessing import image # 加载已训练权重compileFalse 避免自定义层报错 model load_model(sampleLenet.h5, compileFalse) print(模型输入尺寸:, model.input_shape) # 读一张测试图尺寸按模型输入调整 img image.load_img(test.jpg, target_size(32, 32)) x image.img_to_array(img) / 255.0 # 归一化到 0~1 x np.expand_dims(x, axis0) # 加 batch 维度 pred model.predict(x) print(预测概率:, pred, 类别:, np.argmax(pred))逻辑说明compileFalse是关键很多课程设计代码在保存模型时带了自定义损失函数直接load_model会报Unknown loss function加上这个参数只加载结构不加载编译配置推理够用。target_size必须和训练时一致LeNet-5 经典输入是 32×32AlexNet 是 224×224用错尺寸模型不会报错但结果全是乱的。归一化除以 255 是这套代码里pre.py最可能的做法如果你发现预测结果始终偏向某一类先检查这里是不是漏了。3. 三种模型怎么选AlexNet 与 LeNet-5 的取舍逻辑这份资源最大的价值不是“能跑”而是给了三个模型做对比。很多人拿到手只跑一个就交差其实模型对比才是课程设计拿高分的关键。理解 AlexNet 和 LeNet-5 的差异你才知道什么场景该用哪个答辩时也讲得出所以然。3.1 网络深度与参数量差异LeNet-5 是 1998 年的老结构两个卷积层加三个全连接层参数量大约 6 万输入 32×32。它的优势是轻CPU 上都能秒级推理适合小数据集和快速验证。AlexNet 是 2012 年的结构五个卷积层加三个全连接层参数量约 6000 万输入 224×224特征提取能力强得多但训练慢、吃显存。放到道路坑洼检测这个任务上坑洼的视觉特征其实不算复杂——无非是路面上的暗色不规则区域、边缘纹理突变。如果数据集只有几百到几千张LeNet-5 往往就够用甚至因为参数少反而不容易过拟合。AlexNet 更适合数据量上千、且坑洼形态差异大的场景。LeNet-5 2.0.py这个命名我推测是在原始 LeNet-5 上加了 BN 层或 Dropout用来缓解过拟合这也是课程设计里常见的改进点。3.2 用 test.py 做横向对比要真正比出差异得让三个模型在同一测试集上跑一遍。test.py和testmodel.py应该就是干这个的但如果你发现它们只测了一个模型可以自己写个循环import numpy as np from tensorflow.keras.models import load_model from tensorflow.keras.preprocessing.image import ImageDataGenerator # 测试集目录按类别分子文件夹 test_dir dataset/test datagen ImageDataGenerator(rescale1./255) # 三个模型分别评估注意输入尺寸不同 configs [ (sampleLenet.h5, (32, 32)), (sampleLeNet-5.h5, (32, 32)), # AlexNet 权重若存在输入改 224 ] for weight, size in configs: model load_model(weight, compileFalse) gen datagen.flow_from_directory( test_dir, target_sizesize, batch_size16, class_modecategorical, shuffleFalse) loss, acc model.evaluate(gen) print(f{weight} 输入{size} 准确率: {acc:.4f})逻辑说明flow_from_directory要求测试集按类别分文件夹比如test/坑洼/和test/正常/这是 Keras 的标准约定pre.py里大概率也是这么组织的。shuffleFalse很重要评估时打乱顺序会导致后面导出 Excel 时图片名和预测结果对不上。class_modecategorical对应多分类的 one-hot 标签如果只有两类也可以用binary但要同步改模型最后一层的激活函数。参数怎么调batch_size在评估时不影响准确率只影响速度和显存16 或 32 都行。真正影响结果的是target_size必须和训练时严格一致。我见过有人 LeNet 用 32、AlexNet 也偷懒用 32结果 AlexNet 准确率反而低就是因为输入尺寸不匹配导致特征提取失效。3.3 结果导出与对比表excel.py的存在说明这套代码支持把预测结果落成表格这在课程设计里是加分项。你可以把三个模型的准确率、精确率、召回率整理成一张对比表放进报告模型输入尺寸参数量级训练速度适用场景LeNet-532×32约 6 万快小数据集、快速验证LeNet-5 2.032×32略高较快加了正则化抗过拟合AlexNet224×224约 6000 万慢大数据集、复杂特征这张表比单纯写“我用了三种模型”有说服力得多。答辩时老师问“为什么选 LeNet-5”你能答出参数量和数据集规模的匹配关系分数自然就上去了。4. 训练与预测的避坑排查那些报错背后的真实原因这套代码能跑通但“能跑通”和“跑出好结果”是两回事。我在拆这类课程设计代码时踩过的坑基本集中在路径、尺寸、编码和权重加载四类。下面按“现象 → 原因 → 解决”列出来你对照着排查能省不少时间。4.1 路径与中文目录导致的读取失败现象cv2.imread返回 None或者flow_from_directory报Found 0 images。原因Windows 下路径含中文或空格OpenCV 对非 ASCII 路径支持不好或者数据集目录层级不对Keras 要求每个类别一个子文件夹。解决把数据集放到纯英文路径下比如D:/pothole/dataset/用os.path.join拼路径而不是手写反斜杠确认目录结构是dataset/train/坑洼/这种两级结构。4.2 输入尺寸不匹配的静默错误现象模型能跑不报错但预测结果全是同一类准确率约等于瞎猜。原因推理时的target_size和训练时不一致或者归一化方式不同训练除了 255推理没除。解决打开pre.py看训练时的预处理流程把推理脚本的尺寸和归一化对齐在load_model后打印model.input_shape确认期望尺寸。4.3 .h5 权重加载报 Unknown layer现象load_model(sampleLenet.h5)抛Unknown layer: xxx或Unknown loss function。原因保存模型时用了自定义层或自定义损失加载环境里没有对应定义。解决加compileFalse只加载结构如果还报错找到定义自定义层的脚本在加载前 import 进来实在不行就用model.load_weights只加载权重结构自己重建。4.4 Excel 导出乱码或覆盖现象excel.py跑完xlsx 打开是乱码或者每次运行都覆盖上一次结果。原因to_excel默认编码和 Excel 打开方式不匹配输出文件名写死了。解决用df.to_excel(result.xlsx, indexFalse, engineopenpyxl)指定引擎输出文件名带上时间戳比如result_20250101.xlsx避免覆盖。4.5 显存不足与 batch_size 的取舍现象训练 AlexNet 时CUDA out of memory或者程序直接卡死。原因AlexNet 参数量大batch_size设太大显存扛不住。解决把batch_size从 32 降到 8 或 4如果还是不够用 CPU 训练小批量先验证流程或者冻结 AlexNet 的卷积层只训练全连接层减少显存占用。注意这五条里路径和尺寸问题占了八成。遇到报错先别怀疑模型先检查数据和路径这是血泪经验。5. 从跑通到改出花模型替换与数据增强的进阶玩法跑通只是起点。这份代码真正的价值在于它是个可改的骨架你可以在上面做模型替换、数据增强、甚至换成目标检测。下面说两个我常用的进阶方向都是在这套结构上能直接落地的。5.1 把 LeNet-5 换成更现代的小网络LeNet-5 太老答辩时容易被问“为什么不用 ResNet”。但直接上 ResNet-50 又太重小数据集上反而过拟合。我的做法是换成 MobileNetV2 或一个精简版 CNN参数量介于两者之间from tensorflow.keras import layers, models # 精简 CNN输入 64x64适合中等规模数据集 def build_small_cnn(input_shape(64, 64, 3), num_classes2): model models.Sequential([ layers.Conv2D(32, 3, activationrelu, input_shapeinput_shape), layers.BatchNormalization(), layers.MaxPooling2D(), layers.Conv2D(64, 3, activationrelu), layers.BatchNormalization(), layers.MaxPooling2D(), layers.Conv2D(128, 3, activationrelu), layers.GlobalAveragePooling2D(), # 替代 Flatten减少参数 layers.Dropout(0.5), layers.Dense(num_classes, activationsoftmax) ]) return model model build_small_cnn() model.summary() # 看参数量控制在百万级以内逻辑说明GlobalAveragePooling2D替代Flatten能大幅减少全连接层参数是小数据集上防过拟合的常用手段。BatchNormalization加速收敛Dropout(0.5)进一步抑制过拟合。这套结构参数量大概几十万比 LeNet-5 强、比 AlexNet 轻很适合作为课程设计的“改进模型”写进报告。5.2 数据增强补足样本不足道路坑洼数据集通常不大增强是性价比最高的提升手段。在main.py的ImageDataGenerator里加几个参数就行from tensorflow.keras.preprocessing.image import ImageDataGenerator train_datagen ImageDataGenerator( rescale1./255, rotation_range20, # 随机旋转 ±20 度 width_shift_range0.1, # 水平平移 10% height_shift_range0.1, # 垂直平移 10% horizontal_flipTrue, # 水平翻转 zoom_range0.1, # 随机缩放 fill_modenearest # 填充方式 )参数说明rotation_range对坑洼检测有用因为拍摄角度不固定horizontal_flip要谨慎如果坑洼有方向性比如长条形翻转可能引入不合理样本fill_modenearest是旋转后边缘填充的默认做法比补零更自然。增强只加在训练集上验证集和测试集保持原样否则评估结果不可信。5.3 验证改进是否真的有效改完模型别急着高兴得用同一测试集对比。我一般会固定随机种子跑三次取平均避免单次波动误导判断import tensorflow as tf import numpy as np # 固定种子保证可复现 tf.random.set_seed(42) np.random.seed(42) # 训练后在同一测试集评估记录准确率 # 对比原始 LeNet-5 和改进模型的 acc提升超过 2% 才算有效从那以后我每次改模型都强制走一遍“固定种子 → 同测试集 → 跑三次取平均”的流程不然很容易被一次偶然的高分骗过去。这套源码的骨架够清晰改起来不费劲关键是别跳过验证这一步。希望这份拆解能帮你把课程设计跑通、改好、讲明白。本文还有配套的精品资源点击获取
