動画データを読み込む

TensorFlow.org で表示 Google Colab で実行 GitHubでソースを表示 ノートブックをダウンロード

このチュートリアルでは、UCF101 人間行動データセットを使用して AVI 動画データを読み込んで前処理する方法を実演します。データを前処理すると、動画の分類/認識、キャプション、クラスタリングなどのタスクに使用できます。元のデータセットには、チェロの演奏、歯磨き、アイメイクなど、YouTube から収集された 101 のカテゴリのリアルなアクション動画が含まれています。このチュートリアルでは以下を見ていきます。

  • zip ファイルからデータを読み込む。

  • 動画を個別のフレームに分割する。

  • 動画データを視覚化する。

  • パフォーマンスを向上するために、データセットを tf.data.Dataset でラップする。

セットアップ

まず、ZIP ファイルの内容を検査するための remotezip、 プログレス バーを使用するための tqdm、動画ファイルを処理するための OpenCV{ :.external}、Jupyter ノートブックにデータを埋め込むための tensorflow_docs などの必要なライブラリをインストールしてインポートします。

pip install remotezip tqdm opencv-python
pip install -q git+https://github.com/tensorflow/docs
import tqdm
import random
import pathlib
import itertools
import collections

import os
import cv2
import numpy as np
import remotezip as rz

import tensorflow as tf

# Some modules to display an animation using imageio.
import imageio
from IPython import display
from urllib import request
from tensorflow_docs.vis import embed
2022-12-15 01:00:24.460612: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /tmpfs/src/tf_docs_env/lib/python3.9/site-packages/cv2/../../lib64:
2022-12-15 01:00:24.460733: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /tmpfs/src/tf_docs_env/lib/python3.9/site-packages/cv2/../../lib64:
2022-12-15 01:00:24.460745: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.

UCF101 データセットのサブセットをダウンロードする

UCF101 データセットには、101 カテゴリの動画内のさまざまなアクションが含まれており、主にアクション認識で使用されます。 このデモでは、これらのカテゴリのサブセットを使用します。

URL = 'https://storage.googleapis.com/thumos14_files/UCF101_videos.zip'

上記の URL には、UCF 101 データセットの zip ファイルが含まれています。remotezip ライブラリを使用してその URL の zip ファイルの内容を調べる関数を作成します。

def list_files_from_zip_url(zip_url):
  """ List the files in each class of the dataset given a URL with the zip file.

    Args:
      zip_url: A URL from which the files can be extracted from.

    Returns:
      List of files in each of the classes.
  """
  files = []
  with rz.RemoteZip(URL) as zip:
    for zip_info in zip.infolist():
      files.append(zip_info.filename)
  return files
files = list_files_from_zip_url(URL)
files = [f for f in files if f.endswith('.avi')]
files[:10]
['UCF101/v_ApplyEyeMakeup_g01_c01.avi',
 'UCF101/v_ApplyEyeMakeup_g01_c02.avi',
 'UCF101/v_ApplyEyeMakeup_g01_c03.avi',
 'UCF101/v_ApplyEyeMakeup_g01_c04.avi',
 'UCF101/v_ApplyEyeMakeup_g01_c05.avi',
 'UCF101/v_ApplyEyeMakeup_g01_c06.avi',
 'UCF101/v_ApplyEyeMakeup_g02_c01.avi',
 'UCF101/v_ApplyEyeMakeup_g02_c02.avi',
 'UCF101/v_ApplyEyeMakeup_g02_c03.avi',
 'UCF101/v_ApplyEyeMakeup_g02_c04.avi']

いくつかの動画とトレーニング用の限られた数のクラスから始めます。上記のコードブロックを実行した後、クラス名が各動画のファイル名に含まれていることに注意してください。

ファイル名からクラス名を取得する get_class 関数を定義します。次に、すべてのファイル (上記の files) のリストを各クラスのファイルをリストするディクショナリに変換する get_files_per_class という関数を作成します。

def get_class(fname):
  """ Retrieve the name of the class given a filename.

    Args:
      fname: Name of the file in the UCF101 dataset.

    Returns:
      Class that the file belongs to.
  """
  return fname.split('_')[-3]
def get_files_per_class(files):
  """ Retrieve the files that belong to each class. 

    Args:
      files: List of files in the dataset.

    Returns:
      Dictionary of class names (key) and files (values).
  """
  files_for_class = collections.defaultdict(list)
  for fname in files:
    class_name = get_class(fname)
    files_for_class[class_name].append(fname)
  return files_for_class

クラスごとのファイルのリストを取得したら、データセットを作成するために、使用するクラスの数と、クラスごとに必要な動画の数を選択します。

NUM_CLASSES = 10
FILES_PER_CLASS = 50
files_for_class = get_files_per_class(files)
classes = list(files_for_class.keys())
print('Num classes:', len(classes))
print('Num videos for class[0]:', len(files_for_class[classes[0]]))
Num classes: 101
Num videos for class[0]: 145

データセット内に存在するクラスのサブセットと、クラスごとに特定の数のファイルを選択する select_subset_of_classes という新しい関数を作成します。

def select_subset_of_classes(files_for_class, classes, files_per_class):
  """ Create a dictionary with the class name and a subset of the files in that class.

    Args:
      files_for_class: Dictionary of class names (key) and files (values).
      classes: List of classes.
      files_per_class: Number of files per class of interest.

    Returns:
      Dictionary with class as key and list of specified number of video files in that class.
  """
  files_subset = dict()

  for class_name in classes:
    class_files = files_for_class[class_name]
    files_subset[class_name] = class_files[:files_per_class]

  return files_subset
files_subset = select_subset_of_classes(files_for_class, classes[:NUM_CLASSES], FILES_PER_CLASS)
list(files_subset.keys())
['ApplyEyeMakeup',
 'ApplyLipstick',
 'Archery',
 'BabyCrawling',
 'BalanceBeam',
 'BandMarching',
 'BaseballPitch',
 'BasketballDunk',
 'Basketball',
 'BenchPress']

動画をトレーニングセット、検証セット、およびテストセットに分割するヘルパー関数を定義します。動画は zip ファイルを含む URL からダウンロードされ、それぞれのサブディレクトリに配置されます。

def download_from_zip(zip_url, to_dir, file_names):
  """ Download the contents of the zip file from the zip URL.

    Args:
      zip_url: A URL with a zip file containing data.
      to_dir: A directory to download data to.
      file_names: Names of files to download.
  """
  with rz.RemoteZip(zip_url) as zip:
    for fn in tqdm.tqdm(file_names):
      class_name = get_class(fn)
      zip.extract(fn, str(to_dir / class_name))
      unzipped_file = to_dir / class_name / fn

      fn = pathlib.Path(fn).parts[-1]
      output_file = to_dir / class_name / fn
      unzipped_file.rename(output_file)

次の関数は、まだデータのサブセットに配置されていない残りのデータを返します。残りのデータを次に指定されたデータのサブセットに配置します。

def split_class_lists(files_for_class, count):
  """ Returns the list of files belonging to a subset of data as well as the remainder of
    files that need to be downloaded.

    Args:
      files_for_class: Files belonging to a particular class of data.
      count: Number of files to download.

    Returns:
      Files belonging to the subset of data and dictionary of the remainder of files that need to be downloaded.
  """
  split_files = []
  remainder = {}
  for cls in files_for_class:
    split_files.extend(files_for_class[cls][:count])
    remainder[cls] = files_for_class[cls][count:]
  return split_files, remainder

次の download_ufc_101_subset 関数を使用すると、UCF101 データセットのサブセットをダウンロードして、トレーニングセット、検証セット、テストセットに分割できます。使用するクラスの数を指定できます。splits 引数を使用すると、ディクショナリを渡すことができます。ディクショナリの主な値はサブセットの名前 (例: 「トレーニング」) とクラスごとの動画の数です。

def download_ufc_101_subset(zip_url, num_classes, splits, download_dir):
  """ Download a subset of the UFC101 dataset and split them into various parts, such as
    training, validation, and test.

    Args:
      zip_url: A URL with a ZIP file with the data.
      num_classes: Number of labels.
      splits: Dictionary specifying the training, validation, test, etc. (key) division of data 
              (value is number of files per split).
      download_dir: Directory to download data to.

    Return:
      Mapping of the directories containing the subsections of data.
  """
  files = list_files_from_zip_url(zip_url)
  for f in files:
    path = os.path.normpath(f)
    tokens = path.split(os.sep)
    if len(tokens) <= 2:
      files.remove(f) # Remove that item from the list if it does not have a filename

  files_for_class = get_files_per_class(files)

  classes = list(files_for_class.keys())[:num_classes]

  for cls in classes:
    random.shuffle(files_for_class[cls])

  # Only use the number of classes you want in the dictionary
  files_for_class = {x: files_for_class[x] for x in classes}

  dirs = {}
  for split_name, split_count in splits.items():
    print(split_name, ":")
    split_dir = download_dir / split_name
    split_files, files_for_class = split_class_lists(files_for_class, split_count)
    download_from_zip(zip_url, split_dir, split_files)
    dirs[split_name] = split_dir

  return dirs
download_dir = pathlib.Path('./UCF101_subset/')
subset_paths = download_ufc_101_subset(URL,
                                       num_classes = NUM_CLASSES,
                                       splits = {"train": 30, "val": 10, "test": 10},
                                       download_dir = download_dir)
train :
100%|██████████| 300/300 [00:27<00:00, 10.96it/s]
val :
100%|██████████| 100/100 [00:10<00:00,  9.33it/s]
test :
100%|██████████| 100/100 [00:10<00:00,  9.79it/s]

データをダウンロードすると、UCF101 データセットのサブセットのコピーが作成されます。次のコードを実行して、データのすべてのサブセットの中にある動画の総数を出力します。

video_count_train = len(list(download_dir.glob('train/*/*.avi')))
video_count_val = len(list(download_dir.glob('val/*/*.avi')))
video_count_test = len(list(download_dir.glob('test/*/*.avi')))
video_total = video_count_train + video_count_val + video_count_test
print(f"Total videos: {video_total}")
Total videos: 500

また、データ ファイルのディレクトリをプレビューすることもできます。

find ./UCF101_subset
./UCF101_subset
./UCF101_subset/val
./UCF101_subset/val/BenchPress
./UCF101_subset/val/BenchPress/v_BenchPress_g02_c05.avi
./UCF101_subset/val/BenchPress/UCF101
./UCF101_subset/val/BenchPress/v_BenchPress_g08_c07.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g18_c07.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g04_c01.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g19_c04.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g10_c03.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g23_c02.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g22_c01.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g07_c06.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g13_c07.avi
./UCF101_subset/val/BandMarching
./UCF101_subset/val/BandMarching/v_BandMarching_g08_c06.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g01_c05.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g02_c06.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g13_c02.avi
./UCF101_subset/val/BandMarching/UCF101
./UCF101_subset/val/BandMarching/v_BandMarching_g21_c02.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g14_c01.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g10_c02.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g15_c05.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g17_c01.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g03_c07.avi
./UCF101_subset/val/BabyCrawling
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g09_c04.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g06_c02.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g07_c02.avi
./UCF101_subset/val/BabyCrawling/UCF101
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g17_c01.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g12_c01.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g24_c03.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g23_c01.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g16_c05.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g22_c04.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g02_c05.avi
./UCF101_subset/val/Basketball
./UCF101_subset/val/Basketball/v_Basketball_g09_c02.avi
./UCF101_subset/val/Basketball/v_Basketball_g22_c07.avi
./UCF101_subset/val/Basketball/UCF101
./UCF101_subset/val/Basketball/v_Basketball_g19_c05.avi
./UCF101_subset/val/Basketball/v_Basketball_g17_c02.avi
./UCF101_subset/val/Basketball/v_Basketball_g04_c04.avi
./UCF101_subset/val/Basketball/v_Basketball_g23_c04.avi
./UCF101_subset/val/Basketball/v_Basketball_g06_c02.avi
./UCF101_subset/val/Basketball/v_Basketball_g10_c05.avi
./UCF101_subset/val/Basketball/v_Basketball_g08_c04.avi
./UCF101_subset/val/Basketball/v_Basketball_g01_c03.avi
./UCF101_subset/val/BasketballDunk
./UCF101_subset/val/BasketballDunk/UCF101
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g25_c01.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g25_c03.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g03_c03.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g14_c02.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g17_c04.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g10_c05.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g19_c03.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g04_c01.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g07_c01.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g03_c05.avi
./UCF101_subset/val/Archery
./UCF101_subset/val/Archery/v_Archery_g04_c05.avi
./UCF101_subset/val/Archery/v_Archery_g18_c02.avi
./UCF101_subset/val/Archery/UCF101
./UCF101_subset/val/Archery/v_Archery_g07_c01.avi
./UCF101_subset/val/Archery/v_Archery_g23_c05.avi
./UCF101_subset/val/Archery/v_Archery_g09_c06.avi
./UCF101_subset/val/Archery/v_Archery_g01_c06.avi
./UCF101_subset/val/Archery/v_Archery_g25_c02.avi
./UCF101_subset/val/Archery/v_Archery_g24_c04.avi
./UCF101_subset/val/Archery/v_Archery_g04_c01.avi
./UCF101_subset/val/Archery/v_Archery_g02_c07.avi
./UCF101_subset/val/ApplyLipstick
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g06_c01.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g02_c01.avi
./UCF101_subset/val/ApplyLipstick/UCF101
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g24_c05.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g13_c03.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g06_c03.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g01_c02.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g19_c04.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g03_c01.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g10_c04.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g11_c02.avi
./UCF101_subset/val/BalanceBeam
./UCF101_subset/val/BalanceBeam/UCF101
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g21_c01.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g06_c07.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g19_c03.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g23_c04.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g19_c01.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g24_c01.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g25_c03.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g15_c03.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g06_c05.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g06_c01.avi
./UCF101_subset/val/ApplyEyeMakeup
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g01_c01.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g23_c06.avi
./UCF101_subset/val/ApplyEyeMakeup/UCF101
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g12_c05.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g09_c04.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g11_c02.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g04_c07.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g07_c04.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g20_c06.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g11_c04.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g03_c03.avi
./UCF101_subset/val/BaseballPitch
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g10_c01.avi
./UCF101_subset/val/BaseballPitch/UCF101
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g07_c04.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g22_c02.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g23_c01.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g13_c03.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g03_c04.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g08_c07.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g14_c02.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g17_c07.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g06_c01.avi
./UCF101_subset/train
./UCF101_subset/train/BenchPress
./UCF101_subset/train/BenchPress/v_BenchPress_g21_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g03_c06.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g07_c04.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g16_c03.avi
./UCF101_subset/train/BenchPress/UCF101
./UCF101_subset/train/BenchPress/v_BenchPress_g10_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g22_c07.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g06_c07.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g11_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g25_c04.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g19_c06.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g17_c02.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g18_c05.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g08_c05.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g09_c04.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g04_c07.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g13_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g08_c03.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g02_c03.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g12_c04.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g16_c05.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g09_c06.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g01_c03.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g11_c03.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g22_c03.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g01_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g02_c07.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g14_c06.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g25_c02.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g24_c03.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g22_c05.avi
./UCF101_subset/train/BandMarching
./UCF101_subset/train/BandMarching/v_BandMarching_g11_c05.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g08_c02.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g11_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g11_c01.avi
./UCF101_subset/train/BandMarching/UCF101
./UCF101_subset/train/BandMarching/v_BandMarching_g20_c04.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g07_c01.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g24_c01.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g09_c05.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g14_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g04_c02.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g24_c05.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g07_c05.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g02_c02.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g23_c05.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g19_c05.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g06_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g25_c05.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g15_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g02_c04.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g09_c07.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g03_c01.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g01_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g25_c01.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g09_c01.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g07_c07.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g10_c06.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g10_c04.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g24_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g19_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g23_c03.avi
./UCF101_subset/train/BabyCrawling
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g20_c05.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g16_c03.avi
./UCF101_subset/train/BabyCrawling/UCF101
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g07_c06.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g13_c05.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g25_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g07_c04.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g19_c02.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g03_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g19_c04.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g15_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g09_c02.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g17_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g15_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g14_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g12_c05.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g18_c04.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g13_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g05_c05.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g17_c05.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g11_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g12_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g11_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g03_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g06_c06.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g02_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g18_c06.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g05_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g22_c02.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g25_c05.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g25_c03.avi
./UCF101_subset/train/Basketball
./UCF101_subset/train/Basketball/v_Basketball_g25_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g11_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g25_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g24_c04.avi
./UCF101_subset/train/Basketball/UCF101
./UCF101_subset/train/Basketball/v_Basketball_g24_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g15_c01.avi
./UCF101_subset/train/Basketball/v_Basketball_g11_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g15_c05.avi
./UCF101_subset/train/Basketball/v_Basketball_g19_c07.avi
./UCF101_subset/train/Basketball/v_Basketball_g21_c05.avi
./UCF101_subset/train/Basketball/v_Basketball_g05_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g14_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g22_c01.avi
./UCF101_subset/train/Basketball/v_Basketball_g12_c03.avi
./UCF101_subset/train/Basketball/v_Basketball_g10_c01.avi
./UCF101_subset/train/Basketball/v_Basketball_g16_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g03_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g20_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g22_c03.avi
./UCF101_subset/train/Basketball/v_Basketball_g19_c01.avi
./UCF101_subset/train/Basketball/v_Basketball_g12_c05.avi
./UCF101_subset/train/Basketball/v_Basketball_g20_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g15_c03.avi
./UCF101_subset/train/Basketball/v_Basketball_g12_c01.avi
./UCF101_subset/train/Basketball/v_Basketball_g05_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g07_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g22_c05.avi
./UCF101_subset/train/Basketball/v_Basketball_g20_c06.avi
./UCF101_subset/train/Basketball/v_Basketball_g03_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g16_c02.avi
./UCF101_subset/train/BasketballDunk
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g09_c02.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g12_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g03_c01.avi
./UCF101_subset/train/BasketballDunk/UCF101
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g17_c06.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g22_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g10_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g20_c05.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g01_c02.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g05_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g20_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g06_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g14_c06.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g15_c05.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g15_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g16_c02.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g12_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g08_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g05_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g21_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g24_c02.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g01_c04.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g18_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g10_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g02_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g14_c04.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g23_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g01_c06.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g08_c05.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g05_c05.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g08_c01.avi
./UCF101_subset/train/Archery
./UCF101_subset/train/Archery/v_Archery_g12_c03.avi
./UCF101_subset/train/Archery/v_Archery_g02_c03.avi
./UCF101_subset/train/Archery/v_Archery_g21_c04.avi
./UCF101_subset/train/Archery/UCF101
./UCF101_subset/train/Archery/v_Archery_g14_c02.avi
./UCF101_subset/train/Archery/v_Archery_g14_c04.avi
./UCF101_subset/train/Archery/v_Archery_g25_c04.avi
./UCF101_subset/train/Archery/v_Archery_g11_c04.avi
./UCF101_subset/train/Archery/v_Archery_g13_c03.avi
./UCF101_subset/train/Archery/v_Archery_g09_c04.avi
./UCF101_subset/train/Archery/v_Archery_g23_c01.avi
./UCF101_subset/train/Archery/v_Archery_g15_c04.avi
./UCF101_subset/train/Archery/v_Archery_g24_c02.avi
./UCF101_subset/train/Archery/v_Archery_g11_c02.avi
./UCF101_subset/train/Archery/v_Archery_g15_c06.avi
./UCF101_subset/train/Archery/v_Archery_g16_c03.avi
./UCF101_subset/train/Archery/v_Archery_g20_c07.avi
./UCF101_subset/train/Archery/v_Archery_g18_c04.avi
./UCF101_subset/train/Archery/v_Archery_g09_c02.avi
./UCF101_subset/train/Archery/v_Archery_g03_c02.avi
./UCF101_subset/train/Archery/v_Archery_g01_c02.avi
./UCF101_subset/train/Archery/v_Archery_g10_c07.avi
./UCF101_subset/train/Archery/v_Archery_g24_c06.avi
./UCF101_subset/train/Archery/v_Archery_g16_c05.avi
./UCF101_subset/train/Archery/v_Archery_g20_c05.avi
./UCF101_subset/train/Archery/v_Archery_g17_c02.avi
./UCF101_subset/train/Archery/v_Archery_g11_c06.avi
./UCF101_subset/train/Archery/v_Archery_g15_c02.avi
./UCF101_subset/train/Archery/v_Archery_g20_c03.avi
./UCF101_subset/train/Archery/v_Archery_g02_c05.avi
./UCF101_subset/train/Archery/v_Archery_g23_c07.avi
./UCF101_subset/train/ApplyLipstick
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g18_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g14_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g24_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g04_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g15_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g12_c02.avi
./UCF101_subset/train/ApplyLipstick/UCF101
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g24_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g25_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g25_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g16_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g23_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g15_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g04_c05.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g22_c06.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g09_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g04_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g17_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g21_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g03_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g22_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g15_c05.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g12_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g21_c05.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g07_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g14_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g07_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g10_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g19_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g21_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g20_c04.avi
./UCF101_subset/train/BalanceBeam
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g18_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g21_c05.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g22_c04.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g10_c04.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g01_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g16_c03.avi
./UCF101_subset/train/BalanceBeam/UCF101
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g22_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g23_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g21_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g11_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g03_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g02_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g25_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g18_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g13_c04.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g17_c05.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g17_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g20_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g04_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g10_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g03_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g08_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g09_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g06_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g16_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g01_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g14_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g02_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g09_c04.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g11_c04.avi
./UCF101_subset/train/ApplyEyeMakeup
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g23_c04.avi
./UCF101_subset/train/ApplyEyeMakeup/UCF101
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g05_c02.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g03_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g13_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g07_c02.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g17_c04.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g16_c05.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g25_c05.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g18_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g17_c02.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g15_c02.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g14_c05.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g08_c05.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g19_c02.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g05_c04.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g06_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g18_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g07_c06.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g15_c06.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g24_c04.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g02_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g14_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g10_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g12_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g12_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g14_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g22_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g04_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g16_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g03_c05.avi
./UCF101_subset/train/BaseballPitch
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g12_c01.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g01_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g25_c03.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g18_c06.avi
./UCF101_subset/train/BaseballPitch/UCF101
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g19_c03.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g15_c04.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g13_c05.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g05_c04.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g07_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g10_c05.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g01_c06.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g01_c04.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g17_c03.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g05_c06.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g17_c05.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g20_c04.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g24_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g21_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g24_c04.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g15_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g03_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g03_c06.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g22_c06.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g13_c01.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g23_c05.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g23_c03.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g11_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g16_c05.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g18_c04.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g06_c05.avi
./UCF101_subset/test
./UCF101_subset/test/BenchPress
./UCF101_subset/test/BenchPress/v_BenchPress_g15_c01.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g03_c02.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g07_c02.avi
./UCF101_subset/test/BenchPress/UCF101
./UCF101_subset/test/BenchPress/v_BenchPress_g17_c06.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g12_c06.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g04_c05.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g20_c06.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g18_c01.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g06_c03.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g05_c06.avi
./UCF101_subset/test/BandMarching
./UCF101_subset/test/BandMarching/UCF101
./UCF101_subset/test/BandMarching/v_BandMarching_g16_c06.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g01_c07.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g25_c07.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g18_c05.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g20_c02.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g04_c04.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g22_c02.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g05_c04.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g18_c01.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g06_c01.avi
./UCF101_subset/test/BabyCrawling
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g15_c05.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g24_c05.avi
./UCF101_subset/test/BabyCrawling/UCF101
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g16_c01.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g13_c01.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g24_c01.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g01_c03.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g10_c02.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g10_c04.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g18_c02.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g08_c04.avi
./UCF101_subset/test/Basketball
./UCF101_subset/test/Basketball/v_Basketball_g23_c02.avi
./UCF101_subset/test/Basketball/UCF101
./UCF101_subset/test/Basketball/v_Basketball_g01_c01.avi
./UCF101_subset/test/Basketball/v_Basketball_g18_c04.avi
./UCF101_subset/test/Basketball/v_Basketball_g19_c03.avi
./UCF101_subset/test/Basketball/v_Basketball_g16_c06.avi
./UCF101_subset/test/Basketball/v_Basketball_g25_c06.avi
./UCF101_subset/test/Basketball/v_Basketball_g13_c04.avi
./UCF101_subset/test/Basketball/v_Basketball_g04_c02.avi
./UCF101_subset/test/Basketball/v_Basketball_g09_c04.avi
./UCF101_subset/test/Basketball/v_Basketball_g21_c03.avi
./UCF101_subset/test/BasketballDunk
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g13_c04.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g02_c01.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g21_c03.avi
./UCF101_subset/test/BasketballDunk/UCF101
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g23_c03.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g13_c02.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g15_c07.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g22_c03.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g04_c03.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g06_c03.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g11_c02.avi
./UCF101_subset/test/Archery
./UCF101_subset/test/Archery/UCF101
./UCF101_subset/test/Archery/v_Archery_g01_c04.avi
./UCF101_subset/test/Archery/v_Archery_g06_c05.avi
./UCF101_subset/test/Archery/v_Archery_g04_c03.avi
./UCF101_subset/test/Archery/v_Archery_g19_c03.avi
./UCF101_subset/test/Archery/v_Archery_g06_c01.avi
./UCF101_subset/test/Archery/v_Archery_g10_c01.avi
./UCF101_subset/test/Archery/v_Archery_g23_c03.avi
./UCF101_subset/test/Archery/v_Archery_g02_c01.avi
./UCF101_subset/test/Archery/v_Archery_g12_c01.avi
./UCF101_subset/test/Archery/v_Archery_g13_c01.avi
./UCF101_subset/test/ApplyLipstick
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g23_c03.avi
./UCF101_subset/test/ApplyLipstick/UCF101
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g16_c04.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g06_c05.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g22_c02.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g05_c04.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g17_c05.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g02_c03.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g18_c04.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g08_c04.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g13_c01.avi
./UCF101_subset/test/BalanceBeam
./UCF101_subset/test/BalanceBeam/UCF101
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g12_c02.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g05_c01.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g17_c03.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g12_c04.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g07_c04.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g15_c01.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g07_c02.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g24_c03.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g08_c04.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g20_c01.avi
./UCF101_subset/test/ApplyEyeMakeup
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g21_c04.avi
./UCF101_subset/test/ApplyEyeMakeup/UCF101
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g08_c01.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g19_c04.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g06_c07.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g02_c01.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g24_c02.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g21_c02.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g06_c03.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g09_c02.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g05_c06.avi
./UCF101_subset/test/BaseballPitch
./UCF101_subset/test/BaseballPitch/UCF101
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g13_c07.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g22_c04.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g06_c03.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g07_c06.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g25_c05.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g02_c04.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g09_c06.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g08_c01.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g19_c05.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g15_c06.avi

各動画ファイルからフレームを作成する

次の関数は、動画をフレームに分割し、動画ファイルからランダムに選択された n_frames のスパンを読み取り、それらを NumPy array として返します。メモリと計算のオーバーヘッドを削減するには、小さいフレーム数を選択してください。さらに、各動画から同じ数のフレームを選択すると、データのバッチ処理が容易になります。

def frames_from_video_file(video_path, n_frames, output_size = (224,224)):
  """ Creates frames from each video file present for each category.

    Args:
      video_path: File path to the video.
      n_frames: Number of frames to be created per video file.
      output_size: Pixel size of the output frame image.

    Return:
      An NumPy array of frames in the shape of (n_frames, height, width, channels).
  """
  # Read each frame by frame
  count = 0
  result = []
  src = cv2.VideoCapture(str(video_path))  

  video_length = src.get(cv2.CAP_PROP_FRAME_COUNT)

  # If the number of frames wanted is greater than the length of the video, then start from beginning
  if n_frames > video_length:
    start = 0
  else:
    # Otherwise, start at another random point within the video
    max_start = video_length - n_frames
    start = random.randint(0, max_start)

  src.set(cv2.CAP_PROP_POS_FRAMES, start)

  for _ in range(n_frames):
    ret, frame = src.read()
    if ret:
      frame = tf.image.convert_image_dtype(frame, tf.float32)
      frame = tf.image.resize_with_pad(frame, *output_size)
      result.append(frame)
    else:
      result.append(np.zeros_like(result[0]))
  src.release()
  # Ensure that the color scheme is not inverted
  result = np.array(result)[..., [2, 1, 0]]

  return result

動画データを視覚化する

一連のフレームを NumPy 配列として返す frames_from_video_file 関数。Patrick Gillett による Wikimedia の新しい動画でこの関数を使用してみてください。

curl -O https://upload.wikimedia.org/wikipedia/commons/8/86/End_of_a_jam.ogv
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 55.0M  100 55.0M    0     0  25.6M      0  0:00:02  0:00:02 --:--:-- 25.6M
video_path = "End_of_a_jam.ogv"
sample_video = frames_from_video_file(video_path, n_frames = 10)
sample_video.shape
(10, 224, 224, 3)
def to_gif(images):
  converted_images = np.clip(images * 255, 0, 255).astype(np.uint8)
  imageio.mimsave('./animation.gif', converted_images, fps=10)
  return embed.embed_file('./animation.gif')
to_gif(sample_video)

gif

この動画を調べるだけでなく、UCF-101 データを表示することもできます。これを行うには、次のコードを実行します。

# docs-infra: no-execute
ucf_sample_video = frames_from_video_file(next(subset_paths['train'].glob('*/*.avi')), 50)
to_gif(ucf_sample_video)

次に、TensorFlow データパイプラインにデータをフィードする反復可能なオブジェクトを作成するために、FrameGenerator クラスを定義します。ジェネレーター (__call__) 関数は、frames_from_video_file によって生成されたフレーム配列と、一連のフレームに関連付けられたラベルのワンホットエンコードされたベクトルを生成します。

class FrameGenerator:
  def __init__(self, path, n_frames):
    """ Returns a set of frames with their associated label. 

      Args:
        path: Video file paths.
        classes: List of labels for classification.
    """
    self.path = path
    self.n_frames = n_frames
    self.class_names = sorted(set(p.name for p in self.path.iterdir() if p.is_dir()))
    self.class_ids_for_name = dict((name, idx) for idx, name in enumerate(self.class_names))

  def get_files_and_class_names(self):
    video_paths = list(self.path.glob('*/*.avi'))
    classes = [p.parent.name for p in video_paths] 
    return video_paths, classes

  def __call__(self):
    video_paths, classes = self.get_files_and_class_names()

    pairs = list(zip(video_paths, classes))

    random.shuffle(pairs)

    shuffled_video_paths, shuffled_classes = zip(*pairs)

    for path, name in pairs:
      video_frames = frames_from_video_file(path, self.n_frames) 
      label = self.class_ids_for_name[name] # Encode labels
      yield video_frames, label

TensorFlow Dataset オブジェクトとしてラップする前に、FrameGenerator オブジェクトをテストします。

fg = FrameGenerator(subset_paths['train'], 10)

frames, label = next(fg())

print(f"Shape: {frames.shape}")
print(f"Label: {label}")
Shape: (10, 224, 224, 3)
Label: 1

最後に、TensorFlow データ入力パイプラインを作成します。ジェネレーターオブジェクトから作成するこのパイプラインを使用すると、ディープラーニングモデルにデータをフィードできます。この動画パイプラインでは、各要素はフレームとそれに関連付けられたラベルの 1 つのセットです。

# Create the training set
output_signature = (tf.TensorSpec(shape = (None, None, None, 3), dtype = tf.float32),
                    tf.TensorSpec(shape = (), dtype = tf.int16))
train_ds = tf.data.Dataset.from_generator(FrameGenerator(subset_paths['train'], 10),
                                          output_signature = output_signature)
# Create the validation set
val_ds = tf.data.Dataset.from_generator(FrameGenerator(subset_paths['val'], 10),
                                        output_signature = output_signature)
# Print the shapes of the data
train_frames, train_labels = next(iter(train_ds))
print(f'Shape of training set of frames: {train_frames.shape}')
print(f'Shape of training labels: {train_labels.shape}')

val_frames, val_labels = next(iter(val_ds))
print(f'Shape of validation set of frames: {val_frames.shape}')
print(f'Shape of validation labels: {val_labels.shape}')
Shape of training set of frames: (10, 224, 224, 3)
Shape of training labels: ()
Shape of validation set of frames: (10, 224, 224, 3)
Shape of validation labels: ()

データセットを構成してパフォーマンスを改善する

I/O がブロックされることなくディスクからデータを取得できるように、バッファ付きプリフェッチを使用します。以下の 2 つの関数は、データを読み込むときに使用する必要がある重要な方法です。

  • Dataset.cacheは、最初のエポック中に画像をディスクから読み込んだ後、メモリに保持します。これにより、モデルのトレーニング中にデータセットがボトルネックになることを回避できます。データセットが大きすぎてメモリに収まらない場合は、この方法を使用して、パフォーマンスの高いオンディスクキャッシュを作成することもできます。

  • Dataset.prefetch は、トレーニング中にデータの前処理とモデルの実行をオーバーラップさせます。詳しくは、tf.data によるパフォーマンスの向上を参照してください。

AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size = AUTOTUNE)
val_ds = val_ds.cache().shuffle(1000).prefetch(buffer_size = AUTOTUNE)

モデルにフィードするデータを準備するには、以下に示すようにバッチ処理を使用します。AVI ファイルなどの動画データを扱う場合、データを [batch_size, number_of_frames, height, width, channels] の5 次元オブジェクトの形状にする必要があることに注意してください。対照的に、画像には [batch_size, height, width, channels] の 4 つの次元があります。下の画像は、動画データの形状がどのように表現されるかを示したものです。

動画データ形状

train_ds = train_ds.batch(2)
val_ds = val_ds.batch(2)

train_frames, train_labels = next(iter(train_ds))
print(f'Shape of training set of frames: {train_frames.shape}')
print(f'Shape of training labels: {train_labels.shape}')

val_frames, val_labels = next(iter(val_ds))
print(f'Shape of validation set of frames: {val_frames.shape}')
print(f'Shape of validation labels: {val_labels.shape}')
Shape of training set of frames: (2, 10, 224, 224, 3)
Shape of training labels: (2,)
Shape of validation set of frames: (2, 10, 224, 224, 3)
Shape of validation labels: (2,)

次のステップ

ここで作成したラベル付きの動画フレームの TensorFlow Dataset はディープラーニングモデルで使用できます。事前トレーニング済みの EfficientNet を使用する次の分類モデルは、数分で高精度にトレーニングされます。

net = tf.keras.applications.EfficientNetB0(include_top = False)
net.trainable = False

model = tf.keras.Sequential([
    tf.keras.layers.TimeDistributed(net),
    tf.keras.layers.Dense(10),
    tf.keras.layers.GlobalAveragePooling3D()
])

model.compile(optimizer = 'adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits = True),
              metrics=['accuracy'])

model.fit(train_ds, 
          epochs = 10,
          validation_data = val_ds,
          callbacks = tf.keras.callbacks.EarlyStopping(patience = 2, monitor = 'val_loss'))
Downloading data from https://storage.googleapis.com/keras-applications/efficientnetb0_notop.h5
16705208/16705208 [==============================] - 0s 0us/step
Epoch 1/10
2022-12-15 01:02:16.215023: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:954] layout failed: INVALID_ARGUMENT: Size of values 0 does not match size of permutation 4 @ fanin shape insequential/time_distributed/efficientnetb0/block2b_drop/dropout/SelectV2-2-TransposeNHWCToNCHW-LayoutOptimizer
150/150 [==============================] - 19s 57ms/step - loss: 2.4595 - accuracy: 0.0700 - val_loss: 2.3957 - val_accuracy: 0.1000
Epoch 2/10
150/150 [==============================] - 6s 37ms/step - loss: 2.4175 - accuracy: 0.0833 - val_loss: 2.3642 - val_accuracy: 0.1000
Epoch 3/10
150/150 [==============================] - 6s 37ms/step - loss: 2.4162 - accuracy: 0.0967 - val_loss: 2.4628 - val_accuracy: 0.1000
Epoch 4/10
150/150 [==============================] - 6s 37ms/step - loss: 2.4078 - accuracy: 0.0900 - val_loss: 2.4265 - val_accuracy: 0.1000
<keras.callbacks.History at 0x7f5d2e4f9070>