MOAI 2025 備考完全指南:從理論基石到實戰巔峰
MOAI 2025 備考完全指南:從理論基石到實戰巔峰
這份指南由國際人工智慧奧林匹克(IOAI/MOAI)金牌教練與技術架構師精心編寫。IOAI 個人賽是一項極高強度的挑戰,要求參賽者在為期兩天、每天六小時的現場賽中,針對複雜數據進行建模。本手冊旨在幫助參賽者在「Bohrium 平台」與「受限網路環境」下,轉化理論為本能,掌握奪冠所需的技術精度與戰術深度。
先看這張表
| 你現在要準備什麼 | 先看哪一節 |
|---|---|
| 想知道比賽時怎樣快速建 baseline | 第 1 節 |
| 想補理論與公式 | 第 2 節 |
| 想安排 6 小時作戰節奏 | 第 3 節 |
| 想記住常用程式模板 | 第 4 節 |
1. 編程實戰題(Kaggle 模式)提示詞指南
1.1 模擬「白名單環境」下的解題邏輯
在 IOAI 現場賽中,參賽者僅能訪問 scikit-learn.org 等白名單文檔。在無法依賴外部搜尋引擎或高級 LLM(僅限平台內置緊湊型模型)的情況下,必須內化標準化建模流程。
監督式學習標準化流程清單(Syllabus 規範):
| 階段 | 建議做法 | 短例子 |
|---|---|---|
| 數據預處理 | 使用 StandardScaler 或 MinMaxScaler | scaler.fit_transform(X) |
| 模型訓練 | 先用 RandomForestClassifier 建 baseline | RandomForestClassifier() |
| 延伸模型 | 準備 SVC 覆蓋 SVM 考點 | SVC() |
| 評估與調優 | 用 Cross-validation 檢查泛化能力 | cross_val_score(...) |
離線環境 API 查詢技巧: 當文檔訪問不便時,請利用 Python 內置函數進行「自救」:
| 方法 | 用途 | 小提醒 |
|---|---|---|
help(EstimatorName) | 查參數與用法 | 適合忘記 max_depth 這類參數時使用 |
dir(fitted_model) | 看模型訓練後有哪些屬性 | 常用來找 feature_importances_ |
1.2 數據清理與特徵工程(不聯網策略)
在離線環境下,熟練 API 簽名(Signature)是防止開發中斷的唯一方法。特別注意:在 inference.py 中,應優先選擇 Scikit-learn 的轉換器以保證訓練與預測的一致性。
| 函數/方法名稱 | 語法範例 | 適用場景與差異解釋 |
|---|---|---|
SimpleImputer | imputer.fit_transform(X) | 缺失值處理。支持均值、中位數或眾數填充。 |
OneHotEncoder | ohe.fit_transform(X) | 無序類別變量。建議在 Pipeline 中使用,比 get_dummies 更容易處理預測時出現的新類別。 |
LabelEncoder | le.fit_transform(y) | 目標標籤編碼。專用於將 Target 轉為整數,不可用於特徵 。 |
get_dummies | pd.get_dummies(df) | 快速 EDA。pandas 內置,適合在初步探索階段快速查看類別特徵分佈。 |
OrdinalEncoder | oe.fit_transform(X) | 有序類別變量。適用於有等級關係(如:等級 A > B > C)的特徵。 |
短例子:
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy="median")
X_num = imputer.fit_transform(X_num)
2. 理論與計算題備考專區(佔分 25-30%)
2.1 卷積神經網絡 (CNN) 維度推導實戰
維度推導是 IOAI 第一日(紙筆輪)的核心。維度不對齊是神經網絡實作與反向傳播失敗的首要原因。
核心計算公式: 其中 為輸入尺寸、 為卷積核大小、 為步長、 為填充(Padding)。
實戰計算案例: 假設輸入尺寸 ,卷積核 ,步長 ,填充 。
- 計算有效輸入長度:。
- 應用步長除法:。
- 取地板函數值(Floor):。
- 加上最終偏移量:。
- 結論: 輸出維度為 。
| 已知條件 | 數值 |
|---|---|
輸入尺寸 I | 224 |
卷積核 K | 3 |
步長 S | 2 |
Padding P | 1 |
輸出尺寸 O | 112 |
維度對齊與反向傳播 (Backpropagation): 在神經網絡中,維度對齊不僅是為了前向傳播,更是為了矩陣乘法的求導規則。在反向傳播中,權重梯度 的計算依賴於誤差項 與前層輸入 的外積()。如果張量維度未嚴格對齊,鏈式法則(Chain Rule)將無法執行。
3. 奪冠戰術:6 小時全時程控管
3.1 六小時編程挑戰(Bohrium 平台實施計畫)
IOAI 個人賽每天長達 6 小時。雖然時長充足,但考慮到 24GB RAM 的限制與 歸一化評分機制(Score Normalized against Best Solution),效率與穩定性同樣重要。
開發時程表:
| 時間 | 要做什麼 | 重點 |
|---|---|---|
00:00 - 00:30 | 高效 EDA | 檢查數據一致性,觀察 Bohrium I/O 速度 |
00:30 - 01:00 | 建立 Baseline | 先做出一個能提交的 inference.py |
01:00 - 04:30 | 核心模型迭代 | 嘗試集成樹模型、SVM、特徵工程 |
04:30 - 05:30 | 模型集成與穩定化 | 整合不同模型結果 |
05:30 - 06:00 | 打包與驗證 | 最後完整測試一次 |
Bohrium 生存技巧: 24GB RAM 對於大型數據集非常吃緊。必須養成隨手清理內存的習慣:
import gc
del massive_dataframe
gc.collect() # 強制回收內存,防止 Kernel 崩潰
3.2 最後 30 分鐘:數據與模型打包檢查清單
- inference.py: 檢查是否包含所有自定義類別,且不依賴外部 API 或白名單外的庫。
- model.pth / model.joblib: 確認模型權重已正確導出。
- submission.csv: 格式必須與範例完全一致。
- 無網路運行驗證: 重啟 Kernel 並在不聯網狀態下完整運行一遍
inference.py。
4. Wing 的備考策略 (Preparation Strategy)
4.1 建立「代碼肌肉記憶」:Emergency Manual
在受限環境中,查閱文檔會浪費大量時間。請透過「盲寫(Blind Coding)」將以下代碼塊轉化為肌肉記憶。
| 模板 | 你要記住什麼 |
|---|---|
| PyTorch DataLoader | 資料怎樣分 batch 與 shuffle |
| GridSearchCV | 如何做交叉驗證調參 |
| Matplotlib | 怎樣快速看資料分佈 |
1. PyTorch DataLoader (深度學習核心):
from torch.utils.data import DataLoader
loader = DataLoader(dataset, batch_size=32, shuffle=True, num_workers=2)
2. Scikit-learn GridSearchCV (自動調參):
from sklearn.model_selection import GridSearchCV
param_grid = {'n_estimators': [100, 200], 'max_depth': [None, 10, 20]}
grid = GridSearchCV(RandomForestClassifier(), param_grid, cv=5, scoring='f1')
3. Matplotlib EDA (視覺化觀察):
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.hist(df['target']); plt.title('Distribution'); plt.show()
4.2 自動化打包腳本 (The Submission Path)
為避免手動打包遺漏文件或包含多餘數據,請準備以下自動化腳本。該腳本具備邏輯檢查功能,會自動過濾 data 或 datasets 等大文件夾。
import zipfile
import os
def package_submission(zip_name='submission.zip'):
# 定義必須包含的文件
required_files = ['inference.py', 'model.pth', 'requirements.txt']
# 定義要排除的關鍵字(如原始數據集)
excluded_keywords = ['data', 'dataset', 'tmp', '__pycache__']
with zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk('.'):
# 邏輯過濾:跳過包含特定關鍵字的目錄
if any(key in root.lower() for key in excluded_keywords):
continue
for file in files:
if file in required_files or file.endswith('.py'):
file_path = os.path.join(root, file)
zipf.write(file_path, arcname=file)
print(f"Successfully added: {file_path}")
if __name__ == '__main__':
package_submission()
最後速記
| 類型 | 一句話提醒 |
|---|---|
| Baseline | 先求能跑,再求高分 |
| 理論題 | 維度、公式、推導要穩 |
| 比賽策略 | 第 1 小時先拿保底分 |
| 打包 | 重啟後完整跑一次 |
結語: 金牌選手與普通選手的差別,在於對底層理論(維度對齊與微積分)的透徹理解,以及對實戰限制(內存管理與離線 API)的優雅應對。祝你在 IOAI 2025 的賽場上精確出擊。