MOAI 2025 備考完全指南:從理論基石到實戰巔峰

這份指南由國際人工智慧奧林匹克(IOAI/MOAI)金牌教練與技術架構師精心編寫。IOAI 個人賽是一項極高強度的挑戰,要求參賽者在為期兩天、每天六小時的現場賽中,針對複雜數據進行建模。本手冊旨在幫助參賽者在「Bohrium 平台」與「受限網路環境」下,轉化理論為本能,掌握奪冠所需的技術精度與戰術深度。


先看這張表

你現在要準備什麼先看哪一節
想知道比賽時怎樣快速建 baseline第 1 節
想補理論與公式第 2 節
想安排 6 小時作戰節奏第 3 節
想記住常用程式模板第 4 節

1. 編程實戰題(Kaggle 模式)提示詞指南

1.1 模擬「白名單環境」下的解題邏輯

在 IOAI 現場賽中,參賽者僅能訪問 scikit-learn.org 等白名單文檔。在無法依賴外部搜尋引擎或高級 LLM(僅限平台內置緊湊型模型)的情況下,必須內化標準化建模流程。

監督式學習標準化流程清單(Syllabus 規範):

階段建議做法短例子
數據預處理使用 StandardScalerMinMaxScalerscaler.fit_transform(X)
模型訓練先用 RandomForestClassifier 建 baselineRandomForestClassifier()
延伸模型準備 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 的轉換器以保證訓練與預測的一致性。

函數/方法名稱語法範例適用場景與差異解釋
SimpleImputerimputer.fit_transform(X)缺失值處理。支持均值、中位數或眾數填充。
OneHotEncoderohe.fit_transform(X)無序類別變量。建議在 Pipeline 中使用,比 get_dummies 更容易處理預測時出現的新類別。
LabelEncoderle.fit_transform(y)目標標籤編碼。專用於將 Target yy 轉為整數,不可用於特徵 XX
get_dummiespd.get_dummies(df)快速 EDApandas 內置,適合在初步探索階段快速查看類別特徵分佈。
OrdinalEncoderoe.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 第一日(紙筆輪)的核心。維度不對齊是神經網絡實作與反向傳播失敗的首要原因。

核心計算公式: O=IK+2PS+1O = \lfloor \frac{I - K + 2P}{S} \rfloor + 1 其中 II 為輸入尺寸、KK 為卷積核大小、SS 為步長、PP 為填充(Padding)。

實戰計算案例: 假設輸入尺寸 I=224I = 224,卷積核 K=3K=3,步長 S=2S=2,填充 P=1P=1

  1. 計算有效輸入長度:2243+2(1)=223224 - 3 + 2(1) = 223
  2. 應用步長除法:223/2=111.5223 / 2 = 111.5
  3. 取地板函數值(Floor):111.5=111\lfloor 111.5 \rfloor = 111
  4. 加上最終偏移量:111+1=112111 + 1 = 112
  5. 結論: 輸出維度為 112×112112 \times 112
已知條件數值
輸入尺寸 I224
卷積核 K3
步長 S2
Padding P1
輸出尺寸 O112

維度對齊與反向傳播 (Backpropagation): 在神經網絡中,維度對齊不僅是為了前向傳播,更是為了矩陣乘法的求導規則。在反向傳播中,權重梯度 LW\frac{\partial L}{\partial W} 的計算依賴於誤差項 δ\delta 與前層輸入 XX 的外積(LW=δXT\frac{\partial L}{\partial W} = \delta \cdot X^T)。如果張量維度未嚴格對齊,鏈式法則(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)

為避免手動打包遺漏文件或包含多餘數據,請準備以下自動化腳本。該腳本具備邏輯檢查功能,會自動過濾 datadatasets 等大文件夾。

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 的賽場上精確出擊。

Built with LogoFlowershow