『PPYOLO tiny尝鲜』基于PaddleDetection的人脸疲劳检测
老規矩,先上
B站視頻
AIStudio鏈接
背景介紹
背景一(老師的福音)
??講臺上老師認真上課,口若懸河;講臺下同學頻頻點頭,雙目具閉!
??45分鐘是很緊張的,老師在這個時間段內需要把計劃的教學任務完成,而如果學生無法積極配合、認真聽講,還在“閉目養神”、留著口水,老師還需要在課堂上叫醒那些“已經睡著了的人”,其實課堂效率就大大降低了。
??而如果此時能夠通過室內攝像頭捕捉學生面部表情及動作,以此來識別學生是否在打瞌睡,并向同學及老師積極反饋,或許能夠大大提高課堂效率,也方便老師及時了解學生課堂情況。
背景二(交通出行)
??一個人開車是一件很累的事,尤其是開長途,到了行車后期,人會非常疲憊,會出現“閉目”、“打哈欠”等動作。而此時,由于人的反應能力受阻,很容易發生交通事故。
??此時若有一個檢測設備,監測駕駛員的面部表情,在其疲憊時及時提醒駕駛員注意休息,能夠有效避免因疲勞駕駛而導致的車禍發生。
??而“眼睛”的睜閉和“嘴”的張閉是檢測人是否疲勞的一種合理方案。
技術方案
??本項目基于PaddleDetection目標檢測開發套件,選取1.3M超輕量PPYOLO tiny進行項目開發,并部署于windows端。
PPYOLO tiny是什么?
??在當前移動互聯網、物聯網、車聯網等行業迅猛發展的背景下,邊緣設備上直接部署目標檢測的需求越來越旺盛。生產線上往往需要在極低硬件成本的硬件例如樹莓派、FPGA、K210 等芯片上部署目標檢測算法。而我們常用的手機 App,也很難直接在終端采用超過 6M 的深度學習算法。如何在盡量不損失精度的前提下,獲得體積更小、運算速度更快的算法呢?得益于 PaddleSlim 飛槳模型壓縮工具的能力,體積僅為 1.3M 的 PP-YOLO Tiny 誕生了!!
精度速度數據
??那 PP-YOLO Tiny 具體采用了哪些優化策略呢?
??首先,PP-YOLO Tiny 沿用了 PP-YOLO 系列模型的 spp,iou loss, drop block, mixup, sync bn 等優化方法,并進一步采用了近 10 種針對移動端的優化策略:
??1、更適用于移動端的骨干網絡:
????骨干網絡可以說是一個模型的核心組成部分,對網絡的性能、體積影響巨大。PP-YOLO Tiny 采用了移動端高性價比骨干網絡 MobileNetV3。
??2、更適用移動端的檢測頭(head):
????除了骨干網絡,PP-YOLO Tiny 的檢測頭(head)部分采用了更適用于移動端的深度可分離卷積(Depthwise Separable Convolution),相比常規的卷積操作,有更少的參數量和運算成本, 更適用于移動端的內存空間和算力。
??3、去除對模型體積、速度有顯著影響的優化策略:
????在 PP-YOLO 中,采用了近 10 種優化策略,但并不是每一種都適用于移動端輕量化網絡,比如 iou aware 和 matrix nms 等。這類 Trick 在服務器端容易計算,但在移動端會引入很多額外的時延,對移動端來說性價比不高,因此去掉反而更適當。
??4、使用更小的輸入尺寸
????為了在移動端有更好的性能,PP-YOLO Tiny 采用 320 和 416 這兩種更小的輸入圖像尺寸。并在 PaddleDetection2.0 中提供 tools/anchor_cluster.py 腳本,使用戶可以一鍵式的獲得與目標數據集匹配的 Anchor。例如,在 COCO 數據集上,我們使用 320*320 尺度重新聚類了 anchor,并對應的在訓練過程中把每 batch 圖?的縮放范圍調整到 192-512 來適配?尺?輸?圖片的訓練,得到更高性能。
??5、召回率優化
????在使??尺寸輸入圖片時,對應的目標尺寸也會被縮?,漏檢的概率會變大,對應的我們采用了如下兩種方法來提升目標的召回率:
????a.原真實框的注冊方法是注冊到網格?最匹配的 anchor 上,優化后還會同時注冊到所有與該真實框的 IoU 不小于 0.25 的 anchor 上,提?了真實框注冊的正例。
????b.原來所有與真實框 IoU 小于 0.7 的 anchor 會被當錯負例,優化后將該閾值減小到 0.5,降低了負例比例。
????通過以上增加正例、減少負例的方法,彌補了在小尺寸上的正負例傾斜問題,提高了召回率。
??6、更大的 batch size
????往往更大的 Batch Size 可以使訓練更加穩定,獲取更優的結果。在 PP-YOLO Tiny 的訓練中,單卡 batch size 由 24 提升到了 32,8 卡總 batch size=8*32=256,最終得到在 COCO 數據集上體積 4.3M,精度與預測速度都較為理想的模型。
??7、量化后壓縮
????最后,結合 Paddle Inference 和 Paddle Lite 預測庫支持的后量化策略,即在將權重保存成量化后的 int8 數據。這樣的操作,是模型體積直接壓縮到了 1.3M,而預測時使用 Paddle Lite 加載權重,會將 int8 數據還原回 float32 權重,所以對精度和預測速度?乎沒有任何影響。
??通過以上一系列優化,我們就得到了 1.3M 超超超輕量的 PP-YOLO tiny 模型,而算法可以通過 Paddle Lite 直接部署在麒麟 990 等輕量化芯片上,預測效果也非常理想。
實地操作
# 先將PaddleDetection從gitee上download下來 !git clone https://gitee.com/paddlepaddle/PaddleDetection.git數據處理
??由于原數據集中存在圖片數據與標注數據不匹配的問題,故需要將不匹配的這部分數據刪除。
import os,shutiljpeg = 'dataset/JPEGImages' jpeg_list = os.listdir(jpeg)anno = 'dataset/Annotations' anno_list = os.listdir(anno)for pic in jpeg_list:name = pic.split('.')[0]anno_name = name + '.xml'print(anno_name)if anno_name not in anno_list:os.remove(os.path.join(jpeg,pic)) 這里我們通過paddlex中的數據集劃分工具幫助我們進行數據集劃分。 !pip install paddlex !pip install paddle2onnx 我們設置了訓練集、驗證集、測試集比例為8:1:1,訓練集共2332個sammples,驗證集和測試集均為291個samples。 !paddlex --split_dataset --format VOC --dataset_dir dataset --val_value 0.1 --test_value 0.1 PaddleDetection中提供了VOC數據集轉COCO數據集的腳本,但提供的腳本存在一些bug,本人在PaddleDetection的Github issue中找到了一個修復后的腳本:x2coco.py。 這里我們將前面修改完畢的VOC格式的數據集轉化為符合PaddleDetection PPYOLO tiny的COCO數據集格式。 !python x2coco.py --dataset_type voc --voc_anno_dir /home/aistudio/dataset/Annotations/ --voc_anno_list /home/aistudio/dataset/ImageSets/Main/train.txt --voc_label_list /home/aistudio/dataset/labels.txt --voc_out_name voc_test.json !python x2coco.py --dataset_type voc --voc_anno_dir /home/aistudio/dataset/Annotations/ --voc_anno_list /home/aistudio/dataset/ImageSets/Main/val.txt --voc_label_list /home/aistudio/dataset/labels.txt --voc_out_name voc_val.json !python x2coco.py --dataset_type voc --voc_anno_dir /home/aistudio/dataset/Annotations/ --voc_anno_list /home/aistudio/dataset/ImageSets/Main/test.txt --voc_label_list /home/aistudio/dataset/labels.txt --voc_out_name voc_train.json !mv voc_train.json dataset/ !mv voc_test.json dataset/ !mv voc_val.json dataset/ Start converting ! 100%|████████████████████████████████████| 1631/1631 [00:00<00:00, 12327.36it/s] Start converting ! 100%|██████████████████████████████████████| 583/583 [00:00<00:00, 12504.37it/s] Start converting ! 100%|████████████████████████████████████| 1283/1283 [00:00<00:00, 12609.82it/s]修改配置文件(./PaddleDetection/configs/ppyolo/ppyolo_tiny_650e_coco.yml)
在yolo系列模型中,可以運行tools/anchor_cluster.py來得到適用于你的數據集Anchor,使用方法如下:
!python tools/anchor_cluster.py -c configs/ppyolo/ppyolo_tiny_650e_coco.yml -n 9 -s 608 -m v2 -i 1000為了適配在自定義數據集上訓練,需要對參數配置做一些修改:
數據路徑配置: 在yaml配置文件中,依據數據準備中準備好的路徑,配置TrainReader、EvalReader和TestReader的路徑。
其余參數具體可參照PaddleDetection,這里不作過多介紹。
然后執行訓練腳本即可。
%cd PaddleDetection/ !pip install -r requirements.txt !python -u tools/train.py -c configs/ppyolo/ppyolo_tiny_650e_coco.yml \-o pretrain_weights=https://paddledet.bj.bcebos.com/models/pretrained/MobileNetV3_large_x0_5_pretrained.pdparams \--eval \-r output/ppyolo_tiny_650e_coco/1200 \--vdl_log_dir vdl_log_dir/scalar數據導出
??訓練完后我們將訓練過程中保存的模型導出為inference格式模型,其原因在于:PaddlePaddle框架保存的權重文件分為兩種:支持前向推理和反向梯度的訓練模型 和 只支持前向推理的推理模型。二者的區別是推理模型針對推理速度和顯存做了優化,裁剪了一些只在訓練過程中才需要的tensor,降低顯存占用,并進行了一些類似層融合,kernel選擇的速度優化。而導出的inference格式模型包括__model__、__params__和model.yml三個文件,分別表示模型的網絡結構、模型權重和模型的配置文件(包括數據預處理參數等)。
# 導出模型,默認存儲于output/ppyolo目錄 !python tools/export_model.py -c configs/ppyolo/ppyolo_tiny_650e_coco.yml -o weights=Poutput/ppyolo_tiny_650e_coco/best_model同樣的,PaddleDetection也提供了基于Python的預測腳本供開發者使用。
參數說明如下:
| –model_dir | Yes | 上述導出的模型路徑 |
| –image_file | Option | 需要預測的圖片 |
| –image_dir | Option | 要預測的圖片文件夾路徑 |
| –video_file | Option | 需要預測的視頻 |
| –camera_id | Option | 用來預測的攝像頭ID,默認為-1(表示不使用攝像頭預測,可設置為:0 - (攝像頭數目-1) ),預測過程中在可視化界面按q退出輸出預測結果到:output/output.mp4 |
| –use_gpu | No | 是否GPU,默認為False |
| –run_mode | No | 使用GPU時,默認為fluid, 可選(fluid/trt_fp32/trt_fp16/trt_int8) |
| –batch_size | No | 預測時的batch size,在指定image_dir時有效 |
| –threshold | No | 預測得分的閾值,默認為0.5 |
| –output_dir | No | 可視化結果保存的根目錄,默認為output/ |
| –run_benchmark | No | 是否運行benchmark,同時需指定--image_file或--image_dir |
| –enable_mkldnn | No | CPU預測中是否開啟MKLDNN加速 |
| –cpu_threads | No | 設置cpu線程數,默認為1 |
當然,在本項目中也提供了PaddleX 訓練及導出方式,可供讀者朋友嘗試不同的飛槳套件。
# 環境變量配置,用于控制是否使用GPU # 說明文檔:https://paddlex.readthedocs.io/zh_CN/develop/appendix/parameters.html#gpu import os os.environ['CUDA_VISIBLE_DEVICES'] = '0'from paddlex.det import transforms import paddlex as pdx# 定義訓練和驗證時的transforms # API說明 https://paddlex.readthedocs.io/zh_CN/develop/apis/transforms/det_transforms.html train_transforms = transforms.Compose([transforms.MixupImage(mixup_epoch=250), transforms.RandomDistort(),transforms.RandomExpand(), transforms.RandomCrop(), transforms.Resize(target_size=608, interp='RANDOM'), transforms.RandomHorizontalFlip(),transforms.Normalize() ])eval_transforms = transforms.Compose([transforms.Resize(target_size=608, interp='CUBIC'), transforms.Normalize() ])# 定義訓練和驗證所用的數據集 # API說明:https://paddlex.readthedocs.io/zh_CN/develop/apis/datasets.html#paddlex-datasets-vocdetection train_dataset = pdx.datasets.VOCDetection(data_dir='dataset',file_list='dataset/train_list.txt',label_list='dataset/labels.txt',transforms=train_transforms,shuffle=True) eval_dataset = pdx.datasets.VOCDetection(data_dir='dataset',file_list='dataset/val_list.txt',label_list='dataset/labels.txt',transforms=eval_transforms)# 初始化模型,并進行訓練 # 可使用VisualDL查看訓練指標,參考https://paddlex.readthedocs.io/zh_CN/develop/train/visualdl.html num_classes = len(train_dataset.labels)# API說明: https://paddlex.readthedocs.io/zh_CN/develop/apis/models/detection.html#paddlex-det-ppyolo model = pdx.det.PPYOLO(num_classes=num_classes)# API說明: https://paddlex.readthedocs.io/zh_CN/develop/apis/models/detection.html#train # 各參數介紹與調整說明:https://paddlex.readthedocs.io/zh_CN/develop/appendix/parameters.html model.train(num_epochs=270,train_dataset=train_dataset,train_batch_size=8,eval_dataset=eval_dataset,learning_rate=0.000125,lr_decay_epochs=[210, 240],save_dir='output/ppyolo',save_interval_epochs=1,use_vdl=True) !paddlex --export_inference --model_dir=output/ppyolo/best_model --save_dir=./inference_model總結
以上是生活随笔為你收集整理的『PPYOLO tiny尝鲜』基于PaddleDetection的人脸疲劳检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爸,这下你还敢抽烟么?
- 下一篇: 『森林火灾检测』基于PaddleX实现森