實戰(zhàn):Python傳統(tǒng)機器學習源碼解析與避坑指南)
簡介面向高校機器學習課程大作業(yè)場景這份壓縮包提供了基于Python的人臉識別與性別識別完整實現(xiàn)適合作為本科生課程項目參考。內(nèi)容覆蓋照片與視頻兩類輸入既包含人臉與眼睛檢測也演示了調用卷積神經(jīng)網(wǎng)絡模型進行性別識別的兩種方式有助于理解從圖像預處理、模型加載到輸出結果的完整工程流程。壓縮包大小約3.52MB核心文件包括Python源碼、預訓練模型、工程說明文檔以及BP神經(jīng)網(wǎng)絡性別檢測工作報告針對照片與視頻分別設置了多個獨立模塊便于按需學習。目前已有1449人學習下載多為正在完成人臉識別或機器學習大作業(yè)的學生。除可直接運行的代碼外報告還系統(tǒng)梳理了BP神經(jīng)網(wǎng)絡的工作流程、數(shù)據(jù)集處理與實驗分析可顯著降低起步門檻。對于需要同時提交源碼、課程報告和項目說明的讀者這份材料提供了完整參考既便于復現(xiàn)實驗也方便在此基礎上擴展新功能。1. 人臉識別大作業(yè)這套Python機器學習源碼包先解決能跑再解決能講期末周最忙的幾件事里機器學習課程設計一定排得上號。人臉識別作為各校大作業(yè)的高頻題搜出來的資源大多是源碼課程報告項目說明三件套的壓縮包。它解決的不是從零發(fā)明算法而是兩個更現(xiàn)實的問題交上去能跑出結果答辯時能講清原理。這類包的內(nèi)容通常是一條基于Python傳統(tǒng)機器學習的完整流程——讀取人臉圖片、統(tǒng)一尺寸、提取特征、訓練分類器、對新照片預測再把過程寫進課程報告配一份讓老師照著命令能復現(xiàn)的項目說明。適合三類人課程設計臨期想穩(wěn)過的學生、剛入門Python還不熟悉工程結構的初學者、想拿基準流程做對比實驗的畢設起步者。先給結論這類包的價值在流程骨架不在模型精度你要做的是跑通它、改參數(shù)、把三件事講清楚。2. 從原理到選型為什么這個題目用傳統(tǒng)機器學習而不是扔給深度學習2.1 三條技術路線特征臉、Fisherface和LBPH差在哪大作業(yè)源碼里最常見的算法不是CNN而是三種傳統(tǒng)方法PCA特征臉、LDA Fisherface、LBPH局部二值模式。特征臉Eigenface的思路是把每張人臉照片拉成一維向量計算所有向量的協(xié)方差矩陣用特征值分解找出一組主成分方向。這些主成分向量還原成圖像后看起來像一張模糊的人臉輪廓所以叫特征臉。識別時把新照片投影到特征空間和每個已注冊的人臉向量算歐氏距離距離最近的標簽就是預測結果。這個方法的數(shù)學干凈答辯時老師問你PCA做了什么一張?zhí)卣髂樋梢暬瘓D就能說明白。Fisherface是在PCA基礎上加了類別意識。PCA只關心整體方差最大不關心不同人之間的區(qū)分LDA則轉而最大化類間散度/類內(nèi)散度這個比值讓同一人的照片聚攏、不同人的照片分開。實驗里Fisherface在光照變化不大的數(shù)據(jù)集上通常比純PCA略好但它對樣本數(shù)的需求更高——每類樣本太少時類內(nèi)散度矩陣估不準。LBPH走的是另一條路它不計算全局投影而是給每個像素統(tǒng)計鄰域紋理模式生成局部二值模式直方圖再用直方圖之間的相似度做識別。優(yōu)點是計算快、對光照變化相對魯棒OpenCV的face模塊里直接封裝了現(xiàn)成接口很多課程設計源碼會用OpenCV那一套而不是自己手寫PCA。2.2 為什么是機器學習而不是深度學習人臉識別在工業(yè)界早就被深度學習統(tǒng)治了但大作業(yè)場景里傳統(tǒng)機器學習依然是更穩(wěn)的選擇四個原因第一數(shù)據(jù)量不匹配。公開的課程級數(shù)據(jù)集一般很小ORL一共400張、Yale大概165張這點樣本喂給CNN訓練驗證集準確率波動會非常大很容易陷入訓練集98%測試集不到70%的尷尬。傳統(tǒng)方法參數(shù)少幾百張圖足以擬合一個SVM。第二算力限制。CNN訓練要么借GPU要么在CPU上干等一個下午。傳統(tǒng)方法在CPU上幾十秒就能完成交叉驗證迭代調參的體驗完全不同。第三可解釋性。答辯老師會追問為什么選這個特征為什么分類錯誤。PCA降維、SVM間隔、距離閾值這些概念一句話能講清楚而深度學習是個黑匣子學生版本的CNN很難從內(nèi)部機理上給出有說服力的回答。第四課程評分標準本身不要求SOTA。大多數(shù)大作業(yè)的給分維度是功能完整、可復現(xiàn)、報告清晰不是識別率排名。一套調好的傳統(tǒng)流程已經(jīng)能拿到90%以上的識別率足夠支撐報告里的實驗章節(jié)。2.3 選型對照表先定算法再動手寫代碼拿到zip之后第一步不是跑代碼是先弄清里面用的是哪條技術路線這決定了你后面所有修改方向。路線適合數(shù)據(jù)量光照魯棒性可解釋性答辯友好度PCA特征臉小每類5~10張弱高高LDA/Fisherface中每類至少8~10張弱高高LBPH小到中中等中中CNN很大每類數(shù)百張強低低課程設計源碼里最常見的技術組合是兩種一是自己用scikit-learn實現(xiàn)PCA降維 SVM分類二是直接調OpenCV的EigenFaceRecognizer或LBPHFaceRecognizer。前者的好處是每行代碼都能寫進報告后者的好處是代碼量少、接口穩(wěn)定。如果你拿到的包是前者恭喜它的可改空間最大——換分類器、調主成分數(shù)、做對比實驗都很順手。實際選型時還要考慮一個容易被忽略的點zip里的項目說明寫的是什么。項目說明如果承諾Windows 10 Python 3.8可直接運行你就不要擅自升級Python大版本否則OpenCV的輪子可能裝不上后面全是在修環(huán)境的活。3. 把源碼跑起來環(huán)境配置、ORL數(shù)據(jù)集與三個最小命令3.1 Python環(huán)境準備用獨立虛擬環(huán)境避開python安裝的坑很多新手第一次翻車不是翻在算法而是翻在環(huán)境。系統(tǒng)Python里裝了一堆亂七八糟的包新版舊版互相打架最后import cv2直接崩。拿到源碼包之后第一件事是建一個干凈的虛擬環(huán)境——這是你交作業(yè)前的后悔藥。我用conda建環(huán)境的習慣是conda create -n face_det python3.8 -y conda activate face_det然后裝依賴。注意大作業(yè)源碼一般依賴這幾個包命令里我特意把opencv-contrib-python寫在前面因為普通opencv-python不帶face模塊裝了也調不出cv2.face.LBPHFaceRecognizer。pip install opencv-contrib-python scikit-learn numpy matplotlib pillow joblib參數(shù)說明opencv-contrib-pythonOpenCV主庫加擴展模塊face識別器在這個包里。只裝opencv-python的話代碼跑到cv2.face會直接報no attribute。scikit-learnPCA、SVM、train_test_split、GridSearchCV都靠它。joblib模型持久化用比pickle更省事后面講。裝完可以用一行命令驗證環(huán)境到位python -c import cv2, sklearn; print(cv2.__version__, sklearn.__version__)能打出兩個版本號就說明基礎依賴沒有缺。如果是在VSCode里跑記得右下角把解釋器切到face_det這個虛擬環(huán)境否則終端里裝的包IDE里全找不到這個坑我見人踩過無數(shù)次。3.2 數(shù)據(jù)集準備ORL人臉庫的目錄結構ORLATT人臉庫是這類大作業(yè)最常見的配套數(shù)據(jù)集40個人每人10張共400張112x92的灰度PGM圖片。使用前先確認你的數(shù)據(jù)集目錄長什么樣。常見的目錄結構是orl_faces/ s1/ 1.pgm 2.pgm ... 10.pgm s2/ 1.pgm 2.pgm ... 10.pgm ... s40/ 1.pgm 2.pgm ... 10.pgm在跑訓練之前先花一分鐘寫個腳本掃描目錄別急著訓練防止數(shù)據(jù)集路徑不對導致訓練腳本讀零張圖import os from collections import Counter dataset_root orl_faces person_dirs [d for d in sorted(os.listdir(dataset_root)) if os.path.isdir(os.path.join(dataset_root, d))] counts {} for person in person_dirs: path os.path.join(dataset_root, person) files [f for f in os.listdir(path) if f.lower().endswith((.pgm, .jpg, .png))] counts[person] len(files) print(f檢測到 {len(person_dirs)} 個人) print(f每人圖片數(shù)量: {set(counts.values())}) print(f異常樣本: {[(k, v) for k, v in counts.items() if v ! 10]})這段代碼的邏輯是先枚舉根目錄下所有子目錄把每個子目錄里的圖片文件數(shù)統(tǒng)計出來。set(counts.values())輸出一個集合如果結果是{10}說明每人10張全部正常只要集合里出現(xiàn)別的數(shù)字就說明某個人的照片缺失或有雜質先去把數(shù)據(jù)修好再往下走。注意數(shù)據(jù)集里偶爾混入隱藏文件和縮略圖過濾條件里我加了擴展名校驗能避開大部分干擾。3.3 訓練、驗證、識別三個命令項目說明要寫的自助流程源碼包里那份項目說明文檔本質上是給老師看的復現(xiàn)手冊。你自己復現(xiàn)時先把訓練、測試、識別三步跑通python train.py --data orl_faces --model output/face_model.pkl --n_components 50 python test.py --model output/face_model.pkl --data orl_faces python recognize.py --model output/face_model.pkl --image test.jpg三步的含義分別是第一條命令讀取orl_faces目錄下的所有人臉圖片做PCA降維到50維訓練SVM分類器把模型存成output/face_model.pkl第二條命令重新讀一遍數(shù)據(jù)集按經(jīng)典劃分比例分成訓練集和測試集加載模型跑準確率第三條命令加載同一個模型對準單張圖片輸出預測的人的編號。這里的參數(shù)需要解釋一下--n_components 50PCA保留的主成分個數(shù)。50是一個中庸的起點最后你改這個數(shù)字去畫準確率曲線就是報告里的實驗內(nèi)容。--model模型文件的輸出或加載路徑。訓練和識別必須用同一個路徑否則會出現(xiàn)識別時加載的模型和剛才訓的不是同一個的烏龍。很多源碼包的項目說明里會寫將數(shù)據(jù)集放在orl_faces目錄下運行python train.py即可但它未必會告訴你路徑分隔符在Windows上要怎么寫。如果你在Windows的cmd里跑output/face_model.pkl這種正斜杠路徑是沒有問題的Python會自己處理真正坑的是數(shù)據(jù)集路徑里帶了中文OpenCV的imread在Windows上讀有中文路徑的圖片會靜默返回None圖片讀成空訓練數(shù)據(jù)全是零向量準確率直接崩。項目說明文檔里正常會提醒改成純英文路徑如果沒提醒你自己改一下。3.4 模型持久化pkl文件是交作業(yè)前的后悔藥訓練一個模型可能只要一分鐘但反復調參的過程會消耗大量時間。把模型存下來的意義在于每次調完參存一份帶參數(shù)的pkl最后比對哪份在測試集上最好就不用每次識別都重訓一遍。import joblib # 訓練完成后保存 joblib.dump(pipe, output/face_model.pkl) # 識別時加載 pipe joblib.load(output/face_model.pkl) pred pipe.predict([face_vector])[0]說明一下dump的第一個參數(shù)是訓練好的Pipeline對象第二個參數(shù)是文件路徑load負責讀回來讀回來的對象保留了完整的PCA變換、標準化參數(shù)和SVM權重不需要重新計算任何東西。我習慣把模型文件命名為{算法}_{主成分數(shù)}_{準確率}.pkl比如pca50_svm_0.965.pkl這樣交作業(yè)前整理實驗數(shù)據(jù)時一眼就能看出哪份模型是最好的不用重新跑。4. 核心代碼拆解數(shù)據(jù)加載、PCA降維與SVM分類的落地寫法4.1 數(shù)據(jù)加載與預處理灰度、resize和直方圖均衡化的順序拿到源碼后第一段值得精讀的代碼就是數(shù)據(jù)加載。它決定了后面所有環(huán)節(jié)的數(shù)據(jù)質量。典型寫法如下import cv2 import glob import numpy as np def load_dataset(data_root, target_size(112, 92)): images, labels [], [] for person_idx, person_dir in enumerate(sorted(glob.glob(str(data_root) /*))): for img_path in glob.glob(person_dir /*.pgm): img cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) # 統(tǒng)一讀成灰度圖 img cv2.resize(img, target_size) # 尺寸統(tǒng)一 img cv2.equalizeHist(img) # 直方圖均衡化 images.append(img.flatten()) # 二維轉一維向量 labels.append(person_idx) return np.array(images), np.array(labels)這段代碼有三個關鍵點。一是IMREAD_GRAYSCALE人臉識別不需要顏色顏色信息只會增加PCA的計算量。二是resizeORL本身是112x92但很多源碼包為了統(tǒng)一輸入會強制resize到固定尺寸訓練和識別時尺寸必須完全一致否則特征向量長度對不上。三是equalizeHist直方圖均衡化把灰度分布拉開讓人臉在光線不均勻時依然能看出五官輪廓這一步對LBPH和PCA都有顯著的魯棒性提升。注意flatten()之后每張圖片變成了10304維112乘92的一維向量。這個維度數(shù)就是后面PCA要降維的對象。4.2 PCA主成分分析特征臉與累計方差貢獻率的取舍PCA在scikit-learn里封裝得非常簡單但代碼簡單不代表參數(shù)可以亂填。核心問題是n_components到底取多少from sklearn.decomposition import PCA pca PCA(n_components50) X_pca pca.fit_transform(X) # X來自上一個函數(shù)的輸出 print(pca.explained_variance_ratio_.cumsum()[-1]) # 打印前50個主成分的累計方差貢獻率這段代碼的輸出會是一個0到1之間的小數(shù)比如0.9327。含義是前50個主成分保留了原圖93.27%的方差信息。這個數(shù)字越大保留的信息越多但主成分數(shù)越多特征維度越高訓練越慢、越容易過擬合。我一般把目標定在0.9到0.95之間。如果50個主成分已經(jīng)到0.93就不用再加如果只有0.85則把n_components提到80或100重跑一次。你把這個主成分數(shù)-累計方差貢獻率-識別準確率的對應關系做成表格直接就是課程報告里的一節(jié)實驗結果。還有一個小細節(jié)pca.components_里存的就是特征臉向量用numpy重排成112x92像素再matplotlib畫出來能畫出網(wǎng)格狀的人臉輪廓圖。這張圖畫進報告答辯時展示效果遠好于貼一堆代碼。4.3 SVM分類器訓練把PCA和SVM包進一條Pipeline在大作業(yè)里SVM是比樸素貝葉斯和KNN更好的選擇它處理高維特征更穩(wěn)定而且有明確的參數(shù)可以調。這里我用Pipeline把預處理、降維、分類串成一條流水線識別時直接對單張圖片操作不容易漏步驟。from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.decomposition import PCA from sklearn.svm import SVC pipe Pipeline(steps[ (pca, PCA(n_components50)), (scaler, StandardScaler()), (svm, SVC(kernelrbf, C10.0, gamma0.01)) ]) pipe.fit(X_train, y_train) print(測試集準確率:, pipe.score(X_test, y_test))Pipeline的邏輯是fit時按順序執(zhí)行PCA變換、標準化、SVM訓練predict時對輸入自動做同樣的PCA和標準化不需要你手動調用pca.transform再scaler.transform。這里有個值得寫的技術點為什么PCA之后還要StandardScaler。PCA輸出的各主成分方差差異很大第一個主成分的數(shù)值范圍可能比第十幾個大一個數(shù)量級而RBF核的SVM對特征尺度敏感不做標準化數(shù)值大的主成分會主導距離計算導致分類邊界被帶偏。這個細節(jié)寫進報告老師會認為你是真調過參的不是只會黏貼代碼。4.4 評估與報告數(shù)據(jù)準確率、混淆矩陣和一張測試截圖光是打出一個準確率數(shù)字不夠課程報告需要有分析深度。評估環(huán)節(jié)至少要有三樣輸出準確率、每個類別的精確率召回率、混淆矩陣。from sklearn.metrics import classification_report, confusion_matrix y_pred pipe.predict(X_test) print(classification_report(y_test, y_pred, digits3)) print(confusion_matrix(y_test, y_pred))classification_report會輸出每個類別的精確率、召回率、F1值digits3把小數(shù)位數(shù)擴展到三位數(shù)據(jù)更好看。confusion_matrix輸出40行40列的矩陣如果按ORL的40人來算矩陣對角線越亮越好。看報告時重點看兩類問題一是哪些人的識別率明顯低于平均說明這兩人的樣本可能存在姿態(tài)或表情差異過大的情況二是哪兩個人容易互相混淆說明特征空間里這兩類樣本距離太近PCA保留的信息不夠區(qū)分他們。這些分析寫進課程報告里比單純貼一行準確率有價值得多。必要的時候再對測試集里的某張圖片做一次完整的識別展示——原圖、預測標簽、真實標簽、模型置信度或距離值截圖貼到報告里答辯時直接給老師看這個效果圖。5. 大作業(yè)避坑指南五個讓訓練直接翻車的低級錯誤5.1 模型把所有照片都識別成同一個人現(xiàn)象訓練結束準確率看起來有90%以上但拿一張不在訓練集里的人臉去識別永遠輸出第一個人。原因最常見的是標簽錯位。數(shù)據(jù)加載時images和labels兩個列表的追加順序不一致比如images按s1到s40順序讀labels卻使用了從某個臨時字典里取的值導致特征和標簽錯位。另一種可能是測試圖片的預處理和訓練時不一致比如訓練時做了equalizeHist識別時忘了做特征分布完全對不上分類器只能把一切情況歸到最近的訓練樣本。解決先打印pipe.predict用的向量維度和訓練時的X_train.shape[1]比對維度不一致是預處理鏈路斷了。維度一致再看標簽寫幾行代碼隨機抽取十張測試圖手工標注真實身份和預測結果逐一對照很快就能定位是錯位還是預處理問題。踩過這個坑之后我養(yǎng)成了習慣數(shù)據(jù)加載函數(shù)里最后加一行assert len(images) len(labels)這句斷言能擋住大多數(shù)低級錯誤。5.2 OpenCV提示 face 屬性不存在現(xiàn)象cv2.face.LBPHFaceRecognizer_create()報AttributeError: module cv2 has no attribute face。原因opencv-python這個包的主庫不帶face模塊只有opencv-contrib-python才有。很多安裝教程只讓裝opencv-python代碼一跑就直接翻車。解決先卸載再裝pip uninstall opencv-python opencv-contrib-python -y pip install opencv-contrib-python裝完驗證import cv2 print(hasattr(cv2, face))輸出True就正常了。這個坑出現(xiàn)的概率極高我建議拿到源碼包后先跑這一行驗證再繼續(xù)。5.3 訓練集準確率高、留出集卻很低現(xiàn)象訓練集上識別率95%以上test_score只有60%甚至不到怎么調參都上不去。原因數(shù)據(jù)劃分時沒有打亂或者數(shù)據(jù)泄漏。比如訓練和測試都直接取orl_faces里按順序排列的樣本測試集恰好集中了某幾個人全部照片模型沒有見過這類樣本自然預測很差。更隱蔽的一種是同一個人不同照片之間高度相似導致的信息泄漏如果劃分時沒有按人分組同一個人的幾張照片同時出現(xiàn)在訓練集和測試集測試集準確率會被虛高估計。解決用train_test_split顯式打亂并固定隨機種子from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test train_test_split( X_pca, y, test_size0.2, shuffleTrue, random_state42 )shuffleTrue是關鍵random_state42保證每次運行結果一致方便課程報告里貼數(shù)據(jù)。如果數(shù)據(jù)集是按人分組的建議直接用GroupShuffleSplit按人劃分保證同一人的照片不會同時出現(xiàn)在訓練集和測試集——這個細節(jié)講出來答辯老師會眼前一亮。5.4 攝像頭實時識別卡頓、誤判多現(xiàn)象用筆記本攝像頭做實時演示時畫面一卡一卡識別結果亂跳甚至把背景當人臉框出來。原因實時識別里最常見的做法是每一幀都跑一遍完整流程——檢測人臉、預處理、PCA、SVM預測四個步驟疊在一起普通筆記本CPU根本扛不住。另一個問題是OpenCV的Haar級聯(lián)人臉檢測器漏檢和誤檢同時存在光線變化時檢測框位置和大小抖動導致同一張臉連續(xù)幾幀被resize到不同尺寸特征不穩(wěn)定。解決實時pipeline做三件事。一是降低處理頻率每5幀只做一次檢測中間幀直接用上一次定位的人臉區(qū)域二是檢測框外擴10%左右再裁剪把下巴和額頭邊緣包進去減少因為裁切位置抖動帶來的特征變化三是對連續(xù)幀的預測結果做簡單的多數(shù)投票連續(xù)三幀里出現(xiàn)次數(shù)最多的標簽作為最終輸出能有效壓制偶發(fā)誤判。5.5 課程報告交上去查重率超標現(xiàn)象代碼跑通了但課程報告因為大段復述教材和網(wǎng)上的原理介紹查重率紅得刺眼。原因課程報告里PCA原理SVM原理這種章節(jié)最容易被復制粘貼。這些知識性內(nèi)容本來就有標準表述抄來抄去查重率必然爆表。解決把知識性內(nèi)容壓縮到最少把篇幅留給你自己的東西實驗環(huán)境、數(shù)據(jù)集信息、參數(shù)設置表、準確率曲線、混淆矩陣、踩坑記錄。原理部分用自己的話重新組織長度控制在總篇幅的三分之一以內(nèi)。另一個技巧是把你調試過程中真實遇到過的問題寫進去比如OpenCV的face模塊在普通包里不存在訓練集和測試集劃分初版忘記打亂導致驗證分數(shù)失真這些是查重系統(tǒng)里獨一無二的內(nèi)容也是答辯老師最愿意聽的部分因為它們是真實工作痕跡。6. 讓它變成你的作業(yè)加一個實時攝像頭模塊再做兩個對比實驗6.1 攝像頭識別的低配版管線大作業(yè)如果能現(xiàn)場演示實時識別效果遠比只跑命令行截圖好。最低配的攝像頭識別管線是Haar級聯(lián)檢測人臉裁剪、resize、均衡化再丟進訓練好的Pipeline預測。import cv2 face_cascade cv2.CascadeClassifier( cv2.data.haarcascades haarcascade_frontalface_default.xml ) cap cv2.VideoCapture(0) while True: ok, frame cap.read() gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces face_cascade.detectMultiScale( gray, scaleFactor1.1, minNeighbors5, minSize(80, 80) ) for (x, y, w, h) in faces: face cv2.resize(gray[y:yh, x:xw], (112, 92)) face cv2.equalizeHist(face) pred pipe.predict(face.flatten().reshape(1, -1))[0] cv2.rectangle(frame, (x, y), (x w, y h), (0, 255, 0), 2) cv2.putText(frame, fid{pred}, (x, y - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) cv2.imshow(face_recognition, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()代碼里的scaleFactor1.1是檢測窗口每次縮放的步長越小檢測越細但越慢minNeighbors5控制一個區(qū)域需要被多少個鄰近窗口確認才算人臉數(shù)值越大誤檢越少但也容易漏檢。這兩個參數(shù)對門禁、考勤這類近景場景比較友好若是遠景多人場景minNeighbors可以降到3。6.2 兩個能放進答辯PPT的實驗實驗一改變n_components從20到120每隔20取一個點畫一條主成分數(shù)-準確率曲線能看出曲線上升后飽和甚至下降的拐點說明PCA降維確實在起作用。實驗二在完全相同的訓練集測試集劃分下比較LBPH和PCASVM的準確率與單次訓練耗時——這組對比實驗展示的不只是你跑通了代碼而是你理解了不同算法的邊界。6.3 一點收尾做完這個項目后我最大的習慣改變是先搭評估流程再調模型。很多同學先把模型調到自我感覺良好最后發(fā)現(xiàn)測試腳本寫的漏洞百出所有指標都不可信。我后來所有實驗都先把準確率打印、模型保存、隨機種子固定這三件事做完再回頭調參。課程報告里的每個數(shù)字都能追溯答辯被追問時心里不慌。這個習慣一直用到現(xiàn)在希望幫到你。本文還有配套的精品資源點擊獲取