【MQL5】OnnxCreateFromBuffer関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク
  1. OnnxCreateFromBuffer関数の働き・役割
  2. OnnxCreateFromBuffer関数の引数について
    1. 第1引数: const uchar& buffer[]
    2. 第2引数: ulong flags
  3. OnnxCreateFromBuffer関数の戻り値について
    1. 戻り値の詳細
  4. OnnxCreateFromBuffer関数を使ったサンプルコード
  5. サンプルコード解説1:グローバル領域部分
    1. 1. ExtOutputShapeとExtInputShape
    2. 2. リソースとしてのONNXファイル定義
    3. 3. MQL5におけるリソース定義の役割
  6. サンプルコード解説2:OnStart関数部分その1
    1. 1. OnStart関数の役割
    2. 2. matrix型の役割
    3. 3. CopyRates関数でデータを取得
  7. サンプルコード解説3:OnStart関数部分その2
    1. 1. データの転置と格納
    2. 2. 平均値と標準偏差の取得
    3. 3. vectorの文法的役割
    4. 4. 平均と標準偏差の行列への変換
  8. サンプルコード解説4:OnStart関数部分その3
    1. 1. 各行に平均と標準偏差をコピーする
    2. 2. データの正規化
    3. 正規化の意義
  9. サンプルコード解説5:OnStart関数部分その4
    1. 1. モデルの作成とハンドルの取得
    2. 2. モデルの入力データの形状を設定
    3. 3. エラーチェックとセッションの解放
  10. サンプルコード解説6:OnStart関数部分その5
    1. 1. モデルの出力データの形状を設定
    2. 2. エラーチェックとセッションの解放
  11. サンプルコード解説7:OnStart関数部分その6
    1. 1. 正規化された入力データをfloat型に変換
    2. 2. モデルの出力データを格納するベクトルを初期化
    3. matrixfとmatrixの違い
  12. サンプルコード解説8:OnStart関数部分その7
    1. 1. モデルの実行
    2. 2. エラーチェックとセッションの解放
  13. サンプルコード解説9:OnStart関数部分その8
    1. 1. モデルの出力結果をログに出力
    2. 2. 逆変換による実際の価格予測値の取得
    3. 3. セッションの解放

OnnxCreateFromBuffer関数の働き・役割

OnnxCreateFromBuffer関数は、データ配列からONNX形式のモデルを読み込み、ONNXセッションを作成するために使用されます。
ONNXは機械学習モデルのオープンフォーマットであり、MQL5ではこの関数を使って、外部で訓練されたONNXモデルを取り込んで活用できます。これにより、アルゴリズムトレーディングやエキスパートアドバイザーに、学習済みのモデルを組み込むことが可能になります。

OnnxCreateFromBuffer関数の引数について

long  OnnxCreateFromBuffer(
  const uchar& buffer[],   // 配列の参照
  ulong         flags       // モデル作成フラグ
  );

OnnxCreateFromBuffer関数は、2つの引数を取ります。

第1引数: const uchar& buffer[]

この引数は、ONNXモデルデータを格納した配列参照です。この配列には、あらかじめ外部で保存されたONNX形式のモデルがバイナリデータ(0と1の並び)として含まれている必要があります。uchar型は、1バイトの符号なし文字を表しており、バイナリデータの取り扱いに適しています。

第2引数: ulong flags

この引数は、モデル作成時の動作を指定するフラグです。ENUM_ONNX_FLAGSの値を使用して、モデル作成の際にONNX_COMMON_FOLDERONNX_DEBUG_LOGSなどのモードを指定することができます。以下は代表的なフラグの意味です。

flagsはフラグ(個別の動作オプション)を1つまたは複数指定することで、モデル作成の方法を柔軟にコントロールします。

OnnxCreateFromBuffer関数の戻り値について

OnnxCreateFromBuffer関数は、ONNXセッションのハンドル戻り値として返します。このハンドルは、作成されたセッションを識別するためのもので、今後そのセッションを操作する際に使用されます。

戻り値の詳細

  • 成功時には、作成されたセッションのハンドルが返されます。このハンドルは、他のONNX関連の関数で使用するための識別子となります。
  • エラーが発生した場合には、INVALID_HANDLEが返されます。エラーが発生した際は、GetLastError関数を使用してエラーコードを取得することで、詳細な情報を得ることができます。

セッションハンドルは、ONNXモデルのロードに成功したかどうかを確認する重要な指標となります。INVALID_HANDLEが返された場合は、ONNXモデルのフォーマットやバッファデータに問題がある可能性があるため、エラーコードを確認して適切に対処する必要があります。

OnnxCreateFromBuffer関数を使ったサンプルコード

const long                             ExtOutputShape[] = {1,1};   // モデルの出力形状を定義
const long                             ExtInputShape [] = {1,10,4}; // モデルの入力形状を定義
#resource "Python/model.onnx" as uchar ExtModel[]                   // モデルのONNXファイルをリソースとして定義
//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                     |
//+------------------------------------------------------------------+
int OnStart(void)
{
  matrix rates;
  //--- EURUSDのH1足から最新の10バー分のOHLCデータを取得する
  if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC,2,10))
    return(-1);

  //--- 取得したOHLCデータを転置してx_normに格納する
  matrix x_norm=rates.Transpose();
  //--- 転置したデータの平均を取得する
  vector m=x_norm.Mean(0);
  //--- 転置したデータの標準偏差を取得する
  vector s=x_norm.Std(0);
  //--- 平均と標準偏差を行列に変換
  matrix mm(10,4);
  matrix ms(10,4);
  //--- 各行に平均と標準偏差のデータをコピーする
  for(int i=0; i<10; i++)
  {
    mm.Row(m,i);
    ms.Row(s,i);
  }
  
  //--- 入力データを正規化するために、平均を引き、標準偏差で割る
  x_norm-=mm;
  x_norm/=ms;

  //--- モデルをバッファから作成し、ハンドルを取得する
  long handle=OnnxCreateFromBuffer(ExtModel,ONNX_DEBUG_LOGS);

  //--- モデルの入力データの形状を設定する
  if(!OnnxSetInputShape(handle,0,ExtInputShape))
  {
    Print("OnnxSetInputShape failed, error ",GetLastError());
    //--- エラーが発生した場合、セッションを解放する
    OnnxRelease(handle);
    return(-1);
  }

  //--- モデルの出力データの形状を設定する
  if(!OnnxSetOutputShape(handle,0,ExtOutputShape))
  {
    Print("OnnxSetOutputShape failed, error ",GetLastError());
    //--- エラーが発生した場合、セッションを解放する
    OnnxRelease(handle);
    return(-1);
  }

  //--- 正規化された入力データをfloat型に変換する
  matrixf x_normf;
  x_normf.Assign(x_norm);

  //--- モデルの出力データを格納するためのベクトルを初期化(価格予測用)
  vectorf y_norm(1);

  //--- モデルを実行し、価格予測を行う
  if(!OnnxRun(handle,ONNX_DEBUG_LOGS | ONNX_NO_CONVERSION,x_normf,y_norm))
  {
    Print("OnnxRun failed, error ",GetLastError());
    //--- エラーが発生した場合、セッションを解放する
    OnnxRelease(handle);
    return(-1);
  }

  //--- モデルの出力値(正規化された価格予測値)をログに出力する
  Print(y_norm);

  //--- 逆変換を行い、実際の価格予測値を取得する
  double y_pred=y_norm[0]*s[3]+m[3];
  Print("price predicted:",y_pred);

  //--- 処理が終了したのでONNXセッションを解放する
  OnnxRelease(handle);

  return(0);
}

このサンプルコードは、ニューラルネットワークモデルONNX形式)を使用して為替データ(EURUSDの1時間足)から価格予測を行うものです。以下が全体の流れです。

  1. データの取得:
    EURUSDの最新10本分のローソク足データ(OHLC: 始値、高値、安値、終値)を取得します。
  2. データの前処理(正規化:
    取得したOHLCデータを転置し、それぞれのデータ(始値、高値、安値、終値)の平均値と標準偏差を計算します。その後、データを平均値で引き、標準偏差で割ることで正規化を行い、モデルに入力できる形式に整えます。
  3. ONNXモデルの実行:
    事前にリソースとして定義されたONNXモデルを作成し、正規化されたデータを入力してモデルを実行します。モデルは価格予測値を出力します。
  4. 逆変換による実際の価格予測:
    モデルが出力した正規化された予測値を、元のスケールに戻す(逆変換)ことで、実際の価格予測値を計算します。
  5. セッションの解放と終了:
    モデル実行が完了した後、ONNXセッションを解放してプログラムを終了します。

全体として、このコードは取得した過去のデータを基に、ニューラルネットワークを使って未来の価格を予測するスクリプトです。

サンプルコード解説1:グローバル領域部分

const long                             ExtOutputShape[] = {1,1};   // モデルの出力形状を定義
const long                             ExtInputShape [] = {1,10,4}; // モデルの入力形状を定義
#resource "Python/model.onnx" as uchar ExtModel[]                   // モデルのONNXファイルをリソースとして定義

このセクションでは、サンプルコードのグローバル領域部分について解説します。この部分では、ONNXモデルに必要な入力と出力の形状や、モデルファイルそのものを定義しています。これらの定義は、後の処理で使用されるため、事前に宣言されます。

1. ExtOutputShapeとExtInputShape

これらの変数は、モデルが処理するデータの形状を定義しています。

  • ExtOutputShape: モデルの出力形状を定義しています。今回の例では、{1,1}となっており、これは1つの予測値(例えば価格)が1つ返されることを示します。
  • ExtInputShape: モデルの入力形状を定義しています。{1,10,4}という配列は、1つのデータセット(バッチ)に10本のローソク足データがあり、それぞれに4つの特徴(OHLC:始値、高値、安値、終値)があることを意味しています。

2. リソースとしてのONNXファイル定義

次に、ONNXファイルのモデルデータをリソースとして定義しています。

  • “Python/model.onnx”: モデルのファイルパスを指定しています。このファイルには、ニューラルネットワークの学習済みモデルが含まれています。
  • uchar型配列としてモデルデータを定義しています。この配列は、後のモデル作成処理で使用されます。

3. MQL5におけるリソース定義の役割

#resourceは、MQL5におけるリソースの定義を行うディレクティブです。通常、画像やサウンド、ファイルなどの外部リソースをコードに埋め込むために使用されます。この場合は、ONNXモデルファイルをプログラム内で扱うためにリソースとして定義しています。リソースを使うことで、外部ファイルを直接プログラムに組み込み、コードの一部として使用することが可能になります。

asは、リソースをどのデータ型として扱うかを指定します。ここでは、uchar型配列としてONNXモデルを扱うことで、バイト単位でモデルデータにアクセスできるようにしています。これにより、後にONNXモデルの作成処理で使用することが可能となります。

サンプルコード解説2:OnStart関数部分その1

//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                     |
//+------------------------------------------------------------------+
int OnStart(void)
{
  matrix rates;
  //--- EURUSDのH1足から最新の10バー分のOHLCデータを取得する
  if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC,2,10))
    return(-1);

このセクションでは、OnStart関数の最初の部分について解説します。ここでは、EURUSDのH1足(1時間足)のOHLCデータを取得し、それを処理するための準備が行われています。

1. OnStart関数の役割

OnStart関数は、スクリプトが実行された際に最初に呼び出される関数です。スクリプトのエントリーポイントとして、データの取得やモデルの実行などの主要な処理がこの関数内で行われます。この例では、モデルに入力する価格データを取得し、処理の初期設定を行っています。

2. matrix型の役割

matrixはMQL5で利用可能なデータ型の一つで、行列データを扱うためのクラスです。この例では、ratesという名前の行列が宣言され、後にOHLCデータを格納するために使用されます。OHLCとは、Open(始値)、High(高値)、Low(安値)、Close(終値)を指しており、価格チャートを構成する基本的な要素です。

  • matrix型: これは行列データを扱うデータ型で、複数の数値データを効率的に管理するために使用されます。金融データや価格データの処理に便利です。例えば、10本のローソク足のOHLCデータを一括で保持するために利用されています。

3. CopyRates関数でデータを取得

次に、CopyRates関数を使用してEURUSDの1時間足データを取得しています。CopyRates関数は、指定した通貨ペア(ここではEURUSD)のOHLCデータをコピーしてくるために使用されます。この例では、直近10本のローソク足データを取得し、それをrates行列に格納しています。

  • EURUSD: 通貨ペアのシンボル(特定の文字や記号)で、EUR(ユーロ)とUSD(米ドル)の為替レートを指します。
  • PERIOD_H1: 1時間足のデータを指定しています。
  • COPY_RATES_OHLC: 始値、終値、高値、安値の4つのデータを取得するオプションです。
  • 2, 10: 最初の「2」は取得の開始位置、次の「10」は取得するバーの数を示しています。ここでは直近10バー分のデータを取得します。

この部分では、実際にOHLCデータを取得し、モデルに入力するためのデータを用意する最初のステップを行っています。

サンプルコード解説3:OnStart関数部分その2

  //--- 取得したOHLCデータを転置してx_normに格納する
  matrix x_norm=rates.Transpose();
  //--- 転置したデータの平均を取得する
  vector m=x_norm.Mean(0);
  //--- 転置したデータの標準偏差を取得する
  vector s=x_norm.Std(0);
  //--- 平均と標準偏差を行列に変換
  matrix mm(10,4);
  matrix ms(10,4)

このセクションでは、OnStart関数の中盤部分について解説します。ここでは、取得したOHLCデータを転置し、そのデータに対して統計的な処理を行っています。

1. データの転置と格納

まず、rates.Transpose()を使って、取得したOHLCデータを転置し、新しい行列であるx_normに格納しています。転置とは、行列の行と列を入れ替える操作です。この操作を行うことで、各ローソク足(始値、高値、安値、終値)のデータを別々に扱いやすくしています。

2. 平均値と標準偏差の取得

次に、転置したデータから各列(OHLCデータ)の平均と標準偏差を計算します。

  • x_norm.Mean(0)は、OHLCデータの各列(始値、高値、安値、終値)の平均値を計算し、その結果をmというベクトルに格納します。
  • x_norm.Std(0)は、OHLCデータの各列の標準偏差を計算し、その結果をsというベクトルに格納します。

3. vectorの文法的役割

vectorは、MQL5におけるベクトルデータを扱うクラスです。ベクトルとは、一次元の数値データの集合を指します。今回のコードでは、OHLCデータの各列(4つの特徴)に対する平均や標準偏差など、数値の集合を保持するためにvectorを使用しています。

  • vector: ベクトルは一次元の数値列を管理するためのデータ型で、金融データや統計計算において広く使われます。ここでは、OHLCデータの各列に対する平均や標準偏差などの統計情報を効率的に管理するために使用されています。

4. 平均と標準偏差の行列への変換

次に、msで取得したベクトル(それぞれの平均と標準偏差の値)を行列mmmsに変換します。この処理によって、後の正規化処理が容易になります。

  • matrix mm(10,4)matrix ms(10,4)は、10行4列の行列を作成し、各ローソク足ごとに対応する平均と標準偏差を格納する準備をしています。

この部分では、モデルに入力する前のデータを整えるために、統計的な処理(平均と標準偏差の計算)が行われており、後の正規化処理に役立てられます。

サンプルコード解説4:OnStart関数部分その3

 //--- 各行に平均と標準偏差のデータをコピーする
  for(int i=0; i<10; i++)
  {
    mm.Row(m,i);
    ms.Row(s,i);
  }
  
  //--- 入力データを正規化するために、平均を引き、標準偏差で割る
  x_norm-=mm;
  x_norm/=ms;

このセクションでは、OnStart関数の後半部分について解説します。ここでは、データの正規化を行うために平均と標準偏差を使用し、モデルに入力するデータを整えています。

1. 各行に平均と標準偏差をコピーする

まず、forループを使用して、平均値と標準偏差を各行に適用しています。

  • mm.Rowは、mベクトル(各列の平均値)をmm行列のi行目にコピーしています。これにより、すべてのローソク足に対して、対応するOHLCデータの平均値を繰り返し適用します。
  • 同様に、ms.Rowは、sベクトル(各列の標準偏差)をms行列のi行目にコピーしています。これも、すべてのローソク足に対して標準偏差を適用するための処理です。

これにより、各ローソク足に対応する行列mmとmsが作成され、平均値と標準偏差がすべてのデータに適用できる状態が整います。

2. データの正規化

次に、モデルに入力するデータを正規化します。正規化とは、データを統一されたスケールに変換するプロセスであり、ニューラルネットワークの学習や推論において非常に重要です。この正規化によって、異なるスケールを持つ特徴量を比較しやすくします。

  • x_normからmmを引く操作は、各ローソク足のOHLCデータから対応する平均値を引いています。これにより、データは平均からの差を示す形になり、データの中心を0に調整します。
  • x_normをmsで割る操作は、各データを対応する標準偏差で割ることで、スケールを調整し、すべてのデータが同じスケールになるようにします。これにより、異なる大きさの値が統一されたスケールに変換され、ニューラルネットワークモデルに入力する準備が整います。

正規化の意義

データを正規化することで、入力データの値が極端に大きかったり小さかったりする影響を抑え、モデルの精度を向上させることができます。特に、金融データのように数値の範囲が広い場合は、正規化によってモデルの学習や推論がより安定します。

この部分では、モデルに入力するデータを均一なスケールに整え、後に続くONNXモデルの実行に備えています。

サンプルコード解説5:OnStart関数部分その4

 //--- モデルをバッファから作成し、ハンドルを取得する
  long handle=OnnxCreateFromBuffer(ExtModel,ONNX_DEBUG_LOGS);

  //--- モデルの入力データの形状を設定する
  if(!OnnxSetInputShape(handle,0,ExtInputShape))
  {
    Print("OnnxSetInputShape failed, error ",GetLastError());
    //--- エラーが発生した場合、セッションを解放する
    OnnxRelease(handle);
    return(-1);
  }

このセクションでは、OnStart関数の後半部分について解説します。ここでは、ONNXモデルを作成し、モデルに必要な入力データの形状を設定する手順が行われています。

1. モデルの作成とハンドルの取得

まず、モデルバッファから作成しています。このバッファは、事前に定義されたリソースであるONNXモデルファイルから読み込まれます。OnnxCreateFromBuffer関数を使用して、モデルメモリ上にロードし、そのハンドル識別子)を取得します。

ハンドルは、モデルを操作するために使用するONNXセッションの識別子です。ハンドルを使用することで、モデルへの操作やデータの入力、実行が可能になります。

2. モデルの入力データの形状を設定

次に、OnnxSetInputShape関数を使用して、モデルに入力するデータの形状を設定しています。モデルには、事前に定義された入力形状(ExtInputShape)に従ってデータを渡す必要があります。この形状設定により、モデルはどのようなフォーマットのデータを受け取るかを認識します。

ハンドルは、先ほど取得したモデルのセッションハンドルです。0は、モデルの最初の入力を示しており、複数の入力を持つモデルの場合には、異なるインデックスが指定されます。ExtInputShapeは、モデルに入力するデータの形状で、事前に定義された{1,10,4}という3次元の配列です。これは、1つのバッチで10本のローソク足のデータを持ち、それぞれのローソク足には始値、高値、安値、終値の4つの特徴があることを表しています。

3. エラーチェックとセッションの解放

OnnxSetInputShape関数が失敗した場合には、エラーメッセージを出力し、GetLastError関数でエラーコードを確認します。このエラーハンドリングにより、何らかの問題が発生した場合でも、適切に対応できるようになります。

エラーが発生した場合、OnnxRelease関数を呼び出して、取得したセッションハンドルを解放し、メモリリークを防ぎます。その後、return(-1)で関数を終了し、処理が中断されます。

この部分では、モデルの作成から入力データの形状設定、エラーハンドリングまでの一連の流れが実行されています。モデルの適切な設定が行われることで、後続の推論処理がスムーズに進行する準備が整います。

サンプルコード解説6:OnStart関数部分その5

  //--- モデルの出力データの形状を設定する
  if(!OnnxSetOutputShape(handle,0,ExtOutputShape))
  {
    Print("OnnxSetOutputShape failed, error ",GetLastError());
    //--- エラーが発生した場合、セッションを解放する
    OnnxRelease(handle);
    return(-1);
  }

このセクションでは、OnStart関数内でONNXモデルの出力データの形状を設定する部分について解説します。ここでは、入力データの形状設定に続き、モデルの出力データがどのように取り扱われるかを説明しています。

1. モデルの出力データの形状を設定

モデルの実行において、入力データと同様に出力データの形状も正しく設定する必要があります。この部分では、OnnxSetOutputShape関数を使用して、モデルの出力の形状を指定しています。

  • handleは、先ほど取得したONNXセッションのハンドルを指します。
  • 0は、モデルの出力インデックスを表しています。通常、1つの出力しかない場合は0を指定しますが、複数の出力を持つモデルの場合は異なるインデックスが指定されます。
  • ExtOutputShapeは、事前に定義された出力形状で、{1,1}という形状を指定しています。この指定は、モデルが1つの予測値(例えば価格予測)を返すことを意味しています。

2. エラーチェックとセッションの解放

OnnxSetOutputShape関数が失敗した場合、エラーメッセージをエキスパートログに出力し、GetLastError関数を使ってエラーの詳細を取得します。このエラーチェックは、正しくない出力形状が指定された場合に、後続の処理でエラーが発生するのを防ぐためのものです。

もしエラーが発生した場合、OnnxRelease関数を使ってセッションを解放します。セッションハンドルを解放することで、不要なメモリ消費を防ぎ、プログラムが正常に終了するようにします。その後、return(-1)によって関数を終了し、処理を中断します。

この部分では、モデルの出力形状を適切に設定し、エラー処理を行うことで、モデルの実行が正しく行われるよう準備が整います。出力データの形状設定が成功することで、モデルが返すデータの受け取り準備が完了します。

サンプルコード解説7:OnStart関数部分その6

  //--- 正規化された入力データをfloat型に変換する
  matrixf x_normf;
  x_normf.Assign(x_norm);

  //--- モデルの出力データを格納するためのベクトルを初期化(価格予測用)
  vectorf y_norm(1);

このセクションでは、OnStart関数内で正規化された入力データを処理し、モデルの出力データを受け取る準備を行う部分について解説します。ここでは、データ型の変換や出力データの格納のための変数を設定しています。

1. 正規化された入力データをfloat型に変換

まず、正規化された入力データをfloat型の行列に変換しています。この処理では、matrixfを使用してデータをfloat型に変換する準備を行います。

matrixfは、浮動小数点型(float型)でデータを保持するための行列データ型です。matrixと異なり、matrixfはより精密な計算が必要な場合、特にニューラルネットワークなどで使われます。matrixは通常、整数や倍精度浮動小数点(double型)でデータを扱いますが、matrixfはメモリ消費を抑えながら、高速な計算が可能なfloat型でデータを管理します。

Assignメソッドを使用して、正規化されたmatrix型のデータ(x_norm)をmatrixf型のx_normfにコピーしています。この変換によって、後のモデル実行で効率的にデータを処理できるようになります。

2. モデルの出力データを格納するベクトルを初期化

次に、モデルの出力データを受け取るためのvectorf型のベクトルを初期化しています。

vectorfは、float型のベクトルデータを扱うためのクラスです。vectorfは、1次元のfloat型の数値列を保持し、浮動小数点型のデータを格納するために使用されます。
この例では、vectorf y_norm(1)としてベクトルを初期化しており、モデルの出力として1つの値(価格予測値)を格納するための準備をしています。予測値が1つだけ返されるため、このベクトルは1つの要素を持つ構造になっています。

matrixfとmatrixの違い

  • matrix: 倍精度浮動小数点(double型)や整数型のデータを扱う行列です。主に高精度の計算が必要な場面や、精密さを重視する場面で使用されます。
  • matrixf: float型(単精度浮動小数点)のデータを扱う行列です。計算速度やメモリの効率を重視する場面、特に機械学習やニューラルネットワークの推論処理など、計算負荷の高い処理において使用されます。

この部分では、正規化されたデータをfloat型に変換し、モデル実行に備えて出力結果を受け取る準備が行われています。matrixfとvectorfを用いることで、メモリ効率の良いデータ管理が可能になります。

サンプルコード解説8:OnStart関数部分その7

  if(!OnnxRun(handle,ONNX_DEBUG_LOGS | ONNX_NO_CONVERSION,x_normf,y_norm))
  {
    Print("OnnxRun failed, error ",GetLastError());
    //--- エラーが発生した場合、セッションを解放する
    OnnxRelease(handle);
    return(-1);
  }

このセクションでは、OnStart関数内でONNXモデルを実行し、価格予測を行う部分について解説します。ここでは、正規化された入力データを使ってモデルを実行し、予測結果を取得する処理が行われています。

1. モデルの実行

まず、OnnxRun関数を使用して、ONNXモデルの実行を開始しています。この関数は、指定されたモデルハンドルを使って入力データをモデルに渡し、結果として予測値を出力するために使用されます。

handleは、先ほど作成したONNXセッションのハンドルです。このハンドルを使用することで、モデルを操作できます。
ONNX_DEBUG_LOGSは、デバッグ用のログを出力するためのフラグです。このフラグを指定することで、モデル実行中の詳細なログを確認することができます。
ONNX_NO_CONVERSIONは、データ型の自動変換を無効にするオプションです。これにより、データ型がそのまま保持され、余計な変換が行われないようにしています。
x_normfは、事前に正規化されたfloat型の入力データで、これがモデルに渡されます。
y_normは、モデルの出力結果を格納するためのfloat型のベクトルです。このベクトルには、モデルが予測した価格データが入ります。

2. エラーチェックとセッションの解放

OnnxRun関数が失敗した場合、エラーメッセージをエキスパートログに出力し、GetLastError関数を使ってエラーの詳細を取得します。このエラーハンドリングにより、実行中に問題が発生した場合でも原因を特定しやすくなります。

もしエラーが発生した場合、OnnxRelease関数を使ってセッションを解放します。セッションハンドルを解放することで、不要なメモリの消費を防ぎ、プログラムが正常に終了するようにします。その後、return(-1)によって関数を終了し、処理が中断されます。

この部分では、モデルの実行と結果の取得を行い、エラーが発生した際には適切な処理を行う仕組みが実装されています。正しくモデルが実行されれば、次に進んで出力データを使用する準備が整います。

サンプルコード解説9:OnStart関数部分その8

 //--- モデルの出力値(正規化された価格予測値)をログに出力する
  Print(y_norm);

  //--- 逆変換を行い、実際の価格予測値を取得する
  double y_pred=y_norm[0]*s[3]+m[3];
  Print("price predicted:",y_pred);

  //--- 処理が終了したのでONNXセッションを解放する
  OnnxRelease(handle);

  return(0);
}

このセクションでは、OnStart関数の最終部分について解説します。ここでは、ONNXモデルの出力結果を取得し、正規化された値を元に戻して実際の価格予測値を計算し、最後にセッションを解放する処理が行われています。

1. モデルの出力結果をログに出力

まず、モデルの出力結果(正規化された価格予測値)をエキスパートログに出力しています。この部分では、モデルが出力した予測値を確認できるようにログに記録するだけの処理です。

y_normは、モデルの実行結果を格納するベクトルであり、ここにモデルが予測した値が入っています。この値は正規化された状態で出力されるため、まだ実際の価格とは異なります。

2. 逆変換による実際の価格予測値の取得

次に、正規化された価格予測値を実際の価格に戻すために逆変換を行っています。正規化されたデータを元に戻すには、正規化の際に使用した平均値と標準偏差を逆に適用します。

y_predは、正規化された予測値y_norm[0]に標準偏差s[3]を掛け、平均値m[3]を足すことで、元のスケールに戻した実際の価格予測値を計算しています。ここでs[3]とm[3]は、それぞれ終値(Close値)の標準偏差と平均値を指しています。

3. セッションの解放

最後に、ONNXセッションを解放しています。OnnxRelease関数を使用して、モデルのセッションを終了し、メモリを解放する処理が行われています。この操作により、不要なリソースの消費を防ぎ、プログラムが終了する際にメモリリークが発生しないようにします。

関数の最後でreturn(0)が呼ばれ、処理が正常に完了したことを示します。

この部分では、モデルからの予測結果を取得し、逆変換によって実際の価格に戻す操作を行い、処理が完了した後にONNXセッションを適切に解放する一連の流れが実装されています。

タイトルとURLをコピーしました