东西湖网站建设公司,四团网站建设,西安seo技术培训班,头条淘宝联盟网站推广怎么做【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A#xff1a;基于计算机视觉的坑洼道路检测和识别 python 代码解析
1 题目
坑洼道路检测和识别是一种计算机视觉任务#xff0c;旨在通过数字图像#xff08;通常是地表坑洼图像#xff09;识别出存在坑洼的道路。这…【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A基于计算机视觉的坑洼道路检测和识别 python 代码解析
1 题目
坑洼道路检测和识别是一种计算机视觉任务旨在通过数字图像通常是地表坑洼图像识别出存在坑洼的道路。这对于地质勘探、航天科学和自然灾害等领域的研究和应用具有重要意义。例如它可以帮助在地球轨道上识别坑洼以及分析和模拟地球表面的形态。
在坑洼道路检测任务中传统的分类算法往往不能取得很好的效果因为坑洼图像的特征往往是非常复杂和多变的。然而近年来深度学习技术的发展为坑洼道路检测提供了新的解决方案。
深度学习具有很强的特征提取和表示能力可以从图像中自动提取出最重要的特征。在坑洼图像分类任务中利用深度学习可以提取到坑洼的轮廓、纹理和形态等特征并将其转换为更容易分类的表示形式。同时还可以通过迁移学习和知识蒸馏等技术进一步提升分类性能。例如一些研究者使用基于深度学习的方法对路图像进行分类将其分为正常、坑洼两类另外一些研究者还使用基于迁移学习的方法从通用的预训练模型中学习坑洼图像的特征并利用这些特征来分类坑洼图像。
本赛题希望通过对已标记的道路图像进行分析、特征提取与建模从而对于一张新的道路图像能够自动识别坑洼状态。具体任务如下 初赛问题 问题1 结合给出的图像文件提取图像特征建立一个识别率高、速度快、分类准确的模型用于识别图像中的道路是正常或者坑洼。 问題2 对问题1中构建的模型进行训练并从不同维度进行模型评估。 问题3 利用已训练的模型识别测试集中的坑洼图像并将识别结果放在“test_result.csv’中。注测试集将在竞赛结束前48小时公布下载链接请及时关注报名网站)
附件说明 附件1data.zip; 训练数据集文件中共包含301张图片。 文件名中包含“normal’字符表示正常道路否则为坑洼道路。 图1正常道路示例 图2坑洼道路示例
附件2test_result.csv 测试结果提交文件文件中表头保持不变数据仅做示例提交的时候删除后重新填写字段描述见下表。 表1test_result表字段说明
字段说明fnames测试图片的文件名label分类标识填写 1 和 01 表示正常道路 0 表示坑洼道路
附件3test_data.zip
测试数据集文件中包含几千张图片具体数量以公布的数据为准。
测试数据集在竞赛结束前48小时公布下载链接请及时关注报名网站。
2 思路分析
首先训练集只有301张图片说明这个一个小样本问题。按照以下流程去建立baseline之后再在每个部分逐步优化。
1数据预处理
对图像进行尺寸调整由于深度学习模型对输入图像尺寸要求较为严格可以使用图像处理算法如OpenCV库中的resize函数将图像统一缩放到固定的尺寸。以下例子统一大小 为224*224。数据增强可以使用图像增强算法如OpenCV库中的平移、旋转、翻转等函数对图像进行增强以扩充样本数量和增加数据多样性。
2特征提取
基于传统计算机视觉算法的特征提取可以使用传统的图像特征提取算法如SIFT、HOG、LBP等来提取图像的局部或全局特征用于训练深度学习模型。基于深度学习模型的特征提取可以使用预训练的卷积神经网络如VGG、ResNet、Inception等提取图像的高层特征将这些特征作为输入用于训练深度学习模型。以下是VGG提取特征为例见3.3部分。
3可视化分析数据集
使用图像处理算法如OpenCV库中的imshow函数显示图像可以随机选择一些正常道路和坑洼道路的样本图像并使用图像处理算法将它们可视化显示出来以了解数据集的特点和难点。绘制直方图、散点图等统计图表可以通过统计学手段如绘制正常道路和坑洼道路图像像素的直方图、颜色特征的散点图等来观察数据集的分布情况判断图像特征是否有区分度。
4建立深度学习模型
baseline使用卷积神经网络如VGG、ResNet、Inception等、自编码器、循环神经网络等并根据数据集的特点进行微调或迁移学习。其他前沿的图像分类技术包括 迁移学习将在大规模数据集上训练好的模型如ImageNet迁移到小样本问题上通过微调或特征提取来解决分类问题。数据增强使用图像增强算法如旋转、平移、翻转、裁剪等对样本进行扩充增加样本数量和多样性。生成对抗网络GAN通过合成样本数据来增加样本数量用GAN生成器生成逼真的样本来扩充数据。元学习Meta Learning学习如何从有限样本中较快地学习和泛化通过学习到的先验知识来优化样本的利用效率。半监督学习利用少量的有标签样本和大量的无标签样本进行训练提升分类准确率。主动学习Active Learning利用主动选择和标注关键样本以降低标注成本并提高模型性能。小样本学习方法针对小样本问题提出专门的算法和方法如Few-shot Learning、One-shot Learning、Zero-shot Learning等。增量学习Incremental Learning逐步学习和增量更新模型以适应新样本的引入和旧样本的遗忘。模型压缩和量化通过模型剪枝、量化和蒸馏等技术减少模型参数和计算量使其适应小样本问题。集成学习将多个分类器的结果进行结合提高分类准确率和鲁棒性如bagging、boosting等。
5模型评估和优化
采用交叉验证方法对模型进行评估可以使用k折交叉验证等方法对模型进行评估得到准确率、召回率等指标从而判断模型的性能。对模型进行调参和优化可以尝试不同的损失函数、优化器、学习率等超参数以及增加数据集规模、减少模型复杂度等方式来优化深度学习模型。
3 python代码实现
3.1 数据预处理
import os
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Convolution2D, MaxPooling2D, ZeroPadding2D
from tensorflow.keras import optimizers
from tensorflow.keras import applications
from tensorflow.keras.models import Model
from IPython.display import Image
from tensorflow.keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import os
from sklearn.model_selection import train_test_split
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import pandas as pd
from PIL import Image
import os
# 将图片统一像素格式并分别存储到文件夹中# 创建文件夹
processed_normal_dir data/processed_normal
processed_wavy_dir data/processed_wavy
os.makedirs(processed_normal_dir, exist_okTrue)
os.makedirs(processed_wavy_dir, exist_okTrue)# 处理图像
data_dir data
for filename in os.listdir(data_dir):img_path os.path.join(data_dir, filename)img Image.open(img_path)# 对图像进行缩放img img.resize((224, 224))# 决定图像应该存储在哪个文件夹中if normal in filename:save_dir processed_normal_direlse:save_dir processed_wavy_dir# 保存图像save_path os.path.join(save_dir, filename)img.save(save_path)
2数据加载
总共301张图片选择30张图片作为测试集1张图片单独拿出来测试否则不好整数划分。
img_width, img_height 224, 224
num_classes 2
batch_size 10datagen ImageDataGenerator(rescale1./255)X []
y []
normal_dir data/processed_normal
wavy_dir data/processed_wavyfor img_name in os.listdir(normal_dir):img_path os.path.join(normal_dir, img_name)X.append(img_path)y.append(0)
for img_name in os.listdir(wavy_dir):img_path os.path.join(wavy_dir, img_name)X.append(img_path)y.append(1)X_train, X_val, y_train, y_val train_test_split(X, y, test_size0.1, random_state42)
train_df pd.DataFrame(data{filename: X_train, class: y_train})
val_df pd.DataFrame(data{filename: X_val, class: y_val})train_generator datagen.flow_from_dataframe(...略validation_generator datagen.flow_from_dataframe(...略Found 270 validated image filenames belonging to 2 classes. Found 30 validated image filenames belonging to 2 classes. 3.2 卷积模型训练
1定义卷积网络
model Sequential()
model.add(Convolution2D(32, (3, 3), input_shape(img_width, img_height,3)))
model.add(Activation(relu))
model.add(MaxPooling2D(pool_size(2, 2)))model.add(Convolution2D(32, (3, 3)))
model.add(Activation(relu))
model.add(MaxPooling2D(pool_size(2, 2)))model.add(Convolution2D(64, (3, 3)))
model.add(Activation(relu))
model.add(MaxPooling2D(pool_size(2, 2)))model.add(Flatten())
model.add(Dense(64))
model.add(Activation(relu))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation(sigmoid))model.compile(lossbinary_crossentropy,optimizerrmsprop,metrics[accuracy])2模型训练
epochs 20
train_samples 270
validation_samples 30
batch_size 10
model.fit_generator(train_generator,steps_per_epochtrain_samples // batch_size,epochsepochs,validation_datavalidation_generator,validation_stepsvalidation_samples// batch_size,)model.save_weights(models/basic_cnn_20_epochs.h5)
model.load_weights(models_trained/basic_cnn_30_epochs.h5)3模型验证
# 将多余出来的一张图片拿出来预测
img load_img(data/normal1.jpg)
x img_to_array(img)
prediction model.predict(x.reshape((1,img_width, img_height,3)),batch_size10, verbose0)
print(prediction)0 model.evaluate_generator(validation_generator, validation_samples)[0.7280968427658081, 0.8999999761581421] 3.3 数据增强训练
1数据增强
通过对训练集应用随机变换用新的未见过的图像人为地增强了的数据集。减少过拟合并为我们的网络提供更好的泛化能力。
train_datagen_augmented ImageDataGenerator(rescale1./255, # normalize pixel values to [0,1]shear_range0.2, # randomly applies shearing transformationzoom_range0.2, # randomly applies shearing transformationhorizontal_flipTrue) # randomly flip the imagestrain_generator_augmented train_datagen_augmented.flow_from_dataframe(...略
2模型训练
model.fit_generator(train_generator_augmented,steps_per_epochtrain_samples // batch_size,epochsepochs,validation_datavalidation_generator,validation_stepsvalidation_samples // batch_size,)3模型评估
model.save_weights(models/augmented_20_epochs.h5)
#model.load_weights(models_trained/augmented_30_epochs.h5)model.evaluate_generator(validation_generator, validation_samples)[0.2453145980834961, 0.8666666746139526] 3.4 预训练模型
通过使用通用的、预训练的图像分类器可以在性能和效率方面超越以前的模型。这个例子使用了VGG16一个在ImageNet数据集上训练的模型该数据集包含了被分类为1000个类别的数百万张图像。
1加载VGG模型的权重
model_vgg train_generator_bottleneck datagen.flow_from_dataframe(dataframetrain_df,directoryNone,x_colfilename,y_colclass,target_size(img_width, img_height),batch_sizebatch_size,class_modebinary)validation_generator_bottleneck datagen.flow_from_dataframe(dataframeval_df,directoryNone,x_colfilename,y_colclass,target_size(img_width, img_height),batch_sizebatch_size,class_modebinary)2用模型提取特征
bottleneck_features_train model_vgg.predict_generator(train_generator_bottleneck, train_samples // batch_size)
np.save(open(models/bottleneck_features_train.npy, wb), bottleneck_features_train)bottleneck_features_validation model_vgg.predict_generator(validation_generator_bottleneck, validation_samples // batch_size)
np.save(open(models/bottleneck_features_validation.npy, wb), bottleneck_features_validation)3读取预处理的数据
train_data np.load(open(models/bottleneck_features_train.npy, rb))
train_labels np.array([0] * (train_samples // 2) [1] * (train_samples // 2))validation_data np.load(open(models/bottleneck_features_validation.npy, rb))
validation_labels np.array([0] * (validation_samples // 2) [1] * (validation_samples // 2))4全连接网络模型训练
model_top Sequential()
model_top.add(Flatten(input_shapetrain_data.shape[1:]))
model_top.add(Dense(256, activationrelu))
model_top.add(Dropout(0.5))
model_top.add(Dense(1, activationsigmoid))model_top.compile(optimizerrmsprop, lossbinary_crossentropy, metrics[accuracy])model_top.fit(train_data, train_labels,epochsepochs, batch_sizebatch_size,validation_data(validation_data, validation_labels))model_top.save_weights(models/bottleneck_20_epochs.h5)5模型评估
model_top.evaluate(validation_data, validation_labels)[2.3494818210601807, 0.4333333373069763] 3.5 微调预训练模型
在卷积模型之上建立一个分类器模型。为了进行微调从一个经过充分训练的分类器开始。将使用早期模型中的权重。然后把这个模型加到卷积基上
weights_path weight/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5
model_vgg applications.VGG16(include_topFalse, weightsweights_path, input_shape(224, 224, 3))top_model Sequential()
top_model.add(Flatten(input_shapemodel_vgg.output_shape[1:]))
top_model.add(Dense(256, activationrelu))
top_model.add(Dropout(0.5))
top_model.add(Dense(1, activationsigmoid))top_model.load_weights(models/bottleneck_20_epochs.h5)#model_vgg.add(top_model)
model Model(inputs model_vgg.input, outputs top_model(model_vgg.output))
# 微调只需要训练几层。这一行将设置前25层(直到conv块)为不可训练的。for layer in model_vgg.layers[:15]:layer.trainable Falsemodel.compile(lossbinary_crossentropy,optimizeroptimizers.SGD(lr1e-4, momentum0.9),metrics[accuracy])数据增强
# 数据增强
train_datagen ImageDataGenerator(rescale1./255,shear_range0.2,zoom_range0.2,horizontal_flipTrue)test_datagen ImageDataGenerator(rescale1./255)train_generator datagen.flow_from_dataframe(...略validation_generator datagen.flow_from_dataframe(...略模型微调
# 微调模型
model.fit_generator(train_generator,steps_per_epochtrain_samples // batch_size,epochsepochs,validation_datavalidation_generator,validation_stepsvalidation_samples // batch_size)model.save_weights(models/finetuning_20epochs_vgg.h5)
model.load_weights(models/finetuning_20epochs_vgg.h5)模型评估
model.evaluate_generator(validation_generator, validation_samples)[nan, 0.8666666746139526] 最后这种方式模型不收敛说明这个网络设置过程中存在不合理的地方比如冻结参数的层数使用的网络模型是否需要数据增强等因素都会影响。提供这种方式有待同学们去改进。
4 下载完整程序
以上代码是不完整的需要完整的请下载后源文件 包括训练好的模型和权重文件