《人工智能導論》實驗3 卷積神經網絡(CNN)手寫數字識別_第1頁
《人工智能導論》實驗3 卷積神經網絡(CNN)手寫數字識別_第2頁
《人工智能導論》實驗3 卷積神經網絡(CNN)手寫數字識別_第3頁
《人工智能導論》實驗3 卷積神經網絡(CNN)手寫數字識別_第4頁
《人工智能導論》實驗3 卷積神經網絡(CNN)手寫數字識別_第5頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

實驗3卷積神經網絡(CNN)手寫數字識別一、實驗目的及要求理解卷積神經網絡(CNN)的核心思想:局部連接、權值共享、卷積、池化與平移不變性。掌握使用Keras/TensorFlow構建LeNet-5風格CNN的方法。能夠對比CNN與MLP在手寫數字識別任務上的性能差異,理解CNN在圖像任務中的優勢。理解CNN的層次化特征學習:淺層學習邊緣,中層學習部件,深層學習語義。培養對我國計算機視覺自主創新成果的關注與興趣。二、實驗學時3學時(建議時間分配:講解15分鐘,任務實踐130分鐘,總結報告15分鐘)三、實驗前準備軟件環境:Python3.8及以上,建議使用JupyterNotebook或VSCode。依賴庫:NumPy、Matplotlib、TensorFlow(包含Keras)。安裝命令如下:pipinstallnumpymatplotlibtensorflow知識儲備:已學習教材第6.3節(卷積神經網絡)內容,了解卷積、池化、局部連接與權值共享。說明:TensorFlow安裝包較大,建議課前完成安裝并驗證`importtensorflowastf`無報錯;數據集使用scikit-learn內置的load_digits,無需聯網下載。在JupyterNotebook中運行繪圖代碼前,建議先執行`%matplotlibinline`,以保證圖像正常顯示。四、實驗任務任務1加載與預處理手寫數字數據(15分鐘)使用sklearn.datasets.load_digits加載手寫數字數據;將像素值歸一化到[0,1];增加通道維度;標簽保持整數類型。任務2構建LeNet-5風格CNN(30分鐘)搭建網絡:卷積層(16個3×3卷積核)→最大池化→卷積層(32個3×3卷積核)→最大池化→展平→全連接層(64)→輸出層(10)。理解每一層的作用。任務3訓練與評估模型(50分鐘)使用Adam優化器和sparse_categorical_crossentropy損失函數訓練模型;記錄訓練過程中的損失與準確率;在測試集上評估最終性能。任務4與MLP對比(15分鐘)記錄CNN的測試準確率;與實驗七中MLP的結果進行對比,分析CNN如何利用局部連接與權值共享提升圖像分類效果。任務5可視化卷積核與特征圖(20分鐘)抽取第一個卷積層的部分卷積核進行可視化;選擇一張測試樣本,觀察其在第一個卷積層輸出的特征圖,理解CNN如何檢測邊緣等低級特征。參考代碼以下為完整可運行代碼。完整訓練通常只需十幾秒到一分鐘(取決于硬件):#實驗八:卷積神經網絡(CNN)手寫數字識別

importwarnings

warnings.filterwarnings('ignore')

importnumpyasnp

importmatplotlib.pyplotasplt

importtensorflowastf

fromtensorflowimportkeras

fromtensorflow.kerasimportlayers

fromsklearn.datasetsimportload_digits

fromsklearn.model_selectionimporttrain_test_split

fromsklearn.metricsimportaccuracy_score,classification_report

#設置中文字體

plt.rcParams['font.sans-serif']=['SimHei','MicrosoftYaHei','ArialUnicodeMS']

plt.rcParams['axes.unicode_minus']=False

print("TensorFlow版本:",tf.__version__)

#1.加載手寫數字數據集(load_digits為scikit-learn內置數據集,無需聯網)

print("正在加載手寫數字數據集...")

digits=load_digits()

X=digits.images.astype('float32')/16.0#像素值范圍0-16,歸一化到[0,1]

y=digits.target

X=np.expand_dims(X,-1)#增加通道維度->(1797,8,8,1)

print(f"樣本數:{X.shape[0]},圖像尺寸:{X.shape[1:4]},類別數:{len(np.unique(y))}")

#2.劃分訓練集與測試集

X_train,X_test,y_train,y_test=train_test_split(

X,y,test_size=0.2,random_state=42,stratify=y

)

print(f"訓練樣本數:{X_train.shape[0]},測試樣本數:{X_test.shape[0]}")

#3.構建CNN模型

model=keras.Sequential([

layers.Input(shape=(8,8,1)),

layers.Conv2D(16,(3,3),activation='relu',padding='same',name='conv1'),

layers.MaxPooling2D((2,2)),

layers.Conv2D(32,(3,3),activation='relu',padding='same',name='conv2'),

layers.MaxPooling2D((2,2)),

layers.Flatten(),

layers.Dense(64,activation='relu'),

layers.Dense(10,activation='softmax')

])

model.summary()

pile(optimizer='adam',

loss='sparse_categorical_crossentropy',

metrics=['accuracy'])

#4.訓練

print("\n開始訓練CNN...")

history=model.fit(X_train,y_train,epochs=15,batch_size=32,

validation_split=0.1,verbose=1)

#5.評估

test_loss,test_acc=model.evaluate(X_test,y_test,verbose=0)

print(f"\n測試集準確率:{test_acc:.4f}")

y_pred=model.predict(X_test,verbose=0)

y_pred_labels=np.argmax(y_pred,axis=1)

print("\n分類報告:")

print(classification_report(y_test,y_pred_labels))

#6.繪制訓練曲線

plt.figure(figsize=(12,5))

plt.subplot(1,2,1)

plt.plot(history.history['loss'],label='訓練損失')

plt.plot(history.history['val_loss'],label='驗證損失')

plt.xlabel('Epoch')

plt.ylabel('Loss')

plt.title('損失曲線')

plt.legend()

plt.grid(True)

plt.subplot(1,2,2)

plt.plot(history.history['accuracy'],label='訓練準確率')

plt.plot(history.history['val_accuracy'],label='驗證準確率')

plt.xlabel('Epoch')

plt.ylabel('Accuracy')

plt.title('準確率曲線')

plt.legend()

plt.grid(True)

plt.show()

#7.可視化第一個卷積層的部分卷積核

conv1_weights=model.get_layer('conv1').get_weights()[0]

plt.figure(figsize=(8,4))

foriinrange(16):

plt.subplot(2,8,i+1)

plt.imshow(conv1_weights[:,:,0,i],cmap='gray')

plt.axis('off')

plt.suptitle('第一個卷積層前16個卷積核')

plt.tight_layout()

plt.show()

#8.可視化某張測試樣本在conv1輸出的特征圖

sample=X_test[0:1]

conv1_output_model=keras.Model(inputs=model.layers[0].input,

outputs=model.get_layer('conv1').output)

feature_maps=conv1_output_model.predict(sample,verbose=0)[0]

plt.figure(figsize=(10,4))

plt.subplot(1,9,1)

plt.imshow(sample[0,:,:,0],cmap='gray')

plt.title('原圖')

plt.axis('off')

foriinrange(8):

plt.subplot(1,9,i+2)

plt.imshow(feature_maps[:,:,i],cmap='gray')

plt.title(f'特征圖{i+1}')

plt.axis('off')

plt.suptitle('輸入樣本與第一個卷積層特征圖')

plt.tight_layout()

plt.show()預期結果(參考)在1,437條訓練樣本上訓練15個epoch,測試集準確率通常可達0.95–0.97,與同規模MLP相比參數量更少且性能相近。訓練損失和驗證損失同步下降,準確率快速上升。卷積核可視化可觀察到邊緣、筆畫等低級特征檢測器;特征圖顯示網絡在數字筆畫處響應較強。結果記錄表項目MLP(實驗七)CNN(本實驗)對比分析測試準確率CNN通常更高訓練時間與硬件相關輸入處理方式64維向量8×8×1張量CNN保留空間結構參數規模CNN通常更少對平移的魯棒性CNN更強五、實驗重點、難點重點:CNN的網絡結構(卷積→池化→展平→全連接)、局部連接與權值共享、卷積核與特征圖的可視化。難點:理解卷積運算的滑動點積過程、池化層的作用、CNN為何比MLP更適合圖像任務。六、操作要點TensorFlow安裝包較大,建議課前完成安裝;若使用AppleSiliconMac,可安裝tensorflow-macos或tensorflow-metal以加速。本實驗使用scikit-learn內置的load_digits數據集(1,437條訓練樣本),建議訓練15個epoch;課后可嘗試MNIST等更大規模數據。model.summary()可查看每層輸出形狀和參數量,建議結合教材中的“參數爆炸”問題進行分析。可視化特征圖時,選擇邊緣清晰的樣本效果更明顯。七、注意事項輸入數據的通道維度必須正確:load_digits圖像為(8,8,1),MNIST圖像為(28,28,1),彩色圖為(H,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論