深層学習を使用したビデオとオプティカルフロ,デ,タのアクティビティ認識gydF4y2Ba
この例では,まず,事前学習済みの膨胀3 d (I3D) 2ストリーム畳み込みニューラルネットワークをベースとしたビデオ分類器を使用してアクティビティ認識を行う方法を説明し,次に,ビデオのRGBデータとオプティカルフローデータを使用して,転移学習によりそのようなビデオ分類器に学習させる方法を説明しますgydF4y2Ba[1]gydF4y2Ba。gydF4y2Ba
概要gydF4y2Ba
視覚ベースのアクティビティ認識では,一連のビデオフレームを使用し,歩く,泳ぐ,座るといったオブジェクトのアクションを予測します。ビデオのアクティビティ認識は、ヒューマン コンピューター インタラクション、ロボット学習、異常検出、監視、オブジェクト検出といったさまざまな分野で応用されています。たとえば、複数のカメラから入力されるビデオから複数のアクションをオンラインで予測することは、ロボット学習にとって重要です。ビデオのデータ セットに含まれるグラウンド トゥルース データは不正確で、ビデオ内のアクターによって実行される動作は多種多様であり、データ セットのクラスは非常に偏っており、ロバストな分類器にゼロから学習させるには大量のデータが必要であるため、ビデオを使用したアクション認識はイメージ分類と比べてモデル化が困難です。I3D 2 ストリーム畳み込みネットワーク[1]gydF4y2Ba, r (2+1) d [gydF4y2Ba4gydF4y2Ba],および慢速[gydF4y2Ba5gydF4y2Ba]などの深層学習手法では,Kinetics-400 [gydF4y2Ba6gydF4y2Ba]などの大規模なビデオアクティビティ認識データセットで事前学習済みのネットワークを使用して転移学習を行うことにより,小規模なデータセットでパフォーマンスを改善できることが示されています。gydF4y2Ba
メモ:gydF4y2Baこの例では,计算机视觉工具箱™模型膨胀- 3d视频分类が必要です。计算机视觉工具箱Model for Inflated-3D Video Classification はアドオン エクスプローラーからインストールできます。アドオンのインストールの詳細については、アドオンの取得と管理gydF4y2Baを参照してください。gydF4y2Ba
事前学習済みの膨胀3dビデオ分類器を使用したアクティビティ認識の実行gydF4y2Ba
事前学習済みのInflated-3Dビデオ分類器,およびアクティビティ認識を行うビデオファイルをダウンロードします。ダウンロドしたzipファルのサズは約89 MBです。gydF4y2Ba
下载文件夹= fullfile(tempdir,gydF4y2Ba“hmdb51”gydF4y2Ba,gydF4y2Ba“pretrained”gydF4y2Ba,gydF4y2Ba“I3D”gydF4y2Ba);gydF4y2Ba如果gydF4y2Ba~ isfolder (downloadFolder) mkdir (downloadFolder);gydF4y2Ba结束gydF4y2Ba文件名=gydF4y2Ba“activityRecognition-I3D-HMDB51-21b.zip”gydF4y2Ba;zipFile = fullfile(下载文件夹,文件名);gydF4y2Ba如果gydF4y2Ba~ isfile zipFile disp (gydF4y2Ba“下载预先训练好的网络……”gydF4y2Ba);downloadURL =gydF4y2Ba“https://ssd.mathworks.com/万博1manbetxsupportfiles/vision/data/”gydF4y2Ba+文件名;websave (zipFile downloadURL);解压缩(zipFile downloadFolder);gydF4y2Ba结束gydF4y2Ba
事前学習済みの膨胀3dビデオ分類器を読み込みます。gydF4y2Ba
pretrainedDataFile = fullfile(下载文件夹,gydF4y2Ba“inflated3d-FiveClasses-hmdb51.mat”gydF4y2Ba);pretrainedDataFile (pretrainedDataFile);inflated3dPretrained = pretrained.data.inflated3d;gydF4y2Ba
事前学習済みのビデオ分類器のクラスラベル名を表示します。gydF4y2Ba
classes = inflated3dPretrained。类gydF4y2Ba
类=gydF4y2Ba5×1分类gydF4y2Ba吻笑捡倒俯卧撑gydF4y2Ba
VideoReadergydF4y2Ba
とgydF4y2Ba愿景。V我deoPl一个yergydF4y2Ba
を使用し,ビデオgydF4y2Bapour.avigydF4y2Ba
を読み取って表示します。gydF4y2Ba
videoFilename = fullfile(下载文件夹,gydF4y2Ba“pour.avi”gydF4y2Ba);videereader = videereader (videoFilename);videoPlayer = vision.VideoPlayer;放像机。Name =gydF4y2Ba“倒”gydF4y2Ba;gydF4y2Ba而gydF4y2BahasFrame(视频阅读器)frame = readFrame(视频阅读器);gydF4y2Ba调整显示帧的大小。gydF4y2BaFrame = imresize(Frame, 1.5);步骤(放像机、框架);gydF4y2Ba结束gydF4y2Ba释放(放像机);gydF4y2Ba
ビデオの分類に使用する10個のビデオシ,ケンスをランダムに選択します。その際,ビデオ内で最も顕著なアクションクラスを検出できるように,ファイル全体から均等に選択します。gydF4y2Ba
numSequences = 10;gydF4y2Ba
関数gydF4y2BaclassifyVideoFilegydF4y2Ba
を使用して,ビデオファ。gydF4y2Ba
[actionLabel,score] = classifyVideoFile(inflated3dPretrained, videoFilename,gydF4y2Ba“NumSequences”gydF4y2BanumSequences)gydF4y2Ba
actionLabel =gydF4y2Ba分类gydF4y2Ba倒gydF4y2Ba
分数=gydF4y2Ba单gydF4y2Ba0.4482gydF4y2Ba
動作認識用のビデオ分類器の学習gydF4y2Ba
この例のこの節では,転移学習を使用して前述のビデオ分類器に学習させる方法を示します。学習の完了を待ことなく事前学習済みのビデオ分類器を使用するには,変数gydF4y2BadoTraininggydF4y2Ba
をgydF4y2Ba假gydF4y2Ba
に設定します。一方,ビデオ分類器に学習させる場合は,変数gydF4y2BadoTraininggydF4y2Ba
をgydF4y2Ba真正的gydF4y2Ba
に設定します。gydF4y2Ba
doTraining = false;gydF4y2Ba
学習デ,タと検証デ,タのダウンロ,ドgydF4y2Ba
この例では,gydF4y2BaHMDB51gydF4y2Baデ,タセットを使用して膨胀3d (I3D)ビデオ分類器に学習させます。この例の最後にリストされている補助関数gydF4y2BadownloadHMDB51gydF4y2Ba
を使用し,hmdb51デタセットをgydF4y2Bahmdb51gydF4y2Ba
という名前のフォルダ,にダウンロ,ドします。gydF4y2Ba
下载文件夹= fullfile(tempdir,gydF4y2Ba“hmdb51”gydF4y2Ba);downloadHMDB51 (downloadFolder);gydF4y2Ba
ダウンロドが完了したら,rarファルgydF4y2Bahmdb51_org.rargydF4y2Ba
をgydF4y2Bahmdb51gydF4y2Ba
フォルダ,に解凍します。次に,この例の最後にリストされている補助関数gydF4y2BacheckForHMDB51FoldergydF4y2Ba
を使用し,ダウンロ,ドして解凍したファ,ルが所定の場所にあることを確認します。gydF4y2Ba
allClasses = checkForHMDB51Folder(下载文件夹);gydF4y2Ba
デ,タセットには,gydF4y2Ba“飲む”,gydF4y2Ba“走る”,gydF4y2Ba“握手する”など,51を超えるクラスの7000個のクリップから成る約2 GBのビデオデータが格納されています。各ビデオフレ,ムの高さは240ピクセルで,最小幅は176ピクセルです。フレ,ム数は,18から約1000までの範囲になります。gydF4y2Ba
この例では,学習時間を短縮するために,データセットに含まれる51のすべてのクラスではなく,5つのアクションクラスを分類するようにアクティビティ認識ネットワークに学習させます。51のすべてのクラスにのすべてのクラスにいて学習させる場合はgydF4y2BauseAllDatagydF4y2Ba
をgydF4y2Ba真正的gydF4y2Ba
に設定します。gydF4y2Ba
useAllData = false;gydF4y2Ba如果gydF4y2BauseAllData classes = allClasses;gydF4y2Ba结束gydF4y2BadataFolder = fullfile(下载文件夹,gydF4y2Ba“hmdb51_org”gydF4y2Ba);gydF4y2Ba
データセットを,分類器に学習させるための学習セットと分類器を評価するためのテストセットに分割します。デ,タの80%を学習セットに使用し,残りをテストセットに使用します。gydF4y2Bafolders2labelsgydF4y2Ba
およびgydF4y2BasplitlabelsgydF4y2Ba
を使用し,フォルダーからラベル情報を作成し,各ラベルに基づいてデータを学習データセットとテストデータセットに分割します。この処理は,各ラベルのファ。gydF4y2Ba
[labels,files] = folders2labels(fullfile(dataFolder,string(classes)),gydF4y2Ba...gydF4y2Ba“IncludeSubfolders”gydF4y2Ba,真的,gydF4y2Ba...gydF4y2Ba“FileExtensions”gydF4y2Ba,gydF4y2Ba“.avi”gydF4y2Ba);索引= splitlabels(标签,0.8,gydF4y2Ba“随机”gydF4y2Ba);trainfilename =文件(索引{1});testfilename =文件(索引{2});gydF4y2Ba
ネットワークの入力データを正規化するために,データセットの最小値および最大値が,この例に添付されている垫ファイルgydF4y2BainputStatistics.matgydF4y2Ba
に用意されています。異なるデタセットの最小値および最大値を見けるには,この例の最後にリストされているサポト関数gydF4y2BainputStatisticsgydF4y2Ba
を使用します。gydF4y2Ba
inputStatsFilename =gydF4y2Ba“inputStatistics.mat”gydF4y2Ba;gydF4y2Ba如果gydF4y2Ba~存在(inputStatsFilenamegydF4y2Ba“文件”gydF4y2Ba) disp (gydF4y2Ba“读取所有训练数据以输入统计数据……”gydF4y2Ba) inputStats = inputStatistics(数据文件夹);gydF4y2Ba其他的gydF4y2Bad = load(inputStatsFilename);inputStats = d.inputStats;gydF4y2Ba结束gydF4y2Ba
デ,タセットの読み込みgydF4y2Ba
この例では,データストアを使用して,ビデオシーン,対応するオプティカルフローデータ,および対応するラベルをビデオファイルから読み取ります。gydF4y2Ba
デ,タストアからデ,タを読み取るたびに,デ,タストアに出力させるビデオフレ,ム数を指定します。gydF4y2Ba
numFrames = 64;gydF4y2Ba
ここでは,メモリ使用量と分類時間のバランスをとるために,64の値を使用します。一般的に,16,32,64,または128の値を検討してください。より多くのフレームを使用すればより多くの時間情報を取得できますが,より多くのメモリが必要になります。システムリソ,スによっては,この値を下げることが必要になる場合もあります。最適なフレ,ム数を決定するには,経験的解析が必要です。gydF4y2Ba
次に,デ,タストアに出力させるフレ,ムの高さと幅を指定します。データストアは,複数のビデオシーケンスをバッチ処理できるように,生のビデオフレームのサイズを指定されたサイズに自動的に変更します。gydF4y2Ba
frameSize = [112,112];gydF4y2Ba
ビデオシ,ンに含まれる長い時間関係を取得する場合,[112 112]の値が使用されます。これは,長時間続くアクティビティを分類するのに役立ます。サ▪▪▪ズの一般的な値は[112 112],[224 224],または[256 256]です。サイズを小さくすると,メモリ使用量と処理時間が増え,空間分解能が下がりますが,より多くのビデオフレームを使用できるようになります。HMDB51データセット内のビデオフレームの高さと幅の最小値は,それぞれ240と176です。データストアが読み取るフレームのサイズを最小値よりも大きく((256、256)など)指定する場合,まず,gydF4y2BaimresizegydF4y2Ba
を使用してフレムのサズを変更します。最適なフレ,ム数の値を決定するには,経験的解析が必要です。gydF4y2Ba
RGBビデオサブネットワ,クのチャネル数をgydF4y2Ba3.gydF4y2Ba
, i3dビデオ分類器のオプティカルフロ,サブネットワ,クのチャネル数をgydF4y2Ba2gydF4y2Ba
として指定します。オプティカルフロデタの2のチャネルは,速度のgydF4y2Ba
成分とgydF4y2Ba
成分であるgydF4y2Ba
とgydF4y2Ba
をそれぞれ表します。gydF4y2Ba
rgbChannels = 3;flowChannels = 2;gydF4y2Ba
補助関数gydF4y2BacreateFileDatastoregydF4y2Ba
を使用して,デ,タを読み込むための2のgydF4y2BaFileDatastoregydF4y2Ba
オブジェクトを設定します。1つは学習用、もう 1 つは検証用です。この補助関数は、この例の終わりにリストされています。各データストアは、ビデオ ファイルを読み取って、RGB データおよび対応するラベル情報を提供します。
isDataForTraining = true;dsTrain = createFileDatastore(trainfilename,numFrames,rgbChannels,classes,isDataForTraining);isDataForTraining = false;dsVal = createFileDatastore(testfilename,numFrames,rgbChannels,classes,isDataForTraining);gydF4y2Ba
ネットワ,クア,キテクチャの定義gydF4y2Ba
I3dネットワ,クgydF4y2Ba
3次元CNNの使用は,ビデオから時空間特徴を抽出するための自然なアプロ,チです。2次元フィルターとプーリング カーネルを 3 次元に拡張することにより、事前学習済みの 2 次元イメージ分類ネットワーク (Inception v1 や ResNet-50 など) から I3D ネットワークを作成できます。この手順では、イメージ分類タスクから学習した重みを再利用し、ビデオ認識タスクをブートストラップします。
2次元畳み込み層を3次元畳み込み層に拡張する方法を示したサンプルです。この拡張では3番目の次元(時間次元)を追加することにより,フィルターサイズ,重み,バイアスを拡張します。gydF4y2Ba
2ストリムi3dネットワクgydF4y2Ba
ビデオデータは,空間コンポーネントと時間コンポーネントという2つの部分をもつと見なすことができます。gydF4y2Ba
空間コンポ,ネントは,ビデオ内のオブジェクトの形状,テクスチャ,色に関する情報で構成されます。RGBデ,タにはこの情報が含まれています。gydF4y2Ba
時間コンポーネントは,フレーム全体のオブジェクトのモーションに関する情報で構成され,カメラと,シーン内のオブジェクトの間の重要な動作を表します。オプティカルフロ,の計算は,ビデオから時間情報を抽出するための一般的な手法です。gydF4y2Ba
2ストリムCNNには,空間サブネットワクと時間サブネットワクが組み込まれていますgydF4y2Ba[2]gydF4y2Ba。密度の高いオプティカルフローとビデオデータストリームで学習させた畳み込みニューラルネットワークは,スタックされた生のRGBフレームよりも,制限された学習データを使ってパフォーマンスを改善できます。次の図は,典型的な2ストリ,ムi3dネットワ,クを表しています。gydF4y2Ba
転移学習用の膨胀3d (I3D)ビデオ分類器の設定gydF4y2Ba
この例では动力学- 400データセットで事前学習させた3次元畳み込みニューラルネットワークビデオ分類器であるGoogLeNetアーキテクチャに基づいて,I3Dビデオ分類器を作成します。gydF4y2Ba
2つのサブネットワーク(1つはビデオデータ用,もう1つはオプティカルフローデータ用)を含むI3Dビデオ分類器のバックボーンとなる畳み込みニューラルネットワークアーキテクチャとして,GoogLeNetを指定します。gydF4y2Ba
baseNetwork =gydF4y2Ba“googlenet-video-flow”gydF4y2Ba;gydF4y2Ba
膨胀3dビデオ分類器の入力サ显卡ズを指定します。gydF4y2Ba
inputSize = [frameSize, rgbChannels, numFrames];gydF4y2Ba
inputStatistics.matgydF4y2Ba
ファ@ @ルから読み込まれたgydF4y2BainputStatsgydF4y2Ba
構造体のRGBデ,タおよびオプティカルフロ,デ,タの最小値と最大値を取得します。これらの値は,入力デ,タを正規化するために必要です。gydF4y2Ba
oflowMin = squeeze(inputStats.oflowMin)';oflowMax = squeeze(inputStats.oflowMax)';rgbMin = squeeze(inputStats.rgbMin)';rgbMax = squeeze(inputStats.rgbMax)';stats.Video.Min = rgbMin;stats.Video.Max = rgbMax;stats.Video.Mean = [];stats.Video.StandardDeviation = [];stats.OpticalFlow.Min = oflowMin(1:flowChannels);stats.OpticalFlow.Max = oflowMax(1:flowChannels); stats.OpticalFlow.Mean = []; stats.OpticalFlow.StandardDeviation = [];
関数gydF4y2Bainflated3dVideoClassifiergydF4y2Ba
を使用して,i3dビデオ分類器を作成します。gydF4y2Ba
i3d = inflated3dVideoClassifier(baseNetwork,string(classes),gydF4y2Ba...gydF4y2Ba“InputSize”gydF4y2BainputSize,gydF4y2Ba...gydF4y2Ba“InputNormalizationStatistics”gydF4y2Ba、统计数据);gydF4y2Ba
ビデオ分類器のモデル名を指定します。gydF4y2Ba
i3d。ModelName =gydF4y2Ba基于视频和光流的膨胀三维活动识别器gydF4y2Ba;gydF4y2Ba
学習デ,タの拡張と前処理gydF4y2Ba
デ,タ拡張を使用すると,限られたデ,タセットで学習を行うことができます。フレームのコレクション(ビデオシーケンス)では,ネットワークの入力サイズに基づき,ビデオデータに対して同じ拡張を適用しなければなりません。平行移動,トリミング,変換などのわずかな変更をイメージに加えることで,ロバストなビデオ分類器の学習に使用できる特徴的な一意のイメージが新たに作成されます。デ,タストアは,デ,タの集合の読み取りや拡張に便利です。この例の終わりに定義されているサポ,ト関数gydF4y2BaaugmentVideogydF4y2Ba
を使用して,学習ビデオデ,タを拡張します。gydF4y2Ba
dsTrain = transform(dsTrain, @augmentVideo);gydF4y2Ba
前処理として,この例の終わりに定義されているgydF4y2BapreprocessVideoClipsgydF4y2Ba
を使用し,Inflated-3Dビデオ分類器の入力サイズに合わせて学習ビデオデータのサイズを変更します。ビデオ分類器のgydF4y2BaInputNormalizationStatisticsgydF4y2Ba
プロパティ,および前処理関数への入力のサaaplズを,構造体gydF4y2BapreprocessInfogydF4y2Ba
のフィ,ルド値として指定します。gydF4y2BaInputNormalizationStatisticsgydF4y2Ba
プロパティは,ビデオフレームとオプティカルフローデータを1 ~ 1に再スケーリングするのに使用されます。入力サesc escズは,構造体gydF4y2Ba信息gydF4y2Ba
のgydF4y2BaSizingOptiongydF4y2Ba
の値に基づき,gydF4y2BaimresizegydF4y2Ba
を使用してビデオフレムのサズを変更するのに使用されます。あるいは,gydF4y2Ba“randomcrop”gydF4y2Ba
またはgydF4y2Ba“centercrop”gydF4y2Ba
を使用して,ビデオ分類器の入力サイズに合わせて入力データをランダムにトリミングするか中央でトリミングできます。デ,タ拡張は,テストデ,タと検証デ,タには適用されないことに注意してください。理想的には,テストデータと検証データは元のデータを代表するもので,バイアスのない評価を行うために変更なしで使用されなければなりません。gydF4y2Ba
preprocessInfo。统计信息= i3d.InputNormalizationStatistics;preprocessInfo。InputSize=我nputSize; preprocessInfo.SizingOption =“调整”gydF4y2Ba;dsTrain = transform(dsTrain, @(data)preprocessVideoClips(data, preprocessInfo));dsVal = transform(dsVal, @(数据)preprocessVideoClips(数据,preprocessInfo));gydF4y2Ba
モデル勾配関数の定義gydF4y2Ba
この例の最後にリストされているサポ,ト関数gydF4y2BamodelGradientsgydF4y2Ba
を作成します。関数gydF4y2BamodelGradientsgydF4y2Ba
は,i3dビデオ分類器gydF4y2Bai3dgydF4y2Ba
,入力デ,タgydF4y2BadlRGBgydF4y2Ba
およびgydF4y2BadlFlowgydF4y2Ba
のミニバッチ,グラウンドトゥル,スラベルデ,タgydF4y2Ba海底gydF4y2Ba
のミニバッチを入力として受け取ります。関数は、学習損失値、分類器の学習可能パラメーターについての損失の勾配、および分類器のミニバッチの精度を返します。
損失は,各サブネットワークから得られる予測の交差エントロピー損失の平均を求めることによって計算されます。ネットワ,クの出力予測は,各クラスに,いて0 ~ 1の確率となります。gydF4y2Ba
各分類器の精度は,RGBおよびオプティカルフローの予測の平均を受け取り,それを入力のグラウンドトゥルースラベルと比較することによって計算されます。gydF4y2Ba
学習オプションの指定gydF4y2Ba
ミニバッチサesc escズを20,反復回数を600として学習させます。gydF4y2BaSaveBestAfterIterationgydF4y2Ba
パラメ,タ,を使用し,最大の検証精度でビデオ分類器を保存するまでの反復回数を指定します。gydF4y2Ba
コサンアニリング学習率スケジュル[gydF4y2Ba3.gydF4y2Ba]パラメ,タ,を指定します。gydF4y2Ba
最小学習率として1e-4。gydF4y2Ba
最大学習率として1e-3。gydF4y2Ba
学習率スケジュルサクルが再開するまでのコサンの反復数として100,200,300。オプションgydF4y2Ba
CosineNumIterationsgydF4y2Ba
では,各コサaaplンサaaplクルの幅を定義します。gydF4y2Ba
SGDM最適化のパラメ,タ,を指定します。学習開始時にSGDM最適化パラメ,タ,を初期化します。gydF4y2Ba
モ,メンタムとして0.9 .;gydF4y2Ba
[]gydF4y2Ba
として初期化された初期速度パラメタ。gydF4y2BaL2正則化係数として0.0005。gydF4y2Ba
並列プ,ルを使用し,バックグラウンドでデ,タのディスパッチを実行するように指定します。gydF4y2BaDispatchInBackgroundgydF4y2Ba
が真正に設定されている場合,並列ワーカーの指定された数で並列プールを開き,この例の一部として提供されるgydF4y2BaDispatchInBackgroundDatastoregydF4y2Ba
を作成します。そして,非同期のデータの読み込みと前処理を使用して学習を高速化するために,バックグラウンドでデータのディスパッチを行います。既定では,この例は利用可能なgpuがある場合にそれを使用します。そうでない場合はCPUが使用されます。GPUを使用するには,并行计算工具箱™,およびCUDA®対応のNVIDIA GPU®が必要です。サポトされる计算能力の詳細にいては,gydF4y2BaGpu計算の要件gydF4y2Ba(并行计算工具箱)gydF4y2Baを参照してください。gydF4y2Ba
参数个数。类=cl一个年代年代e年代;参数个数。MiniBatchSize = 20;参数个数。NumIterations = 600; params.SaveBestAfterIteration = 400; params.CosineNumIterations = [100, 200, 300]; params.MinLearningRate = 1e-4; params.MaxLearningRate = 1e-3; params.Momentum = 0.9; params.VelocityRGB = []; params.VelocityFlow = []; params.L2Regularization = 0.0005; params.ProgressPlot = true; params.Verbose = true; params.ValidationData = dsVal; params.DispatchInBackground = false; params.NumWorkers = 4;
I3dビデオ分類器の学習gydF4y2Ba
RGBビデオデ,タとオプティカルフロ,デ,タを使用し,i3dビデオ分類器に学習させます。gydF4y2Ba
各エポックで次を行います。gydF4y2Ba
デ,タのミニバッチをル,プ処理する前にデ,タをシャッフルします。gydF4y2Ba
minibatchqueuegydF4y2Ba
を使用してミニバッチをル,プ処理します。この例の最後にリストされているサポ,ト関数gydF4y2BacreateMiniBatchQueuegydF4y2Ba
は,指定された学習デ,タストアを使用してgydF4y2BaminibatchqueuegydF4y2Ba
を作成します。gydF4y2Ba検証デ,タgydF4y2Ba
dsValgydF4y2Ba
を使用してネットワ,クを検証します。gydF4y2Baこの例の最後にリストされているサポ,ト関数gydF4y2Ba
displayVerboseOutputEveryEpochgydF4y2Ba
を使用し,各エポックの損失と精度の結果を表示します。gydF4y2Ba
各ミニバッチで次を行います。gydF4y2Ba
ビデオデ,タまたはオプティカルフロ,デ,タとラベルを,基となる型が单のgydF4y2Ba
dlarraygydF4y2Ba
オブジェクトに変換します。gydF4y2BaI3Dビデオ分類器を使用してビデオデータの時間次元を処理できるようにするには,時間シーケンスの次元gydF4y2Ba
“T”gydF4y2Ba
を指定します。ビデオデータに次元ラベル“SSCTB”gydF4y2Ba
(空间、空间、通道、时间、批)を指定し,ラベルデータにgydF4y2Ba“CB”gydF4y2Ba
を指定します。gydF4y2Ba
minibatchqueuegydF4y2Ba
オブジェクトは,この例の最後にリストされているサポ,ト関数gydF4y2BabatchVideoAndFlowgydF4y2Ba
を使用し,rgbビデオデ,タとオプティカルフロ,デ,タをバッチ処理します。gydF4y2Ba
参数个数。ModelFilename =gydF4y2Ba“inflated3d-FiveClasses-hmdb51.mat”gydF4y2Ba;gydF4y2Ba如果gydF4y2BadoTraining epoch = 1;bestLoss = realmax;accTrain = [];accTrainRGB = [];accTrainFlow = [];lossTrain = [];迭代= 1;开始= tic;trainTime =开始;shuffleTrainDs(dsTrain);gydF4y2Ba输出数量为3个:一个RGB帧,一个光流gydF4y2Ba% data,一个用于ground truth标签。gydF4y2BanumOutputs = 3;mbq = createMiniBatchQueue(shuffered, numOutputs, params);gydF4y2Ba使用initializeTrainingProgressPlot和initializeVerboseOutputgydF4y2Ba%支万博1manbetx持函数(示例末尾列出)用于初始化gydF4y2Ba%的训练进度图和详细输出显示训练gydF4y2Ba%损失、训练准确率和验证准确率。gydF4y2Baploters = initializeTrainingProgressPlot(params);initializeVerboseOutput (params);gydF4y2Ba而gydF4y2Ba迭代<= params。NumIterationsgydF4y2Ba遍历数据集。gydF4y2Ba[dlVideo,dlFlow,dlY] = next(mbq);gydF4y2Ba使用dlfeval评估模型梯度和损失。gydF4y2Ba[gradRGB gradFlow,损失,acc, accRGB accFlow, stateRGB, stateFlow] =gydF4y2Ba...gydF4y2Badlfeval (@modelGradients i3d、dlVideo dlFlow,海底);gydF4y2Ba累积损失和精度。gydF4y2BalossTrain = [lossTrain, loss];accTrain = [accTrain, acc];accTrainRGB = [accTrainRGB, accRGB];accTrainFlow = [accTrainFlow, accFlow];gydF4y2Ba更新网络状态。gydF4y2Bai3d。V我deoState = stateRGB; i3d.OpticalFlowState = stateFlow;更新RGB和光流的梯度和参数gydF4y2Ba%的子网使用SGDM优化器。gydF4y2Ba[i3d.VideoLearnables,参数个数。VelocityRGB] =gydF4y2Ba...gydF4y2BaupdateLearnables (i3d.VideoLearnables gradRGB params, params.VelocityRGB,迭代);[i3d.OpticalFlowLearnables,参数个数。VelocityFlow learnRate] =gydF4y2Ba...gydF4y2BaupdateLearnables (i3d.OpticalFlowLearnables gradFlow params, params.VelocityFlow,迭代);gydF4y2Ba如果gydF4y2Ba~hasdata(mbq) ||迭代==参数。NumIterationsgydF4y2Ba当前纪元已完成。进行验证并更新进度。gydF4y2BatrainTime = toc(trainTime);(cmat validationTime, lossValidation、accValidation accValidationRGB, accValidationFlow] =gydF4y2Ba...gydF4y2BadoValidation (params, i3d);accTrain = mean(accTrain);accTrainRGB = mean(accTrainRGB);accTrainFlow = mean(accTrainFlow);lossTrain = mean(lossTrain);gydF4y2Ba更新培训进度。gydF4y2BadisplayVerboseOutputEveryEpoch(参数、启动、learnRate时代,迭代,gydF4y2Ba...gydF4y2BaaccTrain、accTrainRGB accTrainFlow,gydF4y2Ba...gydF4y2BaaccValidation、accValidationRGB accValidationFlow,gydF4y2Ba...gydF4y2BalossTrain lossValidation,火车离站时刻表,validationTime);updateProgressPlot (params,策划者,时代,迭代,开始,lossTrain, accTrain, accValidation);gydF4y2Ba保存训练的视频分类器和给出的参数gydF4y2Ba%是迄今为止最好的验证损失。使用saveData支持函数,万博1manbetxgydF4y2Ba%列在本例末尾。gydF4y2BabestLoss = saveData(i3d,bestLoss,迭代,cmat,lossTrain,lossValidation,gydF4y2Ba...gydF4y2BaaccTrain、accValidation params);gydF4y2Ba结束gydF4y2Ba如果gydF4y2Ba~hasdata(mbq) && iteration <参数。NumIterationsgydF4y2Ba当前纪元已完成。初始化训练损失,准确度高gydF4y2Ba% values,以及下一个纪元的minibatchqueue。gydF4y2BaaccTrain = [];accTrainRGB = [];accTrainFlow = [];lossTrain = [];trainTime = tic;Epoch = Epoch + 1;shuffleTrainDs(dsTrain);numOutputs = 3;mbq = createMiniBatchQueue(shuffered, numOutputs, params);gydF4y2Ba结束gydF4y2Ba迭代=迭代+ 1;gydF4y2Ba结束gydF4y2Ba培训完成时显示消息。gydF4y2BaendVerboseOutput (params);disp (gydF4y2Ba“模型保存到:”gydF4y2Ba+ params.ModelFilename);gydF4y2Ba结束gydF4y2Ba
学習済みネットワ,クの評価gydF4y2Ba
テストデ,タセットを使用し,学習済みのビデオ分類器の精度を評価します。gydF4y2Ba
学習中に保存された最適なモデルを読み込むか,事前学習済みのモデルを使用します。gydF4y2Ba
如果gydF4y2BadoTraining transferLearned = load(params.ModelFilename);inflated3dPretrained = transferLearned.data.inflated3d;gydF4y2Ba结束gydF4y2Ba
minibatchqueuegydF4y2Ba
オブジェクトを作成し,テストデ,タのバッチを読み込みます。gydF4y2Ba
numOutputs = 3;mbq = createMiniBatchQueue(参数。V一个l我d一个t我onData, numOutputs, params);
テストデータの各バッチについて,RGBネットワークとオプティカルフローネットワークを使用して予測を行い,予測の平均を求め,混同行列を使用して予測精度を計算します。gydF4y2Ba
numClasses = nummel(类);cmat = sparse(numClasses,numClasses);gydF4y2Ba而gydF4y2Bahasdata(mbq) [dlRGB, dlFlow, dlY] = next(mbq);gydF4y2Ba将视频输入作为RGB和光流数据通过gydF4y2Ba%双流I3D视频分类器,得到单独的预测。gydF4y2Ba[dlYPredRGB,dlYPredFlow] = predict(inflated3dpre训练,dlRGB,dlFlow);gydF4y2Ba通过计算预测的平均值来融合预测。gydF4y2BadlYPred = (dlYPredRGB + dlYPredFlow)/2;gydF4y2Ba计算预测的准确性。gydF4y2Ba[~,YTest] = max(dlY,[],1);[~,YPred] = max(dlYPred,[],1);cmat = aggregateConfusionMetric(cmat,YTest,YPred);gydF4y2Ba结束gydF4y2Ba
学習済みのネットワ,クの平均分類精度を計算します。gydF4y2Ba
= sum(diag(cmat))./sum(cmat,gydF4y2Ba“所有”gydF4y2Ba)gydF4y2Ba
精确度= 0.8850gydF4y2Ba
混同行列を表示します。gydF4y2Ba
Figure chart = confusionchart(cmat,classes);gydF4y2Ba
动力学- 400データセットで事前学習させたInflated-3Dビデオ分類器は,転移学習を行うことで行動認識の性能が向上します。前述の学習は,24GB Titan-X GPUで約100分間実行されました。小規模なアクティビティ認識ビデオデータセットでゼロから学習させる場合,事前学習済みのビデオ分類器を使用する場合と比べて学習と収束により多くの時間がかかります。动力学- 400で事前学習させたInflated-3Dビデオ分類器を使用して転移学習を行うと,実行エポック数が大きい場合の過適合を防ぐこともできます。ただし动力学- 400データセットで事前学習させたSlowFastビデオ分類器やR(2 + 1)维ビデオ分類器は,Inflated-3Dビデオ分類器と比べ,学習時の性能が高く,より短時間で収束します。深層学習を使用したビデオ認識の詳細にいては,gydF4y2Ba开始使用深度学习进行视频分类gydF4y2Baを参照してください。gydF4y2Ba
サポ,ト関数gydF4y2Ba
inputStatisticsgydF4y2Ba
関数gydF4y2BainputStatisticsgydF4y2Ba
は,HMDB51データを格納するフォルダーの名前を入力として受け取り,RGBデータとオプティカルフローデータの最小値と最大値を計算します。最小値と最大値は,ネットワ,クの入力層への正規化入力として使用されます。この関数は,ネットワークの学習中およびテスト中に,後で使用する各ビデオファイルのフレーム数も取得します。異なるデータセットの最小値および最大値を見つけるには,データセットを格納しているフォルダー名でこの関数を使用します。gydF4y2Ba
函数gydF4y2BainputStats = inputStatistics(数据文件夹)ds = createDatastore(数据文件夹);ds。ReadFcn = @getMinMax;抽搐;Tt =高(ds);Varnames = {gydF4y2Ba“rgbMax”gydF4y2Ba,gydF4y2Ba“rgbMin”gydF4y2Ba,gydF4y2Ba“oflowMax”gydF4y2Ba,gydF4y2Ba“oflowMin”gydF4y2Ba};统计数据=收集(groupsummary(tt,[],{gydF4y2Ba“马克斯”gydF4y2Ba,gydF4y2Ba“最小值”gydF4y2Ba}, varnames));inputStats。Filename = gather(tt.Filename);inputStats。NumFrames = gather(tt.NumFrames);inputStats。rgbMax = stats.max_rgbMax; inputStats.rgbMin = stats.min_rgbMin; inputStats.oflowMax = stats.max_oflowMax; inputStats.oflowMin = stats.min_oflowMin; save(“inputStatistics.mat”gydF4y2Ba,gydF4y2Ba“inputStats”gydF4y2Ba);toc;gydF4y2Ba结束gydF4y2Ba函数gydF4y2Badata = getMinMax(文件名)reader = VideoReader(文件名);opticFlow = opticalFlowFarneback;数据= [];gydF4y2Ba而gydF4y2BahasFrame(reader) = readFrame(reader);[rgb,oflow] = findMinMax(frame,opticFlow);data = assignMinMax(data, rgb, oflow);gydF4y2Ba结束gydF4y2BatotalFrames = floor(阅读器。Duration * reader.FrameRate);totalFrames = min(totalFrames, reader.NumFrames);[labelName, filename] = getLabelFilename(filename);数据。Filename = fullfile(labelName, Filename);数据。NumFrames = totalFrames;数据= struct2table(数据,gydF4y2Ba“AsArray”gydF4y2Ba,真正的);gydF4y2Ba结束gydF4y2Ba函数gydF4y2Ba[labelName, filename] = getLabelFilename(filename) fileNameSplit = split(filename,gydF4y2Ba' / 'gydF4y2Ba);labelName = fileNameSplit{end-1};filename = fileNameSplit{end};gydF4y2Ba结束gydF4y2Ba函数gydF4y2Badata = assignMinMax(data, rgb, oflow)gydF4y2Ba如果gydF4y2Baisempty(数据)的数据。rgbMax = rgb.Max;数据。rgbMin = rgb.Min; data.oflowMax = oflow.Max; data.oflowMin = oflow.Min;返回gydF4y2Ba;gydF4y2Ba结束gydF4y2Ba数据。rgbMax = max(data.rgbMax, rgb.Max); data.rgbMin = min(data.rgbMin, rgb.Min); data.oflowMax = max(data.oflowMax, oflow.Max); data.oflowMin = min(data.oflowMin, oflow.Min);结束gydF4y2Ba函数gydF4y2Ba[rgbMinMax,oflowMinMax] = findMinMax(rgb, opticFlow) rgbMinMax。Max = Max (rgb,[],[1,2]);rgbMinMax。Min = Min (rgb,[],[1,2]);灰色= rgb2gray(rgb);流量= estimateFlow(opticFlow,灰色);oflow = cat(3,流量。vx,流量。vy,流量。量级);oflowMinMax。Max = Max (oflow,[],[1,2]);oflowMinMax。Min = Min (oflow,[],[1,2]);gydF4y2Ba结束gydF4y2Ba函数gydF4y2Bads = createDatastore(文件夹)gydF4y2Ba...gydF4y2Ba“IncludeSubfolders”gydF4y2Ba,真的,gydF4y2Ba...gydF4y2Ba“FileExtensions”gydF4y2Ba,gydF4y2Ba“.avi”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba“UniformRead”gydF4y2Ba,真的,gydF4y2Ba...gydF4y2Ba“ReadFcn”gydF4y2Ba, @getMinMax);disp (gydF4y2Ba”NumFiles:“gydF4y2Ba+元素个数(ds.Files));gydF4y2Ba结束gydF4y2Ba
createFileDatastoregydF4y2Ba
関数gydF4y2BacreateFileDatastoregydF4y2Ba
は,指定されたファgydF4y2BaFileDatastoregydF4y2Ba
オブジェクトを作成します。gydF4y2BaFileDatastoregydF4y2Ba
オブジェクトはgydF4y2Ba“partialfile”gydF4y2Ba
モードでデータを読み取るため,すべての読み取りにおいてビデオから部分的に読み取ったフレームを返すことができます。この特徴は,大きなビデオファイルの読み取りで,フレームのすべてをメモリに取り込めない場合に役立ちます。gydF4y2Ba
函数gydF4y2Badatastore = createFileDatastore(trainingFolder,numFrames,numChannels,classes,isDataForTraining) readFcn = @(f,u)readVideo(f,u,numFrames,numChannels,classes,isDataForTraining);数据存储= fileDatastore(训练文件夹,gydF4y2Ba...gydF4y2Ba“IncludeSubfolders”gydF4y2Ba,真的,gydF4y2Ba...gydF4y2Ba“FileExtensions”gydF4y2Ba,gydF4y2Ba“.avi”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba“ReadFcn”gydF4y2BareadFcn,gydF4y2Ba...gydF4y2Ba“ReadMode”gydF4y2Ba,gydF4y2Ba“partialfile”gydF4y2Ba);gydF4y2Ba结束gydF4y2Ba
shuffleTrainDsgydF4y2Ba
関数gydF4y2BashuffleTrainDsgydF4y2Ba
は,学習デ,タストアgydF4y2BadsTraingydF4y2Ba
に存在するファ@ @ルをシャッフルします。gydF4y2Ba
函数gydF4y2BashuffleTrainDs(dsTrain) shuffle =复制(dsTrain);转换= isa(洗牌,gydF4y2Ba“matlab.io.datastore.TransformedDatastore”gydF4y2Ba);gydF4y2Ba如果gydF4y2Ba转换文件= shuffle .底层数据存储{1}.Files;gydF4y2Ba其他的gydF4y2Bafiles = shuffle . files;gydF4y2Ba结束gydF4y2BaN = numel(文件);shuffledIndices = randperm(n);gydF4y2Ba如果gydF4y2Ba改变shuffled.UnderlyingDatastores{1}。Files = Files (shuffledIndices);gydF4y2Ba其他的gydF4y2Ba重新洗了一遍。Files = Files (shuffledIndices);gydF4y2Ba结束gydF4y2Ba重置(重组);gydF4y2Ba结束gydF4y2Ba
readVideogydF4y2Ba
関数gydF4y2BareadVideogydF4y2Ba
は,ビデオフレ,ム,および指定されたビデオファ,ルの対応するラベル値を読み取ります。学習中,読み取り関数は,ランダムに選択された開始フレームを使用し,ネットワークの入力サイズに従って特定の数のフレームを読み取ります。テスト中,すべてのフレ,ムは順番に読み取られます。ビデオフレームは、学習用、テスト用、および検証用に、分類器ネットワークで必要とされる入力サイズになるようにサイズが変更されます。
函数gydF4y2Ba[data,userdata,done] = readVideo(filename,userdata,numFrames,numChannels,classes,isDataForTraining)gydF4y2Ba如果gydF4y2Baisempty(用户数据)用户数据。re一个der=VideoReader(f我len一个米e);用户数据。batchesRead = 0; userdata.label = getLabel(filename,classes); totalFrames = floor(userdata.reader.Duration * userdata.reader.FrameRate); totalFrames = min(totalFrames, userdata.reader.NumFrames); userdata.totalFrames = totalFrames; userdata.datatype = class(read(userdata.reader,1));结束gydF4y2BaReader = userdata.reader;totalFrames = userdata.totalFrames;标签= userdata.label;batchesRead = userdata.batchesRead;gydF4y2Ba如果gydF4y2BaisDataForTraining视频= readForTraining(reader, numFrames, totalFrames);gydF4y2Ba其他的gydF4y2Ba视频= readForValidation(读取器,用户数据。d一个t一个type,numChannels, numFrames, totalFrames);结束gydF4y2Ba数据={视频,标签};batchesRead = batchesRead + 1;用户数据。b一个tchesRead = batchesRead;如果gydF4y2BanumFrames > totalFrames numbatch = 1;gydF4y2Ba其他的gydF4y2BanumBatches = floor(totalFrames/numFrames);gydF4y2Ba结束gydF4y2Ba如果读取器已经读取了所有帧,则将done标志设置为truegydF4y2Ba%如果是训练。gydF4y2Badone = batchesRead == numbatch || isDataForTraining;gydF4y2Ba结束gydF4y2Ba
readForTraininggydF4y2Ba
関数gydF4y2BareadForTraininggydF4y2Ba
は,ビデオ分類器の学習に使用するビデオフレ,ムを読み取ります。この関数は,ランダムに選択された開始フレームを使用し,ネットワークの入力サイズに従って特定の数のフレームを読み取ります。十分なフレ,ムが残っていない場合,必要なフレ,ム数となるようにビデオシ,ケンスが繰り返されます。gydF4y2Ba
函数gydF4y2Bavideo = readForTraining(reader, numFrames, totalFrames)gydF4y2Ba如果gydF4y2BanumFrames >= totalFrames startIdx = 1;endIdx = totalFrames;gydF4y2Ba其他的gydF4y2BastartIdx = randperm(totalFrames - numFrames + 1);startIdx = startIdx(1);endIdx = startIdx + numFrames - 1;gydF4y2Ba结束gydF4y2Bavideo = read(reader,[startIdx,endIdx]);gydF4y2Ba如果gydF4y2BanumFrames > totalFramesgydF4y2Ba添加更多帧以填充网络输入大小。gydF4y2Ba附加= ceil(numFrames/totalFrames);视频= repmat(视频,1,1,1,附加);video = video(:,:,:,1:numFrames);gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
readForValidationgydF4y2Ba
関数gydF4y2BareadForValidationgydF4y2Ba
は,学習済みビデオ分類器の評価に使用するビデオフレ,ムを読み取ります。この関数は、ネットワ、クの入力サ、ズに従って特定の数のフレ、ムを順番に読み取ります。十分なフレ,ムが残っていない場合,必要なフレ,ム数となるようにビデオシ,ケンスが繰り返されます。gydF4y2Ba
函数gydF4y2BaH = readForValidation(reader, datatype, numChannels, numFrames, totalFrames);W = reader.Width;toRead = min([numFrames,totalFrames]);视频= 0 ([H,W,numChannels,toRead],数据类型);frameIndex = 0;gydF4y2Ba而gydF4y2BahasFrame(reader) && frameIndex < numFrames frame = readFrame(reader);frameIndex = frameIndex + 1;video(:,:,:,frameIndex) =帧;gydF4y2Ba结束gydF4y2Ba如果gydF4y2BaframeIndex < numFrames video = video(:,:,:,1:frameIndex);附加= ceil(numFrames/frameIndex);视频= repmat(视频,1,1,1,附加);video = video(:,:,:,1:numFrames);gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
getLabelgydF4y2Ba
関数gydF4y2BagetLabelgydF4y2Ba
は,ファ。ファ@ @ルのラベルは,そのファ@ @ルが存在するフォルダ@ @です。たとえば,ファgydF4y2Ba“/道路/ /数据/鼓掌/ video_0001.avi”gydF4y2Ba
である場合,ラベル名はgydF4y2Ba“鼓掌”gydF4y2Ba
となります。gydF4y2Ba
函数gydF4y2Ba标签= getLabel(文件名,类)文件夹= fileparts(字符串(文件名));[~,label] = fileparts(文件夹);Label = categorical(string(Label), string(classes));gydF4y2Ba结束gydF4y2Ba
augmentVideogydF4y2Ba
関数gydF4y2BaaugmentVideogydF4y2Ba
は,サポ,ト関数gydF4y2BaaugmentTransformgydF4y2Ba
によって提供される拡張変換関数を使用して,ビデオシ,ケンス全体に同じ拡張を適用します。gydF4y2Ba
函数gydF4y2Badata = augmentVideo(data) numSequences = size(data,1);gydF4y2Ba为gydF4y2Baii = 1:numSequences视频=数据{ii,1};gydF4y2Ba% HxWxCgydF4y2BaSz = size(视频,[1,2,3]);gydF4y2Ba每个序列增加一次gydF4y2BaaugmentFcn = augmentTransform(sz);data{ii,1} = augmentFcn(视频);gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
augmentTransformgydF4y2Ba
関数gydF4y2BaaugmentTransformgydF4y2Ba
は,ランダムな左右反転係数とスケ,リング係数を使った拡張方法を作成します。gydF4y2Ba
函数gydF4y2BaaugmentFcn = szgydF4y2Ba%随机翻转和缩放图像。gydF4y2Batform = randomAffine2d(gydF4y2Ba“XReflection”gydF4y2Ba,真的,gydF4y2Ba“规模”gydF4y2Ba1.1 [1]);rout = affineOutputView(sz,tform,gydF4y2Ba“BoundsStyle”gydF4y2Ba,gydF4y2Ba“CenterOutput”gydF4y2Ba);augmentFcn = @(data)augmentData(data,tform,rout);gydF4y2Ba函数gydF4y2Badata = augmentData(data,tform,rout) data = imwarp(data,tform, rout)gydF4y2Ba“OutputView”gydF4y2Ba,溃败);gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
preprocessVideoClipsgydF4y2Ba
関数gydF4y2BapreprocessVideoClipsgydF4y2Ba
は,前処理として,Inflated-3Dビデオ分類器の入力サイズに合わせて学習ビデオデータのサイズを変更します。これは,構造体gydF4y2Ba信息gydF4y2Ba
に含まれるビデオ分類器のgydF4y2BaInputNormalizationStatisticsgydF4y2Ba
プロパティとgydF4y2BaInputSizegydF4y2Ba
プロパティを受け取ります。gydF4y2BaInputNormalizationStatisticsgydF4y2Ba
プロパティは,ビデオフレームとオプティカルフローデータを1 ~ 1に再スケーリングするのに使用されます。入力サesc escズは,構造体gydF4y2Ba信息gydF4y2Ba
のgydF4y2BaSizingOptiongydF4y2Ba
の値に基づき,gydF4y2BaimresizegydF4y2Ba
を使用してビデオフレムのサズを変更するのに使用されます。あるいは,gydF4y2Ba“randomcrop”gydF4y2Ba
またはgydF4y2Ba“centercrop”gydF4y2Ba
をgydF4y2BaSizingOptiongydF4y2Ba
の値として使用して,ビデオ分類器の入力サイズに合わせて入力データをランダムにトリミングするか中央でトリミングできます。gydF4y2Ba
函数gydF4y2Ba预处理= preprocessVideoClips(数据,信息)inputSize = info. inputSize (1:2);sizingOption = info.SizingOption;gydF4y2Ba开关gydF4y2BasizingOptiongydF4y2Ba情况下gydF4y2Ba“调整”gydF4y2Basize = @(x)imresize(x,inputSize);gydF4y2Ba情况下gydF4y2Ba“randomcrop”gydF4y2BasizingFcn = @(x)cropVideo(x,@ randomcropwindow2d,inputSize);gydF4y2Ba情况下gydF4y2Ba“centercrop”gydF4y2BasizingFcn = @(x)cropVideo(x,@ centercropwindow2d,inputSize);gydF4y2Ba结束gydF4y2BanumClips = size(data,1);rgbMin = info.Statistics.Video.Min;rgbMax = info.Statistics.Video.Max;oflowMin = info.Statistics.OpticalFlow.Min;oflowMax = info.Statistics.OpticalFlow.Max;numChannels = length(rgbMin);rgbMin =重塑(rgbMin, 1,1, numChannels);rgbMax =重塑(rgbMax, 1,1, numChannels);numChannels = length(oflowMin);oflowMin =重塑(oflowMin, 1,1, numChannels); oflowMax = reshape(oflowMax, 1, 1, numChannels); preprocessed = cell(numClips, 3);为gydF4y2Baii = 1:numClips video = data{ii,1};resized = sizingFcn(视频);oflow = computeFlow(resized,inputSize);gydF4y2Ba将输入转换为单个。gydF4y2BaResized =单个(调整大小);Oflow =单(Oflow);gydF4y2Ba在-1到1之间重新缩放输入。gydF4y2Baresize = rescale(resize,-1,1,gydF4y2Ba“InputMin”gydF4y2BargbMin,gydF4y2Ba“InputMax”gydF4y2Ba, rgbMax);Oflow = rescale(Oflow,-1,1,gydF4y2Ba“InputMin”gydF4y2BaoflowMin,gydF4y2Ba“InputMax”gydF4y2Ba, oflowMax);预处理{ii,1} =调整大小;预处理{ii,2} = oflow;预处理{ii,3} =数据{ii,2};gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba函数gydF4y2BaoutData = cropVideo(data, cropFcn, inputSize) imsz = size(data,[1,2]);cropWindow = cropFcn(imsz, inputSize);numFrames = size(data,4);sz = [inputSize, size(data,3), numFrames];outData = 0 (sz,gydF4y2Ba“喜欢”gydF4y2Ba、数据);gydF4y2Ba为gydF4y2Baf = 1: numFrames outData (:,:: f) = imcrop(数据(:,::f), cropWindow);gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
computeFlowgydF4y2Ba
関数gydF4y2BacomputeFlowgydF4y2Ba
は,入力としてビデオシ,ケンスgydF4y2BavideoFramesgydF4y2Ba
を受け取り,gydF4y2BaopticalFlowFarnebackgydF4y2Ba
を使用して対応するオプティカルフロ,デ,タgydF4y2BaopticalFlowDatagydF4y2Ba
を計算します。オプティカルフロ,デ,タには,速度のgydF4y2Ba
成分とgydF4y2Ba
成分に対応する2のチャネルが含まれています。gydF4y2Ba
函数gydF4y2BaopticalFlowData = computeFlow(videoFrames, inputSize) opticalFlow = opticalFlowFarneback;numFrames = size(videoFrames,4);sz = [inputSize, 2, numFrames];opticalFlowData = 0 (sz,gydF4y2Ba“喜欢”gydF4y2Ba, videoFrames);gydF4y2Ba为gydF4y2Baf = 1:numFrames gray = rgb2gray(videoFrames(:,:,:,f));流量= estimateFlow(opticalFlow,灰色);opticalFlowData (:,:: f) =猫(3 flow.Vx flow.Vy);gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
createMiniBatchQueuegydF4y2Ba
関数gydF4y2BacreateMiniBatchQueuegydF4y2Ba
は,指定されたデ,タストアからのデ,タ量gydF4y2BaminiBatchSizegydF4y2Ba
を提供するgydF4y2BaminibatchqueuegydF4y2Ba
オブジェクトを作成します。また,並列プ,ルが開いている場合は,gydF4y2BaDispatchInBackgroundDatastoregydF4y2Ba
も作成します。gydF4y2Ba
函数gydF4y2Bambq = createMiniBatchQueue(数据存储,numOutputs, params)gydF4y2Ba如果gydF4y2Ba参数个数。DispatchInBackground && isempty(gcp(gydF4y2Ba“nocreate”gydF4y2Ba))gydF4y2Ba如果DispatchInBackground为true,则启动并行池调度gydF4y2Ba%的数据在后台使用并行池。gydF4y2BaC = parcluster(gydF4y2Ba“本地”gydF4y2Ba);c.NumWorkers = params.NumWorkers;parpool (gydF4y2Ba“本地”gydF4y2Ba, params.NumWorkers);gydF4y2Ba结束gydF4y2BaP = gcp(gydF4y2Ba“nocreate”gydF4y2Ba);gydF4y2Ba如果gydF4y2Ba~isempty(p) datastore = DispatchInBackgroundDatastore(datastore, p. numworkers);gydF4y2Ba结束gydF4y2BainputFormat (1: numOutputs-1) =gydF4y2Ba“SSCTB”gydF4y2Ba;outputFormat =gydF4y2Ba“CB”gydF4y2Ba;mbq = minibatchqueue(数据存储,numOutputs,gydF4y2Ba...gydF4y2Ba“MiniBatchSize”gydF4y2Ba,参数个数。MiniBatchSize,gydF4y2Ba...gydF4y2Ba“MiniBatchFcn”gydF4y2Ba@batchVideoAndFlow,gydF4y2Ba...gydF4y2Ba“MiniBatchFormat”gydF4y2BainputFormat, outputFormat]);gydF4y2Ba结束gydF4y2Ba
batchVideoAndFlowgydF4y2Ba
関数gydF4y2BabatchVideoAndFlowgydF4y2Ba
は、细胞配列から取得したビデオデータ,オプティカルフローデータ,およびラベルデータをバッチ処理します。これは,関数gydF4y2BaonehotencodegydF4y2Ba
使用して,グラウンドトゥル,スカテゴリカルラベルを一热配列に符号化します。一热符号化された配列では,ラベルのクラスに対応する位置にgydF4y2Ba1gydF4y2Ba
が格納され,その他のすべての位置にgydF4y2Ba0gydF4y2Ba
が格納されます。gydF4y2Ba
函数gydF4y2Ba[视频,流,标签]= batchVideoAndFlow(视频,流,标签)gydF4y2Ba批量尺寸:5gydF4y2BaVideo = cat(5, Video {:});流量= cat(5,流量{:});gydF4y2Ba批处理尺寸:2gydF4y2Ba标签= cat(2,标签{:});gydF4y2Ba特征维数:1gydF4y2Ba标签= onehotencode(标签,1);gydF4y2Ba结束gydF4y2Ba
modelGradientsgydF4y2Ba
関数gydF4y2BamodelGradientsgydF4y2Ba
は,rgbデ,タgydF4y2BadlRGBgydF4y2Ba
のミニバッチ,対応するオプティカルフロ,デ,タgydF4y2BadlFlowgydF4y2Ba
,および対応するタ,ゲットgydF4y2Ba海底gydF4y2Ba
を入力として受け取り,対応する損失,学習可能なパラメーターについての損失の勾配,および学習精度を返します。勾配を計算するため,学習ル,プの中で関数gydF4y2BadlfevalgydF4y2Ba
を使用して,関数gydF4y2BamodelGradientsgydF4y2Ba
を評価します。gydF4y2Ba
函数gydF4y2Ba[gradientsRGB,gradientsFlow,loss,acc,accRGB,accFlow,stateRGB,stateFlow] = modelGradients(i3d,dlRGB,dlFlow,Y)gydF4y2Ba将视频输入作为RGB和光流数据通过双流gydF4y2Ba%网络。gydF4y2Ba[dlYPredRGB,dlYPredFlow,stateRGB,stateFlow] = forward(i3d,dlRGB,dlFlow);gydF4y2Ba计算两流的熔合损耗、梯度和精度gydF4y2Ba%的预测。gydF4y2BargbLoss = crossentropy(dlYPredRGB,Y);flowLoss = crossentropy(dlYPredFlow,Y);gydF4y2Ba%熔断损失。gydF4y2Ba损失= mean([rgbLoss,flowLoss]);gradientsRGB = dlgradient(rgbLoss,i3d.VideoLearnables);gradientsFlow = dlgradient(flowLoss,i3d.OpticalFlowLearnables);gydF4y2Ba通过计算预测的平均值来融合预测。gydF4y2BadlYPred = (dlYPredRGB + dlYPredFlow)/2;gydF4y2Ba计算预测的准确性。gydF4y2Ba[~,YTest] = max(Y,[],1);[~,YPred] = max(dlYPred,[],1);acc = gather(extractdata(sum(YTest == YPred)./ nummel (YTest)));gydF4y2Ba计算RGB和流量预测的准确性。gydF4y2Ba[~,YTest] = max(Y,[],1);[~,YPredRGB] = max(dlYPredRGB,[],1);[~,YPredFlow] = max(dlYPredFlow,[],1);accRGB = gather(extractdata(sum(YTest == YPredRGB)./ nummel (YTest)));accFlow = gather(extractdata(sum(YTest == YPredFlow)./ nummel (YTest)));gydF4y2Ba结束gydF4y2Ba
updateLearnablesgydF4y2Ba
関数gydF4y2BaupdateLearnablesgydF4y2Ba
は,sgdm最適化関数gydF4y2BasgdmupdategydF4y2Ba
を使用して,勾配およびその他のパラメ,タ,と共に,指定されたgydF4y2Ba可学的gydF4y2Ba
を更新します。gydF4y2Ba
函数gydF4y2Ba[learnables,velocity,learnRate] = updateLearnables(learnables,gradients,params,velocity,iteration)gydF4y2Ba使用余弦退火学习率计划确定学习率。gydF4y2BalearnRate = cosineAnnealingLearnRate(迭代,params);gydF4y2Ba对权重应用L2正则化。gydF4y2BaIdx =可学习物。参数= =gydF4y2Ba“重量”gydF4y2Ba;梯度(idx,:) = dlupdate(@(g,w) g +参数。l2Regularization*w, gradients(idx,:), learnables(idx,:));使用SGDM优化器更新网络参数。gydF4y2Ba[learnables, velocity] = sgdmupdate(learnables, gradients, velocity, learnRate, params.Momentum);gydF4y2Ba结束gydF4y2Ba
cosineAnnealingLearnRategydF4y2Ba
関数gydF4y2BacosineAnnealingLearnRategydF4y2Ba
は,現在の反復回数,最小学習率,最大学習率,およびアニーリングの反復回数に基づいて学習率を計算します[gydF4y2Ba3.gydF4y2Ba]。gydF4y2Ba
函数gydF4y2Balr = cosineAnnealingLearnRate(迭代,参数)gydF4y2Ba如果gydF4y2BaIteration == params。NumIterationslr=参数个数。MinLearningRate;返回gydF4y2Ba;gydF4y2Ba结束gydF4y2BacosineNumIter = [0, params.CosineNumIterations];csum = cumsum(cosineNumIter);Block = find(csum >=迭代,1,gydF4y2Ba“第一”gydF4y2Ba);cosineIter =迭代- csum(block - 1);annealingIteration = mod(cosineIter, cosineenumiter (block));cosineIteration = cosineNumIter(block);minR = params.MinLearningRate;maxR = params.MaxLearningRate;cosMult = 1 + cos(pi * annealingIteration / cosineIteration);lr = minR + ((maxR - minR) * cosMult / 2);gydF4y2Ba结束gydF4y2Ba
aggregateConfusionMetricgydF4y2Ba
関数gydF4y2BaaggregateConfusionMetricgydF4y2Ba
は,予測される結果gydF4y2BaYPredgydF4y2Ba
と期待される結果gydF4y2Ba欧美gydF4y2Ba
を@ @ンクリメンタルに混同行列に追加します。gydF4y2Ba
函数gydF4y2Bacmat = aggregateConfusionMetric(cmat,YTest,YPred) YTest = gather(extractdata(YTest));YPred = gather(extractdata(YPred));[m,n] = size(cmat);cmat = cmat + full(稀疏(YTest,YPred,1,m,n));gydF4y2Ba结束gydF4y2Ba
doValidationgydF4y2Ba
関数gydF4y2BadoValidationgydF4y2Ba
は,検証デ,タを使用してビデオ分類器を検証します。gydF4y2Ba
函数gydF4y2Ba[validationTime, cmat, lossValidation, accValidation, accValidationRGB, accValidationFlow] = doValidation(params, i3d) validationTime = tic;numOutputs = 3;mbq = createMiniBatchQueue(参数。V一个l我d一个t我onData, numOutputs, params); lossValidation = []; numClasses = numel(params.Classes); cmat = sparse(numClasses,numClasses); cmatRGB = sparse(numClasses,numClasses); cmatFlow = sparse(numClasses,numClasses);而gydF4y2Bahasdata(mbq) [dlX1,dlX2,dlY] = next(mbq);[loss,YTest,YPred,YPredRGB,YPredFlow] = predictValidation(i3d,dlX1,dlX2,dlY);lossValidation = [lossValidation,loss];cmat = aggregateConfusionMetric(cmat,YTest,YPred);cmatRGB = aggregateConfusionMetric(cmatRGB,YTest,YPredRGB);cmatFlow = aggregateConfusionMetric(cmatFlow,YTest,YPredFlow);gydF4y2Ba结束gydF4y2BalossValidation = mean(lossValidation);accValidation = sum(diag(cmat))./sum(cmat,gydF4y2Ba“所有”gydF4y2Ba);accValidationRGB = sum(diag(cmatRGB))./sum(cmatRGB,gydF4y2Ba“所有”gydF4y2Ba);accValidationFlow = sum(diag(cmatFlow))./sum(cmatFlow,gydF4y2Ba“所有”gydF4y2Ba);validationTime = toc(validationTime);gydF4y2Ba结束gydF4y2Ba
predictValidationgydF4y2Ba
関数gydF4y2BapredictValidationgydF4y2Ba
は,RGBデータとオプティカルフローデータに対して,指定されたビデオ分類器を使用して損失と予測値を計算します。gydF4y2Ba
函数gydF4y2Ba[loss,YTest,YPred,YPredRGB,YPredFlow] = predictValidation(i3d,dlRGB,dlFlow,Y)gydF4y2Ba将视频输入通过双流膨胀- 3d视频分类器。gydF4y2Ba[dlYPredRGB,dlYPredFlow] = predict(i3d,dlRGB,dlFlow);gydF4y2Ba分别计算两个流输出的交叉熵。gydF4y2BargbLoss = crossentropy(dlYPredRGB,Y);flowLoss = crossentropy(dlYPredFlow,Y);gydF4y2Ba%熔断损失。gydF4y2Ba损失= mean([rgbLoss,flowLoss]);gydF4y2Ba通过计算预测的平均值来融合预测。gydF4y2BadlYPred = (dlYPredRGB + dlYPredFlow)/2;gydF4y2Ba计算预测的准确性。gydF4y2Ba[~,YTest] = max(Y,[],1);[~,YPred] = max(dlYPred,[],1);[~,YPredRGB] = max(dlYPredRGB,[],1);[~,YPredFlow] = max(dlYPredFlow,[],1);gydF4y2Ba结束gydF4y2Ba
saveDatagydF4y2Ba
関数gydF4y2BasaveDatagydF4y2Ba
は,指定されたInflated-3dビデオ分類器,精度,損失,およびその他の学習パラメーターを垫ファイルに保存します。gydF4y2Ba
函数gydF4y2BabestLoss = saveData(inflated3d,bestLoss,迭代,cmat,lossTrain,lossValidation,gydF4y2Ba...gydF4y2BaaccTrain、accValidation params)gydF4y2Ba如果gydF4y2Ba迭代>= params。SaveBestAfterIteration lossValidation = extractdata(gather(lossValidation));gydF4y2Ba如果gydF4y2Balossvalidation < bestLoss params = rmfield(params,gydF4y2Ba“VelocityRGB”gydF4y2Ba);参数= rmfield(参数,gydF4y2Ba“VelocityFlow”gydF4y2Ba);bestLoss = lossvalidation;inflated3d = gatherFromGPUToSave(inflated3d);数据。BestLoss = BestLoss;数据。TrainingLoss = extractdata(gather(lossTrain));数据。训练准确性= accTrain;数据。V一个lidationAccuracy = accValidation; data.ValidationConfmat= cmat; data.inflated3d = inflated3d; data.Params = params; save(params.ModelFilename,“数据”gydF4y2Ba);gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
gatherFromGPUToSavegydF4y2Ba
関数gydF4y2BagatherFromGPUToSavegydF4y2Ba
は,ビデオ分類器をディスクに保存するためにgpuからデ,タを収集します。gydF4y2Ba
函数gydF4y2Baclassifier = gatherFromGPUToSavegydF4y2Ba如果gydF4y2Ba~ canUseGPUgydF4y2Ba返回gydF4y2Ba;gydF4y2Ba结束gydF4y2BaP = string(属性(分类器));p = p(endsWith)gydF4y2Ba“可学的”gydF4y2Ba,gydF4y2Ba“状态”gydF4y2Ba)));gydF4y2Ba为gydF4y2BaJj = 1:数字(p)道具= p(Jj);classifier.(prop) = gatherValues(classifier.(prop));gydF4y2Ba结束gydF4y2Ba函数gydF4y2Batbl = gatherValues(tbl)gydF4y2Ba为gydF4y2BaIi = 1:高度(tbl) tbl。V一个lue{ii} = gather(tbl.Value{ii});结束gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
checkForHMDB51FoldergydF4y2Ba
関数gydF4y2BacheckForHMDB51FoldergydF4y2Ba
は,ダウンロ,ドフォルダ,にあるダウンロ,ド済みのデ,タをチェックします。gydF4y2Ba
函数gydF4y2Ba类= checkForHMDB51Folder(dataLoc)gydF4y2Ba“hmdb51_org”gydF4y2Ba);gydF4y2Ba如果gydF4y2Ba~ isfolder (hmdbFolder)错误(gydF4y2Ba在运行示例之前,使用支持函数“downloadHMDB51”下载“hmdb51_or万博1manbetxg.rar”文件并提取RAR文件。gydF4y2Ba);gydF4y2Ba结束gydF4y2Ba类= [gydF4y2Ba“brush_hair”gydF4y2Ba,gydF4y2Ba“车轮”gydF4y2Ba,gydF4y2Ba“抓”gydF4y2Ba,gydF4y2Ba“咀嚼”gydF4y2Ba,gydF4y2Ba“鼓掌”gydF4y2Ba,gydF4y2Ba“爬”gydF4y2Ba,gydF4y2Ba“climb_stairs”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba“潜水”gydF4y2Ba,gydF4y2Ba“draw_sword”gydF4y2Ba,gydF4y2Ba“口水”gydF4y2Ba,gydF4y2Ba“喝”gydF4y2Ba,gydF4y2Ba“吃”gydF4y2Ba,gydF4y2Ba“fall_floor”gydF4y2Ba,gydF4y2Ba“击剑”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba“flic_flac”gydF4y2Ba,gydF4y2Ba“高尔夫球”gydF4y2Ba,gydF4y2Ba“倒立”gydF4y2Ba,gydF4y2Ba“打”gydF4y2Ba,gydF4y2Ba“拥抱”gydF4y2Ba,gydF4y2Ba“跳”gydF4y2Ba,gydF4y2Ba“踢”gydF4y2Ba,gydF4y2Ba“kick_ball”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba“吻”gydF4y2Ba,gydF4y2Ba“笑”gydF4y2Ba,gydF4y2Ba“选择”gydF4y2Ba,gydF4y2Ba“倒”gydF4y2Ba,gydF4y2Ba“引体向上”gydF4y2Ba,gydF4y2Ba“打”gydF4y2Ba,gydF4y2Ba“推”gydF4y2Ba,gydF4y2Ba“俯卧撑”gydF4y2Ba,gydF4y2Ba“ride_bike”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba“ride_horse”gydF4y2Ba,gydF4y2Ba“运行”gydF4y2Ba,gydF4y2Ba“shake_hands”gydF4y2Ba,gydF4y2Ba“shoot_ball”gydF4y2Ba,gydF4y2Ba“shoot_bow”gydF4y2Ba,gydF4y2Ba“shoot_gun”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba“坐”gydF4y2Ba,gydF4y2Ba“仰卧起坐”gydF4y2Ba,gydF4y2Ba“微笑”gydF4y2Ba,gydF4y2Ba“烟”gydF4y2Ba,gydF4y2Ba“筋斗”gydF4y2Ba,gydF4y2Ba“站”gydF4y2Ba,gydF4y2Ba“swing_baseball”gydF4y2Ba,gydF4y2Ba“剑”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba“sword_exercise”gydF4y2Ba,gydF4y2Ba“交谈”gydF4y2Ba,gydF4y2Ba“扔”gydF4y2Ba,gydF4y2Ba“转”gydF4y2Ba,gydF4y2Ba“走”gydF4y2Ba,gydF4y2Ba“波”gydF4y2Ba];expectFolders = fullfile(hmdbFolder, classes);gydF4y2Ba如果gydF4y2Ba~所有(arrayfun (@ (x)存在(x,gydF4y2Ba“dir”gydF4y2Ba), expectFolders)错误(gydF4y2Ba在运行示例之前,使用支持函数“downloadHMDB51”下载hmd万博1manbetxb51_org.rar并提取RAR文件。gydF4y2Ba);gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
downloadHMDB51gydF4y2Ba
関数gydF4y2BadownloadHMDB51gydF4y2Ba
は,デ,タセットをダウンロ,ドしてディレクトリに保存します。gydF4y2Ba
函数gydF4y2BadownloadHMDB51 (dataLoc)gydF4y2Ba如果gydF4y2Banargin == 0 dataLoc = pwd;gydF4y2Ba结束gydF4y2BadataLoc = string(dataLoc);gydF4y2Ba如果gydF4y2Ba~ isfolder (dataLoc) mkdir (dataLoc);gydF4y2Ba结束gydF4y2BadataUrl =gydF4y2Ba“http://serre-lab.clps.brown.edu/wp-content/uploads/2013/10/hmdb51_org.rar”gydF4y2Ba;选项= weboptions(gydF4y2Ba“超时”gydF4y2Ba、正);rarFileName = fullfile(dataLoc,gydF4y2Ba“hmdb51_org.rar”gydF4y2Ba);gydF4y2Ba下载RAR文件并保存到下载文件夹。gydF4y2Ba如果gydF4y2Ba~ isfile rarFileName disp (gydF4y2Ba"下载hmdb51_org.rar (2gb)到文件夹:"gydF4y2Ba(dataLoc) disp(gydF4y2Ba“下载需要几分钟……”gydF4y2Ba) websave(rarFileName, dataUrl,选项);disp (gydF4y2Ba“下载完成了。”gydF4y2Ba) disp (gydF4y2Ba"将hmdb51_org.rar文件内容解压缩到文件夹:"gydF4y2Ba) disp (dataLoc)gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
initializeTrainingProgressPlotgydF4y2Ba
関数gydF4y2BainitializeTrainingProgressPlotgydF4y2Ba
は,学習損失,学習精度,および検証精度を表示する2のプロットを構成します。gydF4y2Ba
函数gydF4y2Ba绘图仪= initializeTrainingProgressPlot(参数)gydF4y2Ba如果gydF4y2Ba参数个数。Progre年代年代PlotgydF4y2Ba绘制损失、训练准确率和验证准确率。gydF4y2Ba数字gydF4y2Ba%损失图gydF4y2Ba次要情节(2,1,1)策划者。lo年代年代Plotter=一个n我米一个tedline; xlabel(“迭代”gydF4y2Ba) ylabel (gydF4y2Ba“损失”gydF4y2Ba)gydF4y2Ba%准确度图gydF4y2Ba次要情节(2,1,2)策划者。TrainAccPlotter =动画线(gydF4y2Ba“颜色”gydF4y2Ba,gydF4y2Ba“b”gydF4y2Ba);策划者。V一个lAccPlotter = animatedline(“颜色”gydF4y2Ba,gydF4y2Ba‘g’gydF4y2Ba);传奇(gydF4y2Ba“训练的准确性”gydF4y2Ba,gydF4y2Ba“验证准确性”gydF4y2Ba,gydF4y2Ba“位置”gydF4y2Ba,gydF4y2Ba“西北”gydF4y2Ba);包含(gydF4y2Ba“迭代”gydF4y2Ba) ylabel (gydF4y2Ba“准确性”gydF4y2Ba)gydF4y2Ba其他的gydF4y2Baploters = [];gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
updateProgressPlotgydF4y2Ba
関数gydF4y2BaupdateProgressPlotgydF4y2Ba
は,学習中の損失と精度の情報で進行状況プロットを更新します。gydF4y2Ba
函数gydF4y2BaupdateProgressPlot (params,策划者,时代,迭代,开始,lossTrain, accuracyTrain, accuracyValidation)gydF4y2Ba如果gydF4y2Ba参数个数。Progre年代年代PlotgydF4y2Ba更新培训进度。gydF4y2BaD = duration(0,0,toc(start),gydF4y2Ba“格式”gydF4y2Ba,gydF4y2Ba“hh: mm: ss”gydF4y2Ba);标题(plotters.LossPlotter.Parent,gydF4y2Ba”时代:“gydF4y2Ba+ epoch +gydF4y2Ba,消失:"gydF4y2Ba+字符串(D));addpoints (plotters.LossPlotter、迭代、双(收集(extractdata (lossTrain))));addpoints (plotters.TrainAccPlotter迭代,accuracyTrain);addpoints (plotters.ValAccPlotter迭代,accuracyValidation);drawnowgydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
initializeVerboseOutputgydF4y2Ba
関数gydF4y2BainitializeVerboseOutputgydF4y2Ba
は,学習値のテ,ブルの列見出しを表示します。列見出しは,エポック,ミニバッチ精度,その他の学習値を示しますgydF4y2Ba
函数gydF4y2BainitializeVerboseOutput (params)gydF4y2Ba如果gydF4y2Ba参数个数。Verbo年代edisp (gydF4y2Ba”“gydF4y2Ba)gydF4y2Ba如果gydF4y2BacanUseGPU disp (gydF4y2Ba“GPU培训。”gydF4y2Ba)gydF4y2Ba其他的gydF4y2Badisp (gydF4y2Ba“CPU培训。”gydF4y2Ba)gydF4y2Ba结束gydF4y2BaP = gcp(gydF4y2Ba“nocreate”gydF4y2Ba);gydF4y2Ba如果gydF4y2Ba~ isempty (p) disp (gydF4y2Ba“并行集群训练”gydF4y2Ba+ p.Cluster.Profile +gydF4y2Ba”’。”gydF4y2Ba)gydF4y2Ba结束gydF4y2Badisp (gydF4y2Ba”NumIterations:“gydF4y2Ba+字符串(params.NumIterations));disp (gydF4y2Ba”MiniBatchSize:“gydF4y2Ba+字符串(params.MiniBatchSize));disp (gydF4y2Ba“类:”gydF4y2Ba+加入(字符串(params.Classes),gydF4y2Ba","gydF4y2Ba));disp (gydF4y2Ba"|=======================================================================================================================================================================|"gydF4y2Ba) disp (gydF4y2Ba| Epoch | Iteration | Time Elapsed | Mini-Batch Accuracy | Validation Accuracy | Mini-Batch | Validation | Base Learning | Train Time | Validation Time |gydF4y2Ba) disp (gydF4y2Ba“| | | (hh: mm: ss) | (Avg: RGB:流)| (Avg: RGB:流)| | | |率损失损失(hh: mm: ss) | (hh: mm: ss) |”gydF4y2Ba) disp (gydF4y2Ba"|=======================================================================================================================================================================|"gydF4y2Ba)gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
displayVerboseOutputEveryEpochgydF4y2Ba
関数gydF4y2BadisplayVerboseOutputEveryEpochgydF4y2Ba
は,エポック,ミニバッチ精度,検証精度,ミニバッチ損失など,学習値の詳細出力を表示します。gydF4y2Ba
函数gydF4y2BadisplayVerboseOutputEveryEpoch(参数、启动、learnRate时代,迭代,gydF4y2Ba...gydF4y2BaaccTrain、accTrainRGB accTrainFlow, accValidation、accValidationRGB accValidationFlow, lossTrain, lossValidation,火车离站时刻表,validationTime)gydF4y2Ba如果gydF4y2Ba参数个数。Verbo年代eD = duration(0,0,toc(start),gydF4y2Ba“格式”gydF4y2Ba,gydF4y2Ba“hh: mm: ss”gydF4y2Ba);trainTime = duration(0,0,trainTime,gydF4y2Ba“格式”gydF4y2Ba,gydF4y2Ba“hh: mm: ss”gydF4y2Ba);validationTime = duration(0,0,validationTime,gydF4y2Ba“格式”gydF4y2Ba,gydF4y2Ba“hh: mm: ss”gydF4y2Ba);lossValidation = gather(extractdata(lossValidation));lossValidation = compose(gydF4y2Ba“% .4f”gydF4y2Ba, lossValidation);accValidation = composePadAccuracy(accValidation);accValidationRGB = composePadAccuracy(accValidationRGB);accValidationFlow = composePadAccuracy(accValidationFlow);accVal = join([accValidation,accValidationRGB,accValidationFlow],gydF4y2Ba": "gydF4y2Ba);lossTrain = gather(extractdata(lossTrain));lossTrain = compose(gydF4y2Ba“% .4f”gydF4y2Ba, lossTrain);accTrain = composePadAccuracy(accTrain);accTrainRGB = composePadAccuracy(accTrainRGB);accTrainFlow = composePadAccuracy(accTrainFlow);accTrain = join([accTrain,accTrainRGB,accTrainFlow],gydF4y2Ba": "gydF4y2Ba);learnRate =合成(gydF4y2Ba“% .13f”gydF4y2Ba, learnRate);disp (gydF4y2Ba“|”gydF4y2Ba+gydF4y2Ba...gydF4y2Ba垫(string(时代),5,gydF4y2Ba“两个”gydF4y2Ba) +gydF4y2Ba“|”gydF4y2Ba+gydF4y2Ba...gydF4y2Ba垫(字符串(迭代)9gydF4y2Ba“两个”gydF4y2Ba) +gydF4y2Ba“|”gydF4y2Ba+gydF4y2Ba...gydF4y2Ba垫(string (D) 12gydF4y2Ba“两个”gydF4y2Ba) +gydF4y2Ba“|”gydF4y2Ba+gydF4y2Ba...gydF4y2Ba垫(string (accTrain), 26岁,gydF4y2Ba“两个”gydF4y2Ba) +gydF4y2Ba“|”gydF4y2Ba+gydF4y2Ba...gydF4y2Ba垫(string (accVal), 26岁,gydF4y2Ba“两个”gydF4y2Ba) +gydF4y2Ba“|”gydF4y2Ba+gydF4y2Ba...gydF4y2Ba垫(string (lossTrain) 10gydF4y2Ba“两个”gydF4y2Ba) +gydF4y2Ba“|”gydF4y2Ba+gydF4y2Ba...gydF4y2Ba垫(string (lossValidation) 10gydF4y2Ba“两个”gydF4y2Ba) +gydF4y2Ba“|”gydF4y2Ba+gydF4y2Ba...gydF4y2Ba垫(string (learnRate), 13日gydF4y2Ba“两个”gydF4y2Ba) +gydF4y2Ba“|”gydF4y2Ba+gydF4y2Ba...gydF4y2Ba垫(string(火车离站时刻表)10gydF4y2Ba“两个”gydF4y2Ba) +gydF4y2Ba“|”gydF4y2Ba+gydF4y2Ba...gydF4y2Ba垫(string (validationTime) 15gydF4y2Ba“两个”gydF4y2Ba) +gydF4y2Ba“|”gydF4y2Ba)gydF4y2Ba结束gydF4y2Ba函数gydF4y2Baacc = composePadAccuracy(acc)gydF4y2Ba“% .2f”gydF4y2Ba, 100年acc *) +gydF4y2Ba“%”gydF4y2Ba;Acc = pad(string(Acc),6,gydF4y2Ba“左”gydF4y2Ba);gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
endVerboseOutputgydF4y2Ba
関数gydF4y2BaendVerboseOutputgydF4y2Ba
は,学習中の詳細出力の末尾を表示します。gydF4y2Ba
函数gydF4y2BaendVerboseOutput (params)gydF4y2Ba如果gydF4y2Ba参数个数。Verbo年代edisp (gydF4y2Ba"|=======================================================================================================================================================================|"gydF4y2Ba)gydF4y2Ba结束gydF4y2Ba结束gydF4y2Ba
参考文献gydF4y2Ba
卡雷拉,若昂和安德鲁·泽瑟曼。“Quo Vadis, Action Recognition?”一个新的模型和动力学数据集。gydF4y2BaIEEE计算机视觉与模式识别会议论文集gydF4y2Ba(CVPR): 6299 ? 6308。檀香山,HI: IEEE, 2017。gydF4y2Ba
Simonyan, Karen, Andrew Zisserman。“用于视频动作识别的双流卷积网络。”gydF4y2Ba神经信息处理系统研究进展gydF4y2Ba27,加州长滩:NIPS, 2017。gydF4y2Ba
Loshchilov, Ilya和Frank Hutter。SGDR:随机梯度下降与热重启gydF4y2Ba2017学习表现国际会议gydF4y2Ba.土伦,法国:ICLR, 2017。gydF4y2Ba
[4]杜tran,王恒,洛伦佐·托雷萨尼,杰米·雷,扬·勒昆,马诺哈尔·帕卢里。《动作识别的时空卷积研究》。Proceed我ng年代ofthe IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2018, pp. 6450-6459.
[5] Christoph Feichtenhofer,樊浩奇,Jitendra Malik,和开明。视频识别的慢速网络gydF4y2BaIEEE计算机视觉与模式识别会议论文集gydF4y2Ba(CVPR), 2019年。gydF4y2Ba
Will Kay, Joao Carreira, Karen Simonyan, Brian Zhang, Chloe Hillier, Sudheendra Vijayanarasimhan, Fabio Viola, Tim Green, Trevor Back, Paul Natsev, Mustafa Suleyman, Andrew Zisserman。“动力学人体动作视频数据集。”gydF4y2BaarXiv预印arXiv:1705.06950gydF4y2Ba, 2017年。gydF4y2Ba