---
# System prepended metadata

title: 深度學習導論MLP報告資工四411121273鄭宇翔

---

# 深度學習導論報告--Function Approximation Using Multilayer Perceptron
> *資工四 411121273 鄭宇翔*
> 下表是我在kaggle上的名稱與帳號
> ![SCR-20260106-eily](https://hackmd.io/_uploads/SJMBY9FVZe.png)

> 
### 1. 目標
本次作業希望我們利用教授提供的資料集，設計並訓練一個MLP模型，擬合一個「二輸入、一輸出」的回歸問題。

---

### 2. 訓練與預測
訓練 與 預測兩個步驟我分別撰寫為檔案 train 與 pre，
由於教授特別在kaggle上說明***not including the data files***，所以壓縮檔中只包含了:
1. train.py
2. pre.py
3. REPORT_LINK.txt

沒有包括下面報告中用到的圖表、模型以及教授給定的三個csv檔案。

**執行方式**:
分爲兩步驟
1. 執行train.py 
-> 會讀取訓練集，訓練並產生五個模型檔案

2. 執行pre.py 
-> 會讀取測試集，讀取訓練好的五個模型做預測 
-> 生成預測結果result.csv檔案


### 2.1 模型設計
#### 2.1.1 人工特徵工程
在訓練初期，我嘗試單純透過增加 MLP 的深度與複雜度來提升效能，但在大量的參數調整後，我發現模型在測試集的表現遭遇瓶頸（kaggle上的分數），此外因為教授提供的資料集是有限的，如果一味的增加模型的複雜度會擔心發生維度災難的問題讓模型無法學習到高維空間的流形，因此我希望可以增加一些人工的特徵工程，來幫助模型做擬合：

* **數據視覺化**
資料集為三維資料（輸入 $x_1, x_2$，輸出 $y$），剛好可以用簡單的程式碼將資料點繪製於三維空間中進行觀察，如下圖所示。

![圖片 1](https://hackmd.io/_uploads/B1iWdEYVWg.png)
![Figure_1](https://hackmd.io/_uploads/Sy8fuEKNbl.png)
![2](https://hackmd.io/_uploads/BkhG_4t4Wg.png)


* **觀察圖形**
  透過視覺化，我發現資料在空間中呈現**波形結構**，且從俯視角度觀察，資料分佈呈現**圓形**。

* **特徵工程**
  基於上述觀察，我引入了人工特徵工程，將輸入維度由原本的 **2 維擴展至 6 維**。
    擴展後的特徵向量定義如下：
    $$
    \mathbf{x}' = \begin{bmatrix} 
    x_1 \\ 
    x_2 \\ 
    \sqrt{x_1^2 + x_2^2} \\ 
    x_1^2 + x_2^2 \\ 
    \sin(6 \cdot (x_1^2 + x_2^2)) \\ 
    \cos(6 \cdot (x_1^2 + x_2^2)) 
    \end{bmatrix}
    $$

  包含：
  1.**原始特徵**
  2.**圓形幾何特徵**：徑向分佈
  3.**波動特徵**：sin與cos函數，兩者常數項設定為 **6**，此數值是經過多次訓練後，實驗得出的最佳超參數，如下圖所示，當k=6時，驗證MSE最低，如下圖所示：
   ![k](https://hackmd.io/_uploads/rkGQUtK4-g.png)


* **有特徵工程 vs 沒有特徵工程**
下圖為在固定模型架構與隨機種子的前提下，有無特徵工程對模型訓練MSE loss下降的影響：
![feature](https://hackmd.io/_uploads/r1i-ZKtVWl.png)

從圖中我們可以觀察到：
1. 加入人工特徵工程的模型（藍線）相較之下原始特徵模型（紅線），收斂速度更快。

2. 訓練結束後，特徵工程組的MSE下降到 0.02244，小於原始特徵組的 0.02970，可以證明加入特徵工程後的模型突破了原始維度下的特徵瓶頸。

---

#### 2.1.2 神經網路架構
為了有效提取特徵並進行回歸預測，我設計了如下的網路架構：

* **層數與神經元數：**
  $$Input(6) \rightarrow 256 \rightarrow 128 \rightarrow 64 \rightarrow Output(1)$$
  
* **激活函數**：
  激活函數我選擇的是**SiLU**。
  雖然在課程中ReLU是範例經常提到的選擇，但經過在kaggle上的跑分與在實驗中針對驗證集loss的比較，我發現SiLU相較於ReLU能讓模型表現有些微的提升，從loss下降歷史，我們也可以觀察到SiLU可以收斂到的loss比ReLU更低，兩者的比較如下圖所示：
  ![si vs re](https://hackmd.io/_uploads/SyzGE9tEbx.png)

雖然我設計的模型沒有到很深，但我猜測可能仍有輕微的梯度消失問題，因此選用SiLU可以改善ReLU產生的梯度消失問題。

* **正規化**：
  在每一層加入 **Batch Normalization**，確保輸入分佈穩定。
  
下圖為模型整體架構：
![SCR-20260105-thpr](https://hackmd.io/_uploads/HkJnYBKVbl.jpg)

---

#### 2.1.3 優化器與學習策略
* **優化器**：
  我使用課程中提過的 **Adam** 優化器，並搭配 **Weight Decay** 正規化，防止過擬合，雖然觀察loss圖表，實驗中似乎沒有發生過擬合現象，但是加入正規化方法後，模型在kaggle上的表現有所提升。

* **學習率調整**：
  在訓練過程中我觀察到Loss曲線容易在低點附近震盪，這通常是因為學習率過大導致無法下降到山谷的最底部。因此我們希望當Loss停滯不前時，程式可以降低學習率，使模型能夠更好的收斂到局部最小值。

* **K-fold方法**：
  採用 **5-Fold交叉驗證**，確保模型的評分結果有良好的穩定性。
  
* **評估指標**
    報告中的圖表與模型性能評估我以MSE作為指標，因為Kaggle平台是用MSE作為評分標準。

---
### 2.2 預測
* 因為教授給定的測試集仍是二輸入，但我們訓練的模型因有人工特徵工程，將輸入擴充為6維輸入，因此在預測時，我們使用同樣需將測試資料擴充為6維。

* 此外為了讓預測結果更準確且穩定，我將交叉驗證中訓練出來的 **5個模型** 全部拿來做預測。

**具體的預測流程如下：**
* 1.  **載入模型**：
    我們依序讀取之前存檔的 5 個模型檔案。
* 2.  **個別預測**：
    先用對應的Scaler將測試資料標準化，再丟入模型進行預測。
* 3.  **取平均值**：
    將這5個模型的預測結果取平均值，作為最終提交給Kaggle的答案。
    
![SCR-20260105-tihv](https://hackmd.io/_uploads/BJ8aTHFNZx.jpg)


### 2.3 程式訓練與預測流程圖
![SCR-20260105-tmnj](https://hackmd.io/_uploads/rJ-PhHKVZg.jpg)

---

### 3. 實驗成果
下圖為5-fold的五次訓練集與驗證集loss曲線圖，SEED設定為4419，可以觀察到訓練與驗證兩條曲線最終都收斂到一個穩定的數值，且驗證loss沒有在訓練末段發生上升趨勢，表示模型沒有過擬合的情況發生，此外這五個模型經預測後平均產生的預測結果，在kaggle平台上的公開測試分數為0.00651，私榜在作業截止前尚未公開因此無法得知。


![loss](https://hackmd.io/_uploads/SJjBkHY4Zx.png)

---

### 4. 心得與反思
#### 4.1 遇到的困難：
##### 4.1.1 版本控制
一開始由於沒有經驗，模型經過多次修改與參數調整，我經常發現 改版後 的模型有時不如 改版前。然而，由於沒有做好版本控制與備份，導致無法輕易回退到之前表現較好的版本，許多跑出高分的實驗設定因此遺失。
此外在測試時，我發現相同的程式碼與超參數設定用不同的種子碼下去跑出來的結果截然不同，因此可能好不容易跑出一個好結果的種子碼，因為沒有良好的版本管理導致同樣也導致結果無法重現。因此有慘痛的教訓後，我只要測出更好的模型，就會將資料進行備份。

##### 4.1.2 kaggle公私榜
因為kaggle上的分數並不代表最後截止時的分數，因此在大量提交並根據Public跑分結果來修改模型的過程，也讓我擔心是否把公榜壓到很低的誤差，反而可能讓私榜變差。

##### 4.1.3 過高的自由度
以往的課程作業通常會給我們固定的測資與固定的目標，或是給定一個程式框架，讓我們完成裡面其中一個funtion，但這次深度學習的作業透過kaggle競賽的方式，需要從0開始建構自己的模型，一方面讓我們可以充分發會課程中所學到的技巧也可以將自己的創意融入模型中，但同時沒有固定的評分標準也提升了作業的難度。

#### 4.2 學到了什麼？
在課程中，教授講述了不同的訓練方法、優化器、模型架構等原理與技巧，透過這次作業，我能將課程中所學到的知識應用到實務中，也能透過反覆修改模型與更改方法來體驗到不同設定之間模型會如何改變，講義中所描述的問題也都能在反覆修改與訓練中漸漸被驗證。

此外，我也深刻體會到在資料有限且模型不能太複雜的情況下，特徵工程對模型性能的影響，在沒有加入特徵工程的情況下，不管我怎麼調整超參數與模型，在kaggle平台上的分數都不太會有進步，但加入特徵工程後，我觀察到模型的準確度與分數有了顯著提升。

這次作業不僅提升了我對經典MLP神經網路的認識，也透過親自搭建模型並預測，將課程中所學到的技巧融入實作中，也在過程中發現模型不是越大越複雜越好，而是不同訓練方法、優化器與學習策略之間的配合及有耐心的調整參數，才能逐步提升模型的穩定性與預測表現。透過本次作業，我也更理解深度學習中理論與實作之間的差異，也體會到反覆實驗與觀察結果在模型訓練中的重要性。