STM32 X-CUBE-AI: Pytorch モデルの導入プロセス

概要

STM32 CUBE MX 拡張パッケージ: X-CUBE-AI 導入プロセス:モデル変換、CUBEAI モデル検証、CUBEAI モデル適用
深層学習アーキテクチャは、複数の LSTM と完全に接続された層 (ドロップアウトおよび活性化関数層を含む) を含む Pytorch モデルを使用します。

バージョン:

STM32CUBEMX: 6.8.1
X-CUBE-AI: 8.1.0 (このバージョンが推奨され、LSTM サポートが更新されています)
ONNX: 1.14.0

参考文献

エラーやバグが発生した場合は、ST コミュニティにアクセスして質問できます: STコミュニティ
CUBEAI スタート ガイド ダウンロード アドレス: X-CUBE-AI スタート ガイド マニュアル
公式アプリケーション例:導入例

STM32CUBEAIのインストール

CUBEAI 拡張機能パッケージのインストールに関するチュートリアルはすでに多数あるため、ここでは詳しく説明しません。CUBEAI のインストール
STM32CUBEMX に CUBEAI をインストールする場合、CUBEAI の最新バージョンがインストールされていない可能性があることに注意してください。そのため、ST 公式 Web サイトにアクセスして最新バージョンをダウンロードできます (最新バージョンはモデルの実装を更新します)。https://www.st.com/zh/embedded-software/x-cube-ai.html
ここに画像の説明を挿入

CUBEAIモデルのサポート

現在、CUBEAI は 3 種類のモデルをサポートしています。

  1. 大声:.h5
  2. TensorFlow:.tflite
  3. ONNX 形式に変換できるすべてのモデル: .onnx

CUBEAI をデプロイする Pytorch は、Pytorch で生成されたモデル .pth を .onnx に変換する必要があります。

LSTM モデル変換の考慮事項

  1. CUBEAI 拡張パッケージと LSTM 変換の ONNX の制限により、Pytorch モデルを構築するときは、LSTM を設定する必要がありますbatch_first=False(モデルのトレーニングとアプリケーションには影響しません)。設定後は、形式に注意する必要があります。入力データと出力データの。
  2. LSTM モデル内の全結合層を入力する前に、データをスライスし、最後の時間ステップを実行して、いくつかの問題を回避します。
  3. 複数の LSTM の場合、関数はforward複数の入力の形式を取ることができx、それぞれがxLSTM の入力になります。

モデル変換

  1. Pytorch->Onnx は
    、変数を動的に設定できる torch.onnx.export() 関数を使用します。関数の使用方法については多くのチュートリアルがあるため、ここでは繰り返しません。PytorchからONNXへの移行と検証デプロイ後の
    モデル適用段階に属するため、入力データは自身で設定できbatch=1動的パラメータも設定可能です(動的パラメータとして設定後、CUBEMXで検証したサンプルデータ内)。seq_lengthinput_numseq_lengthseq_length=1

  2. Onnx->STM32の一般的なプロセスは
    次のとおりです。STM32 モデルの検証
    STM32CUBEMX で対応するモデルを選択すると、その後のネットワーク展開を容易にするためにモデル名を変更できます (デフォルトのネットワーク名は使用しないでください)。
    ここに画像の説明を挿入
    検証フェーズではさまざまな問題が発生する可能性があります。エラーの種類については、以下を参照してください。
    ここに画像の説明を挿入

モデルアプリケーション

これまでのところ、Pytorch モデルは ONNX に正常に変換され、検証されて CUBEMX に渡されています。以下は STM32 のモデル アプリケーション部分です。

keil でプロジェクトを開いた後、次のディレクトリにモデル関連ファイルを保存します。使用される主な関数は次のとおりです。 (modelName.c、modelName.hここで、modelNameは CUBEMX で定義されたモデル名)。
ここに画像の説明を挿入
主に使用する機能は以下の通りです。

  1. ai_modelName_create_and_init: モデルの作成と初期化用
  2. ai_modelName_inputs_get: モデル入力データを取得するために使用されます
  3. ai_modelName_outputs_get: モデル出力データを取得するために使用されます
  4. ai_pytorch_ftc_lstm_run: モデルをフィードフォワード実行して出力を取得するために使用されます。
  5. ai_mnetwork_get_error: デバッグのためにモデルのエラー コードを取得するために使用されます。

各機能の関連パラメータと使用方法は以下のとおりです。同様のコードは、X-CUBE-AI スタート マニュアル
にあります。

1 エラーの種類とコード

/*!
 * @enum ai_error_type
 * @ingroup ai_platform
 *
 * Generic enum to list network error types.
 */
typedef enum {
    
    
  AI_ERROR_NONE                         = 0x00,     /*!< No error */
  AI_ERROR_TOOL_PLATFORM_API_MISMATCH   = 0x01,
  AI_ERROR_TYPES_MISMATCH               = 0x02,
  AI_ERROR_INVALID_HANDLE               = 0x10,
  AI_ERROR_INVALID_STATE                = 0x11,
  AI_ERROR_INVALID_INPUT                = 0x12,
  AI_ERROR_INVALID_OUTPUT               = 0x13,
  AI_ERROR_INVALID_PARAM                = 0x14,
  AI_ERROR_INVALID_SIGNATURE            = 0x15,
  AI_ERROR_INVALID_SIZE                 = 0x16,
  AI_ERROR_INVALID_VALUE                = 0x17,
  AI_ERROR_INIT_FAILED                  = 0x30,
  AI_ERROR_ALLOCATION_FAILED            = 0x31,
  AI_ERROR_DEALLOCATION_FAILED          = 0x32,
  AI_ERROR_CREATE_FAILED                = 0x33,
} ai_error_type;

/*!
 * @enum ai_error_code
 * @ingroup ai_platform
 *
 * Generic enum to list network error codes.
 */
typedef enum {
    
    
  AI_ERROR_CODE_NONE                = 0x0000,    /*!< No error */
  AI_ERROR_CODE_NETWORK             = 0x0010,
  AI_ERROR_CODE_NETWORK_PARAMS      = 0x0011,
  AI_ERROR_CODE_NETWORK_WEIGHTS     = 0x0012,
  AI_ERROR_CODE_NETWORK_ACTIVATIONS = 0x0013,
  AI_ERROR_CODE_LAYER               = 0x0014,
  AI_ERROR_CODE_TENSOR              = 0x0015,
  AI_ERROR_CODE_ARRAY               = 0x0016,
  AI_ERROR_CODE_INVALID_PTR         = 0x0017,
  AI_ERROR_CODE_INVALID_SIZE        = 0x0018,
  AI_ERROR_CODE_INVALID_FORMAT      = 0x0019,
  AI_ERROR_CODE_OUT_OF_RANGE        = 0x0020,
  AI_ERROR_CODE_INVALID_BATCH       = 0x0021,
  AI_ERROR_CODE_MISSED_INIT         = 0x0030,
  AI_ERROR_CODE_IN_USE              = 0x0040,
  AI_ERROR_CODE_LOCK                = 0x0041,
} ai_error_code;

2 モデルの作成と初期化

/*!
 * @brief Create and initialize a neural network (helper function)
 * @ingroup pytorch_ftc_lstm
 * @details Helper function to instantiate and to initialize a network. It returns an object to handle it;
 * @param network an opaque handle to the network context
 * @param activations array of addresses of the activations buffers
 * @param weights array of addresses of the weights buffers
 * @return an error code reporting the status of the API on exit
 */
AI_API_ENTRY
ai_error ai_modelName_create_and_init(
  ai_handle* network, const ai_handle activations[], const ai_handle weights[]);

入力パラメータnetworkactivations:datatypesai_handleに注目してくださいvoid*初期化方法は以下の通りです。

	ai_error err;
	ai_handle network = AI_HANDLE_NULL;
	const ai_handle act_addr[] = {
    
     activations };
		
	// 实例化神经网络
	err = ai_modelName_create_and_init(&network, act_addr, NULL);
	if (err.type != AI_ERROR_NONE)
	{
    
    
		printf("E: AI error - type=%d code=%d\r\n", err.type, err.code);
	}

3 入力および出力データ変数を取得する

/*!
 * @brief Get network inputs array pointer as a ai_buffer array pointer.
 * @ingroup pytorch_ftc_lstm
 * @param network an opaque handle to the network context
 * @param n_buffer optional parameter to return the number of outputs
 * @return a ai_buffer pointer to the inputs arrays
 */
AI_API_ENTRY
ai_buffer* ai_modelName_inputs_get(
  ai_handle network, ai_u16 *n_buffer);

/*!
 * @brief Get network outputs array pointer as a ai_buffer array pointer.
 * @ingroup pytorch_ftc_lstm
 * @param network an opaque handle to the network context
 * @param n_buffer optional parameter to return the number of outputs
 * @return a ai_buffer pointer to the outputs arrays
 */
AI_API_ENTRY
ai_buffer* ai_modelName_outputs_get(
  ai_handle network, ai_u16 *n_buffer);

最初に入力データと出力データを作成する必要があります。

// 输入输出结构体
ai_buffer* ai_input;
ai_buffer* ai_output;

// 结构体内容如下
/*!
 * @struct ai_buffer
 * @ingroup ai_platform
 * @brief Memory buffer storing data (optional) with a shape, size and type.
 * This datastruct is used also for network querying, where the data field may
 * may be NULL.
 */
typedef struct ai_buffer_ {
    
    
  ai_buffer_format        format;     /*!< buffer format */
  ai_handle               data;       /*!< pointer to buffer data */
  ai_buffer_meta_info*    meta_info;  /*!< pointer to buffer metadata info */
  /* New 7.1 fields */
  ai_flags                flags;      /*!< shape optional flags */
  ai_size                 size;       /*!< number of elements of the buffer (including optional padding) */
  ai_buffer_shape         shape;      /*!< n-dimensional shape info */
} ai_buffer;

次に、関数を呼び出して構造体を割り当てます。

	ai_input = ai_modelName_inputs_get(network, NULL);
	ai_output = ai_modelName_outputs_get(network, NULL);

次に、構造体のデータに値を割り当てる必要があります。ai_input と ai_output はどちらも入力アドレスと出力アドレスです。複数の入力を持つモデルの場合、配列内の複数の入力にインデックスを付けることができます。

// 单输入
ai_float *pIn;
ai_output[0].data = AI_HANDLE_PTR(pIn);

// 多输入
ai_float *pIn[]
for(int i=0; i<AI_MODELNAME_IN_NUM; i++)
	{
    
    
		ai_input[i].data = AI_HANDLE_PTR(pIn[i]);
	}
// 输出
ai_float *pOut;
ai_output[0].data = AI_HANDLE_PTR(pOut);

pInこれはポインタの配列であり、複数の入力データ ポインタが配列に格納され、AI_MODELNAME_IN_NUM入力データの量を示すマクロ定義です。
AI_HANDLE_PTRこれはai_handle型マクロ定義であり、ai_float *ポインターを渡し、データをai_handle型に変換します。

#define AI_HANDLE_PTR(ptr_)           ((ai_handle)(ptr_))

4 モデルのフィードフォワード出力を取得します

/*!
 * @brief Run the network and return the output
 * @ingroup pytorch_ftc_lstm
 *
 * @details Runs the network on the inputs and returns the corresponding output.
 * The size of the input and output buffers is stored in this
 * header generated by the code generation tool. See AI_PYTORCH_FTC_LSTM_*
 * defines into file @ref pytorch_ftc_lstm.h for all network sizes defines
 *
 * @param network an opaque handle to the network context
 * @param[in] input buffer with the input data
 * @param[out] output buffer with the output data
 * @return the number of input batches processed (default 1) or <= 0 if it fails
 * in case of error the error type could be queried by 
 * using @ref ai_pytorch_ftc_lstm_get_error
 */
AI_API_ENTRY
ai_i32 ai_modelName_run(
  ai_handle network, const ai_buffer* input, ai_buffer* output);

この関数は、ネットワーク ハンドル、入力および出力バッファー ポインターを渡し、処理されたバッチの数を返します (アプリケーション ステージは 1 である必要があります)。戻り値が 1 であるかどうかで、モデルが正常に実行されたかどうかを判断できます。

	printf("---------Running Network-------- \r\n");
	batch = ai_modelName_run(network, ai_input, ai_output);
	printf("---------Running End-------- \r\n");
	if (batch != BATCH) {
    
    
		err = ai_mnetwork_get_error(network);
		printf("E: AI error - type=%d code=%d\r\n", err.type, err.code);
		Error_Handler();
	}

実行後、pOut配列データを表示することでモデルの出力を取得できます。

void printData_(ai_float *pOut, ai_i8 num)
{
    
    
	printf("(Total Num: %d): ", num);
	for (int i=0; i < num; i++)
	{
    
    
		if (i == num-1)
		{
    
    
			printf("%.4f. \r\n", pOut[i]);
		}
		else
		{
    
    
			printf("%.4f, ", pOut[i]);
		}
	}
}

モデル適用の概要

公式の展開例の方法に従ってパッケージ化できますAI_InitAI_Run

まとめ

発生したバグは継続的に更新されます。

おすすめ

転載: blog.csdn.net/qq_48691686/article/details/131438689