ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

浅いニューラル ネットワークの時系列予測およびモデル化

動的ニューラル ネットワークは、時系列予測に適しています。開ループ形式、閉ループ形式、および開/閉ループ複数ステップ予測で適用されている NARX ネットワークの使用例については、ニューラル ネットワークの複数ステップの予測を参照してください。

ヒント

時系列データを使用した深層学習については、代わりに深層学習を使用したシーケンスの分類を参照してください。

たとえば、pH 中和プロセスから得られたデータがあるとします。過去の pH 値、過去の酸性値、およびタンクへの基本流量からタンク内の溶液の pH を予測できるネットワークを設計する必要があります。これらの列をもつ合計 2001 個のタイム ステップがあります。

この問題は 2 つの方法で解くことができます。

通常、はじめに GUI を使用し、次に GUI を使用してコマンド ライン スクリプトを自動的に生成することをお勧めします。どちらの方法を使用する場合にも、まずデータセットを選択することによって問題を定義します。それぞれの GUI から多くの標本データセットにアクセスし、これらを使用してツールボックスの機能を試すことができます。特定の問題を解く必要がある場合、独自のデータをワークスペースに読み込むことができます。次の節では、データ形式について説明します。

問題の定義

ツールボックスに対して時系列問題を定義するには、一連の TS 個の入力ベクトルを cell 配列の列として配置します。次に、別の TS ターゲット ベクトル (各入力ベクトルの正しい出力ベクトル) のセットを 2 番目の cell 配列に配置します (静的データおよび時系列データのデータ書式設定の詳細は、Data Structures を参照してください)。ただし、必要なのはターゲット データセットのみである場合があります。たとえば、時系列の前の値を使用して次の値を予測する、以下の時系列問題を定義できます。

targets = {1 2 3 4 5};

次の節では、Neural Net Time Series アプリ ntstool を使用して、ネットワークを時系列データセットにあてはめるための学習方法を説明します。この例では、ツールボックスに用意されている pH 中和のデータセットを使用します。

Neural Network Time Series アプリの使用

  1. 必要に応じて、次のコマンドを使用してニューラル ネットワーク起動 GUI を開きます。

    nnstart
    

  2. [Time Series App] をクリックして、Neural Network Time Series アプリを開きます (ntstool コマンドを使うこともできます)。

    この最初のペインは、他の GUI の最初のペインとは異なることに注意してください。これは、ntstool を使用して 3 種類の時系列問題を解くことができるためです。

    • 最初のタイプの時系列問題では、時系列 y(t) の将来の値を、この時系列の過去の値および 2 番目の時系列 x(t) の過去の値から予測します。この形式の予測は、外因的 (外部) 入力を使用した非線形自己回帰 (NARX) と呼ばれており (NARX ネットワーク (narxnet、closeloop) を参照してください)、次のように記述できます。

      y(t) = f(y(t – 1), ..., y(t – d), x(t – 1), ..., (t – d))

      このモデルは、失業率、GDP などの経済変数に基づく株または債券の将来の値の予測に使用できます。また、システム同定に使用して、化学プロセス、製造システム、ロボット工学、航空宇宙、自動車などの動的システムを表すモデルの開発が行われることもあります。

    • 2 番目のタイプの時系列問題では、時系列を 1 つだけ使用します。時系列 y(t) の将来の値を、その時系列の過去の値のみから予測します。この形式の予測は、非線形自己回帰 (NAR) と呼ばれており、次のように記述できます。

      y(t) = f(y(t – 1), ..., y(t – d))

      このモデルは金融商品の予測にも使用できますが、この場合には対になる系列を使用しません。

    • 3 番目の時系列問題は、2 つの時系列 (入力時系列 x(t) および出力/ターゲット時系列 y(t)) を使用する最初のタイプと似ています。ここでは、y(t) の前の値に関する情報がない状態で、x(t) の前の値から y(t) の値を予測する必要があります。この入出力モデルは次のように記述できます。

      y(t) = f(x(t – 1), ..., x(t – d))

      NARX モデルでは y(t) の前の値に含まれる追加の情報が使用されるため、この入出力モデルより精度の高い予測が行われます。ただし、アプリケーションによっては y(t) の前の値を使用できないことがあります。このような場合にのみ、NARX モデルではなく入出力モデルを使用する必要があります。

  3. この例では、NARX モデルを選択して、[Next] をクリックし、続行します。

  4. [Select Data] ウィンドウで [Load Example Data Set] をクリックします。[Time Series Data Set Chooser] ウィンドウが開きます。

    メモ

    MATLAB® ワークスペースからデータを読み込む必要がある場合、[Select Data] ウィンドウの [Inputs] および [Targets] オプションを使用します。

  5. [pH Neutralization Process] を選択し、[Import] をクリックします。[Select Data] ウィンドウに戻ります。

  6. [Next] をクリックして、次の図に示す [Validation and Test Data] ウィンドウを開きます。

    検証データセットおよびテスト データセットはそれぞれ元のデータの 15% に設定します。

    これらの設定を使用すると、入力ベクトルおよびターゲット ベクトルが次のように 3 つのセットにランダムに分割されます

    • 70% は学習に使用。

    • 15% は、ネットワークが汎化されていることを検証し、過適合の発生前に学習を停止するために使用。

    • 最後の 15% は、ネットワークの汎化の、完全に独立したテストとして使用。

    (データ分割プロセスの詳細は、データの分割を参照してください)。

  7. [Next] をクリックします。

    標準的な NARX ネットワークは、隠れ層にシグモイド伝達関数、出力層に線形伝達関数を使用した 2 層フィードフォワード ネットワークです。このネットワークでは、x(t) および y(t) シーケンスの前の値を格納するタップ付き遅延線も使用されます。y(t) は y(t – 1)、y(t – 2)、...、y(t – d) の関数であるため、NARX ネットワークの出力 y(t) が (遅延によって) ネットワークの入力にフィードバックされることに注意してください。ただし、学習の効率化のために、このフィードバック ループを開にすることができます。

    ネットワークの学習中は真の出力が使用できるため、上記の開ループ アーキテクチャを使用できます。この場合、推定された出力をフィードバックするのではなく、真の出力が使用されます。これには 2 つの利点があります。1 つ目は、フィードフォワード ネットワークへの入力の精度が高くなることです。2 つ目は、結果として得られるネットワークが純粋なフィードフォワード アーキテクチャを持つようになり、より効率的なアルゴリズムを学習に使用できることです。このネットワークについては、NARX ネットワーク (narxnet, closeloop) で詳しく説明します。

    隠れニューロンの既定の数は、10 に設定されています。遅延の既定の数は 2 です。この値を 4 に変更します。ネットワークの学習の性能が低い場合、これらの数を調整してもかまいません。

  8. [Next] をクリックします。

  9. 学習アルゴリズムを選択し、[Train] をクリックします。レーベンバーグ・マルカート法 (trainlm) は、ほとんどの問題に対して推奨されます。一方で、ノイズを含む問題や小規模な問題の場合は、ベイズ正則化 (trainbr) を使用することで、かかる時間は長くなりますがより良い解が得られます。ただし、大規模な問題の場合には、スケーリング共役勾配法 (trainscg) を使用することをお勧めします。この方法では、他の 2 つのアルゴリズムで使用されるヤコビアン計算よりメモリ効率の高い勾配計算が使用されるためです。この例では、既定のレーベンバーグ・マルカート法を使用します。

    学習は、6 回の反復の間に検証誤差が減少しなくなるまで続行します (検証の停止)。

  10. [Plots] で、[Error Autocorrelation] をクリックします。これは、ネットワーク性能を検証するために使用されます。

    次のプロットは、誤差の自己相関関数を表示しています。これは、予測誤差の時間との関連性を示します。完全な予測モデルの場合、自己相関関数には非ゼロ値が 1 つのみあり、この値がゼロ ラグで発生します (これは、平均二乗誤差です)。これは、予測誤差が相互に完全に無相関 (ホワイト ノイズ) であることを意味します。予測誤差に有意な相関がある場合、通常はタップ付き遅延線の遅延の数を増やすことによって、予測を改善できます。この場合、ゼロ ラグの相関を除く相関がゼロ付近の 95% 信頼限界の範囲内にほぼあるため、適切なモデルであると考えられます。より正確な結果が必要な場合、ntstool[Retrain] をクリックして、ネットワークの再学習を行います。これによってネットワークの初期の重みとバイアスが変更されるため、再学習後に改善されたネットワークが生成される可能性があります。

  11. 入力誤差の相互相関関数を表示して、ネットワーク性能に関する追加の検証を取得します。[Plots] ペインで、[Input-Error Cross-correlation] をクリックします。

    この入力誤差の相互相関関数は、誤差と入力シーケンス x(t) がどのように相関しているのかを示します。完全な予測モデルの場合、すべての相関がゼロになります。入力と誤差に相関がある場合、通常はタップ付き遅延線の遅延の数を増やすことによって、予測を改善できます。この場合、すべての相関がゼロ付近の信頼限界の範囲内にあります。

  12. [Plots] で、[Time Series Response] をクリックします。時間に対する入力、ターゲット、および誤差が表示されます。さらに、学習、テスト、および検証に対してどの時点が選択されたかを示します。

  13. Neural Network Time Series アプリで [Next] をクリックし、ネットワークを評価します。

    この時点で、新しいデータに対してネットワークをテストできます。

    元のデータまたは新しいデータでのネットワーク性能に満足できない場合、次のいずれかを行うことができます。

    • 再度、学習を行う。

    • ニューロンの数や遅延の数を増やす。

    • より大規模な学習データセットを取得する。

    学習セットでの性能は良好であるにもかかわらず、テスト セットでの性能が著しく低い場合には、過適合を示しているため、ニューロンの数を減らすことによって結果を改善できます。

  14. ネットワーク性能に満足できたら、[Next] をクリックします。

  15. このパネルを使用して、MATLAB 関数または Simulink® ブロック線図を生成し、ニューラル ネットワークのシミュレーションを行います。生成されたコードまたはブロック線図を使用して、ニューラル ネットワークが入力から出力を計算する方法について理解を深めたり、MATLAB Compiler™ ツールおよびその他の MATLAB および Simulink コード生成ツールを使用してネットワークを配布したりできます。

  16. この画面のボタンを使用して、スクリプトを生成するか、または結果を保存します。

    • [Simple Script] または [Advanced Script] をクリックして、コマンド ラインから前のすべてのステップを再現するために使用できる MATLAB コードを作成します。MATLAB コードの作成は、ツールボックスのコマンド ライン機能を使用して学習プロセスをカスタマイズする方法を学ぶ必要がある場合に便利です。コマンド ライン関数の使用では、生成されるスクリプトについてさらに詳しく説明します。

    • ネットワークを net という名前でワークスペースに保存することもできます。追加のテストを実行する、または新しい入力の処理に使用することができます。

  17. MATLAB コードを作成して結果を保存したら、[Finish] をクリックします。

コマンド ライン関数の使用

ツールボックスのコマンド ライン関数の使用方法を学ぶ最も簡単な方法は、GUI からスクリプトを生成し、これらのスクリプトを変更してネットワークの学習をカスタマイズすることです。例として、前の節のステップ 15 で作成した簡単なスクリプトを見てみましょう。

% Solve an Autoregression Problem with External 
% Input with a NARX Neural Network
% Script generated by NTSTOOL
%
% This script assumes the variables on the right of 
% these equalities are defined:
%
%   phInputs - input time series.
%   phTargets - feedback time series.

inputSeries = phInputs;
targetSeries = phTargets;

% Create a Nonlinear Autoregressive Network with External Input
inputDelays = 1:4;
feedbackDelays = 1:4;
hiddenLayerSize = 10;
net = narxnet(inputDelays,feedbackDelays,hiddenLayerSize);

% Prepare the Data for Training and Simulation
% The function PREPARETS prepares time series data 
% for a particular network, shifting time by the minimum 
% amount to fill input states and layer states.
% Using PREPARETS allows you to keep your original 
% time series data unchanged, while easily customizing it 
% for networks with differing numbers of delays, with
% open loop or closed loop feedback modes.
[inputs,inputStates,layerStates,targets] = ... 
    preparets(net,inputSeries,{},targetSeries);

% Set up Division of Data for Training, Validation, Testing
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;

% Train the Network
[net,tr] = train(net,inputs,targets,inputStates,layerStates);

% Test the Network
outputs = net(inputs,inputStates,layerStates);
errors = gsubtract(targets,outputs);
performance = perform(net,targets,outputs)

% View the Network
view(net)

% Plots
% Uncomment these lines to enable various plots.
% figure, plotperform(tr)
% figure, plottrainstate(tr)
% figure, plotregression(targets,outputs)
% figure, plotresponse(targets,outputs)
% figure, ploterrcorr(errors)
% figure, plotinerrcorr(inputs,errors)

% Closed Loop Network
% Use this network to do multi-step prediction.
% The function CLOSELOOP replaces the feedback input with a direct
% connection from the output layer.
netc = closeloop(net);
netc.name = [net.name ' - Closed Loop'];
view(netc)
[xc,xic,aic,tc] = preparets(netc,inputSeries,{},targetSeries);
yc = netc(xc,xic,aic);
closedLoopPerformance = perform(netc,tc,yc)

% Early Prediction Network
% For some applications it helps to get the prediction a 
% timestep early.
% The original network returns predicted y(t+1) at the same 
% time it is given y(t+1).
% For some applications such as decision making, it would 
% help to have predicted y(t+1) once y(t) is available, but 
% before the actual y(t+1) occurs.
% The network can be made to return its output a timestep early 
% by removing one delay so that its minimal tap delay is now 
% 0 instead of 1.  The new network returns the same outputs as 
% the original network, but outputs are shifted left one timestep.
nets = removedelay(net);
nets.name = [net.name ' - Predict One Step Ahead'];
view(nets)
[xs,xis,ais,ts] = preparets(nets,inputSeries,{},targetSeries);
ys = nets(xs,xis,ais);
earlyPredictPerformance = perform(nets,ts,ys)

スクリプトを保存し、コマンド ラインから実行して、前の GUI セッションの結果を再現します。スクリプトを編集して、学習プロセスをカスタマイズすることもできます。この場合、スクリプトの各ステップに従います。

  1. スクリプトは、入力ベクトルおよびターゲット ベクトルがワークスペースに読み込み済みであると仮定しています。データが読み込まれていない場合、次のように読み込むことができます。

    load ph_dataset
    inputSeries = phInputs;
    targetSeries = phTargets;
    
  2. ネットワークを作成します。NARX ネットワーク narxnet は、隠れ層に既定の正接シグモイド伝達関数、出力層に線形伝達関数を使用したフィードフォワード ネットワークです。このネットワークには 2 つの入力があります。1 つは外部入力で、もう 1 つはネットワーク出力からのフィードバック接続です (ネットワークの学習が終わったら、このフィードバック接続を閉にすることができます。これについては、後の手順で説明します)。これらの各入力について、前の値を格納するタップ付き遅延線があります。NARX ネットワークのネットワーク アーキテクチャを割り当てるには、各タップ付き遅延線に関連付けられた遅延に加え、隠れ層ニューロンの数も選択しなければなりません。次の手順では、入力遅延およびフィードバック遅延を 1 ~ 4 の範囲に割り当て、隠れニューロンの数を 10 に割り当てます。

    inputDelays = 1:4;
    feedbackDelays = 1:4;
    hiddenLayerSize = 10;
    net = narxnet(inputDelays,feedbackDelays,hiddenLayerSize);
    

    メモ

    ニューロンの数および遅延の数を増やすと、必要な計算量が多くなります。数が多すぎる場合にはデータへの過適合が生じる可能性が高くなりますが、そのネットワークを使用して、より複雑な問題を解けるようになります。層の数を増やすと、必要な計算量が多くなりますが、複雑な問題をそのネットワークでより効率的に解けるようになる可能性があります。複数の隠れ層を使用するには、隠れ層のサイズを fitnet コマンドの配列の要素として入力します。

  3. 学習用のデータを準備します。タップ付き遅延線を含むネットワークの学習を行う場合、ネットワークの入出力の初期値を使って遅延を入力する必要があります。このプロセスを容易にするツールボックス コマンドとして、preparets があります。この関数には、ネットワーク、入力シーケンス、およびターゲット シーケンスの 3 つの入力引数があります。初期条件が削除されている場合、この関数は、タップ付き遅延線をネットワーク、変更された入力シーケンスおよびターゲット シーケンスに入力するために必要な初期条件を返します。この関数は次のように呼び出すことができます。

    [inputs,inputStates,layerStates,targets] = ...
        preparets(net,inputSeries,{},targetSeries);
    
  4. データの分割を設定します。

    net.divideParam.trainRatio = 70/100;
    net.divideParam.valRatio   = 15/100;
    net.divideParam.testRatio  = 15/100;
    

    これらの設定では、入力ベクトルおよびターゲット ベクトルはランダムに分割されます。70% は学習、15% は検証、および 15% はテストに使用されます

  5. ネットワークに学習をさせます。ネットワークの学習には、既定のレーベンバーグ・マルカート法アルゴリズム (trainlm) を使用します。レーベンバーグ・マルカート法によって目的どおりの正確な結果を生成できない問題の場合にはネットワーク学習関数をベイズ正則化 (trainbr) に、あるいは、データが大規模な問題の場合にはネットワーク学習関数をスケーリング共役勾配法 (trainscg) に設定することを検討してください。

    net.trainFcn = 'trainbr';
    net.trainFcn = 'trainscg';

    ネットワークの学習を行うには、次のように入力します。

    [net,tr] = train(net,inputs,targets,inputStates,layerStates);
    

    学習中は、次の学習ウィンドウが開きます。このウィンドウには学習の進行状況が表示されます。[Stop Training] をクリックして、任意の時点で学習を中断できます。

    この学習は、6 回の反復の間に検証誤差が増加したときに停止しています。学習の停止は、44 回目の反復で発生しています。

  6. ネットワークをテストします。ネットワークの学習が終わったら、これを使用してネットワークの出力を計算できます。次のコードでは、ネットワークの出力、誤差、および全体的な性能が計算されます。タップ付き遅延線を使用してネットワークのシミュレーションを行うには、これらの遅延信号に初期値を割り当てる必要があります。これを行うには、初期の段階で preparets によって提供される inputStates および layerStates を使用します。

    outputs = net(inputs,inputStates,layerStates);
    errors = gsubtract(targets,outputs);
    performance = perform(net,targets,outputs)
    
    performance =
    
        0.0042
    
    
  7. ネットワーク図を表示します。

    view(net)
    

  8. 性能学習記録をプロットして、過適合の可能性がないか確認します。

    figure, plotperform(tr)
    

    この図は、強調表示されているエポックまで学習および検証の誤差が減少したことを示しています。検証誤差はこのエポックまでに増加していないため、過適合は発生していないと考えられます。

    検証ステップおよびテスト ステップを含むすべての学習が、開ループ (直並列アーキテクチャとも呼ばれます) で行われています。典型的なワークフローでは、ネットワークを完全に開ループで作成し、(検証ステップおよびテスト ステップを含めて) このネットワークの学習を行った後でのみ、複数ステップ先の予測を行うために閉ループに変換します。同様に、開ループの学習結果に基づいて、GUI の R 値が計算されます。

  9. NARX ネットワークでループを閉にします。NARX ネットワークでフィードバック ループが開になっている場合、1 ステップ先の予測を実行しています。y(t) および x(t) の前の値から、y(t) の次の値を予測しています。閉になっているフィードバック ループを使用すると、複数ステップ先の予測を実行できます。これは、y(t) の実際の将来値の代わりに y(t) の予測が使用されるためです。次のコマンドを使用して、ループを閉にし、閉ループの性能を計算できます。

    netc = closeloop(net);
    netc.name = [net.name ' - Closed Loop'];
    view(netc)
    [xc,xic,aic,tc] = preparets(netc,inputSeries,{},targetSeries);
    yc = netc(xc,xic,aic);
    perfc = perform(netc,tc,yc)
    
    perfc =
    
        2.8744
    
    

  10. 1 タイム ステップ前の予測を行うには、ネットワークから遅延を削除します。

    nets = removedelay(net);
    nets.name = [net.name ' - Predict One Step Ahead'];
    view(nets)
    [xs,xis,ais,ts] = preparets(nets,inputSeries,{},targetSeries);
    ys = nets(xs,xis,ais);
    earlyPredictPerformance = perform(nets,ts,ys)
    
    earlyPredictPerformance =
    
        0.0042
    
    

    この図から、各タップ付き遅延線から 1 つの遅延が削除されていることを除き、ネットワークは前述の開ループ ネットワークと同じであることがわかります。そのため、ネットワークの出力は y(t) ではなく y(t + 1) になります。これは、ネットワークを特定のアプリケーションに対して配布するときに役立つ場合があります。

ネットワーク性能が十分ではない場合、次のいずれかの方法を試してください。

  • init を使用してネットワークの初期の重みとバイアスを新しい値にリセットし、再度学習を行う (重みの初期化 (init) を参照)。

  • 隠れニューロンの数または遅延の数を増やす。

  • 学習ベクトルの数を増やす。

  • より関連性の高い情報がある場合、入力値の数を増やす。

  • 別の学習アルゴリズムを試す (学習アルゴリズムを参照)。

コマンド ライン操作に慣れるため、次のタスクを試してみましょう。

  • 学習中にプロット ウィンドウ (誤差相関プロットなど) を開き、アニメーションを見る。

  • plotresponseploterrcorrplotperform などの関数を使用して、コマンド ラインからプロットする (これらの関数の使用の詳細は、それぞれのリファレンス ページを参照してください)。

また、コマンド ラインから学習を行う場合、その他のオプションについては高度なスクリプトを参照してください。

ニューラル ネットワークでは、学習を行うたびに異なる解が得られる可能性がありますが、これは初期の重みとバイアスの値が異なり、データの学習セット、検証セット、テスト セットへの分割が異なるためです。このため、別のニューラル ネットワークが同じ問題について学習した場合、入力が同じでも出力が異なる場合があります。ニューラル ネットワークで高い精度が得られるようにするためには、何度か再学習を行います。

高い精度が必要な場合は、初期解を改善するための手法が他にいくつかあります。詳細は、浅いニューラル ネットワークの汎化の改善と過適合の回避を参照してください。