當(dāng)大家面臨著復(fù)雜的數(shù)學(xué)建模問(wèn)題時(shí),你是否曾經(jīng)感到茫然無(wú)措?作為2021年美國(guó)大學(xué)生數(shù)學(xué)建模比賽的O獎(jiǎng)得主,我為大家提供了一套優(yōu)秀的解題思路,讓你輕松應(yīng)對(duì)各種難題。
希望這些想法對(duì)大家的做題有一定的啟發(fā)和借鑒意義。
讓我們來(lái)看看MathorCup的A題!
問(wèn)題重述:
問(wèn)題1:圖像特征提取和模型建立
題目要求建立一個(gè)高識(shí)別準(zhǔn)確度、快速的模型,能夠識(shí)別道路圖像是正常的還是坑洼的。具體步驟包括:
- 解壓
data.zip
,準(zhǔn)備訓(xùn)練數(shù)據(jù)。 - 對(duì)圖像進(jìn)行預(yù)處理,如調(diào)整尺寸和數(shù)據(jù)增強(qiáng)。
- 使用深度學(xué)習(xí)模型提取圖像特征。
- 構(gòu)建一個(gè)分類模型,將特征轉(zhuǎn)化為更容易分類的表示形式。
- 使用訓(xùn)練數(shù)據(jù)訓(xùn)練模型。
問(wèn)題2:模型評(píng)估
題目要求對(duì)模型進(jìn)行評(píng)估,從不同維度考察其性能。評(píng)估指標(biāo)可能包括準(zhǔn)確率、召回率、精確度、F1分?jǐn)?shù)等,以及繪制ROC曲線和AUC。
問(wèn)題3:測(cè)試集識(shí)別
題目求使用已經(jīng)訓(xùn)練好的模型對(duì)未標(biāo)記的測(cè)試數(shù)據(jù)集(在競(jìng)賽結(jié)束前48小時(shí)公布下載鏈接)中的圖像進(jìn)行坑洼識(shí)別。將識(shí)別結(jié)果以特定格式填寫(xiě)到test result.csv
中,并將該文件提交以供評(píng)估。
問(wèn)題一
問(wèn)題一的具體建模思路通?;谏疃葘W(xué)習(xí)方法,在這里我們使用卷積神經(jīng)網(wǎng)絡(luò)(CNN)。
-
數(shù)據(jù)準(zhǔn)備:
- 將數(shù)據(jù)集劃分為訓(xùn)練集和驗(yàn)證集,以用于模型訓(xùn)練和評(píng)估。
-
圖像預(yù)處理:
- 調(diào)整圖像大小為固定尺寸,如 224 × 224 224\times224 224×224。
- 數(shù)據(jù)增強(qiáng):對(duì)訓(xùn)練圖像進(jìn)行數(shù)據(jù)增強(qiáng),包括旋轉(zhuǎn)、翻轉(zhuǎn)、縮放和亮度調(diào)整等。
-
特征提取:
- 使用一個(gè)預(yù)訓(xùn)練的卷積神經(jīng)網(wǎng)絡(luò)(如ResNet、VGG、或MobileNet)來(lái)提取圖像特征。這些模型通常包含卷積層,用于捕獲圖像的特征。
- 在模型的前幾層,特征圖會(huì)被提取出來(lái)。
-
模型構(gòu)建:
- 添加一個(gè)或多個(gè)全連接層,用于將提取的特征轉(zhuǎn)換為最終的分類輸出。
- 使用sigmoid激活函數(shù)來(lái)輸出一個(gè)0到1的值,表示道路是否坑洼。
模型的建立可以表示為以下公式:
給定一個(gè)輸入圖像 x x x,表示為一個(gè) W × H × C W\times H\times C W×H×C的三維張量,其中 W W W和 H H H是圖像的寬度和高度, C C C是通道數(shù)。卷積神經(jīng)網(wǎng)絡(luò)(CNN)將圖像 x x x映射到一個(gè)輸出標(biāo)量 y y y,表示道路是否坑洼的概率。這個(gè)映射可以表示為:
y = σ ( f ( x ) ) y = \sigma(f(x)) y=σ(f(x))
其中:
- f ( x ) f(x) f(x)表示卷積神經(jīng)網(wǎng)絡(luò)的前向傳播過(guò)程,包括卷積、池化和全連接等層的組合,用于提取圖像特征。
- σ ( z ) = 1 1 + e ? z \sigma(z) = \frac{1}{1 + e^{-z}} σ(z)=1+e?z1? 是sigmoid激活函數(shù),將 z z z映射到0到1的范圍內(nèi),表示概率。
模型的訓(xùn)練可以使用二元交叉熵(binary cross-entropy)損失函數(shù)來(lái)度量預(yù)測(cè)概率與實(shí)際標(biāo)簽之間的差異:
L ( y , y ^ ) = ? ( y log ? ( y ^ ) + ( 1 ? y ) log ? ( 1 ? y ^ ) ) \mathcal{L}(y, \hat{y}) = -\left(y\log(\hat{y}) + (1 - y)\log(1 - \hat{y})\right) L(y,y^?)=?(ylog(y^?)+(1?y)log(1?y^?))
其中:
- y y y 是實(shí)際標(biāo)簽(0表示坑洼,1表示正常道路)。
- y ^ \hat{y} y^? 是模型的預(yù)測(cè)概率。
訓(xùn)練模型的目標(biāo)是最小化損失函數(shù) L \mathcal{L} L,以使預(yù)測(cè)盡可能接近實(shí)際標(biāo)簽。
二元交叉熵(Binary Cross-Entropy)是一種用于衡量二分類問(wèn)題中模型預(yù)測(cè)與實(shí)際標(biāo)簽之間的差異的損失函數(shù)。它通常用于訓(xùn)練和評(píng)估二分類模型,例如判斷一個(gè)樣本屬于兩個(gè)類別中的哪一個(gè)。
這個(gè)損失函數(shù)的度量原理基于信息論的概念,特別是信息熵。以下是它的度量原理:
假設(shè)我們有一個(gè)二分類問(wèn)題,其中樣本的實(shí)際標(biāo)簽為 y y y,可以取0或1,而模型的預(yù)測(cè)概率為 y ^ \hat{y} y^?,表示樣本屬于類別1的概率。
交叉熵?fù)p失的度量原理基于以下兩種情況:
-
當(dāng)實(shí)際標(biāo)簽 y = 1 y=1 y=1時(shí),交叉熵?fù)p失為:
? log ? ( y ^ ) -\log(\hat{y}) ?log(y^?)
這表示模型預(yù)測(cè)樣本屬于類別1的概率越高,損失越小,反之則損失越大。這是因?yàn)閷?shí)際標(biāo)簽為1時(shí),我們希望模型的預(yù)測(cè)也接近1。
-
當(dāng)實(shí)際標(biāo)簽 y = 0 y=0 y=0時(shí),交叉熵?fù)p失為:
? log ? ( 1 ? y ^ ) -\log(1 - \hat{y}) ?log(1?y^?)
這表示模型預(yù)測(cè)樣本屬于類別0的概率越高,損失越小,反之則損失越大。這是因?yàn)閷?shí)際標(biāo)簽為0時(shí),我們希望模型的預(yù)測(cè)也接近0。
在訓(xùn)練過(guò)程中,我們會(huì)將所有樣本的交叉熵?fù)p失加權(quán)求和,然后嘗試最小化這個(gè)總損失。這意味著模型的目標(biāo)是使其對(duì)于所有樣本的預(yù)測(cè)與實(shí)際標(biāo)簽更加一致,以最小化總的交叉熵?fù)p失。
總的二元交叉熵?fù)p失可以表示為:
L ( y ^ , y ) = ? ( y log ? ( y ^ ) + ( 1 ? y ) log ? ( 1 ? y ^ ) ) \mathcal{L}(\hat{y}, y) = -\left(y\log(\hat{y}) + (1 - y)\log(1 - \hat{y})\right) L(y^?,y)=?(ylog(y^?)+(1?y)log(1?y^?))
其中, L ( y ^ , y ) \mathcal{L}(\hat{y}, y) L(y^?,y)表示損失, y ^ \hat{y} y^?表示模型的預(yù)測(cè)概率, y y y表示實(shí)際標(biāo)簽。最小化這個(gè)損失將使模型盡量接近實(shí)際標(biāo)簽的分布,以更好地進(jìn)行二分類任務(wù)。
代碼:
import tensorflow as tf
from tensorflow import keras
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
# 加載和預(yù)處理數(shù)據(jù)
def load_and_preprocess_data():
# 你需要編寫(xiě)加載和預(yù)處理數(shù)據(jù)的代碼,返回X和y
# X是圖像數(shù)據(jù),y是標(biāo)簽(0表示坑洼,1表示正常道路)
# 這里使用一個(gè)假設(shè)的示例,你需要根據(jù)實(shí)際數(shù)據(jù)進(jìn)行適配
X = np.random.rand(301, 224, 224, 3) # 示例隨機(jī)生成圖像數(shù)據(jù)
y = np.random.randint(2, size=301) # 示例隨機(jī)生成標(biāo)簽
return {'images': X, 'labels': y}
# 構(gòu)建深度學(xué)習(xí)模型
def build_model():
model = keras.Sequential([
keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Conv2D(64, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Flatten(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam',
loss='binary_crossentropy', # 二元交叉熵?fù)p失
metrics=['accuracy'])
return model
# 模型訓(xùn)練
def train_model(X_train, y_train, X_val, y_val):
model = build_model()
#見(jiàn)完整版代碼
題目二
問(wèn)題二的建模思路需要分為兩個(gè)主要部分:模型訓(xùn)練和模型評(píng)估。
模型訓(xùn)練:
-
數(shù)據(jù)加載與劃分:首先,加載問(wèn)題一中準(zhǔn)備好的訓(xùn)練數(shù)據(jù)。將數(shù)據(jù)集劃分為訓(xùn)練集( X train X_{\text{train}} Xtrain?, y train y_{\text{train}} ytrain?)和驗(yàn)證集( X val X_{\text{val}} Xval?, y val y_{\text{val}} yval?),通常采用交叉驗(yàn)證方法,以確保模型在不同數(shù)據(jù)子集上進(jìn)行訓(xùn)練和評(píng)估。
-
模型選擇:選擇問(wèn)題一中構(gòu)建的深度學(xué)習(xí)模型,該模型已包含合適的網(wǎng)絡(luò)結(jié)構(gòu)和損失函數(shù)(二元交叉熵),用于道路坑洼的分類任務(wù)。
-
模型訓(xùn)練:使用訓(xùn)練集進(jìn)行模型訓(xùn)練。迭代多個(gè)周期(epochs),使模型能夠適應(yīng)數(shù)據(jù)。訓(xùn)練過(guò)程中,模型會(huì)自動(dòng)調(diào)整權(quán)重,以最小化損失函數(shù)。
-
超參數(shù)調(diào)優(yōu):根據(jù)需要,進(jìn)行超參數(shù)調(diào)優(yōu),包括學(xué)習(xí)率、批處理大小等。這可以通過(guò)驗(yàn)證集上的性能來(lái)指導(dǎo)。你可以使用交叉驗(yàn)證技術(shù)來(lái)嘗試不同的超參數(shù)組合。
- 數(shù)據(jù)加載與劃分:
X train , y train , X val , y val = train_test_split ( X , y , test_size = 0.2 , random_state = 42 ) X_{\text{train}}, y_{\text{train}}, X_{\text{val}}, y_{\text{val}}=\text{train\_test\_split}(X, y, \text{test\_size}=0.2,\text{random\_state}=42) Xtrain?,ytrain?,Xval?,yval?=train_test_split(X,y,test_size=0.2,random_state=42)
-
模型選擇:
model = build_model ( ) \text{model} = \text{build\_model}() model=build_model() -
模型訓(xùn)練:
model.fit ( X train , y train , epochs = 10 , validation_data = ( X val , y val ) \text{model.fit}(X_{\text{train}}, y_{\text{train}}, \text{epochs}=10, \text{validation\_data}=(X_{\text{val}}, y_{\text{val}}) model.fit(Xtrain?,ytrain?,epochs=10,validation_data=(Xval?,yval?)
模型評(píng)估:
使用ROC曲線和AUC(Area Under the Curve)來(lái)評(píng)估模型的性能是一種常見(jiàn)的方法,特別適用于二分類問(wèn)題。ROC曲線是一種用于可視化分類模型性能的工具,而AUC是ROC曲線下的面積,用于定量評(píng)估模型的性能。
1. 計(jì)算模型的ROC曲線:
在評(píng)估模型之前,你需要使用驗(yàn)證集上的真正例率(True Positive Rate,召回率)和假正例率(False Positive Rate)來(lái)構(gòu)建ROC曲線。這可以通過(guò)不同的分類閾值來(lái)實(shí)現(xiàn)。以下是ROC曲線的構(gòu)建過(guò)程:
-
為了計(jì)算ROC曲線,首先使用模型對(duì)驗(yàn)證集進(jìn)行預(yù)測(cè),獲取每個(gè)樣本的預(yù)測(cè)概率。
-
使用不同的分類閾值(通常是0到1之間的值),將樣本分為正類和負(fù)類。根據(jù)不同閾值,計(jì)算真正例率(TPR)和假正例率(FPR)。
-
繪制TPR和FPR的曲線,即ROC曲線。
2. 計(jì)算AUC值:
AUC(ROC曲線下的面積)用于量化ROC曲線的性能。AUC的值通常在0.5和1之間,越接近1表示模型性能越好。
- 計(jì)算ROC曲線下的面積(AUC)。通常,你可以使用數(shù)值積分方法或庫(kù)函數(shù)來(lái)計(jì)算AUC的值。
3. 評(píng)估模型:
根據(jù)ROC曲線和AUC值進(jìn)行模型評(píng)估。
-
AUC接近1表示模型具有良好的性能,可以很好地區(qū)分正類和負(fù)類樣本。
-
ROC曲線越接近左上角(0,1),表示模型性能越好。
-
如果AUC接近0.5,模型性能可能很差,類似于隨機(jī)猜測(cè)。
-
比較不同模型的AUC值,選擇具有較高AUC值的模型。
-
根據(jù)任務(wù)需求,可以根據(jù)不同的閾值來(lái)調(diào)整模型,以在召回率和精確度之間取得平衡。
import tensorflow as tf
from tensorflow import keras
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
# 加載和預(yù)處理數(shù)據(jù)(與問(wèn)題一相同)
def load_and_preprocess_data():
# 你需要編寫(xiě)加載和預(yù)處理數(shù)據(jù)的代碼,返回X和y
# X是圖像數(shù)據(jù),y是標(biāo)簽(0表示坑洼,1表示正常道路)
# 這里使用一個(gè)假設(shè)的示例,你需要根據(jù)實(shí)際數(shù)據(jù)進(jìn)行適配
X = np.random.rand(301, 224, 224, 3) # 示例隨機(jī)生成圖像數(shù)據(jù)
y = np.random.randint(2, size=301) # 示例隨機(jī)生成標(biāo)簽
return {'images': X, 'labels': y}
# 構(gòu)建深度學(xué)習(xí)模型(與問(wèn)題一相同)
def build_model():
model = keras.Sequential([
# 模型結(jié)構(gòu),與問(wèn)題一相同
])
model.compile(optimizer='adam',
loss='binary_crossentropy', # 二元交叉熵?fù)p失
metrics=['accuracy'])
return model
# 模型訓(xùn)練(與問(wèn)題一相同)
def train_model(X_train, y_train, X_val, y_val):
model = build_model()
model.fit(X_train, y_train, epochs=10, validation_data=(X_val, y_val))
return model
# 計(jì)算ROC曲線和AUC
def calculate_roc_auc(model, X_val, y_val):
y_pred = model.predict(X_val)
fpr, tpr, thresholds = roc_curve(y_val, y_pred)
roc_auc = auc(fpr, tpr)
return fpr, tpr, roc_auc
# 繪制ROC曲線
def plot_roc_curve(fpr, tpr, roc_auc):
plt.figure()
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
#見(jiàn)完整代碼
問(wèn)題三
問(wèn)題三要求使用已訓(xùn)練的模型對(duì)測(cè)試集中的坑洼圖像進(jìn)行識(shí)別,并將識(shí)別結(jié)果保存在一個(gè)CSV文件中。以下是問(wèn)題三的具體建模思路,:
模型應(yīng)用:
-
加載已訓(xùn)練模型:首先,加載問(wèn)題一或問(wèn)題二中訓(xùn)練好的模型。這個(gè)模型應(yīng)該是能夠識(shí)別道路坑洼的模型。
-
加載測(cè)試數(shù)據(jù):加載問(wèn)題一中提供的測(cè)試數(shù)據(jù)集(通常以圖像的形式)。
-
圖像預(yù)處理:對(duì)測(cè)試數(shù)據(jù)進(jìn)行與訓(xùn)練數(shù)據(jù)相同的預(yù)處理,包括圖像歸一化、縮放等操作。
-
模型預(yù)測(cè):使用加載的模型對(duì)測(cè)試數(shù)據(jù)進(jìn)行預(yù)測(cè),得到每張圖像的分類結(jié)果(0表示坑洼,1表示正常道路)。
結(jié)果保存:
- 保存識(shí)別結(jié)果:將圖像文件名與對(duì)應(yīng)的分類結(jié)果(0或1)保存在CSV文件中。這個(gè)文件將作為問(wèn)題三的提交文件。
模型應(yīng)用:
- 加載已訓(xùn)練模型:
model = load_trained_model ( ) \text{model} = \text{load\_trained\_model}() model=load_trained_model()
-
加載測(cè)試數(shù)據(jù):
test_data = load_test_data ( ) \text{test\_data} = \text{load\_test\_data}() test_data=load_test_data()
-
圖像預(yù)處理:
preprocessed_test_data = preprocess_images ( test_data ) \text{preprocessed\_test\_data} = \text{preprocess\_images}(\text{test\_data}) preprocessed_test_data=preprocess_images(test_data)
-
模型預(yù)測(cè):
predictions = model.predict ( preprocessed_test_data ) \text{predictions} = \text{model.predict}(\text{preprocessed\_test\_data}) predictions=model.predict(preprocessed_test_data)
結(jié)果保存:
-
保存識(shí)別結(jié)果:
save_results_to_csv ( test_data_file_names , predictions ) \text{save\_results\_to\_csv}(\text{test\_data\_file\_names}, \text{predictions}) save_results_to_csv(test_data_file_names,predictions)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-717860.html
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow import keras
# 加載已訓(xùn)練的模型
def load_trained_model(model_path):
model = keras.models.load_model(model_path)
return model
# 加載測(cè)試數(shù)據(jù)
def load_test_data(test_data_dir):
# 你需要編寫(xiě)加載測(cè)試數(shù)據(jù)的代碼,返回測(cè)試數(shù)據(jù)集
# 這里使用一個(gè)假設(shè)的示例,你需要根據(jù)實(shí)際數(shù)據(jù)進(jìn)行適配
test_data = np.random.rand(1000, 224, 224, 3) # 示例隨機(jī)生成測(cè)試圖像數(shù)據(jù)
return test_data
# 圖像預(yù)處理(與問(wèn)題二相似)
def preprocess_images(images):
# 你需要編寫(xiě)與問(wèn)題二中相似的圖像預(yù)處理代碼
# 包括圖像歸一化、縮放、通道處理等操作
return preprocessed_images
# 模型預(yù)測(cè)
def predict_with_model(model, test_data):
predictions = model.predict(test_data)
# 假設(shè)模型輸出概率,可以根據(jù)閾值將概率轉(zhuǎn)換為類別(0或1)
predicted_labels = (predictions >= 0.5).astype(int)
return predicted_labels
# 保存識(shí)別結(jié)果到CSV文件
def save_results_to_csv(file_names, predicted_labels, output_csv_file):
results_df = pd.DataFrame({'fnames': file_names, 'label': predicted_labels})
results_df.to_csv(output_csv_file, index=False)
# 示例用法
if __name__ == '__main__':
model_path = 'trained_model.h5' # 已訓(xùn)練模型的文件路徑
test_data_dir = 'test_data' # 測(cè)試數(shù)據(jù)集的目錄
output_csv_file = 'test_results.csv' # 結(jié)果保存的CSV文件名
# 加載已訓(xùn)練的模型
trained_model = load_trained_model(model_path)
#見(jiàn)完整版代碼
完整代碼+思路:
2023年第四屆MathorCup大數(shù)據(jù)競(jìng)賽(A題)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-717860.html
到了這里,關(guān)于2023年第四屆MathorCup大數(shù)據(jù)競(jìng)賽(A題)|坑洼道路檢測(cè)和識(shí)別|數(shù)學(xué)建模完整代碼+建模過(guò)程全解全析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!