深層学習を使用した sequence-to-sequence 分類
この例では、長短期記憶 (LSTM) ネットワークを使用してシーケンス データの各タイム ステップを分類する方法を説明します。
シーケンス データの各タイム ステップを分類するよう深層ニューラル ネットワークに学習させるために、"sequence-to-sequence LSTM ネットワーク" を使用できます。sequence-to-sequence LSTM ネットワークでは、シーケンス データの個々のタイム ステップで異なる予測を行うことができます。
この例では、体に装着したスマートフォンから得られたセンサー データを使用します。この例では、3 つの異なる方向での加速度計の読み取り値を表す時系列データから、装着者の行動を認識するように LSTM ネットワークに学習させます。
シーケンス データの読み込み
行動認識データを読み込みます。学習データには 6 人の人物の時系列データが含まれています。テスト データには、7 番目の人物の 1 つの時系列が含まれています。各シーケンスには 3 つの特徴があり、長さはさまざまです。3 つの特徴は、3 つの異なる方向での加速度計の測定値に対応します。
load HumanActivityTrain
XTrainXTrain=6×1 cell array
{3×64480 double}
{3×53696 double}
{3×56416 double}
{3×50688 double}
{3×51888 double}
{3×54256 double}
1 つの学習シーケンスをプロットで可視化します。最初の学習シーケンスの最初の特徴をプロットし、対応する行動に応じてプロットに色を付けます。
X = XTrain{1}(1,:);
classes = categories(YTrain{1});
figure
for j = 1:numel(classes)
label = classes(j);
idx = find(YTrain{1} == label);
hold on
plot(idx,X(idx))
end
hold off
xlabel("Time Step")
ylabel("Acceleration")
title("Training Sequence 1, Feature 1")
legend(classes,Location="northwest")
LSTM ネットワーク アーキテクチャの定義
LSTM ネットワーク アーキテクチャを定義します。入力をサイズ 3 (入力データの特徴の数) のシーケンスになるように指定します。200 個の隠れユニットを持つ LSTM 層を指定して、シーケンス全体を出力します。最後に、サイズが 5 の全結合層を含めることによって 5 個のクラスを指定し、その後にソフトマックス層を配置します。
numFeatures = 3; numHiddenUnits = 200; numClasses = 5; layers = [ ... sequenceInputLayer(numFeatures) lstmLayer(numHiddenUnits,OutputMode="sequence") fullyConnectedLayer(numClasses) softmaxLayer];
学習オプションを指定します。
Adam ソルバーを使用して学習させます。
学習を 60 エポック行います。
学習データには、チャネルとタイム ステップにそれぞれ対応する行と列を含むシーケンスがあるため、入力データ形式
"CTB"(チャネル、時間、バッチ) を指定します。勾配の発散を防ぐために、勾配しきい値を 2 に設定します。
学習の進行状況をプロットに表示し、詳細出力を非表示にします。
学習中にネットワークの精度を監視します。
options = trainingOptions("adam", ... MaxEpochs=60, ... InputDataFormats="CTB", ... GradientThreshold=2, ... Plots="training-progress", ... Verbose=false, ... Metrics="accuracy");
関数trainnetを使用して LSTM ネットワークに学習させます。分類には、クロスエントロピー損失を使用します。既定では、関数 trainnet は利用可能な GPU がある場合にそれを使用します。GPU での学習には、Parallel Computing Toolbox™ ライセンスとサポートされている GPU デバイスが必要です。サポートされているデバイスの詳細については、「GPU 計算の要件」を参照してください。そうでない場合、関数 trainnet は CPU を使用します。実行環境を手動で選択するには、ExecutionEnvironment 学習オプションを使用します。各ミニバッチには学習セット全体が含まれているので、プロットはエポックごとに更新されます。シーケンスが非常に長いため、各ミニバッチの処理とプロットの更新に時間がかかる場合があります。
net = trainnet(XTrain,YTrain,layers,"crossentropy",options);
LSTM ネットワークのテスト
テスト データを読み込み、タイム ステップごとに行動を分類します。
行動のテスト データを読み込みます。XTest には 3 次元の単一シーケンスが含まれます。YTest には、各タイム ステップでの行動に対応するカテゴリカル ラベルのシーケンスが含まれます。
load HumanActivityTest figure XTest = XTest{1}'; plot(XTest) xlabel("Time Step") ylabel("Acceleration") legend("Feature " + (1:numFeatures)) title("Test Data")

単一の観測値入力の場合は、関数 predict を使用して予測を行います。GPU を使用して予測を行うには、まずデータを gpuArray に変換します。
if canUseGPU XTest = gpuArray(XTest); end scores = predict(net,XTest);
予測スコアをラベルに変換するには、関数 scores2label を使用します。
Y = scores2label(scores,classes);
あるいは、predict 関数を使用して更新されたネットワーク状態を出力として返すことで、1 タイム ステップずつ予測することもできます。その後、状態出力を使用して、ネットワークの State プロパティを更新できます。これは、タイム ステップの値がストリームで到着する場合に役立ちます。通常、1 タイム ステップずつ予測するよりも、シーケンス全体について予測する方が高速です。1 つのタイム ステップでの予測間にネットワークを更新して将来のタイム ステップを予測する方法を示す例については、深層学習を使用した時系列予測を参照してください。
予測の精度を計算します。
acc = sum(Y == YTest{1}')./numel(YTest{1})acc = 0.9983
プロットを使用して予測をテスト データと比較します。
figure plot(Y,".-") hold on plot(YTest{1}) hold off xlabel("Time Step") ylabel("Activity") title("Predicted Activities") legend(["Predicted" "Test Data"])

参考
trainnet | trainingOptions | dlnetwork | lstmLayer | sequenceInputLayer