講義把建一個深度學習模型拆成五步:準備資料、決定網路結構、選 loss、選 optimizer、開始訓練(fit)。每一步都是一個決定,每個決定都可能出錯。下面用講義裡的 MNIST 手寫數字辨識走一遍,同一件事有 Keras 和 PyTorch 兩種寫法。點任何一步,看那一步的程式碼和它在決定什麼。
把資料切好、變成數字。
三份資料:講義的比喻是 testing 是「大考」,用來檢驗模型的普遍性;training 是「小考」,訓練時調權重;validation 是每個 epoch 訓練完的「模擬考」,用來在不同模型、不同超參數之間挑一個。規則只有一條:不能作弊、偷看考題,validation 和 test 都不能用在訓練。validation 的核心用途是挑設定,不是「看看訓練得好不好」;一旦你依照 test 的結果回頭調整,test 就已經被洩漏進模型選擇了。
混有網路資料和自己的資料怎麼切:如果 train 和 test 都來自同一個分佈,照比例切就好。麻煩的是講義的自駕車例子:大量訓練資料來自網路各處,少量才是你真正的車拍的。規則是 validation(dev)和 test 要來自同一個分佈。validation 只從大的網路資料切,或只從小的自己的資料切,都可能和 test 對不上;講義建議兩邊各拿一部分。講義也舉了一個反例:虹膜辨識的研究裡,訓練和測試資料的來源不同,前處理就讓結果大不一樣。
前處理:神經網路的輸入要和權重相乘,所以必須是數字。名目資料用 one-hot encoding,順序資料轉成數值。輸入範圍差很多也會影響訓練:講義的例子是溫度 0 到 40 度、距離 0 到 10000 公尺,loss 的等高線會被拉成細長的橢圓,梯度下降走得很辛苦,所以建議 re-scale。兩個常見做法:
X -= np.mean(X, axis=0)X /= np.std(X, axis=0)。只在「各維尺度不同、但重要性差不多」時才有意義;影像的像素本來就都在 0 到 255,不一定需要這一步。MNIST 的 Keras 版直接除以 255,PyTorch 版用 Normalize(0.1307, 0.3081)。影像增強:it depends。講義引用 MIT 6.S094 的自駕車例子:白天和黑夜、雨天和晴天的畫面差很多,所以需要 data augmentation 讓模型看過這些變化。但「調亮、去霧」這種影像增強不一定有幫助,要看任務。其他常見的影像前處理:統一尺寸和長寬比(通常保留中央)、必要時縮放、降維(要不要只用灰階)。開始前也要先清資料:刪掉重複或無關的樣本(例如只做獨棟房屋卻混進公寓)、修格式錯誤和錯字、檢查標錯的標籤;離群值要有正當理由才刪;缺值不要直接丟掉或硬補,因為「缺」本身就是資訊。
Model selection:先問 inductive bias 是否匹配。CNN 內建局部性、平移等變性、階層特徵,適合影像和語音;Transformer 做內容相關的全域互動,適合文字、語言,也能做影像;RNN 和 SSM 用固定或壓縮的狀態,適合串流和長序列。講義的提醒:模型越通用,通常需要越多資料和算力,才能學到同樣的偏好。
Loss function 怎麼選(講義:depending on your applications):
講義的定義:模型在訓練過程中,意外「看到」了本來不該在訓練階段出現的 test(或未來)資訊,於是評估結果虛高,模型其實沒學到泛化能力。它隱形又致命:程式能跑、分數漂亮、論文好寫,但結果無法重現、無法部署。下面這台模擬器真的在算:產生一段感測器資料,照你選的流程切分和前處理,用 kNN 分類,然後分別考 validation 和一批「真正的新資料」。
常見錯誤 1:先做特徵工程或標準化,再切分。錯的寫法是 X = StandardScaler().fit_transform(X) 之後才 train_test_split:test 的統計量已經進了 scaler。對的寫法是先切,scaler.fit(X_train),再用同一個 scaler 去 transform train 和 test。原則:任何統計量只從 train 計算。講義的表把它延伸到資料不平衡:在 train + test 上一起做 SMOTE 或 oversampling,test 也被「改造」了;資料平衡只能在 train 上做。
常見錯誤 2:用未來的資訊做特徵。感測器和時間序列最常見:預測元件剩餘壽命(RUL),卻用到了未來時間點的振動或溫度;把整段量測的移動平均、頻譜特徵一次算完再隨機切分。講義的例子:用 2023 到 2024 年的資料訓練、2022 年的資料測試,模型等於看見了未來。對的做法是嚴格照時間切:train 用 2020 到 2022、valid 用 2023、test 用 2024,特徵只用「當下已知」的過去資料。
常見錯誤 3:目標洩漏。y 的資訊混進了特徵。例子:預測「病人是否出院」卻把「出院日期」當特徵;用最終測試良率或實際量測功耗,去預測設計階段是否過規格;影像缺陷檢測把標註或後處理結果直接當特徵。只能用「預測那個時間點已經知道」的資訊。
常見錯誤 4:交叉驗證切錯。在 K-Fold 之前就對整份資料做特徵選擇、SMOTE、缺失值填補。每個 fold 都要在自己內部獨立做這些步驟,sklearn 的 Pipeline 加 cross_val_score 是正確寫法的關鍵。
常見錯誤 5:重複或近重複樣本。同一片 PCB、同一顆晶圓的多張缺陷影像同時出現在 train 和 test,或是原圖和 resize 過的版本各在一邊,模型等於在背答案。切分前先去重、檢查近重複(影像資料集和 SPICE 模擬結果特別要查),augmentation 只在 train 做。同一類的還有群體洩漏:同一位病人的 MRI 切片一部分進 train、一部分進 test,模型學到的其實是「病人 ID」;切分要以病人、公司、用戶為單位。講義另一張表的總結:duplicate 灌高 benchmark,group 讓模型記住 identity,preprocess 偷看了 test 分佈,selection(拿 test 調模型或 prompt)讓 test 不再是 test。
實戰 checklist(講義第 34 頁):
正確切分的五個原則:先切分再前處理(標準化、PCA、特徵選擇、缺值填補、SMOTE 都在 train 上 fit);嚴格時間順序(永遠是過去 → 未來);分層抽樣保留類別比例(stratify,同樣先切再處理);最終 test 只碰一次;用 Pipeline 把所有前處理包起來,確保每個 fold 都乾淨。
為什麼研究生特別容易犯:講義列了四個原因。表面看起來很合理,程式能跑、分數還很高,所以不會立刻察覺;評分指標會騙你,有洩漏時指標異常好看;工具的預設操作(先特徵工程再切、用整份資料做 normalization)很容易無意間造成洩漏;時間壓力和經驗不足,急著改模型架構,卻忽略最基本的資料管線。講義說很多論文被拒的主因就在這裡。
訓練要從一組權重開始。全部設成 0 最省事,但講義的第一個問題就是:W = 0 會怎樣?答案是每個神經元得到同樣的輸出、同樣的梯度、同樣的更新,完全學不到東西。隨機設也不夠,隨機的「大小」決定訊號穿過很多層之後還剩多少。下面是一個真的在算的 8 層全連接網路,每層 256 個神經元,丟進 128 筆隨機輸入,畫出每一層 activation 的分佈。
全零的陷阱:所有權重相同時,同一層的每個神經元算出一樣的輸出,backprop 給它們一樣的梯度,更新完還是一樣。講義的原句:same output, same gradient, same update, no learning at all。只要權重是常數(不一定是 0),對稱就打不破,所以一定要隨機。
為什麼要除以 √n:一個神經元的輸出是 Y = W₁X₁ + … + WₙXₙ。如果權重和輸入彼此獨立、平均為 0,
講義的說法是:保持輸入和輸出的方差一致,避免所有輸出值都趨向 0。這就是 Xavier(Glorot)初始化:權重 = N(0,1) / √n。這個推導假設 activation 在 0 附近是線性的,tanh 符合(講義特別標註「tanh 的線性區」)。
He 初始化:ReLU 把負的一半全部變成 0,講義的註解是「half of the neuron is killed in ReLU」,方差每層少一半。補償的方法是讓 Var(W) = 2/n,也就是多乘 √2。講義的結論:ReLU(例如 CNN)用 He;tanh、線性這類接近對稱的 activation,以及 Transformer,常用 Xavier。
其他方法:用 autoencoder 做 pre-training 來初始化,現在已經不用了;現在最常見的是拿一個訓練好的模型(pre-trained model)當起點,再 fine-tune。講義的 TLDR:核心目標是讓訊號與梯度在層間保持合適的方差,避免消失或爆炸;好的初始化能縮短 warmup、減少不必要的正規化負擔,讓深網路更可訓練。為什麼「初始化」本身是一個研究問題?因為它和 activation、normalization(B4 的 Batch Norm)、residual connection 綁在一起,換了其中一個,最好的初始化就跟著變。
這個模組最常被講錯的幾句話。