はじめに
前回は、三次元物体認識の omni3D について説明しました。
今回は、動画から動作認識を行う TimeSformer について、実際に動かすまでの手順を説明していきます。
前提条件
前提条件は以下の通りです。
- Python3.9
- Windows11
- venv 環境
インストール手順
python -m venv venv
python -m pip install -U pip
pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu117
pip install 'git+https://github.com/facebookresearch/fvcore'
pip install simplejson
pip install einops
pip install timm
pip install psutil
pip install av
pip install scikit-learn
pip install opencv-python
pip install tensorboard
git clone https://github.com/facebookresearch/TimeSformer.git
cd TimeSformer
python setup.py build develop
example.py で確認
example.py を以下のように作成します。
import torch
from timesformer.models.vit import TimeSformer
import time
import numpy as np
model_file = './TimeSformer_divST_8x32_224_K600.pyth'
model = TimeSformer(img_size=224, num_classes=600, num_frames=8, attention_type='divided_space_time', pretrained_model=str(model_file))
model.cuda()
device = torch.device("cuda:0")
dummy_video = torch.randn(1, 3, 8, 224, 224, device=device) # (batch x channels x frames x height x width)
start = time.time()
pred = model(dummy_video,) # (2, 600)
pred = pred.detach().cpu().numpy()
max_index = np.argmax(pred[0])
print(max_index, pred[0][max_index])
print("prediction time: ", time.time()-start)
上記を実行してエラーが出なければ、TimeSformer の準備は完了です。
カスタムデータで学習させてみる
学習のために、demo フォルダに動画と train.csv, test.csv, val.csv を配置します。
各 csv ファイルは以下のようにします。
./demo/demo.mp4 0
./demo/demo-1.mp4 0
./demo/demo2.mp4 1
左側はファイルパス、右側はクラス番号です。
各動画は、こちらから 拝借しました。
また、configs/Kinetics/TimeSformer_divST_8x32_224.yaml を以下のようにします。
TRAIN:
ENABLE: True
DATASET: kinetics
BATCH_SIZE: 1
EVAL_PERIOD: 100
CHECKPOINT_PERIOD: 100
AUTO_RESUME: True
DATA:
PATH_TO_DATA_DIR: ./demo
NUM_FRAMES: 8
SAMPLING_RATE: 32
TRAIN_JITTER_SCALES: [256, 320]
TRAIN_CROP_SIZE: 224
TEST_CROP_SIZE: 224
INPUT_CHANNEL_NUM: [3]
TIMESFORMER:
ATTENTION_TYPE: 'divided_space_time'
SOLVER:
BASE_LR: 0.01
LR_POLICY: steps_with_relative_lrs
STEPS: [0, 101, 201]
LRS: [1, 0.1, 0.01]
MAX_EPOCH: 500
MOMENTUM: 0.9
WEIGHT_DECAY: 1e-4
OPTIMIZING_METHOD: sgd
MODEL:
MODEL_NAME: vit_base_patch16_224
NUM_CLASSES: 2
ARCH: vit
LOSS_FUNC: cross_entropy
DROPOUT_RATE: 0.05
TEST:
ENABLE: True
DATASET: kinetics
BATCH_SIZE: 1
NUM_ENSEMBLE_VIEWS: 1
NUM_SPATIAL_CROPS: 3
DATA_LOADER:
NUM_WORKERS: 1
PIN_MEMORY: True
NUM_GPUS: 1
NUM_SHARDS: 1
RNG_SEED: 0
OUTPUT_DIR: .
以下のコマンドで学習可能です。
python tools/run_net.py --cfg configs/Kinetics/TimeSformer_divST_8x32_224.yaml DATA.PATH_TO_DATA_DIR ./demo NUM_GPUS 1 TRAIN.BATCH_SIZE 1
これで loss が減少していけばいいのですが、loss に変化はなく、学習もできていませんでした…。
推論コード
学習がうまくいきませんでしたが、備忘録として推論コードを残しておきます。
import torch
from timesformer.models.vit import TimeSformer
import time
import numpy as np
import cv2
model_file = './checkpoints/checkpoint_epoch_00050.pyth'
model = TimeSformer(img_size=224, num_classes=2, num_frames=8, attention_type='divided_space_time', pretrained_model=str(model_file))
# model.cuda()
movie_path = "./demo/demo.mp4"
cap = cv2.VideoCapture(movie_path)
FRAMES = 8
BATCH = 1
SCALE = 1
while cap.isOpened():
frame_list = []
for i in range(FRAMES):
for _ in range(1):
ret = cap.grab()
ret, frame = cap.retrieve()
height, width, channel = frame.shape
height = int(height/SCALE)
width = int(width/SCALE)
frame = cv2.resize(frame, (width,height))
if not ret:
break
frame_list.append(frame)
input_movie = np.array(frame_list).reshape(BATCH,channel,FRAMES,height,width)/255
input_movie_tensor = torch.from_numpy(input_movie).float()
pred = model(input_movie_tensor,)
pred = pred.detach().cpu().numpy()
max_index = np.argmax(pred[0])
print(max_index, pred[0][max_index], pred.shape, pred)
cv2.imshow("frame", frame)
lastkey = cv2.waitKey(1)
if lastkey == ord("q"):
cv2.destroyAllWindows()
break
おわりに
今回は TimeSformer をカスタムデータで学習させる方法について説明しました。
loss が減少せずうまくいきませんでした。この辺は調査しておきますが issues の回答が 0 件なので難しいです。
次回は別の動画認識AIである 3D-ResNets-PyTorch について説明できればと思います。
コメント