interview / train_all.sh
Lee93whut
chore: initial project scaffold
141a818
#!/usr/bin/env bash
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
# train_all.sh โ€” ไธ€้”ฎๅนถ่กŒๅฏๅŠจๅ››็ป„ DQN ็ฎ—ๆณ•ๅฏนๆฏ”ๅฎž้ชŒ๏ผˆtmux ๅคš็ช—ๅฃ๏ผ‰
#
# ็”จๆณ•๏ผš
# chmod +x train_all.sh && ./train_all.sh
#
# ไพ่ต–๏ผš
# - tmux๏ผˆbrew install tmux / apt install tmux๏ผ‰
# - ๅทฒๆฟ€ๆดป็š„ Python ่™šๆ‹Ÿ็Žฏๅขƒ๏ผˆๅ†…ๅซ torch / gymnasium / tensorboard ็ญ‰๏ผ‰
#
# ไบง็‰ฉ๏ผš
# logs/train_<algo>.log โ€”โ€” ๅ„็ฎ—ๆณ•ๅฎŒๆ•ด่ฎญ็ปƒๆ—ฅๅฟ—
# runs/<algo>_<ts>/ โ€”โ€” TensorBoard ไบ‹ไปถๆ–‡ไปถ
# results/best_model_<algo>.pth โ€”โ€” ๅ„็ฎ—ๆณ•ๆœ€ไผ˜ๆƒ้‡
#
# ๆŸฅ็œ‹่ฟ›ๅบฆ๏ผš
# tmux attach -t maze_train # ๅœจๅ„ pane ไน‹้—ด Ctrl+b โ†’ ๆ–นๅ‘้”ฎๅˆ‡ๆข
# tensorboard --logdir=runs # http://localhost:6006
# โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
set -euo pipefail
SESSION="maze_train"
ALGOS=("vanilla" "double" "dueling" "double_dueling")
SCRIPT="src/train.py"
CONFIG="config.yaml"
LOG_DIR="logs"
# โ”€โ”€ ๆฃ€ๆŸฅไพ่ต– โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
command -v tmux >/dev/null 2>&1 || { echo "[ERROR] tmux ๆœชๅฎ‰่ฃ…"; exit 1; }
command -v python >/dev/null 2>&1 || { echo "[ERROR] python ๆœชๆ‰พๅˆฐ"; exit 1; }
[[ -f "$SCRIPT" ]] || { echo "[ERROR] ๆ‰พไธๅˆฐ $SCRIPT๏ผŒ่ฏทๅœจ้กน็›ฎๆ น็›ฎๅฝ•ๆ‰ง่กŒๆœฌ่„šๆœฌ"; exit 1; }
[[ -f "$CONFIG" ]] || { echo "[ERROR] ๆ‰พไธๅˆฐ $CONFIG"; exit 1; }
mkdir -p "$LOG_DIR" results runs
# โ”€โ”€ ๆ€ๆญปๅŒๅๆ—ง session๏ผˆ้ฟๅ…็ซฏๅฃ/ๆ–‡ไปถๅ†ฒ็ช๏ผ‰โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
tmux kill-session -t "$SESSION" 2>/dev/null || true
# โ”€โ”€ ๅˆ›ๅปบๆ–ฐ session๏ผˆๅŽๅฐ๏ผŒๆ— ้™„ๅŠ ๏ผ‰โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
tmux new-session -d -s "$SESSION" -x 220 -y 50
for i in "${!ALGOS[@]}"; do
ALGO="${ALGOS[$i]}"
LOG_FILE="${LOG_DIR}/train_${ALGO}.log"
CMD="python ${SCRIPT} --config ${CONFIG} --algorithm ${ALGO} \
2>&1 | tee ${LOG_FILE}; echo '[DONE] ${ALGO} ่ฎญ็ปƒ็ป“ๆŸ'; exec bash"
if [[ $i -eq 0 ]]; then
# ็ฌฌไธ€ไธช็ฎ—ๆณ•ๅค็”จๅˆๅง‹ pane๏ผˆwindow 0๏ผ‰
tmux send-keys -t "${SESSION}:0" "$CMD" Enter
else
# ๅŽ็ปญ็ฎ—ๆณ•ๅ„ๅผ€ไธ€ไธชๆ–ฐ window
tmux new-window -t "${SESSION}"
tmux send-keys -t "${SESSION}:${i}" "$CMD" Enter
fi
# ็ป™ๆฏไธช window ๅ–ๆœ‰ๆ„ไน‰็š„ๅๅญ—
tmux rename-window -t "${SESSION}:${i}" "$ALGO"
done
echo "============================================================"
echo " โœ… ๅทฒๅœจ tmux sessionใ€Œ${SESSION}ใ€ไธญๅฏๅŠจ ${#ALGOS[@]} ็ป„ๅฎž้ชŒ"
echo ""
echo " ๆŸฅ็œ‹่ฟ›ๅบฆ๏ผštmux attach -t ${SESSION}"
echo " ็ช—ๅฃๅˆ‡ๆข๏ผšCtrl+b โ†’ ๆ•ฐๅญ—้”ฎ๏ผˆ0~$((${#ALGOS[@]}-1))๏ผ‰"
echo " ๅˆ†็ฆปไผš่ฏ๏ผšCtrl+b d"
echo ""
echo " ๅฎžๆ—ถๆ—ฅๅฟ—๏ผštail -f logs/train_<algo>.log"
echo " TensorBoard๏ผštensorboard --logdir=runs"
echo "============================================================"