常見套件
sudo apt update && \
sudo apt-get install git && \
sudo apt install python3-opencv && \
sudo apt-get install python3-bs4 && \
sudo apt install libopencv-dev
# cuDNN 7.6.5, python 3.6.9, torch 1.6.0, torchvision 0.7.1 in gcp
conda update conda && \
conda env list && \
source activate base && \
pip install torch==1.6.0+cu101 torchvision==0.7.0+cu101 -f https://download.pytorch.org/whl/torch_stable.html
安裝 mish cuda
pip3 install git+https://github.com/JunnYu/mish-cuda.git
建立工作目錄
mkdir YOLOv4-CSP
cd YOLOv4-CSP
下載 yolov4-csp
sudo apt install subversion
svn checkout https://github.com/WongKinYiu/ScaledYOLOv4/branches/yolov4-csp
準備資料集
pip3 install kaggle
建立 kaggle_api_token.py
import json
import os
api_token = {"username":"<user>","key":"<user_key>"}
if not os.path.exists("/home/<user>/.kaggle"):
os.makedirs("/home/<user>/.kaggle")
with open('/home/<user>/.kaggle/kaggle.json', 'w') as file:
json.dump(api_token, file)
下載
kaggle datasets download -d andrewmvd/face-mask-detection
unzip face-mask-detection.zip
轉換
import os
import shutil
from bs4 import BeautifulSoup
import math
def run_convert(all_classes, train_img, train_annotation, yolo_path, write_train_txt, write_val_txt):
now_path = os.getcwd()
data_counter = 0
for data_file in os.listdir(train_annotation):
try:
with open(os.path.join(train_annotation, data_file), 'r') as f:
print("read file...")
soup = BeautifulSoup(f.read(), 'xml')
img_name = soup.select_one('filename').text
for size in soup.select('size'):
img_w = int(size.select_one('width').text)
img_h = int(size.select_one('height').text)
img_info = []
for obj in soup.select('object'):
xmin = int(obj.select_one('xmin').text)
xmax = int(obj.select_one('xmax').text)
ymin = int(obj.select_one('ymin').text)
ymax = int(obj.select_one('ymax').text)
objclass = all_classes.get(obj.select_one('name').text)
x = (xmin + (xmax-xmin)/2) * 1.0 / img_w
y = (ymin + (ymax-ymin)/2) * 1.0 / img_h
w = (xmax-xmin) * 1.0 / img_w
h = (ymax-ymin) * 1.0 / img_h
img_info.append(' '.join([str(objclass), str(x),str(y),str(w),str(h)]))
# copy image to yolo path and rename
img_path = os.path.join(train_img, img_name)
img_format = img_name.split('.')[1] # jpg or png
shutil.copyfile(img_path, yolo_path + str(data_counter) + '.' + img_format)
# create yolo bndbox txt
with open(yolo_path + str(data_counter) + '.txt', 'a+') as f:
f.write('\n'.join(img_info))
data_counter += 1
except Exception as e:
print(e)
print('the file is processed')
# create train and val txt
path = os.path.join(now_path, yolo_path)
datasets = []
for idx in os.listdir(yolo_path):
if not idx.endswith('.txt'):
idx_path = path + idx
datasets.append(idx_path)
len_datasets = math.floor(len(datasets)*0.8)
with open(write_train_txt, 'a') as f:
f.write('\n'.join(datasets[0:len_datasets]))
with open(write_val_txt, 'a') as f:
f.write('\n'.join(datasets[len_datasets:]))
all_classes = {'mask_weared_incorrect': 2, 'without_mask': 1, 'with_mask': 0}
train_img = "Face_Mask_data/images"
train_annotation = "Face_Mask_data/annotations"
yolo_path = "yolo_data/"
write_train_txt = 'yolov4-csp/data/train.txt'
write_val_txt = 'yolov4-csp/data/val.txt'
if not os.path.exists(yolo_path):
os.mkdir(yolo_path)
else:
lsdir = os.listdir(yolo_path)
for name in lsdir:
if name.endswith('.txt') or name.endswith('.jpg') or name.endswith('.png'):
os.remove(os.path.join(yolo_path, name))
cfg_file = write_train_txt.split('/')[0]
if not os.path.exists(cfg_file):
os.mkdir(cfg_file)
if os.path.exists(write_train_txt):
file=open(write_train_txt, 'w')
if os.path.exists(write_val_txt):
file=open(write_val_txt, 'w')
run_convert(all_classes, train_img, train_annotation, yolo_path, write_train_txt, write_val_txt)
報錯
read file...
Couldn't find a tree builder with the features you requested: xml. Do you need to install a parser library?
安裝
sudo apt-get install python3-bs4
cd yolov4-csp
mkdir weights
下載動作執行檔
FILEID="1NQwz47cW0NUgy7L3_xOKaNEfLoQuq3EL"
FILENAME="weights/yolov4-csp.weights"
wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=${FILEID}' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=${FILEID}" -O ${FILENAME} && rm -rf /tmp/cookies.txt
執行
chmod +x download.sh
./download.sh
修改 cfg 中的 width, height, filters, classes
$ cp models/yolov4-csp.cfg models/yolov4-csp_416.cfg# 查看原本參數
$ sed -n -e 8p -e 9p -e 1022p -e 1029p -e 1131p -e 1138p -e 1240p -e 1247p models/yolov4-csp_416.cfg
這裡我將 width, height 修改為 416×416,而口罩資料集的 label 有 3 個類別,因此 → filters=(classes + 5)*3 = (3+5)*3 = 24
sed -i '8s/512/416/' models/yolov4-csp_416.cfg && \
sed -i '9s/512/416/' models/yolov4-csp_416.cfg && \
sed -i '1022s/255/24/' models/yolov4-csp_416.cfg && \
sed -i '1029s/80/3/' models/yolov4-csp_416.cfg && \
sed -i '1131s/255/24/' models/yolov4-csp_416.cfg && \
sed -i '1138s/80/3/' models/yolov4-csp_416.cfg && \
sed -i '1240s/255/24/' models/yolov4-csp_416.cfg && \
sed -i '1247s/80/3/' models/yolov4-csp_416.cfg && \
# 查看修改後的參數
sed -n -e 8p -e 9p -e 1022p -e 1029p -e 1131p -e 1138p -e 1240p -e 1247p models/yolov4-csp_416.cfg
修改預設 anchors 值
nano face.data
train = ./yolov4-csp/data/train.txt
val = ./yolov4-csp/data/val.txt
classes = 3
計算 anchors 值
../darknet/darknet detector calc_anchors ../YOLOv4-CSP/face.data -num_of_clusters 9 -width 416 -height 416 -showpause
# 輸出: Saving anchors to the file: anchors.txt
anchors = 8, 15, 15, 27, 24, 39, 33, 58, 69, 56, 47, 85, 73,123, 131,127, 156,190
- 更改 anchors 值
# 查看原本 anchors 值
cd ./yolov4-csp
sed -n -e 1028p -e 1137p -e 1246p models/yolov4-csp_416.cfg
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
下指令修改
sed -i '1028s/ 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401/8, 15, 15, 27, 24, 39, 33, 58, 69, 56, 47, 85, 73,123, 131,127, 156,190/' models/yolov4-csp_416.cfg && \
sed -i '1137s/ 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401/8, 15, 15, 27, 24, 39, 33, 58, 69, 56, 47, 85, 73,123, 131,127, 156,190/' models/yolov4-csp_416.cfg && \
sed -i '1246s/ 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401/8, 15, 15, 27, 24, 39, 33, 58, 69, 56, 47, 85, 73,123, 131,127, 156,190/' models/yolov4-csp_416.cfg
訓練模型
安裝需要的依賴庫
pip3 install pyyaml tqdm matplotlib scipy
建立 face.yaml,並修改其內容
cd yolov4-csp
cp data/coco.yaml data/face.yaml
修改 face.yaml
train: data/train.txt
val: data/val.txt
# number of classes
nc: 3
# class names
names: ['with_mask', 'without_mask', 'mask_weared_incorrect']
建立 face.names,並修改其內容
with_mask
without_mask
mask_weared_incorrect
執行訓練
python3 train.py --device 0 --batch-size 4 --data data/face.yaml --cfg models/yolov4-csp_416.cfg --weights ‘’ --name yolov4-csp
usr/bin/env /usr/bin/python3 /home/ubuntu/.vscode-server/extensions/ms-python.python-2021.1.502429796/pythonFiles/lib/python/debugpy/launcher 34579 -- train.py --device 0 --batch-size 4 --data data/face.yaml --cfg models/yolov4-csp_416.cfg --name yolov4-csp --weights \'\'