Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

ベイズ最適化を使用した LSTM の学習構成の選択

この例では、ベイズ最適化を使用して、長短期記憶 (LSTM) ネットワーク用の最適なネットワーク ハイパーパラメーターと学習オプションを見つける深層学習実験の作成方法を説明します。この例では、実験マネージャーを使用して、エンジンの残存耐用期間 (RUL) を予測する LSTM ネットワークに学習させます。この実験では、[1] に記載のある Turbofan Engine Degradation Simulation Data Set を使用します (参照を参照)。sequence-to-sequence 回帰用のこのデータ セットの処理に関する詳細については、深層学習を使用した sequence-to-sequence 回帰を参照してください。

ベイズ最適化により、実験においてハイパーパラメーターをスイープするための代替手法が得られます。各ハイパーパラメーターの値の範囲を指定し、最適化するメトリクスを選択します。すると、選択したメトリクスを最適化するハイパーパラメーターの組み合わせを実験マネージャーが検索します。ベイズ最適化には Statistics and Machine Learning Toolbox™ が必要です。詳細については、ベイズ最適化を使用した実験ハイパーパラメーターの調整を参照してください。

RUL は、エンジンが故障する前に行える運転サイクルの回数を取得します。エンジンの故障が近づいてきたときにシーケンス データに着目するために、指定したしきい値で応答をクリップしてデータを前処理します。この前処理の操作によって、ネットワークは RUL 値がこれより高いインスタンスを等価として処理し、故障が近づいたときの予測子データの変動に着目できるようになります。例として、次の図は、最初の応答の観測値、およびそれに対応するしきい値 150 でクリップされた応答を示しています。

深層学習ネットワークに学習させる場合、データの前処理方法、層と隠れユニットの数、およびネットワークの初期学習率が、ネットワークの学習の動作と性能に影響を与える可能性があります。LSTM ネットワークの深さを選択する際は、速度と精度のバランスを考慮します。たとえば、ネットワークを深くすると精度が高まりますが、学習と収束により多くの時間がかかります [2]。

既定では、回帰用に組み込まれている学習実験を実行すると、実験マネージャーによって、実験における各試行の損失および平方根平均二乗誤差 (RMSE) が計算されます。この例では、問題に関するデータ セットに特有のカスタム メトリクスを使用して、各試行のネットワーク性能を比較します。カスタム メトリクス関数の使用の詳細については、メトリクス関数を使用した深層学習実験の評価を参照してください。

実験を開く

まず、例を開きます。実験マネージャーによって、事前構成済みの実験を含むプロジェクトが読み込まれます。実験を開くには、[実験ブラウザー] で、実験の名前 (SequenceRegressionExperiment) をダブルクリックします。

組み込みの学習実験は、説明、ハイパーパラメーターのテーブル、セットアップ関数、および実験の結果を評価するためのメトリクス関数の集合で構成されます。ベイズ最適化を使用する実験には、実験の期間を制限する追加のオプションが含まれます。詳細については、組み込み学習実験の構成を参照してください。

[説明] フィールドには、実験を説明するテキストが表示されます。この例の説明は次のようになります。

Sequence-to-sequence regression to predict the remaining useful life (RUL) of engines.
This experiment compares network performance using Bayesian optimization when changing data
thresholding level, LSTM layer depth, the number of hidden units, and the initial learn rate.

[ハイパーパラメーター テーブル] では、実験で使用する手法 (Bayesian Optimization) とハイパーパラメーター値を指定します。各ハイパーパラメーターについて、次のオプションを指定します。

  • 範囲 — 実数値または整数値のハイパーパラメーターの下限と上限を示す 2 要素のベクトル、または categorical ハイパーパラメーターが取り得る値をリストする string 配列または cell 配列を入力します。

  • real (実数値のハイパーパラメーター)、integer (整数値のハイパーパラメーター)、または categorical (categorical ハイパーパラメーター) を選択します。

  • 変換none (変換なし) または log (対数変換) を選択します。log の場合、ハイパーパラメーターは real またはinteger で正でなければなりません。このオプションを使用すると、ハイパーパラメーターが検索され、対数スケールでモデル化されます。

実験を実行すると、実験マネージャーはハイパーパラメーターの最適な組み合わせを検索します。各試行では、前の試行結果に基づいてハイパーパラメーター値の新しい組み合わせが使用されます。この例では、次のハイパーパラメーターを使用します。

  • Threshold は、しきい値を上回る応答データをすべてしきい値と同じ値に設定します。応答データが一定にならないように、しきい値を 150 以上に設定してください。この実験では、許容される一連の値の上限を 150、200、および 250 に設定するため、Threshold を categorical ハイパーパラメーターとしてモデル化します。

  • LSTMDepth は、ネットワークで使用される LSTM 層の数を示します。このハイパーパラメーターを 1 ~ 3 の整数で指定します。

  • NumHiddenUnits は、ネットワークで使用する隠れユニットの数 (タイム ステップごとに保存される情報の量) を決定します。隠れユニットの数を増やすと、データの過適合が発生して学習に時間がかかる可能性があります。隠れユニットの数を減らすと、データの適合不足が発生する可能性があります。このハイパーパラメーターを 50 ~ 300 の整数で指定します。

  • InitialLearnRate は、学習に使用される初期学習率を指定します。学習率が小さすぎる場合、学習に時間がかかります。学習率が大きすぎる場合、学習結果が準最適になったり、発散したりすることがあります。最適な学習率は、学習させるネットワークにも依りますが、データにも左右されます。この実験では、値が数桁の範囲にわたるため (0.001 ~ 0.1)、このハイパーパラメーターを対数スケールでモデル化します。

[ベイズ最適化オプション] では、実行する試行の最大時間 (秒単位) と最大回数を入力することで、実験の期間を指定できます。ベイズ最適化の能力を最大限に活用するには、目的関数の評価を少なくとも 30 回行います。

[セットアップ関数] は、実験用の学習データ、ネットワーク アーキテクチャ、および学習オプションを構成します。セットアップ関数への入力は、ハイパーパラメーター テーブルのフィールドをもつ構造体です。このセットアップ関数は、イメージ回帰問題用のネットワークに学習させるために使用する 4 つの出力を返します。この例では、セットアップ関数には 3 つのセクションがあります。

  • "データの読み込みと前処理" では、Turbofan Engine Degradation Simulation Data Set を https://ti.arc.nasa.gov/tech/dash/groups/pcoe/prognostic-data-repository/ [3] からダウンロードして解凍します。また、セットアップ関数のセクションでは、一定の値の特徴をフィルターで除外し、ゼロ平均と単位分散をもつように予測子データを正規化し、ハイパーパラメーター Threshold の数値を使用して応答データをクリップし、検証に使用する学習サンプルをランダムに選択します。

dataFolder = fullfile(tempdir,"turbofan");
if ~exist(dataFolder,"dir")
    mkdir(dataFolder);
    oldDir = cd(dataFolder);
    filename = "CMAPSSData.zip";
    websave(filename,"https://ti.arc.nasa.gov/c/6/", ...
        weboptions("Timeout",Inf));
    unzip(filename,dataFolder);
    cd(oldDir);
end
filenameTrainPredictors = fullfile(dataFolder,"train_FD001.txt");
[XTrain,YTrain] = processTurboFanDataTrain(filenameTrainPredictors);
XTrain = helperFilter(XTrain);
XTrain = helperNormalize(XTrain);
thr = str2double(params.Threshold);
for i = 1:numel(YTrain)
    YTrain{i}(YTrain{i} > thr) = thr;
end
for i=1:numel(XTrain)
    sequence = XTrain{i};
    sequenceLengths(i) = size(sequence,2);
end
[~,idx] = sort(sequenceLengths,"descend");
XTrain = XTrain(idx);
YTrain = YTrain(idx);
idx = randperm(numel(XTrain),10);
XValidation = XTrain(idx);
XTrain(idx) = [];
YValidation = YTrain(idx);
YTrain(idx) = [];
  • "ネットワーク アーキテクチャの定義" では、sequence-to-sequence 回帰用の LSTM ネットワークのアーキテクチャを定義します。このネットワークは、まず LSTM 層があり、サイズが 100 の全結合層がそれに続き、ドロップアウトの確率が 0.5 のドロップアウト層がそれに続きます。ハイパーパラメーター LSTMDepth および NumHiddenUnits は、LSTM 層の数、および各層に含まれる隠れユニットの数を指定します。

numResponses = size(YTrain{1},1);
featureDimension = size(XTrain{1},1);
LSTMDepth = params.LSTMDepth;
numHiddenUnits = params.NumHiddenUnits;
layers = sequenceInputLayer(featureDimension);
for i = 1:LSTMDepth
    layers = [layers;lstmLayer(numHiddenUnits,OutputMode="sequence")];
end
layers = [layers
    fullyConnectedLayer(100)
    reluLayer()
    dropoutLayer(0.5)
    fullyConnectedLayer(numResponses)
    regressionLayer];
  • "学習オプションの指定" では、実験の学習オプションを定義します。ネットワークが深いほど収束に時間がかかるため、あらゆる深さのネットワークが確実に収束できるように、エポック数を 300 に設定します。この例では、30 回反復するごとにネットワークを検証します。初期学習率はハイパーパラメーター テーブルから取得した InitialLearnRate の値と等しく、15 エポックごとに 0.2 の係数で減少します。学習オプション ExecutionEnvironment"auto" に設定されていて、GPU が利用できる場合、実験は GPU で実行されます。そうでない場合、実験マネージャーは CPU を使用します。この例では、ネットワークの深さを比較し、多くのエポックで学習を行うため、GPU を使用すると学習時間を大幅に短縮できます。GPU を使用するには、Parallel Computing Toolbox™ とサポートされている GPU デバイスが必要です。詳細については、リリース別の GPU サポート (Parallel Computing Toolbox)を参照してください。

maxEpochs = 300;
miniBatchSize = 20;
options = trainingOptions("adam", ...
    ExecutionEnvironment="auto", ...
    MaxEpochs=maxEpochs, ...
    MiniBatchSize=miniBatchSize, ...
    ValidationData={XValidation,YValidation}, ...
    ValidationFrequency=30, ...
    InitialLearnRate=params.InitialLearnRate, ...
    LearnRateDropFactor=0.2, ...
    LearnRateDropPeriod=15, ...
    GradientThreshold=1, ...
    Shuffle="never", ...
    Verbose=false);

セットアップ関数を検査するには、[セットアップ関数][編集] をクリックします。MATLAB エディターでセットアップ関数が開きます。また、セットアップ関数のコードは、この例の最後の付録 1 にあります。

[メトリクス] セクションは、実験結果を評価するオプションの関数を指定します。ネットワークの学習が完了するたびに、実験マネージャーによってこれらの関数が評価されます。メトリクス関数を検査するには、メトリクス関数の名前を選択して [編集] をクリックします。MATLAB エディターでメトリクス関数が開きます。

エンジンの RUL の予測は、注意深く検討する必要があります。予測によって RUL が過少に見積もられると、エンジンのメンテナンスが必要よりも早い時期にスケジュールされる可能性があります。予測によって RUL が過大に見積もられると、運転中にエンジンが故障する可能性があり、その結果、高額なコストや安全性の懸念が生じる可能性があります。この例では、そのようなシナリオが発生する可能性を低減させるために、メトリクス関数 MeanMaxAbsoluteError を使用し、RUL を過小予測または過大予測するネットワークを特定します。

MeanMaxAbsoluteError メトリクスでは、最大絶対誤差を計算し、学習セット全体で平均化します。このメトリクスは、関数predictを呼び出し、学習セットから RUL 予測のシーケンスを作成します。その後、この関数は、学習用の各応答シーケンスと予測された各応答シーケンスとの間の最大絶対誤差を計算し、すべての最大絶対誤差の平均値を計算します。このメトリクスは、実際の応答と予測された応答との間の最大偏差を特定します。メトリクス関数のコードは、この例の最後の付録 3 にあります。

実験の実行

実験を実行すると、実験マネージャーは、選択されたメトリクスについて、ハイパーパラメーターの最適な組み合わせを検索します。実験の各試行では、前の試行の結果に基づいてハイパーパラメーター値の新しい組み合わせが使用されます。

学習に時間がかかる場合があります。実験の期間を制限するには、[ベイズ最適化オプション] で試行の最大時間または最大回数を減らします。ただし、試行回数が 30 回未満の場合、ベイズ最適化アルゴリズムが最適なハイパーパラメーターのセットに収束しない可能性があることに注意してください。

既定では、実験マネージャーは一度に 1 つの試行を実行します。Parallel Computing Toolbox™ を使用している場合は、複数の試行を同時に実行したり、クラスター内のバッチ ジョブとして実験をオフロードしたりできます。

  • 一度に 1 つの実験を実行するには、実験マネージャー ツールストリップの [モード][Sequential] を選択し、[実行] をクリックします。

  • 複数の試行を同時に実行するには、[モード][Simultaneous] を選択し、[実行] をクリックします。現在の並列プールがない場合、実験マネージャーは既定のクラスター プロファイルを使用して並列プールを起動します。次に、実験マネージャーは、使用可能な並列ワーカーの数に応じて、複数の同時試行を実行します。最良の結果を得るには、実験を実行する前に、GPU と同じ数のワーカーで並列プールを起動します。詳細については、実験マネージャーを使用したネットワークの並列学習リリース別の GPU サポート (Parallel Computing Toolbox)を参照してください。

  • 実験をバッチ ジョブとしてオフロードするには、[Mode][Batch Sequential] または [Batch Simultaneous] を選択し、[クラスター][Pool Size] を指定して、[実行] をクリックします。詳細については、Offload Experiments as Batch Jobs to Clusterを参照してください。

結果テーブルに、各試行のメトリクス関数の値が表示されます。実験マネージャーは、選択されたメトリクスが最適値である試行を強調表示します。たとえば、この実験では、23 番目の試行で最大絶対誤差が最小になっています。

実験の実行中に [学習プロット] をクリックすると、学習プロットが表示され、各試行の進行状況を追跡できます。ネットワークが深くなるにつれて、学習完了までに要する試行時間が長くなります。

結果の評価

結果テーブルに記載されている [MeanMaxAbsoluteError] の値は、ネットワークが RUL をどの程度、過小予測または過大予測したかを定量的に示しています。[検証 RMSE] の値は、未知のデータに対してネットワークがどの程度適切に汎化を行ったかを定量的に示しています。実験で得られた最良の結果を見つけるには、結果テーブルを並べ替え、[MeanMaxAbsoluteError][検証 RMSE] の値が最も小さい試行を選択します。

  1. [MeanMaxAbsoluteError] 列を選択します。

  2. 三角形のアイコンをクリックします。

  3. [昇順に並べ替え] を選択します。

同様に、検証 RMSE が最も小さい試行を見つけるには、[検証 RMSE] 列のドロップダウン メニューを開いて [昇順に並べ替え] を選択します。

両方の値が最小となる試行が 1 つもない場合は、両方のメトリクスに対する順位が良い試行を選択してください。たとえば、この結果を見ると、23 番目の試行は、平均最大絶対誤差が最小で、検証 RMSE は 7 番目に小さい値になっています。検証 RMSE がそれより低い試行を見ると、29 番目の試行のみが、同程度の平均最大絶対誤差になっています。どちらの試行が望ましいかは、平均最大絶対誤差と検証 RMSE のどちらの小さい値を重視するかによって決まります。

実験結果に関する観測結果を記録するには、注釈を追加します。

  1. 結果テーブルで、最適な結果が得られた試行の [MeanMaxAbsoluteError] セルを右クリックします。

  2. [注釈の追加] を選択します。

  3. [注釈] ペインで、テキスト ボックスに観測結果を入力します。

  4. [検証 RMSE] セルについても上記の手順を繰り返します。

実験の最適な試行をテストするには、学習済みのネットワークをエクスポートし、ランダムに選択した各テスト シーケンスについて、予測された応答シーケンスを表示します。

  1. 実験の最適な試行を選択します。

  2. [実験マネージャー] ツールストリップで、[エクスポート][学習済みネットワーク] をクリックします。

  3. ダイアログ ウィンドウで、エクスポートしたネットワークのワークスペース変数の名前を入力します。既定の名前は trainedNetwork です。

  4. エクスポートしたネットワーク、およびネットワークの Threshold の値を、補助関数 plotSequences (この例の最後の付録 4 に掲載) への入力として使用します。たとえば、MATLAB コマンド ウィンドウで次のように入力します。

plotSequences(trainedNetwork,200)

この関数は、未知のテスト データに対する実際の応答および予測された応答のシーケンスをプロットします。

実験を閉じる

[実験ブラウザー] でプロジェクトの名前を右クリックし、[プロジェクトを閉じる] を選択します。実験マネージャーによって、プロジェクトに含まれるすべての実験と結果が閉じられます。

付録 1: セットアップ関数

この関数は、実験用の学習データ、ネットワーク アーキテクチャ、および学習オプションを構成します。

入力

  • params は、実験マネージャーのハイパーパラメーター テーブルのフィールドをもつ構造体です。

出力

  • XTrain は、学習データを含む cell 配列です。

  • YTrain は、学習の回帰値を含む cell 配列です。

  • layers は、ニューラル ネットワーク アーキテクチャを定義する層グラフです。

  • optionstrainingOptions オブジェクトです。

function [XTrain,YTrain,layers,options] = SequenceRegressionExperiment_setup1(params)

dataFolder = fullfile(tempdir,"turbofan");

if ~exist(dataFolder,"dir")
    mkdir(dataFolder);
    oldDir = cd(dataFolder);
    filename = "CMAPSSData.zip";
    websave(filename,"https://ti.arc.nasa.gov/c/6/", ...
        weboptions("Timeout",Inf));
    unzip(filename,dataFolder);
    cd(oldDir);
end

filenameTrainPredictors = fullfile(dataFolder,"train_FD001.txt");
[XTrain,YTrain] = processTurboFanDataTrain(filenameTrainPredictors);

XTrain = helperFilter(XTrain);
XTrain = helperNormalize(XTrain);

thr = str2double(params.Threshold);
for i = 1:numel(YTrain)
    YTrain{i}(YTrain{i} > thr) = thr;
end

for i=1:numel(XTrain)
    sequence = XTrain{i};
    sequenceLengths(i) = size(sequence,2);
end

[~,idx] = sort(sequenceLengths,"descend");
XTrain = XTrain(idx);
YTrain = YTrain(idx);

idx = randperm(numel(XTrain),10);
XValidation = XTrain(idx);
XTrain(idx) = [];
YValidation = YTrain(idx);
YTrain(idx) = [];

numResponses = size(YTrain{1},1);
featureDimension = size(XTrain{1},1);
LSTMDepth = params.LSTMDepth;
numHiddenUnits = params.NumHiddenUnits;

layers = sequenceInputLayer(featureDimension);

for i = 1:LSTMDepth
    layers = [layers;lstmLayer(numHiddenUnits,OutputMode="sequence")];
end

layers = [layers
    fullyConnectedLayer(100)
    reluLayer()
    dropoutLayer(0.5)
    fullyConnectedLayer(numResponses)
    regressionLayer];

maxEpochs = 300;
miniBatchSize = 20;

options = trainingOptions("adam", ...
    ExecutionEnvironment="auto", ...
    MaxEpochs=maxEpochs, ...
    MiniBatchSize=miniBatchSize, ...
    ValidationData={XValidation,YValidation}, ...
    ValidationFrequency=30, ...
    InitialLearnRate=params.InitialLearnRate, ...
    LearnRateDropFactor=0.2, ...
    LearnRateDropPeriod=15, ...
    GradientThreshold=1, ...
    Shuffle="never", ...
    Verbose=false);

end

付録 2: 予知保全データのフィルターと正規化

補助関数 helperFilter は、定数値をもつ特徴を除去してデータをフィルターします。すべてのタイム ステップで一定のままである特徴は、学習に悪影響を与える可能性があります。

function [XTrain,XTest] = helperFilter(XTrain,XTest)
m = min([XTrain{:}],[],2);
M = max([XTrain{:}],[],2);
idxConstant = M == m;
for i = 1:numel(XTrain)
    XTrain{i}(idxConstant,:) = [];
    if nargin>1
        XTest{i}(idxConstant,:) = [];
    end
end
end

補助関数 helperNormalize は、ゼロ平均と単位分散をもつように、学習用およびテスト用の予測子を正規化します。

function [XTrain,XTest] = helperNormalize(XTrain,XTest)
mu = mean([XTrain{:}],2);
sig = std([XTrain{:}],0,2);
for i = 1:numel(XTrain)
    XTrain{i} = (XTrain{i} - mu) ./ sig;
    if nargin>1
        XTest{i} = (XTest{i} - mu) ./ sig;
    end
end
end

付録 3: 最大絶対誤差の平均値の計算

このメトリクス関数は、学習済みネットワークの最大絶対誤差を計算し、学習セット全体で平均化します。

function metricOutput = MeanMaxAbsoluteError(trialInfo)

net = trialInfo.trainedNetwork;
thr = str2double(trialInfo.parameters.Threshold);

filenamePredictors = fullfile(tempdir,"turbofan","train_FD001.txt");
[XTrain,YTrain] = processTurboFanDataTrain(filenamePredictors);
XTrain = helperFilter(XTrain);
XTrain = helperNormalize(XTrain);

for i = 1:numel(YTrain)
    YTrain{i}(YTrain{i} > thr) = thr;
end

YPred = predict(net,XTrain,MiniBatchSize=1);

maxAbsErrors = zeros(1,numel(YTrain));
for i=1:numel(YTrain)
    absError = abs(YTrain{i}-YPred{i});
    maxAbsErrors(i) = max(absError);
end

metricOutput = mean(maxAbsErrors);

end

付録 4: 予知保全シーケンスのプロット

この関数は、実際の応答および予測された応答のシーケンスをプロットします。これにより、学習済みネットワークの性能を評価できます。この関数は、補助関数 helperFilterhelperNormalize (付録 2 に掲載) を使用します。

function plotSequences(net,threshold)

filenameTrainPredictors = fullfile(tempdir,"turbofan","train_FD001.txt");
filenameTestPredictors = fullfile(tempdir,"turbofan","test_FD001.txt");
filenameTestResponses = fullfile(tempdir,"turbofan","RUL_FD001.txt");

[XTrain,YTrain] = processTurboFanDataTrain(filenameTrainPredictors);
[XTest,YTest] = processTurboFanDataTest(filenameTestPredictors,filenameTestResponses);

[XTrain,XTest] = helperFilter(XTrain,XTest);
[~,XTest] = helperNormalize(XTrain,XTest);

for i = 1:numel(YTrain)
  YTrain{i}(YTrain{i} > threshold) = threshold;
  YTest{i}(YTest{i} > threshold) = threshold;
end

YPred = predict(net,XTest,MiniBatchSize=1);

idx = randperm(100,4);
figure
for i = 1:numel(idx)
    subplot(2,2,i)
    plot(YTest{idx(i)},"--")
    hold on
    plot(YPred{idx(i)},".-")
    hold off
    ylim([0 threshold+25])
    title("Test Observation " + idx(i))
    xlabel("Time Step")
    ylabel("RUL")
end
legend(["Test Data" "Predicted"],Location="southwest")
end

参照

[1] Saxena, Abhinav, Kai Goebel, Don Simon, and Neil Eklund. "Damage Propagation Modeling for Aircraft Engine Run-to-Failure Simulation." 2008 International Conference on Prognostics and Health Management (2008): 1–9.

[2] Jozefowicz, Rafal, Wojciech Zaremba, and Ilya Sutskever. "An Empirical Exploration of Recurrent Network Architectures." Proceedings of the 32nd International Conference on Machine Learning (2015): 2342–2350.

[3] Saxena, Abhinav, Kai Goebel. "Turbofan Engine Degradation Simulation Data Set." NASA Ames Prognostics Data Repository, https://ti.arc.nasa.gov/tech/dash/groups/pcoe/prognostic-data-repository/, NASA Ames Research Center, Moffett Field, CA.

参考

アプリ

関数

関連するトピック