비디오 데이터 로드

TensorFlow.org에서 보기 Google Colab에서 실행하기 GitHub에서 소스 보기 노트북 다운로드하기

이 튜토리얼은 UCF101 인간 행동 데이터세트를 사용하여 AVI 비디오 데이터를 로드하고 전처리하는 방법을 보여줍니다. 데이터를 전처리하면 비디오 분류/인식, 캡션 또는 클러스터링과 같은 작업에 사용할 수 있습니다. 원본 데이터세트에는 첼로 연주, 양치질, 눈 화장 등 101개 범주로 YouTube에서 수집한 사실적인 동작 비디오가 포함되어 있습니다. 다음을 수행하는 방법을 배우게 됩니다.

  • zip 파일에서 데이터를 로드합니다.

  • 비디오 파일에서 프레임 시퀀스를 읽습니다.

  • 비디오 데이터를 시각화합니다.

  • 프레임 생성기 tf.data.Dataset을 래핑합니다.

설정

ZIP 파일의 내용을 검사하기 위한 remotezip, 진행률 표시줄을 사용하기 위한 tqdm, 비디오 파일을 처리하기 위한 OpenCV, 및 Jupyter 노트북에 데이터를 내장하기 위한 tensorflow_docs를 포함해 일부 필요한 라이브러리를 설치하고 가져오는 것으로 시작합니다.

# The way this tutorial uses the `TimeDistributed` layer requires TF>=2.10
pip install -U "tensorflow>=2.10.0"
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-14 20:47:24.176363: 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-14 20:47:24.176470: 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-14 20:47:24.176481: 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(zip_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 인수를 사용하면 키 값이 하위 집합의 이름(예: "train")과 클래스당 가지려는 비디오 수인 사전을 전달할 수 있습니다.

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:32<00:00,  9.16it/s]
val :
100%|██████████| 100/100 [00:10<00:00,  9.28it/s]
test :
100%|██████████| 100/100 [00:07<00:00, 12.92it/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/train
./UCF101_subset/train/Archery
./UCF101_subset/train/Archery/v_Archery_g01_c06.avi
./UCF101_subset/train/Archery/v_Archery_g08_c05.avi
./UCF101_subset/train/Archery/v_Archery_g11_c02.avi
./UCF101_subset/train/Archery/v_Archery_g17_c04.avi
./UCF101_subset/train/Archery/v_Archery_g05_c04.avi
./UCF101_subset/train/Archery/v_Archery_g16_c01.avi
./UCF101_subset/train/Archery/v_Archery_g08_c03.avi
./UCF101_subset/train/Archery/v_Archery_g19_c01.avi
./UCF101_subset/train/Archery/v_Archery_g25_c06.avi
./UCF101_subset/train/Archery/v_Archery_g11_c06.avi
./UCF101_subset/train/Archery/v_Archery_g12_c03.avi
./UCF101_subset/train/Archery/v_Archery_g03_c04.avi
./UCF101_subset/train/Archery/v_Archery_g11_c04.avi
./UCF101_subset/train/Archery/v_Archery_g09_c02.avi
./UCF101_subset/train/Archery/v_Archery_g21_c04.avi
./UCF101_subset/train/Archery/v_Archery_g07_c01.avi
./UCF101_subset/train/Archery/v_Archery_g22_c02.avi
./UCF101_subset/train/Archery/v_Archery_g15_c04.avi
./UCF101_subset/train/Archery/v_Archery_g04_c01.avi
./UCF101_subset/train/Archery/UCF101
./UCF101_subset/train/Archery/v_Archery_g14_c04.avi
./UCF101_subset/train/Archery/v_Archery_g10_c01.avi
./UCF101_subset/train/Archery/v_Archery_g03_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_g01_c02.avi
./UCF101_subset/train/Archery/v_Archery_g16_c05.avi
./UCF101_subset/train/Archery/v_Archery_g23_c07.avi
./UCF101_subset/train/Archery/v_Archery_g24_c04.avi
./UCF101_subset/train/Archery/v_Archery_g10_c03.avi
./UCF101_subset/train/Archery/v_Archery_g18_c04.avi
./UCF101_subset/train/ApplyLipstick
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g24_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g20_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g04_c05.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g06_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g15_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g23_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g17_c05.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g17_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g04_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g14_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g18_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g09_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g20_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g06_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g01_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g03_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g22_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g01_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g04_c03.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g05_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g23_c01.avi
./UCF101_subset/train/ApplyLipstick/UCF101
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g24_c05.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g10_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g11_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g14_c01.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g25_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g18_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g07_c02.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g19_c04.avi
./UCF101_subset/train/ApplyLipstick/v_ApplyLipstick_g10_c04.avi
./UCF101_subset/train/BenchPress
./UCF101_subset/train/BenchPress/v_BenchPress_g07_c04.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g12_c04.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g15_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g19_c06.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g11_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g16_c03.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g23_c04.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g01_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g11_c03.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g16_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g21_c03.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g10_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g15_c05.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g17_c02.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g02_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g22_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g13_c05.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g18_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g08_c07.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g13_c07.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g03_c02.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g21_c01.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g19_c02.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g20_c04.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g22_c07.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g24_c05.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g09_c02.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g14_c06.avi
./UCF101_subset/train/BenchPress/UCF101
./UCF101_subset/train/BenchPress/v_BenchPress_g09_c04.avi
./UCF101_subset/train/BenchPress/v_BenchPress_g06_c05.avi
./UCF101_subset/train/BasketballDunk
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g03_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g15_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g25_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g05_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g07_c05.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g14_c04.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g15_c07.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g12_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g08_c05.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g06_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g22_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g02_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g09_c02.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g02_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g20_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g18_c05.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g08_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g20_c05.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g13_c04.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g12_c05.avi
./UCF101_subset/train/BasketballDunk/UCF101
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g10_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g16_c04.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g11_c04.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g01_c04.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g21_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g25_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g19_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g04_c01.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g07_c03.avi
./UCF101_subset/train/BasketballDunk/v_BasketballDunk_g05_c05.avi
./UCF101_subset/train/ApplyEyeMakeup
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g12_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g20_c04.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g17_c02.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g25_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g06_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g08_c05.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g16_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g04_c05.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g03_c05.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g14_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g24_c04.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g20_c02.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g15_c06.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g23_c02.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g07_c04.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g10_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g23_c04.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g08_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g03_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g14_c05.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g19_c04.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g02_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/UCF101
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g10_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g18_c01.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g24_c02.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g16_c03.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g17_c04.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g06_c07.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g25_c07.avi
./UCF101_subset/train/ApplyEyeMakeup/v_ApplyEyeMakeup_g25_c05.avi
./UCF101_subset/train/BandMarching
./UCF101_subset/train/BandMarching/v_BandMarching_g04_c04.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g23_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g25_c05.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g12_c04.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g24_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g10_c02.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g15_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g05_c02.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g09_c07.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g09_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g19_c07.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g12_c06.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g21_c04.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g21_c02.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g07_c01.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g16_c06.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g04_c02.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g11_c01.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g19_c01.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g03_c07.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g24_c01.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g01_c07.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g24_c05.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g07_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g15_c07.avi
./UCF101_subset/train/BandMarching/UCF101
./UCF101_subset/train/BandMarching/v_BandMarching_g25_c07.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g11_c03.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g13_c02.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g06_c01.avi
./UCF101_subset/train/BandMarching/v_BandMarching_g03_c01.avi
./UCF101_subset/train/BalanceBeam
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g04_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g11_c04.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g23_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g16_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g15_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g20_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g21_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g12_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g07_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g06_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g11_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g16_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g06_c07.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g13_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g14_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g23_c04.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g21_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g21_c05.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g17_c03.avi
./UCF101_subset/train/BalanceBeam/UCF101
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g17_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g20_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g10_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g22_c02.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g17_c05.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g13_c04.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g01_c03.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g05_c01.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g10_c04.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g06_c05.avi
./UCF101_subset/train/BalanceBeam/v_BalanceBeam_g09_c04.avi
./UCF101_subset/train/BaseballPitch
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g21_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g14_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g17_c07.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g13_c01.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g01_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g05_c06.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g05_c04.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g06_c03.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g25_c03.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g16_c05.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g24_c04.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g21_c04.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g24_c06.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g25_c07.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g22_c04.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g23_c07.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g17_c01.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g13_c03.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g01_c06.avi
./UCF101_subset/train/BaseballPitch/UCF101
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g09_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g12_c03.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g06_c07.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g23_c01.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g10_c01.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g15_c06.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g23_c05.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g07_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g04_c01.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g11_c02.avi
./UCF101_subset/train/BaseballPitch/v_BaseballPitch_g20_c04.avi
./UCF101_subset/train/Basketball
./UCF101_subset/train/Basketball/v_Basketball_g04_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g06_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g12_c01.avi
./UCF101_subset/train/Basketball/v_Basketball_g03_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g21_c05.avi
./UCF101_subset/train/Basketball/v_Basketball_g20_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g22_c01.avi
./UCF101_subset/train/Basketball/v_Basketball_g16_c06.avi
./UCF101_subset/train/Basketball/v_Basketball_g24_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g01_c03.avi
./UCF101_subset/train/Basketball/v_Basketball_g25_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g23_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g16_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g07_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g02_c06.avi
./UCF101_subset/train/Basketball/v_Basketball_g14_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g18_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g09_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g03_c06.avi
./UCF101_subset/train/Basketball/v_Basketball_g02_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g22_c03.avi
./UCF101_subset/train/Basketball/v_Basketball_g17_c04.avi
./UCF101_subset/train/Basketball/UCF101
./UCF101_subset/train/Basketball/v_Basketball_g16_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g15_c03.avi
./UCF101_subset/train/Basketball/v_Basketball_g05_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g13_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g25_c04.avi
./UCF101_subset/train/Basketball/v_Basketball_g03_c02.avi
./UCF101_subset/train/Basketball/v_Basketball_g15_c01.avi
./UCF101_subset/train/Basketball/v_Basketball_g19_c03.avi
./UCF101_subset/train/BabyCrawling
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g10_c04.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g21_c02.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g05_c05.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g16_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g23_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g20_c05.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g11_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g17_c05.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g23_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g17_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g25_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g13_c05.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g19_c04.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g01_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g02_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g02_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g20_c03.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_g14_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g22_c06.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g18_c02.avi
./UCF101_subset/train/BabyCrawling/UCF101
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g05_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g18_c06.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g07_c06.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g24_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g03_c01.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g16_c03.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g08_c02.avi
./UCF101_subset/train/BabyCrawling/v_BabyCrawling_g07_c04.avi
./UCF101_subset/test
./UCF101_subset/test/Archery
./UCF101_subset/test/Archery/v_Archery_g10_c07.avi
./UCF101_subset/test/Archery/v_Archery_g06_c01.avi
./UCF101_subset/test/Archery/v_Archery_g13_c03.avi
./UCF101_subset/test/Archery/v_Archery_g24_c06.avi
./UCF101_subset/test/Archery/v_Archery_g06_c03.avi
./UCF101_subset/test/Archery/v_Archery_g23_c01.avi
./UCF101_subset/test/Archery/v_Archery_g24_c02.avi
./UCF101_subset/test/Archery/v_Archery_g15_c02.avi
./UCF101_subset/test/Archery/v_Archery_g20_c01.avi
./UCF101_subset/test/Archery/UCF101
./UCF101_subset/test/Archery/v_Archery_g19_c03.avi
./UCF101_subset/test/ApplyLipstick
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g08_c02.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g13_c03.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g21_c05.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g16_c02.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g15_c03.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g12_c02.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g21_c03.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g05_c02.avi
./UCF101_subset/test/ApplyLipstick/UCF101
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g22_c04.avi
./UCF101_subset/test/ApplyLipstick/v_ApplyLipstick_g07_c04.avi
./UCF101_subset/test/BenchPress
./UCF101_subset/test/BenchPress/v_BenchPress_g18_c05.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g04_c03.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g22_c03.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g08_c05.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g02_c03.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g12_c02.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g10_c03.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g25_c02.avi
./UCF101_subset/test/BenchPress/UCF101
./UCF101_subset/test/BenchPress/v_BenchPress_g01_c05.avi
./UCF101_subset/test/BenchPress/v_BenchPress_g03_c04.avi
./UCF101_subset/test/BasketballDunk
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g10_c03.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g17_c02.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g05_c03.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g22_c01.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g10_c05.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g01_c02.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g11_c02.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g03_c03.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g14_c02.avi
./UCF101_subset/test/BasketballDunk/v_BasketballDunk_g20_c01.avi
./UCF101_subset/test/BasketballDunk/UCF101
./UCF101_subset/test/ApplyEyeMakeup
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g21_c02.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g13_c01.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g12_c03.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g07_c06.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g18_c05.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g08_c01.avi
./UCF101_subset/test/ApplyEyeMakeup/UCF101
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g03_c03.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g15_c02.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g06_c01.avi
./UCF101_subset/test/ApplyEyeMakeup/v_ApplyEyeMakeup_g06_c05.avi
./UCF101_subset/test/BandMarching
./UCF101_subset/test/BandMarching/v_BandMarching_g02_c04.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g03_c03.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g25_c01.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g14_c03.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g03_c05.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g22_c04.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g07_c07.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g23_c05.avi
./UCF101_subset/test/BandMarching/v_BandMarching_g15_c01.avi
./UCF101_subset/test/BandMarching/UCF101
./UCF101_subset/test/BandMarching/v_BandMarching_g05_c06.avi
./UCF101_subset/test/BalanceBeam
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g19_c01.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g19_c03.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g02_c01.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g24_c01.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g12_c04.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g25_c01.avi
./UCF101_subset/test/BalanceBeam/UCF101
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g05_c03.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g15_c03.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g01_c01.avi
./UCF101_subset/test/BalanceBeam/v_BalanceBeam_g06_c01.avi
./UCF101_subset/test/BaseballPitch
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g25_c05.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g16_c01.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g03_c06.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g02_c04.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g07_c06.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g20_c02.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g24_c02.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g19_c01.avi
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g22_c02.avi
./UCF101_subset/test/BaseballPitch/UCF101
./UCF101_subset/test/BaseballPitch/v_BaseballPitch_g10_c05.avi
./UCF101_subset/test/Basketball
./UCF101_subset/test/Basketball/v_Basketball_g18_c04.avi
./UCF101_subset/test/Basketball/v_Basketball_g01_c01.avi
./UCF101_subset/test/Basketball/v_Basketball_g11_c02.avi
./UCF101_subset/test/Basketball/v_Basketball_g10_c01.avi
./UCF101_subset/test/Basketball/v_Basketball_g08_c04.avi
./UCF101_subset/test/Basketball/v_Basketball_g02_c02.avi
./UCF101_subset/test/Basketball/v_Basketball_g12_c03.avi
./UCF101_subset/test/Basketball/v_Basketball_g19_c01.avi
./UCF101_subset/test/Basketball/v_Basketball_g10_c03.avi
./UCF101_subset/test/Basketball/v_Basketball_g17_c02.avi
./UCF101_subset/test/Basketball/UCF101
./UCF101_subset/test/BabyCrawling
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g09_c04.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g04_c03.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g03_c03.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g13_c03.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g18_c04.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g25_c05.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g24_c03.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g17_c03.avi
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g12_c03.avi
./UCF101_subset/test/BabyCrawling/UCF101
./UCF101_subset/test/BabyCrawling/v_BabyCrawling_g06_c06.avi
./UCF101_subset/val
./UCF101_subset/val/Archery
./UCF101_subset/val/Archery/v_Archery_g08_c01.avi
./UCF101_subset/val/Archery/v_Archery_g20_c07.avi
./UCF101_subset/val/Archery/v_Archery_g09_c04.avi
./UCF101_subset/val/Archery/v_Archery_g12_c01.avi
./UCF101_subset/val/Archery/v_Archery_g17_c02.avi
./UCF101_subset/val/Archery/v_Archery_g23_c05.avi
./UCF101_subset/val/Archery/UCF101
./UCF101_subset/val/Archery/v_Archery_g07_c03.avi
./UCF101_subset/val/Archery/v_Archery_g22_c04.avi
./UCF101_subset/val/Archery/v_Archery_g13_c01.avi
./UCF101_subset/val/Archery/v_Archery_g02_c03.avi
./UCF101_subset/val/ApplyLipstick
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g06_c05.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g11_c02.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g24_c01.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g02_c03.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g13_c01.avi
./UCF101_subset/val/ApplyLipstick/UCF101
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g16_c04.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g09_c04.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g22_c06.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g21_c01.avi
./UCF101_subset/val/ApplyLipstick/v_ApplyLipstick_g15_c05.avi
./UCF101_subset/val/BenchPress
./UCF101_subset/val/BenchPress/v_BenchPress_g08_c03.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g13_c03.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g11_c05.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g25_c06.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g04_c07.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g17_c04.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g24_c01.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g05_c06.avi
./UCF101_subset/val/BenchPress/v_BenchPress_g07_c02.avi
./UCF101_subset/val/BenchPress/UCF101
./UCF101_subset/val/BenchPress/v_BenchPress_g09_c06.avi
./UCF101_subset/val/BasketballDunk
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g06_c03.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g23_c03.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g17_c06.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g15_c03.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g24_c02.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g07_c01.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g14_c06.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g16_c06.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g15_c05.avi
./UCF101_subset/val/BasketballDunk/v_BasketballDunk_g24_c04.avi
./UCF101_subset/val/BasketballDunk/UCF101
./UCF101_subset/val/ApplyEyeMakeup
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g12_c05.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g13_c05.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g02_c03.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g16_c05.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g23_c06.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g05_c04.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g01_c05.avi
./UCF101_subset/val/ApplyEyeMakeup/UCF101
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g19_c02.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g14_c01.avi
./UCF101_subset/val/ApplyEyeMakeup/v_ApplyEyeMakeup_g09_c02.avi
./UCF101_subset/val/BandMarching
./UCF101_subset/val/BandMarching/v_BandMarching_g10_c04.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g17_c01.avi
./UCF101_subset/val/BandMarching/UCF101
./UCF101_subset/val/BandMarching/v_BandMarching_g11_c05.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g08_c02.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g22_c02.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g10_c06.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g11_c07.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g09_c01.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g02_c02.avi
./UCF101_subset/val/BandMarching/v_BandMarching_g12_c02.avi
./UCF101_subset/val/BalanceBeam
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g08_c02.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g03_c01.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g07_c04.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g24_c03.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g04_c01.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g25_c03.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g09_c02.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g03_c03.avi
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g08_c04.avi
./UCF101_subset/val/BalanceBeam/UCF101
./UCF101_subset/val/BalanceBeam/v_BalanceBeam_g18_c03.avi
./UCF101_subset/val/BaseballPitch
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g13_c05.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g02_c02.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g17_c05.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g09_c06.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g22_c06.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g18_c02.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g09_c04.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g08_c03.avi
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g11_c04.avi
./UCF101_subset/val/BaseballPitch/UCF101
./UCF101_subset/val/BaseballPitch/v_BaseballPitch_g18_c06.avi
./UCF101_subset/val/Basketball
./UCF101_subset/val/Basketball/v_Basketball_g15_c07.avi
./UCF101_subset/val/Basketball/v_Basketball_g19_c07.avi
./UCF101_subset/val/Basketball/v_Basketball_g14_c04.avi
./UCF101_subset/val/Basketball/v_Basketball_g21_c01.avi
./UCF101_subset/val/Basketball/v_Basketball_g09_c02.avi
./UCF101_subset/val/Basketball/v_Basketball_g06_c02.avi
./UCF101_subset/val/Basketball/v_Basketball_g21_c03.avi
./UCF101_subset/val/Basketball/UCF101
./UCF101_subset/val/Basketball/v_Basketball_g08_c02.avi
./UCF101_subset/val/Basketball/v_Basketball_g23_c06.avi
./UCF101_subset/val/Basketball/v_Basketball_g11_c04.avi
./UCF101_subset/val/BabyCrawling
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g02_c05.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g10_c02.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g12_c01.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g14_c01.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g06_c02.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g19_c02.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g05_c03.avi
./UCF101_subset/val/BabyCrawling/UCF101
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g20_c01.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g13_c01.avi
./UCF101_subset/val/BabyCrawling/v_BabyCrawling_g22_c02.avi

각 비디오 파일에서 프레임 만들기

frames_from_video_file 함수는 비디오를 여러 프레임으로 분할하고 비디오 파일에서 무작위로 선택된 n_frames 범위를 읽은 다음, NumPy array로 반환합니다. 메모리와 계산 오버헤드를 줄이려면 적은 수의 프레임을 선택합니다. 또한 각 비디오에서 동일한 수의 프레임을 선택하면 데이터 배치 작업을 더 쉽게 수행할 수 있습니다.

def format_frames(frame, output_size):
  """
    Pad and resize an image from a video.

    Args:
      frame: Image that needs to resized and padded. 
      output_size: Pixel size of the output frame image.

    Return:
      Formatted frame with padding of specified output size.
  """
  frame = tf.image.convert_image_dtype(frame, tf.float32)
  frame = tf.image.resize_with_pad(frame, *output_size)
  return frame
def frames_from_video_file(video_path, n_frames, output_size = (224,224), frame_step = 15):
  """
    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 video frame by frame
  result = []
  src = cv2.VideoCapture(str(video_path))  

  video_length = src.get(cv2.CAP_PROP_FRAME_COUNT)

  need_length = 1 + (n_frames - 1) * frame_step

  if need_length > video_length:
    start = 0
  else:
    max_start = video_length - need_length
    start = random.randint(0, max_start + 1)

  src.set(cv2.CAP_PROP_POS_FRAMES, start)
  # ret is a boolean indicating whether read was successful, frame is the image itself
  ret, frame = src.read()
  result.append(format_frames(frame, output_size))

  for _ in range(n_frames - 1):
    for _ in range(frame_step):
      ret, frame = src.read()
    if ret:
      frame = format_frames(frame, output_size)
      result.append(frame)
    else:
      result.append(np.zeros_like(result[0]))
  src.release()
  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.9M      0  0:00:02  0:00:02 --:--:-- 25.9M
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)

    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 데이터 입력 파이프라인을 만듭니다. 생성기 객체에서 생성하는 이 파이프라인을 사용하면 딥 러닝 모델에 데이터를 공급할 수 있습니다. 이 비디오 파이프라인에서 각 요소는 단일 프레임 세트 및 관련 레이블입니다.

# 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가 차단되지 않고 디스크에서 데이터를 생성할 수 있도록 버퍼링된 프리페치를 사용합니다. 데이터를 로드하는 동안 사용해야 하는 두 가지 중요한 함수는 다음과 같습니다.

  • Dataset.cache: 첫 번째 epoch 동안 디스크에서 로드된 후 프레임 세트를 메모리에 유지합니다. 이 함수는 모델을 훈련하는 동안 데이터세트가 병목을 일으키지 않도록 합니다. 데이터세트가 너무 커서 메모리에 맞지 않는 경우 이 방법을 사용하여 고성능 디스크 캐시를 생성할 수도 있습니다.

  • 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 파일과 같은 비디오 데이터로 작업할 때 데이터는 5차원 객체로 형성되어야 합니다. 이러한 차원은 [batch_size, number_of_frames, height, width, channels]와 같습니다. 이에 비해 이미지에는 [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.Rescaling(scale=255),
    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-14 20:49:22.351795: 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 [==============================] - 22s 59ms/step - loss: 1.1703 - accuracy: 0.7300 - val_loss: 0.5715 - val_accuracy: 0.8800
Epoch 2/10
150/150 [==============================] - 6s 39ms/step - loss: 0.3517 - accuracy: 0.9633 - val_loss: 0.3469 - val_accuracy: 0.9000
Epoch 3/10
150/150 [==============================] - 6s 38ms/step - loss: 0.1933 - accuracy: 0.9867 - val_loss: 0.2519 - val_accuracy: 0.9500
Epoch 4/10
150/150 [==============================] - 6s 39ms/step - loss: 0.1237 - accuracy: 0.9933 - val_loss: 0.2020 - val_accuracy: 0.9600
Epoch 5/10
150/150 [==============================] - 6s 39ms/step - loss: 0.0866 - accuracy: 1.0000 - val_loss: 0.1751 - val_accuracy: 0.9600
Epoch 6/10
150/150 [==============================] - 6s 38ms/step - loss: 0.0625 - accuracy: 1.0000 - val_loss: 0.1491 - val_accuracy: 0.9600
Epoch 7/10
150/150 [==============================] - 6s 39ms/step - loss: 0.0509 - accuracy: 1.0000 - val_loss: 0.1392 - val_accuracy: 0.9600
Epoch 8/10
150/150 [==============================] - 6s 38ms/step - loss: 0.0394 - accuracy: 1.0000 - val_loss: 0.1271 - val_accuracy: 0.9600
Epoch 9/10
150/150 [==============================] - 6s 38ms/step - loss: 0.0318 - accuracy: 1.0000 - val_loss: 0.1217 - val_accuracy: 0.9600
Epoch 10/10
150/150 [==============================] - 6s 39ms/step - loss: 0.0280 - accuracy: 1.0000 - val_loss: 0.1157 - val_accuracy: 0.9600
<keras.callbacks.History at 0x7f8c506f83d0>