Path: blob/master/site/ja/tutorials/video/video_classification.ipynb
25118 views
Copyright 2022 The TensorFlow Authors.
3D 畳み込みニューラルネットワークによる動画分類
This tutorial demonstrates training a 3D convolutional neural network (CNN) for video classification using the UCF101 action recognition dataset. A 3D CNN uses a three-dimensional filter to perform convolutions. The kernel is able to slide in three directions, whereas in a 2D CNN it can slide in two dimensions. The model is based on the work published in A Closer Look at Spatiotemporal Convolutions for Action Recognition by D. Tran et al. (2017). In this tutorial, you will:
入力パイプラインを構築する
Keras Functional API を使って残差接続を伴う 3D 畳み込みニューラルネットワークモデルを構築する
モデルをトレーニングする
モデルを評価してテストする
This video classification tutorial is the second part in a series of TensorFlow video tutorials. Here are the other three tutorials:
Load video data: This tutorial explains much of the code used in this document.
MoViNet for streaming action recognition: Get familiar with the MoViNet models that are available on TF Hub.
Transfer learning for video classification with MoViNet: This tutorial explains how to use a pre-trained video classification model trained on a different dataset with the UCF-101 dataset.
セットアップ
まず、ZIP ファイルの内容を検査するための remotezip、進捗バーを使用するための tqdm、動画ファイルを処理するための OpenCV、より複雑なテンソル演算を実行するための einops、Jupyter ノートブックにデータを埋め込むための tensorflow_docs
を含む、必要なライブラリのインストールとインポートを行います。
注意: このチュートリアルは、TensorFlow 2.10 を使って実行します。TensorFlow 2.10 より後のバージョンでは、正しく実行しない可能性があります。
動画データを読み込んで前処理する
以下の非表示セルは、UCF-101 データセットからデータスライスをダウンロードして tf.data.Dataset
に読み込むヘルパー関数を定義します。具体的な前処理手順については、動画データの読み込みチュートリアルをご覧ください。このコードを手順を追ってより詳しく説明しています。
ここでは、非表示ブロックの最後にある FrameGenerator
クラスが最も重要なユーティリティです。TensorFlow データパイプラインにデータをフィードでキルイテレート可能なオブジェクトを作成します。特に、このクラスには、エンコードされたラベルとともに動画フレームを読み込む Python ジェネレータが含まれます。このジェネレータ(__call__
)関数は、frames_from_video_file
とフレームセットに関連するラベルのワンホットエンコードのベクトルを生成します。
トレーニング、検証、およびテストのセット(train_ds
、val_ds
、test_ds
)を作成します。
モデルを作成する
以下の 3D 畳み込みニューラルネットワークモデルは、D. Tran et al. が 2017 年に発表した「A Closer Look at Spatiotemporal Convolutions for Action Recognition」という論文を基に作られています。この論文では、様々なバージョンの 3D ResNet が比較されています。標準的な ResNet のように次元 (height, width)
を伴う単一の画像で演算するのではなく、これらは動画ボリューム (time, height, width)
で演算します。この問題への最も明確なアプローチは、それぞれの 2D 畳み込み(layers.Conv2D
)を 3D 畳み込み(layers.Conv3D
)と入れ替えることです。
このチュートリアルでは、残差接続を伴う (2 + 1)D 畳み込みを使用します。(2 + 1)D 畳み込みの場合、空間次元と時間次元の分解が可能であるため、2 つのステップが作成されます。このアプローチには、畳み込みを空間次元と時間次元に因数分解することでパラメータを節約できるというメリットがあります。
3D 畳み込みは、出力位置ごとに、ボリュームの 3D パッチからのすべてのベクトルを結合して、出力ボリュームに 1 つのベクトルを作成します。
この演算は time * height * width * channels
の入力を取って channels
出力を生成します(入力チャンネル数と出力チャンネル数が同じであることが前提です)。つまり、カーネルサイズが (3 x 3 x 3)
の 3D 畳み込みレイヤーには、27 * channels ** 2
のエントリを持つ重み行列が必要となります。基準とする論文では、畳み込みを因数分解することがより効果的で効率的なアプローチという結果が導かれています。単一の 3D 畳み込みで時間次元と空間次元を処理するのではなく、空間と時間の次元を個別に処理する "(2+1)D" 畳み込みが提案されています。以下の図は、空間と時間で因数分解した (2 + 1)D 畳み込みを示しています。
このアプローチの主なメリットは、パラメータ数が減ることにあります。(2 + 1)D 畳み込みでは、空間畳み込みは形状 (1, width, height)
のデータを取るのに対し、時間畳み込みは形状 (time, 1, 1)
のデータを取ります。たとえば、カーネルサイズが (3 x 3 x 3)
の (2 + 1)D 畳み込みでは、サイズ (9 * channels**2) + (3 * channels**2)
の重み行列が必要となり、これは、完全な 3D 畳み込みの半分です。このチュートリアルでは、ResNet の各畳み込みを (2+1)D 畳み込みが置き換わった (2 + 1)D ResNet18 を実装します。
ResNet モデルは、一連の残差ブロックから作られています。残差ブロックには 2 つの分岐があります。メインの分岐は計算を実行しますが、勾配を流すのが困難です。残差分岐はメインの計算をバイパスして、ほぼ入力をメイン分岐の出力に追加するだけです。勾配は、この文器を容易に流れるため、損失関数からすべての残差ブロックのメイン分岐にたどり着く簡単な経路は存在することになります。これにより、勾配消失の問題が回避されます。
残差ブロックのメイン分岐を次のクラスで作成します。標準的な ResNet の構造とは対照に、これは layers.Conv2D
ではなく Conv2Plus1D
レイヤーを使用します。
メイン分岐に残差分岐を追加するには、同じサイズである必要があります。以下の Project
レイヤーは、チャンネルの数が分岐で変更されるケースに対処するものです。具体的には、一連の密結合レイヤーと正規化が追加されています。
add_residual_block
を使用して、モデルのレイヤー間にスキップ結合を導入します。
データのダウンサンプリングを行うには、動画サイズの変更が必要です。特に、動画フレームをダウンサンプリングすると、モデルがフレームの特定の箇所を調べてある行動に固有の可能性のあるパターンを検出することができます。重要でない情報は、ダウンサンプリングを通じて破棄することが可能です。さらに、動画のサイズを変更することで、次元を縮小できるため、モデルでの処理が高速化されます。
Keras Functional API を使って、残差ネットワークを構築します。
モデルのトレーニング
このチュートリアルでは、tf.keras.optimizers.Adam
オプティマイザと tf.keras.losses.SparseCategoricalCrossentropy
損失関数を選択します。metrics
引数を使用して、各ステップでのモデルパフォーマンスの精度を確認します。
Keras Model.fit
メソッドを使って、モデルを 50 エポック、トレーニングします。
注意: このサンプルモデルは、このチュートリアルに合理的な時間でトレーニングできるように、より少ないデータポイント(300 個のトレーニングサンプルと 100 個の検証サンプル)でトレーニングされています。また、このサンプルモデルのトレーニングには 1 時間以上かかる可能性があります。
結果を可視化する
トレーニングセットと検証セットで損失と精度のプロットを作成します。
モデルを評価する
Keras Model.evaluate
を使用して、テストデータセットで損失と精度を取得します。
注意: このチュートリアルのサンプルモデルは、合理的な時間でトレーニングできるように、UCF101 データセットのサブセットを使用しています。ハイパーパラメータのチューニングをさらに行ったり、トレーニングデータを増やすことで、精度と損失を改善できる可能性があります。
モデルパフォーマンスをさらに可視化するには、混同行列を使用します。混同行列では、精度を超えて分類モデルのパフォーマンスを評価することができます。このマルチクラス分類問題の混同行列を作成するために、テストセットの実際の値と予測される値を取得します。
各クラスの適合率と再現率の値は、混同行列を使用して計算することもできます。
次のステップ
TensorFlow での動画の操作についての詳細は、以下のチュートリアルをご覧ください。
動画データを読み込む
MoviNet を使った動画分類の転移学習