Darknet YOLO 入坑手冊
Darknet YOLO 入坑手冊
電腦視覺物件偵測實戰課程
Oliver's Tech Workshop 2025
今日議程
- 🎯 電腦視覺與物件偵測簡介
- 🧠 機器學習與神經網路基礎
- 🚀 YOLO 技術原理與最新發展
- 💻 開發環境建置 (CUDA/Docker)
- 🔧 實戰訓練流程 (PyTorch & Darknet)
- 📱 部署到邊緣設備 (Ameba Pro2)
- 🛠️ 故障排除與最佳化技巧
第一章:電腦視覺基礎
什麼是物件偵測?

核心任務
- 🔍 定位 (Localization) - 找出物體在哪裡
- 🏷️ 分類 (Classification) - 判斷物體是什麼
- 📦 邊界框 (Bounding Box) - 框出物體範圍
- 📊 置信度 (Confidence) - 預測的可信度
YOLO 家族演進 (2025更新)
| 版本 | 特點 | 年份 | mAP | 速度 |
|---|---|---|---|---|
| YOLOv1 | 開創性的實時檢測 | 2016 | 63.4% | 45 FPS |
| YOLOv3 | Darknet-53, 多尺度預測 | 2018 | 55.3% | 20 FPS |
| YOLOv4 | CSPDarknet53, Mish激活 | 2020 | 65.7% | 65 FPS |
| YOLOv5 | PyTorch實現, 輕量化 | 2020 | 68.9% | 140 FPS |
| YOLOv7 | 可訓練的包袋式自注意力 | 2022 | 69.7% | 161 FPS |
| YOLOv8 | 統一框架, 多任務 | 2023 | 68.2% | 280 FPS |
| YOLOv9 | PGI + GELAN架構 | 2024 | 70.4% | 104 FPS |
| YOLOv10 | 實時檢測最佳化 | 2024 | 71.2% | 300+ FPS |
為什麼選擇 YOLO?
🚀 速度優勢
- 實時處理: 30+ FPS
- 端到端: 單一神經網路
- 推理快速: 適合邊緣計算
🎯 精度提升
- 多尺度特徵: 檢測大小物體
- 豐富的增強: 資料增強策略
- 損失函數: 針對檢測任務優化
🛠️ 易用性
- 生態成熟: 大量預訓練模型
- 文檔完善: 豐富的學習資源
- 社群活躍: 持續更新維護
第二章:前置準備
學習路線圖
graph TD A[YOLO前置準備] --> B[硬體準備] A --> C[軟體環境] A --> D[知識基礎]
B --> E[GPU/NPU]
B --> F[CUDA/cuDNN]
C --> G[Linux/Docker]
C --> H[Python/PyTorch]
D --> I[神經網路]
D --> J[深度學習]</div>
硬體需求
基本配置
- CPU: i5 以上
- RAM: 16GB+
- GPU: NVIDIA GTX 1060+
推薦配置
- CPU: i7/i9 或 AMD Ryzen 7/9
- RAM: 32GB+
- GPU: RTX 3060+ (12GB VRAM)
GPU vs NPU
| 類型 | 優點 | 缺點 |
|---|---|---|
| GPU | 通用性強、生態完整 | 功耗高、成本高 |
| NPU | 專為AI優化、低功耗 | 生態受限、彈性較低 |
💡 沒有GPU也能學習!可使用:
- Google Colab (免費GPU)
- Kaggle Kernel
- 雲端服務 (AWS, GCP)
第三章:機器學習基礎
什麼是機器學習?
定義
讓電腦從數據中自動學習規律,而無需明確編程
三大類型
- 監督式學習 - 有標註數據 (分類、回歸)
- 非監督式學習 - 無標註數據 (聚類、降維)
- 強化學習 - 透過獎懲機制學習 (遊戲、機器人)
物件偵測屬於監督式學習
- 需要標註的邊界框
- 需要物體類別標籤
- 使用損失函數優化
神經網路 (NN)

基本概念
- 神經元: 最基本的計算單元
- 權重: 控制輸入的重要性
- 激活函數: 增加非線性能力
- 反向傳播: 調整權重的方法
卷積神經網路 (CNN)
為什麼要用 CNN?
- 🖼️ 空間不變性: 位置改變不影響識別
- 🔍 局部感受野: 關注局部特徵
- 📉 參數共享: 減少參數數量
- 🎯 平移不變性: 特徵可以出現在任何位置
CNN 核心組件
# CNN 基本結構
Input Image (224x224x3)
↓
Conv2D (32 filters, 3x3) → ReLU → MaxPool (2x2)
↓
Conv2D (64 filters, 3x3) → ReLU → MaxPool (2x2)
↓
Conv2D (128 filters, 3x3) → ReLU → MaxPool (2x2)
↓
Flatten → Dense (512) → ReLU → Dropout
↓
Dense (num_classes) → Softmax
CNN 層級特徵學習
低層特徵 (前幾層)
- 邊緣檢測: 水平線、垂直線、對角線
- 紋理識別: 點狀、條紋、格子
- 色彩梯度: 顏色變化、亮度變化
中層特徵 (中間層)
- 形狀組合: 圓形、矩形、三角形
- 物體局部: 眼睛、耳朵、輪廓
- 複雜紋理: 毛髮、皮膚、表面材質
高層特徵 (最後幾層)
- 完整物體: 人臉、汽車、動物
- 場景理解: 室內、戶外、街道
- 語義概念: 抽象的物體類別
從分類到檢測
圖像分類 vs 物件偵測
| 任務 | 輸入 | 輸出 | 難度 |
|---|---|---|---|
| 分類 | 整張圖片 | 類別標籤 | 較簡單 |
| 檢測 | 整張圖片 | 位置+類別 | 較複雜 |
檢測的挑戰
- 🔍 多尺度: 大小物體都要檢測
- 📍 精確定位: 邊界框要準確
- 🚀 實時性: 速度要夠快
- 🎯 多物體: 同時檢測多個物體
YOLO 的解決方案
- 單一網路: 端到端訓練
- 網格劃分: 全圖同時預測
- 多尺度: 不同層級特徵融合
第四章:Dataset 資料集
為什麼需要 Dataset?
- 🎯 訓練模型的"教材"
- 📊 評估模型性能
- 🔄 持續改進的基礎
資料集三要素
- 訓練集 (Train) - 70%
- 驗證集 (Valid) - 20%
- 測試集 (Test) - 10%
YOLOv7 資料集結構
dataset/
├── train/
│ ├── images/
│ └── labels/
├── valid/
│ ├── images/
│ └── labels/
├── test/
│ ├── images/
│ └── labels/
└── data.yaml
YOLOv7 資料集結構範例

分別有測試、訓練、驗證三個部分

data.yaml 訓練時會使用到
常用資料集資源
公開資料集平台
- 🌐 Roboflow
- 📊 Kaggle Datasets
- 🏛️ COCO Dataset
Roboflow 資料集下載範例

使用 Yolo v7 PyTorch 格式下載

標註工具
- LabelImg
- CVAT
- Roboflow Annotate
第五章:環境建置
GPU 設備檢查
1. 確認 GPU 支援
# 檢查 GPU 資訊
nvidia-smi
# 檢查 CUDA 版本
nvcc --version
# 檢查 GPU 計算能力
nvidia-smi --query-gpu=compute_cap --format=csv
2. 推薦 GPU 配置
| GPU 型號 | VRAM | 適用場景 |
|---|---|---|
| RTX 4060 | 16GB | 學習/小規模訓練 |
| RTX 4070 | 12GB | 中等規模訓練 |
| RTX 4080+ | 16GB+ | 大規模訓練 |
CUDA & cuDNN 完整安裝
Ubuntu 20.04/22.04 安裝步驟
# 1. 移除舊版本
sudo apt-get --purge remove "*nvidia*" "*cuda*" "*cudnn*"
# 2. 安裝 NVIDIA 驅動
sudo apt update
sudo apt install nvidia-driver-535
# 3. 重開機
sudo reboot
# 4. 安裝 CUDA 11.8
wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run
sudo sh cuda_11.8.0_520.61.05_linux.run
# 5. 設定環境變數
echo 'export PATH=/usr/local/cuda-11.8/bin:$PATH' >> <sub>/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH' >> </sub>/.bashrc
source <sub>/.bashrc
cuDNN 安裝
# 1. 下載 cuDNN 8.7.0 (需要 NVIDIA 帳號)
# 從 https://developer.nvidia.com/cudnn 下載 tar 檔案
# 2. 解壓縮並複製檔案
tar -xvf cudnn-linux-x86_64-8.7.0.84_cuda11-archive.tar.xz
# 3. 複製標頭檔
sudo cp cudnn-*/include/cudnn*.h /usr/local/cuda/include
# 4. 複製函式庫
sudo cp -P cudnn-*/lib64/libcudnn* /usr/local/cuda/lib64
# 5. 設定權限
sudo chmod a+r /usr/local/cuda/include/cudnn*.h
sudo chmod a+r /usr/local/cuda/lib64/libcudnn*
# 6. 驗證安裝
nvidia-smi
nvcc --version
Python 環境設置
Conda 完整設置
# 1. 下載 Miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
# 2. 建立專用環境
conda create -n yolo python=3.8 -y
conda activate yolo
# 3. 安裝 PyTorch (CUDA 11.8)
pip install torch<mark>2.0.1 torchvision</mark>0.15.2 torchaudio==2.0.2 --index-url https://download.pytorch.org/whl/cu118
# 4. 驗證 PyTorch CUDA 支援
python -c "import torch; print(torch.cuda.is_available())"
python -c "import torch; print(torch.cuda.get_device_name(0))"
必要套件安裝
# 基本套件
pip install numpy opencv-python pillow matplotlib seaborn
pip install pandas scikit-learn tqdm
# 深度學習相關
pip install ultralytics # YOLOv8
pip install roboflow # 資料集管理
pip install wandb # 訓練監控
# 圖像處理
pip install albumentations # 資料增強
pip install imgaug # 圖像增強
# 視覺化
pip install tensorboard
pip install plotly
# 驗證安裝
python -c "import cv2; print(cv2.__version__)"
python -c "import ultralytics; print('YOLOv8 安裝成功')"
Docker 環境 (推薦)

優點
- ✅ 環境隔離: 不會影響主系統
- ✅ 可重現性: 團隊環境一致
- ✅ 快速部署: 一鍵啟動完整環境
- ✅ 版本控制: 不同專案用不同版本
Docker 完整設置
1. 安裝 Docker
# Ubuntu 安裝 Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# 安裝 NVIDIA Docker
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-docker2
sudo systemctl restart docker
2. 使用預建映像
# 方式1: 使用官方映像
docker pull nvcr.io/nvidia/pytorch:22.12-py3
# 方式2: 使用自定義映像
docker pull oliver0804/darknet-opencv:latest
# 運行容器
docker run --gpus all -it --rm \
-v $PWD:/workspace \
-p 8888:8888 \
nvcr.io/nvidia/pytorch:22.12-py3
自建 Docker 映像
Dockerfile 範例
FROM nvidia/cuda:11.8-devel-ubuntu20.04
# 安裝基本套件
RUN apt-get update && apt-get install -y \
python3 python3-pip git wget \
libopencv-dev python3-opencv \
&& rm -rf /var/lib/apt/lists/*
# 安裝 Python 套件
RUN pip3 install torch torchvision torchaudio \
opencv-python ultralytics
# 設定工作目錄
WORKDIR /workspace
# 複製專案檔案
COPY . .
# 暴露端口
EXPOSE 8888
# 啟動命令
CMD ["bash"]
建置與使用
# 建置映像
docker build -t my-yolo-env .
# 運行容器
docker run --gpus all -it --rm \
-v $PWD:/workspace \
my-yolo-env
第六章:YOLO 訓練實戰
訓練前準備檢查清單
📋 硬體需求確認
- ✅ GPU 記憶體 > 8GB
- ✅ 系統記憶體 > 16GB
- ✅ 儲存空間 > 50GB
- ✅ CUDA 版本相容
📋 軟體環境確認
# 檢查清單
python --version # Python 3.8+
pip list | grep torch # PyTorch 1.12+
nvidia-smi # GPU 狀態
nvcc --version # CUDA 版本
YOLOv8 完整訓練流程
1. 環境設置
# 安裝 Ultralytics YOLOv8
pip install ultralytics
# 驗證安裝
yolo version
2. 準備資料集
# 資料集結構
dataset/
├── images/
│ ├── train/
│ ├── val/
│ └── test/
├── labels/
│ ├── train/
│ ├── val/
│ └── test/
└── data.yaml
資料集配置檔案
data.yaml 範例
# 資料集路徑
path: ./dataset
train: images/train
val: images/val
test: images/test
# 類別數量
nc: 3
# 類別名稱
names:
0: person
1: bicycle
2: car
標註格式 (YOLO)
# 每行一個物體: class_id x_center y_center width height
# 座標為相對值 (0-1)
0 0.5 0.5 0.3 0.4
1 0.2 0.3 0.1 0.2
訓練腳本詳解
資料集配置範例

此檔案經過修改,將 Path 改為絕對路徑
模型配置選擇

路徑中包含 v7-tiny 版本選項
基本訓練
from ultralytics import YOLO
# 載入模型
model = YOLO('yolov8n.pt') # nano 版本
# 開始訓練
results = model.train(
data='data.yaml',
epochs=100,
imgsz=640,
batch=16,
name='my_experiment'
)
進階訓練設定
# 進階參數設定
results = model.train(
data='data.yaml',
epochs=300,
imgsz=640,
batch=32,
lr0=0.01, # 初始學習率
lrf=0.01, # 最終學習率
momentum=0.937, # 動量
weight_decay=0.0005,# 權重衰減
warmup_epochs=3, # 預熱期
warmup_momentum=0.8,# 預熱動量
box=7.5, # 邊界框損失權重
cls=0.5, # 分類損失權重
dfl=1.5, # 分布焦點損失權重
patience=50, # 早停耐心值
save_period=10, # 保存週期
name='advanced_training'
)
訓練監控與視覺化
1. TensorBoard 監控
# 啟動 TensorBoard
import tensorboard
%load_ext tensorboard
%tensorboard --logdir runs/train
2. Weights & Biases 整合
# 安裝 wandb
pip install wandb
# 登入 wandb
wandb login
# 訓練時自動記錄
results = model.train(
data='data.yaml',
epochs=100,
project='yolo-training', # W&B 專案名稱
name='experiment-1'
)
訓練過程監控
即時監控腳本
import psutil
import GPUtil
import time
def monitor_training():
while True:
# CPU 使用率
cpu_percent = psutil.cpu_percent()
# 記憶體使用率
memory = psutil.virtual_memory()
# GPU 使用率
gpus = GPUtil.getGPUs()
print(f"CPU: {cpu_percent}%")
print(f"RAM: {memory.percent}%")
for gpu in gpus:
print(f"GPU {gpu.id}: {gpu.load*100:.1f}%")
print(f"VRAM: {gpu.memoryUsed}MB/{gpu.memoryTotal}MB")
time.sleep(5)
# 背景執行監控
import threading
monitor_thread = threading.Thread(target=monitor_training, daemon=True)
monitor_thread.start()
訓練過程展示
訓練開始

GPU 資源監控

可以使用 nvtop 進行 GPU 使用資源檢視
超參數調整策略
學習率調整
# 學習率調度策略
schedulers = {
'cosine': 'cos', # 餘弦退火
'linear': 'linear', # 線性衰減
'constant': 'constant' # 常數
}
# 自動學習率尋找
model.tune(
data='data.yaml',
epochs=30,
iterations=300,
optimizer='AdamW',
plots=True,
save=True
)
批次大小優化
# 自動批次大小調整
def find_optimal_batch_size(model, data_yaml):
batch_sizes = [8, 16, 32, 64, 128]
best_batch = 8
for batch in batch_sizes:
try:
results = model.train(
data=data_yaml,
epochs=5,
batch=batch,
verbose=False
)
best_batch = batch
print(f"Batch {batch}: 成功")
except RuntimeError as e:
if "out of memory" in str(e):
print(f"Batch {batch}: 記憶體不足")
break
return best_batch
模型驗證與測試
驗證腳本
# 驗證模型性能
metrics = model.val(
data='data.yaml',
imgsz=640,
batch=32,
conf=0.001,
iou=0.6,
save_json=True,
save_hybrid=True
)
# 輸出指標
print(f"mAP50: {metrics.box.map50:.3f}")
print(f"mAP50-95: {metrics.box.map:.3f}")
print(f"Precision: {metrics.box.mp:.3f}")
print(f"Recall: {metrics.box.mr:.3f}")
測試腳本
# 單張圖片測試
results = model.predict(
source='test.jpg',
conf=0.25,
save=True,
show_labels=True,
show_conf=True
)
# 批次圖片測試
results = model.predict(
source='test_images/',
conf=0.25,
save=True,
save_txt=True, # 保存標註
save_crop=True # 保存裁切圖片
)
# 即時攝影機測試
results = model.predict(
source=0, # 攝影機ID
conf=0.25,
show=True,
save=True
)
模型匯出與部署
多格式匯出
# 匯出為不同格式
model.export(
format='onnx', # ONNX 格式
imgsz=640,
dynamic=True, # 動態輸入尺寸
half=True, # FP16 精度
int8=True, # INT8 量化
optimize=True # 優化
)
# 其他格式
formats = [
'torchscript', # PyTorch Script
'tflite', # TensorFlow Lite
'edgetpu', # Edge TPU
'tfjs', # TensorFlow.js
'coreml' # Core ML
]
for fmt in formats:
model.export(format=fmt)
性能基準測試
# 推理速度測試
import time
import numpy as np
def benchmark_model(model, input_size=(640, 640), iterations=100):
model.eval()
dummy_input = np.random.randn(1, 3, *input_size).astype(np.float32)
# 預熱
for _ in range(10):
model.predict(dummy_input, verbose=False)
# 測試
times = []
for _ in range(iterations):
start = time.time()
model.predict(dummy_input, verbose=False)
end = time.time()
times.append(end - start)
avg_time = np.mean(times)
fps = 1.0 / avg_time
print(f"平均推理時間: {avg_time*1000:.2f}ms")
print(f"FPS: {fps:.2f}")
return avg_time, fps
訓練成果展示
魚類偵測範例
偵測結果

好多好多魚魚 <>< <3

訓練指標
測試集結果

訓練集結果

混淆矩陣

攝影機即時檢測

常見問題解決
記憶體不足
# 解決方案
strategies = {
'降低批次大小': 'batch=8',
'使用混合精度': 'amp=True',
'減少輸入尺寸': 'imgsz=320',
'梯度累積': 'accumulate=2'
}
# 梯度累積範例
model.train(
data='data.yaml',
epochs=100,
batch=8,
accumulate=4, # 等效批次大小 = 8*4 = 32
amp=True # 自動混合精度
)
訓練不收斂
# 診斷與解決
diagnostic_steps = [
"檢查學習率是否過高",
"確認資料集標註正確性",
"檢查類別平衡性",
"調整損失函數權重",
"增加資料增強"
]
# 學習率調整
model.train(
data='data.yaml',
lr0=0.001, # 降低初始學習率
warmup_epochs=5, # 增加預熱期
patience=100 # 增加早停耐心
)
第七章:Darknet 框架
Darknet 簡介
特點
- ✨ C/CUDA 原生實現 - 極致性能
- 🚀 輕量級框架 - 無複雜依賴
- 📦 易於修改 - 源碼清晰
- 🔧 原生支援 - YOLO 官方框架
作者
Joseph Redmon (YOLO v1-v3 原作者)
Alexey Bochkovskiy (YOLOv4 維護者)
與 PyTorch 比較
| 特性 | Darknet | PyTorch |
|---|---|---|
| 速度 | 極快 | 快 |
| 易用性 | 中等 | 高 |
| 生態系統 | 有限 | 豐富 |
| 自定義 | 需要 C 代碼 | Python 即可 |
Darknet 完整安裝
1. 系統依賴安裝
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y build-essential cmake git
# 編譯工具
sudo apt-get install -y gcc g++ make
# 可選:OpenCV 支援
sudo apt-get install -y libopencv-dev
# 可選:OpenMP 支援
sudo apt-get install -y libomp-dev
2. 克隆與編譯
# 克隆改良版 Darknet (推薦)
git clone https://github.com/AlexeyAB/darknet.git
cd darknet
# 編輯 Makefile
nano Makefile
Makefile 配置
# GPU 支援
GPU=1
CUDNN=1
CUDNN_HALF=1
# OpenCV 支援
OPENCV=1
# OpenMP 支援
OPENMP=1
# 偵錯模式
DEBUG=0
# 其他選項
LIBSO=1 # 建立 .so 檔案
ZED_CAMERA=0 # ZED 攝影機支援
編譯指令
# 清理舊檔案
make clean
# 編譯 (使用多核心)
make -j$(nproc)
# 驗證編譯結果
./darknet version
OpenCV 安裝過程截圖
OpenCV 3.4.19 版本確認

編譯過程

基本測試
1. 下載預訓練模型
# YOLOv4 權重
wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights
# YOLOv4-tiny 權重
wget https://github.com/AlexeyAB/darknet/releases/download/yolov4/yolov4-tiny.weights
# YOLOv7-tiny 權重
wget https://github.com/AlexeyAB/darknet/releases/download/yolov4/yolov7-tiny.weights
2. 測試圖片檢測
# YOLOv4 檢測
./darknet detect cfg/yolov4.cfg yolov4.weights data/dog.jpg
# YOLOv4-tiny 檢測
./darknet detect cfg/yolov4-tiny.cfg yolov4-tiny.weights data/dog.jpg
# 自訂閾值
./darknet detect cfg/yolov4.cfg yolov4.weights data/dog.jpg -thresh 0.5
測試結果展示
YOLOv3 檢測結果

YOLOv7-tiny 檢測結果

影片與攝影機檢測
影片檢測
# 檢測影片
./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights test.mp4
# 儲存結果
./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights test.mp4 -out_filename result.avi
攝影機檢測
# 使用 webcam
./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights -c 0
# 使用外接攝影機
./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights -c 1
# 設定參數
./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights -c 0 -thresh 0.25 -here
自定義訓練準備
1. 建立專案資料夾
mkdir my_yolo_project
cd my_yolo_project
# 建立目錄結構
mkdir -p {data,cfg,weights,results}
mkdir -p data/{images,labels}
mkdir -p data/images/{train,valid,test}
mkdir -p data/labels/{train,valid,test}
2. 準備資料集
# 資料集結構
my_yolo_project/
├── data/
│ ├── images/
│ │ ├── train/
│ │ ├── valid/
│ │ └── test/
│ ├── labels/
│ │ ├── train/
│ │ ├── valid/
│ │ └── test/
│ ├── train.txt
│ ├── valid.txt
│ └── test.txt
├── cfg/
│ ├── my_dataset.data
│ ├── my_yolov4.cfg
│ └── my_classes.names
└── weights/
配置檔案設定
1. 建立 .data 檔案
# my_dataset.data
classes = 3
train = data/train.txt
valid = data/valid.txt
names = cfg/my_classes.names
backup = weights/
2. 建立 .names 檔案
# my_classes.names
person
car
bicycle
3. 建立圖片列表
# 產生訓練列表
find $(pwd)/data/images/train -name "*.jpg" > data/train.txt
# 產生驗證列表
find $(pwd)/data/images/valid -name "*.jpg" > data/valid.txt
# 檢查列表
head -5 data/train.txt
模型配置調整
1. 複製基礎配置
# 複製 YOLOv4-tiny 配置
cp ../darknet/cfg/yolov4-tiny.cfg cfg/my_yolov4.cfg
2. 修改配置檔案
# 編輯配置
nano cfg/my_yolov4.cfg
# 關鍵修改點:
# 1. 修改 classes 數量
# 2. 修改 filters 數量
# 3. 調整學習率
# 4. 設定批次大小
重要參數說明
[net]
batch=64 # 批次大小
subdivisions=8 # 子批次
width=416 # 輸入寬度
height=416 # 輸入高度
channels=3 # 通道數
momentum=0.9 # 動量
decay=0.0005 # 權重衰減
angle=0 # 隨機旋轉角度
saturation=1.5 # 飽和度變化
exposure=1.5 # 曝光變化
hue=.1 # 色調變化
learning_rate=0.001 # 學習率
max_batches=6000 # 最大批次 (classes * 2000)
policy=steps # 學習率策略
steps=4800,5400 # 降低學習率的步驟
scales=.1,.1 # 學習率縮放
預訓練權重準備
1. 下載預訓練權重
# YOLOv4-tiny 預訓練權重
wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.conv.29
# YOLOv4 預訓練權重
wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.conv.137
2. 驗證權重檔案
# 檢查檔案大小
ls -lh weights/
# 測試權重載入
./darknet detector test cfg/my_dataset.data cfg/my_yolov4.cfg weights/yolov4-tiny.conv.29
開始訓練
自定義資料集範例
手語識別資料集

自定義設定資料夾

基本訓練指令
# 單 GPU 訓練
./darknet detector train cfg/my_dataset.data cfg/my_yolov4.cfg weights/yolov4-tiny.conv.29
# 多 GPU 訓練
./darknet detector train cfg/my_dataset.data cfg/my_yolov4.cfg weights/yolov4-tiny.conv.29 -gpus 0,1
# 從檢查點繼續訓練
./darknet detector train cfg/my_dataset.data cfg/my_yolov4.cfg weights/my_yolov4_last.weights
# 計算 mAP
./darknet detector train cfg/my_dataset.data cfg/my_yolov4.cfg weights/yolov4-tiny.conv.29 -map
訓練過程監控

訓練監控
1. 查看訓練日誌
# 即時查看訓練進度
tail -f training.log
# 提取損失值
grep "avg" training.log | tail -10
2. 損失函數分析
# 訓練輸出範例
Region xx: cfg: (anchors) ...
1000: 2.950644, 2.950644 avg, 0.000010 rate, 3.456 seconds, 64000 images
參數說明
1000: 當前迭代次數2.950644: 當前損失值2.950644 avg: 平均損失值0.000010 rate: 當前學習率3.456 seconds: 此批次訓練時間64000 images: 已處理圖片數
訓練結果評估
1. 計算 mAP
# 計算驗證集 mAP
./darknet detector map cfg/my_dataset.data cfg/my_yolov4.cfg weights/my_yolov4_best.weights
2. 測試個別圖片
# 測試單張圖片
./darknet detector test cfg/my_dataset.data cfg/my_yolov4.cfg weights/my_yolov4_best.weights data/test.jpg
# 批次測試
./darknet detector test cfg/my_dataset.data cfg/my_yolov4.cfg weights/my_yolov4_best.weights < data/test.txt
3. 調整檢測閾值
# 不同閾值測試
for thresh in 0.1 0.25 0.5 0.75; do
echo "Testing with threshold: $thresh"
./darknet detector test cfg/my_dataset.data cfg/my_yolov4.cfg weights/my_yolov4_best.weights data/test.jpg -thresh $thresh
done
高級功能
1. 資料增強
# 在 [net] 部分加入
mosaic=1 # 馬賽克增強
cutmix=1 # CutMix 增強
mixup=1 # MixUp 增強
2. 多尺度訓練
# 隨機尺度訓練
random=1
# 多尺度設定
width=416
height=416
3. 學習率調度
# 學習率策略
policy=steps
steps=4800,5400
scales=.1,.1
# 或使用多項式衰減
policy=poly
power=4
疑難排解
常見錯誤解決
# 1. CUDA 記憶體不足
# 解決:降低 batch size 或 subdivisions
# 2. 找不到圖片
# 解決:檢查 .txt 檔案中的路徑
# 3. 標註格式錯誤
# 解決:檢查 YOLO 格式是否正確
# 4. 類別數量不匹配
# 解決:確認 classes 和 filters 設定正確
優化建議
- 記憶體優化: 調整
subdivisions - 速度優化: 使用
-dont_show參數 - 精度優化: 增加
max_batches - 穩定訓練: 使用
-map監控 mAP
Docker 部署 (完整版)
1. 使用現成映像
Docker 工作流程示意

# 拉取映像
docker pull oliver0804/darknet-opencv:latest
# 運行容器
docker run --gpus all -it --rm \
-v $(pwd):/workspace \
-v $(pwd)/data:/darknet/data \
-v $(pwd)/cfg:/darknet/cfg \
-v $(pwd)/weights:/darknet/weights \
oliver0804/darknet-opencv:latest
Docker 執行結果

最終檢測結果

2. 在容器中訓練
# 進入容器
docker exec -it <container_id> bash
# 開始訓練
./darknet detector train cfg/my_dataset.data cfg/my_yolov4.cfg weights/yolov4-tiny.conv.29 -dont_show -map
3. 自動化腳本
#!/bin/bash
# auto_train.sh
# 設定參數
DATA_FILE="cfg/my_dataset.data"
CFG_FILE="cfg/my_yolov4.cfg"
WEIGHTS_FILE="weights/yolov4-tiny.conv.29"
# 執行訓練
docker run --gpus all -it --rm \
-v $(pwd):/workspace \
oliver0804/darknet-opencv:latest \
./darknet detector train $DATA_FILE $CFG_FILE $WEIGHTS_FILE -dont_show -map
第八章:邊緣設備部署
Ameba Pro2 簡介
硬體規格
- 處理器: ARM Cortex-M55 @ 500MHz
- AI 加速器: 0.4 TOPS NPU
- 記憶體: 768KB SRAM + 16MB PSRAM
- 攝像頭: 2MP 感光元件
- 連接: Wi-Fi 6 + BLE 5.0
- 尺寸: 35mm x 28mm
為什麼選擇邊緣 AI?
- 🔒 隱私保護: 資料不上雲
- ⚡ 低延遲: 即時推理
- 💰 成本效益: 無雲端費用
- 🔋 低功耗: 適合 IoT 應用
重要注意事項
支援時程
注意: ameba pro2 對 yolo 的支援時間會比較晚
當前限制
- 模型轉換需要線上工具
- 暫無離線版本工具
- 如果在意模型保密需要考慮
適用場景
- 🏠 智慧家居監控
- 🏭 工業品質檢測
- 🚗 車內駕駛行為分析
- 📱 IoT 邊緣計算
模型轉換詳解
1. 準備轉換檔案
檔案要求
# 打包內容
yolo_model.zip
├── yolov4-tiny.weights # 訓練好的權重檔
└── yolov4-tiny.cfg # 對應的配置檔
# 重要限制
❌ 不能包含中文字符
❌ cfg 檔案註解也不能有中文
❌ 檔案路徑不能有中文
配置檔案清理
# 移除中文註解
sed -i '/[\u4e00-\u9fff]/d' yolov4-tiny.cfg
# 檢查檔案編碼
file yolov4-tiny.cfg
# 確保 UTF-8 編碼
iconv -f GB2312 -t UTF-8 yolov4-tiny.cfg > yolov4-tiny_clean.cfg
線上轉換流程
1. 上傳模型

網址: https://www.amebaiot.com/en/amebapro2-ai-convert-model/
2. 轉換過程
- ⏱️ 等待時間: 10-20 分鐘
- 📧 結果通知: 轉換完成會發送郵件
- 📦 輸出格式: .nb 檔案 (Neural Network Binary)
3. 轉換參數
| 參數 | 說明 | 建議值 |
|---|---|---|
| Input Size | 輸入圖片尺寸 | 416x416 |
| Quantization | 量化位元數 | INT8 |
| Optimization | 優化等級 | High |
Arduino IDE 環境設置
1. 安裝 Arduino IDE
# 下載 Arduino IDE 2.0+
wget https://downloads.arduino.cc/arduino-ide/arduino-ide_2.2.1_Linux_64bit.zip
# 或使用套件管理器
sudo apt install arduino
2. 添加開發板支援
開發板管理員 URL
https://github.com/ambiot/ambpro2_arduino/raw/main/Arduino_package/package_realtek.com_amebapro2_index.json

安裝步驟
- 開啟 Arduino IDE
- 檔案 → 偏好設定 → 額外的開發板管理員網址
- 貼上上述 URL
- 工具 → 開發板 → 開發板管理員
- 搜尋 "Realtek Ameba"
- 安裝 "Realtek Ameba Pro2 Boards"
選擇開發板
開發板設定

設定路徑: 工具 → 開發板 → Realtek Ameba Pro2 → "Ameba Pro2"
編譯選項
Board: "Ameba Pro2"
CPU Speed: "500MHz"
Optimization: "Smallest (-Os)"
Upload Speed: "115200"
神經網路範例程式
1. 開啟範例

路徑: 檔案 → 範例 → AmebaNN → YOLO
2. 基本程式結構
#include "NeuralNetwork.h"
#include "VideoStream.h"
#include "RTSP.h"
// 物件類別定義
#define YOLO_CLASSES 26 // 自定義類別數
// 類別名稱陣列
String objectList[YOLO_CLASSES] = {
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y", "Z"
};
void setup() {
Serial.begin(115200);
// 初始化攝像頭
Camera.configVideoChannel(VIDEO_CHN, 416, 416, 30, VIDEO_H264_JPEG);
Camera.videoInit();
// 初始化神經網路
NNObjectDetection.configVideo(VIDEO_CHN);
NNObjectDetection.modelSelect(OBJECT_DETECTION, YOLO_CLASSES, DEFAULT_YOLO, NA_MODEL);
NNObjectDetection.begin();
// 初始化 RTSP
RTSP.configVideo(VIDEO_CHN);
RTSP.begin();
}
void loop() {
// 執行物件偵測
if (NNObjectDetection.available()) {
ObjectDetectionResult result = NNObjectDetection.getResult();
// 處理偵測結果
for (int i = 0; i < result.count(); i++) {
int obj_type = result.type(i);
int score = result.score(i);
if (score > 50) { // 信心度閾值
Serial.printf("偵測到: %s (信心度: %d%%)\n",
objectList[obj_type].c_str(), score);
}
}
}
delay(100);
}
模型替換詳解
1. 找到模型檔案位置

典型路徑:
<sub>/Arduino/libraries/AmebaNN/src/
├── models/
│ ├── yolov4_tiny.nb # 原始模型
│ └── yolov4_tiny_new.nb # 你的新模型
2. 備份原始模型
# 進入模型目錄
cd </sub>/Arduino/libraries/AmebaNN/src/models/
# 備份原始模型
cp yolov4_tiny.nb yolov4_tiny_original.nb
# 替換新模型
cp /path/to/your/model.nb yolov4_tiny.nb
3. 修改類別設定
更新類別數量
// 原始 COCO dataset (80 類)
#define YOLO_CLASSES 80
// 改為你的類別數 (例如: 26 類手語)
#define YOLO_CLASSES 26
更新類別名稱
// 原始 COCO 類別
String objectList[YOLO_CLASSES] = {
"person", "bicycle", "car", ... // 80 個類別
};
// 改為手語字母 (26 類)
String objectList[YOLO_CLASSES] = {
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y", "Z"
};
程式碼修改詳解
1. 修改 OSD 標籤顯示
原始標籤清單

修改後的手語標籤

原始代碼:
// 舊版本 (可能已修正)
printf("%s", item.name());
修正後:
// 新版本
printf("%s", objectList[obj_type].c_str());
2. 物件類型處理

修改位置: 約第 114 行
// 修改前
item.name()
// 修改後
objectList[obj_type].objectName
測試與除錯
1. 序列埠監控
void printDetectionInfo(ObjectDetectionResult result) {
Serial.printf("偵測到 %d 個物件\n", result.count());
for (int i = 0; i < result.count(); i++) {
int obj_type = result.type(i);
int score = result.score(i);
int x = result.xMin(i);
int y = result.yMin(i);
int w = result.width(i);
int h = result.height(i);
Serial.printf("物件 %d: %s\n", i+1, objectList[obj_type].c_str());
Serial.printf(" 信心度: %d%%\n", score);
Serial.printf(" 位置: (%d, %d) 大小: %dx%d\n", x, y, w, h);
}
}
2. 性能監控
unsigned long prev_time = 0;
int frame_count = 0;
void loop() {
if (NNObjectDetection.available()) {
frame_count++;
unsigned long curr_time = millis();
if (curr_time - prev_time >= 1000) { // 每秒統計
Serial.printf("FPS: %d\n", frame_count);
frame_count = 0;
prev_time = curr_time;
}
// 處理偵測結果...
}
}
實際展示效果
1. 手語識別展示
YouTube 影片: Ameba pro2 yolo展示
功能展示
- ✅ 即時手語字母識別
- ✅ 邊界框繪製
- ✅ 信心度顯示
- ✅ RTSP 串流輸出
2. 性能表現
| 指標 | 數值 |
|---|---|
| 推理速度 | 10 FPS |
| 延遲 | <100ms |
| 功耗 | <500mW |
| 精確度 | 85%+ |
模型快速替換工具
1. 問題描述
- 🔍 路徑深層: Arduino 目錄結構複雜
- 🔄 頻繁更換: 需要測試不同模型
- 💾 備份需求: 保存之前的模型版本
2. 自動化腳本
YouTube 教學: Ameba pro2 快速替換模型腳本
Windows 批次檔 (model_swap.bat)
@echo off
setlocal enabledelayedexpansion
echo Ameba Pro2 模型快速替換工具
echo ================================
set ARDUINO_PATH=%USERPROFILE%\Documents\Arduino
set MODEL_PATH=%ARDUINO_PATH%\libraries\AmebaNN\src\models
set BACKUP_PATH=%MODEL_PATH%\backup
REM 建立備份目錄
if not exist "%BACKUP_PATH%" mkdir "%BACKUP_PATH%"
REM 顯示當前模型
echo 當前模型檔案:
dir "%MODEL_PATH%\*.nb" /b
echo.
echo 選擇操作:
echo 1. 替換模型
echo 2. 還原備份
echo 3. 建立備份
set /p choice="請輸入選項 (1-3): "
if "%choice%"=="1" goto REPLACE_MODEL
if "%choice%"=="2" goto RESTORE_BACKUP
if "%choice%"=="3" goto CREATE_BACKUP
goto END
:REPLACE_MODEL
set /p new_model="請輸入新模型檔案路徑: "
if not exist "%new_model%" (
echo 錯誤: 找不到指定的模型檔案
goto END
)
REM 備份當前模型
copy "%MODEL_PATH%\yolov4_tiny.nb" "%BACKUP_PATH%\yolov4_tiny_%date:</sub>0,4%%date:<sub>5,2%%date:</sub>8,2%.nb"
REM 替換模型
copy "%new_model%" "%MODEL_PATH%\yolov4_tiny.nb"
echo 模型替換完成!
goto END
:RESTORE_BACKUP
echo 可用的備份檔案:
dir "%BACKUP_PATH%\*.nb" /b
set /p backup_file="請輸入要還原的備份檔案名: "
copy "%BACKUP_PATH%\%backup_file%" "%MODEL_PATH%\yolov4_tiny.nb"
echo 模型還原完成!
goto END
:CREATE_BACKUP
copy "%MODEL_PATH%\yolov4_tiny.nb" "%BACKUP_PATH%\yolov4_tiny_%date:<sub>0,4%%date:</sub>5,2%%date:~8,2%.nb"
echo 備份建立完成!
goto END
:END
pause
3. Linux/Mac 腳本 (model_swap.sh)
#!/bin/bash
ARDUINO_PATH="$HOME/Arduino"
MODEL_PATH="$ARDUINO_PATH/libraries/AmebaNN/src/models"
BACKUP_PATH="$MODEL_PATH/backup"
# 建立備份目錄
mkdir -p "$BACKUP_PATH"
echo "Ameba Pro2 模型快速替換工具"
echo "================================"
echo "當前模型檔案:"
ls -la "$MODEL_PATH"/*.nb 2>/dev/null || echo "找不到模型檔案"
echo ""
echo "選擇操作:"
echo "1. 替換模型"
echo "2. 還原備份"
echo "3. 建立備份"
read -p "請輸入選項 (1-3): " choice
case $choice in
1)
read -p "請輸入新模型檔案路徑: " new_model
if [ ! -f "$new_model" ]; then
echo "錯誤: 找不到指定的模型檔案"
exit 1
fi
# 備份當前模型
cp "$MODEL_PATH/yolov4_tiny.nb" "$BACKUP_PATH/yolov4_tiny_$(date +%Y%m%d_%H%M%S).nb"
# 替換模型
cp "$new_model" "$MODEL_PATH/yolov4_tiny.nb"
echo "模型替換完成!"
;;
2)
echo "可用的備份檔案:"
ls -1 "$BACKUP_PATH"/*.nb 2>/dev/null || echo "沒有備份檔案"
read -p "請輸入要還原的備份檔案名: " backup_file
cp "$BACKUP_PATH/$backup_file" "$MODEL_PATH/yolov4_tiny.nb"
echo "模型還原完成!"
;;
3)
cp "$MODEL_PATH/yolov4_tiny.nb" "$BACKUP_PATH/yolov4_tiny_$(date +%Y%m%d_%H%M%S).nb"
echo "備份建立完成!"
;;
*)
echo "無效的選項"
;;
esac
疑難排解
常見問題
模型轉換失敗
- 檢查檔案是否包含中文
- 確認 cfg 和 weights 對應
- 重新清理配置檔案
編譯錯誤
- 確認開發板選擇正確
- 檢查類別數量設定
- 更新 Arduino 核心
推理速度慢
- 降低輸入解析度
- 使用 INT8 量化
- 優化模型架構
效能優化建議
- 🎯 模型選擇: 使用 YOLOv4-tiny 而非完整版
- 📏 輸入尺寸: 建議 320x320 或 416x416
- ⚡ 量化: 使用 INT8 量化減少記憶體用量
- 🔄 批次處理: 避免頻繁的模型切換
第九章:實用技巧
OpenCV 應用
電腦視覺基礎操作

OpenCV 可以處理顏色、物件邊緣、光流等,是代碼版本的 Photoshop
影像前處理
import cv2
# 讀取圖片
img = cv2.imread('image.jpg')
# 轉換顏色空間
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 邊緣檢測
edges = cv2.Canny(gray, 50, 150)
# 影像增強
enhanced = cv2.equalizeHist(gray)
進階應用範例
人臉識別應用

透過 OpenCV contrib 實現人臉偵測
OCR 文字識別

使用 Tesseract 進行光學字符識別
資料增強技巧
常用方法
- 旋轉 - 增加角度變化
- 翻轉 - 水平/垂直鏡像
- 縮放 - 尺度不變性
- 色彩調整 - 光照變化
- 加噪 - 提升魯棒性
# Albumentations 範例
transform = A.Compose([
A.RandomRotate90(),
A.Flip(),
A.RandomBrightnessContrast(p=0.2),
])
第十章:常見問題
GPU 記憶體不足
解決方案
- 降低 batch size
- 使用混合精度訓練
- 減少輸入圖片尺寸
- 使用梯度累積
# 梯度累積範例
accumulation_steps = 4
for i, (imgs, targets) in enumerate(dataloader):
loss = model(imgs, targets)
loss = loss / accumulation_steps
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
訓練不收斂
檢查清單
- ✅ 學習率是否合適
- ✅ 資料集是否平衡
- ✅ 標註是否正確
- ✅ 增強是否過度
調試技巧
# 學習率調度
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer, T_max=epochs
)
總結與展望
學習要點回顧
技術堆疊
- ✅ 深度學習基礎
- ✅ YOLO 架構原理
- ✅ 訓練流程實作
- ✅ 模型優化技巧
- ✅ 邊緣設備部署
實戰經驗
- 💡 資料集準備的重要性
- 🔧 超參數調整的藝術
- 📊 性能指標的理解
- 🚀 部署優化的考量
未來發展方向
技術趨勢
- Vision Transformer - 新架構崛起
- 自監督學習 - 減少標註需求
- 邊緣 AI - 更強大的端側推理
- 多模態融合 - 結合語言理解
應用場景
- 🏭 智慧製造
- 🚗 自動駕駛
- 🏥 醫療影像
- 🛡️ 安防監控
參考資源
官方資源
社群資源
- GitHub: AlexeyAB/darknet
- GitHub: WongKinYiu/yolov7
- Roboflow Blog
- PyImageSearch
Q&A 時間
聯絡方式
- 📧 Email: oliver@example.com
- 💬 GitHub: @Oliver0804
- 🌐 Blog: oliver.blog
感謝聆聽!🎉
附錄:快速參考
常用指令
# PyTorch 訓練
python train.py --batch 16 --epochs 100
# Darknet 訓練
./darknet detector train cfg/data.data cfg/yolo.cfg weights.conv
# 模型測試
python detect.py --weights best.pt --source test.jpg
# Docker 運行
docker run --gpus all -it darknet:latest
本文最初發布於 HackMD @BASHCAT。
留言
張貼留言