今天給大家分享一個行人屬性分析系統。從視頻或者相機的視頻流中能識別行人,并標記每個人的屬性。

識別的屬性包括以下 10 類

有些類別有多個屬性,如果身體朝向有:正面、側面和背面,所以,最終訓練的屬性有 26 個。
實現這樣的系統需要 3 個步驟:
- 用 YOlOv5 識別行人
- 用 ByteTrack 跟蹤標記同一個人
- 訓練多標簽圖像分類網絡,識別行人 26 個屬性
1. 行人識別與追蹤
行人識別使用YOLOv5?目標檢測模型,可以自己訓練模型,也可以直接使用YOLOv5預訓練好的模型。
行人追蹤使用的是多目標跟蹤技術(MOT)?技術,視頻是由一幅幅畫面組成,雖然我們人類能夠識別出不同畫面中的同一個人, 但如果不對行人做追蹤,AI?是無法識別的。需要用MOT技術追蹤同一個人并給每個行人分配唯一的ID。
YOLOv5?模型的訓練、使用,以及多目標跟蹤技術(MOT)?技術的原理、實現方案,在上一篇文章有詳細的教程,感興趣的朋友可以查看那邊文章《YOLOv5+ByteTrack統計車流》。
2. 訓練多標簽分類網絡
我們最開始接觸的圖像分類大部分是單標簽分類?的,即:一張圖片歸為1類,類別可以是二分類?也可以是多分類?。假設有三個類別,每一張圖片對應的label可能是下面這總格式:
001.jpg 010
002.jpg 100
003.jpg 100
label?只有一個位置是1。
而我們今天要訓練的多標簽分類網絡?是一張圖片同時包含多個類別,label格式如下:
001.jpg 011
002.jpg 111
003.jpg 100
label?可以有多個位置是1。
訓練這樣的網絡,有兩種方案。一種是把每個類別看成是單標簽分類,單獨計算損失,匯總總,計算梯度更新網絡參數。
另一種可以直接訓練,但對需要注意網絡細節,以ResNet50為例
resnet50 = ResNet50(include_top=False, weights='imagenet')
# 遷移學習,不重新訓練卷積層
for layer in resnet50.layers:
layer.trainable = False
# 新的全連接層
x = Flatten()(resnet50.output)
x = Dense(1024)(x)
x = Activation('relu')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
# 輸出 26 個屬性的多分類標簽
x = Dense(26, activatinotallow='sigmoid')(x)
model = Model(inputs = resnet50.input, outputs=x)
最后輸出層的激活函數?必須要sigmoid?,因為需要每個屬性單獨計算概率。同理,訓練時的損失函數也需要用二分類?交叉熵binary_crossentropy。
實際上,上面兩種方法原理都是類似的,只不過開發的工作量不同。
這里為了方便,我使用的是PaddleCls?進行訓練。Paddle的配置簡單,缺點是有點黑盒,只能按照他那一套來,需要自定義的地方就比較麻煩。
模型訓練使用的是PA100K?數據集,需要注意的是,PA100K?數據集定義的原始label與Paddle雖然含義相同,但順序不同。
如:原始label?第1位代表是否是女性?,而Paddle?要求第1位代表是否戴帽子?,第22位才是是否是女性。

我們按照Paddle?的要求調整下原始label位置即可,這樣我們后面推理會方便些。
下載PaddleClas
git clone https://github.com/PaddlePaddle/PaddleClas
將下載的數據集解壓,放到PaddleClas的dataset目錄。
找到ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml?配置文件,配置圖片和label路徑。
DataLoader:
Train:
dataset:
name: MultiLabelDataset
image_root: "dataset/pa100k/" #指定訓練圖片所在根路徑
cls_label_path: "dataset/pa100k/train_list.txt" #指定訓練列表文件位置
label_ratio: True
transform_ops:
Eval:
dataset:
name: MultiLabelDataset
image_root: "dataset/pa100k/" #指定評估圖片所在根路徑
cls_label_path: "dataset/pa100k/val_list.txt" #指定評估列表文件位置
label_ratio: True
transform_ops:
train_list.txt的格式為
配置好后,就可以直接訓練了
python3 tools/train.py \
-c ./ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml
訓練完后,導出模型
python3 tools/export_model.py \
-c ./ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml \
-o Global.pretrained_model=output/PPLCNet_x1_0/best_model \
-o Global.save_inference_dir=deploy/models/PPLCNet_x1_0_person_attribute_infer
將導出的結果放在~/.paddleclas/inference_model/PULC/person_attribute/目錄下

便可以使用PaddleCls提供的函數直接調用
import paddleclas
model = paddleclas.PaddleClas(model_name="person_attribute")
result = model.predict(input_data="./test_imgs/000001.jpg")
print(result)
輸出結果如下:
[{'attributes': ['Female', 'Age18-60', 'Front', 'Glasses: False', 'Hat: False', 'HoldObjectsInFront: True', 'ShoulderBag', 'Upper: ShortSleeve', 'Lower: Trousers', 'No boots'], 'output': [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0], 'filename': './test_imgs/000001.jpg'}]
模型訓練過程就到這里了,數據集和整個項目的源碼已經打包好了。