30 天把 Breakout DQN 做成可重現、可比較、可部署的強化學習工程專案

30 天把 Breakout DQN 做成可重現、可比較、可部署的強化學習工程專案

從 Atari Breakout 與 DQN 出發,整理我在 30 天鐵人賽中如何把強化學習實驗一路做成可重現、可比較、可部署的 ML Engineering 專案。

我完成了這次 30 天的鐵人賽。

這次我選擇的主題不是單純「用 DQN 玩 Breakout」,而是希望把一個強化學習專案,從實驗階段一路做到接近真正軟體專案的形式。

因此整個系列的核心問題其實是:

如果今天不是只想讓 Agent 學會玩遊戲,而是希望建立一套可重現、可比較、可部署的強化學習工程流程,我需要解決哪些問題?

整個專案最後不只包含訓練程式,也一路延伸到實驗管理、評估流程、模型匯出、ONNX inference、Web Demo 與 Docker。

從一個 DQN 開始

專案以 Atari Breakout 為實驗環境。

最初的目標很單純:建立一個能夠正常訓練的 DQN Agent。

但實際開始之後,很快就會發現,真正困難的部分不只是神經網路本身。

例如:

  • Atari 環境與 ALE 的設定
  • Frame preprocessing 與 frame stacking
  • Replay Buffer
  • Online Network 與 Target Network
  • Exploration strategy
  • Training stability
  • Random seed 與 reproducibility
  • Evaluation protocol
  • Checkpoint 管理

這些東西任何一個地方出錯,都有可能讓實驗結果失去意義。

因此,我開始把這個專案從「能跑」逐漸改造成「能夠被驗證」。

從 DQN 延伸到不同演算法

在建立基礎 DQN 後,我進一步實作與比較不同的改進方法。

包含:

  • DQN
  • Double DQN
  • Dueling DQN
  • 不同 Replay Buffer / sampling 方法
  • 不同超參數與訓練策略

這個過程讓我真正理解很多原本只存在於公式裡的概念。

例如 Double DQN 解決的並不是單純「增加一個 Network」,而是把 Action Selection 與 Action Evaluation 拆開,降低 Q-value overestimation。

而 Dueling DQN 則把 State Value 與 Action Advantage 分開建模,讓模型在「很多 action 差異不大的 state」下,也能更有效率地學習。

比起只閱讀論文,真正實作、訓練、失敗、重新分析結果之後,對這些方法的理解深很多。

Reproducibility 比我原本想像得更重要

這次專案另外一個很大的收穫,是重新認識「實驗可重現性」。

在強化學習裡,即使只改變 random seed,都可能得到非常不同的 learning curve。

因此,只看單次最高分其實很容易得出錯誤結論。

我開始更注意:

  • 固定 random seed
  • 保存 experiment configuration
  • 分離 training 與 evaluation
  • 記錄 episode reward
  • 比較不同 runs
  • 保留 checkpoint
  • 確保實驗條件一致

這也讓這個專案逐漸從「模型實驗」變成比較完整的 ML Engineering workflow。

對我來說,這也是整個鐵人賽很重要的一個轉折:我開始關心的不再只是「這次分數是多少」,而是「這個結果能不能被重新產生、能不能公平比較、能不能知道改了什麼才造成差異」。

不只訓練模型,也把模型真正部署出去

我不希望專案最後停在一個 .pt checkpoint。

因此後期也進一步處理模型部署流程,包括:

  • 模型 export
  • ONNX inference
  • Web Demo
  • Docker
  • 專案結構整理
  • inference pipeline

最後的目標,是讓訓練完成的 Agent 不只是存在 notebook 或 Python script 裡,而是真的可以被其他人執行與展示。

你可以直接在這裡查看目前的 Demo:

breakout.tommypan.dev

這也是我這次鐵人賽最想探索的一件事情:

Machine Learning 專案真正困難的部分,往往不只是在模型本身,而是在如何讓實驗、程式碼與模型成為一個完整系統。

從「演算法作業」變成 ML Engineering 專案

如果只看最前面的版本,這個專案其實很像一份典型的強化學習作業:建立環境、寫 DQN、開始 train,最後看 reward。

但我更想練習的是後面的部分。

一個真正可持續開發的 ML 專案,需要的不只是模型本身,還包括:

  1. 可重現的實驗設定:知道每一次 run 用的是什麼環境、seed、超參數與模型版本。
  2. 一致的評估方式:不能每次都用不同條件判斷模型好壞。
  3. 清楚的程式結構:training、evaluation、model、environment 與 deployment 不應全部混在同一支 script。
  4. 可保存與可交換的模型產物:checkpoint 必須能被重新載入,甚至轉換到其他 inference runtime。
  5. 真正能被使用的展示方式:因此我後來加入 ONNX、Web Demo 與 Docker。

這些工作不一定像換一個新演算法一樣顯眼,但它們決定了一個模型專案能不能繼續被維護、比較與部署。

30 天之後,我最大的收穫

完成這個系列後,我認為最大的收穫並不是「我學會 DQN」。

而是完整走過一次:

Problem → Experiment → Implementation → Evaluation → Debugging → Reproducibility → Deployment

的流程。

在這 30 天裡,我也更清楚地感受到,自己真正有興趣的方向不是只研究單一模型,而是 AI / ML Engineering:

如何把模型、資料、實驗、軟體工程與部署整合成真正能運作的系統。

這個 Breakout 專案不會因為 30 天鐵人賽結束就停止。

接下來我仍會繼續加入新的實驗、改善訓練流程,並嘗試更多強化學習方法,也會繼續把「實驗是否公平、結果是否可重現、模型是否能實際部署」當成專案的一部分,而不只是把它當成一份一次性的模型實驗。

專案連結