AN-2616: MAX78000/MAX78002 を使用した顔同定

要約

このアプリケーション・ノートでは、MAX78000/MAX78002 人工知能(AI)マイクロコントローラで顔認識アプリケーションを実行する方法を解説します。このアプリケーションは、顔検出 CNN モデル、顔同定 CNN モデル、ドット積モデルという 3 つの別々のモデルから成っています。

はじめに

MAX78000[1]と MAX78002[2]は、超低電力の畳み込みニューラル・ネットワーク(CNN)推論エンジンを備えている AI マイクロコントローラであり、バッテリ駆動のモノのインターネット(IoT)デバイスで AI エッジ・アプリケーションを実行できます。このマイクロコントローラは、多くの複雑なCNN ネットワーク処理を実行することで、極めて重要な性能を実現できます。

この文書では、1 つの顔認識アプリケーションを実行するために、以下の 3 つの CNN モデルを利用し、それぞれを異なるタスクとして動作させるアプローチを説明します。

  • 顔検出CNNモデルは、キャプチャされた画像の中で顔を検出し、顔を1つだけ含む長方形のサブ画像を抽出します。
  • 顔同定CNNモデルは、与えられた顔画像に対する埋め込み表現を生成して、顔画像の中の人を同定します。
  • ドット積モデルは、ドット積を出力するもので、与えられた画像の埋め込み表現とデータベースの埋め込み表現の類似度を表現します。

ドット積の類似度を距離の指標として使用し、その埋め込みの距離に基づいて画像を既知のサンプルのいずれかもしくは「Unknown(不明)」として特定します。

MAX78000 による顔画像認識アプリケーション

顔認識アプリケーション[4]は、SD カードに対応する必要があることから、MAX78000FTHR ボード[3]でのみ動作します。

顔検出モデル、顔同定モデル、ドット積モデルは順次実行されます。

このアプリケーションにおける課題は、MAX78000 のCNN エンジンの8 ビット重み容量である432KB とMAX78000 内部フラッシュ・メモリ容量をモデルが超過している条件で、全てのモデルを使用することです。この例では、顔検出モデルとドット積モデルの重みはMAX78000 の内部フラッシュ・メモリに保存され、顔同定CNN モデルの重みは外付けのSD メモリ・カードに保存されて、顔が検出されるとすぐに再ロードされます。

SDHC 重みサブ・プロジェクトを使用して、顔同定CNN モデルの重み(weights_2.h)をSD カードにバイナリ形式で保存します。

顔検出

顔検出CNN モデルには16 の層があり、168x224 のRGB 画像を入力として使用します。

Face Detection CNN:
SUMMARY OF OPS
Hardware: 589,595,888 ops (588,006,720 macc; 1,589,168 comp; 0 add; 0 mul; 0 bitwise)
Layer 0: 4,327,680 ops (4,064,256 macc; 263,424 comp; 0 add; 0 mul; 0 bitwise)
Layer 1: 11,063,808 ops (10,838,016 macc; 225,792 comp; 0 add; 0 mul; 0 bitwise)
Layer 2: 43,502,592 ops (43,352,064 macc; 150,528 comp; 0 add; 0 mul; 0 bitwise)
Layer 3: 86,854,656 ops (86,704,128 macc; 150,528 comp; 0 add; 0 mul; 0 bitwise)
Layer 4: 86,854,656 ops (86,704,128 macc; 150,528 comp; 0 add; 0 mul; 0 bitwise)
Layer 5: 86,854,656 ops (86,704,128 macc; 150,528 comp; 0 add; 0 mul; 0 bitwise)
Layer 6: 173,709,312 ops (173,408,256 macc; 301,056 comp; 0 add; 0 mul; 0 bitwise)
Layer 7 (backbone_conv8): 86,779,392 ops (86,704,128 macc; 75,264 comp; 0 add; 0 mul; 0 bitwise)
Layer 8 (backbone_conv9): 5,513,088 ops (5,419,008 macc; 94,080 comp; 0 add; 0 mul; 0 bitwise)
Layer 9 (backbone_conv10): 1,312,640 ops (1,290,240 macc; 22,400 comp; 0 add; 0 mul; 0 bitwise)
Layer 10 (conv12_1): 647,360 ops (645,120 macc; 2,240 comp; 0 add; 0 mul; 0 bitwise)
Layer 11 (conv12_2): 83,440 ops (80,640 macc; 2,800 comp; 0 add; 0 mul; 0 bitwise)
Layer 12: 1,354,752 ops (1,354,752 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 13: 40,320 ops (40,320 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 14: 677,376 ops (677,376 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 15: 20,160 ops (20,160 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
RESOURCE USAGE
Weight memory: 275,184 bytes out of 442,368 bytes total (62%)
Bias memory: 536 bytes out of 2,048 bytes total (26%)

対応するCNN の重み、バイアス、構成が、実行前に毎回CNN に読み込まれます。

// Power off CNN after unloading result to clear all CNN registers
// It is needed to load and run other CNN models
cnn_disable();
// Enable CNN peripheral, enable CNN interrupt, turn on CNN clock
// CNN clock: 50MHz div 1
cnn_enable(MXC_S_GCR_PCLKDIV_CNNCLKSEL_PCLK, MXC_S_GCR_PCLKDIV_CNNCLKDIV_DIV1);
/* Configure CNN_1 to detect a face */
cnn_1_init(); // Bring CNN state machine into consistent state
cnn_1_load_weights(); // Load CNN kernels
cnn_1_load_bias(); // Load CNN bias
cnn_1_configure(); // Configure CNN state machine

顔検出CNN モデルの出力は、いくつかのボックスの座標および対応するスコアから成るセットです。非最大抑制(NMS)アルゴリズムで、確信度スコアが最大のバウンディング・ボックスを選択し、それがTFT に表示されます。

顔検出CNN モデルが顔を検出すると、顔を1 つだけ含む長方形の部分画像が、顔同定CNN モデルの入力に一致するよう、112x112 のRGB 画像にリサイズされます。

顔同定

顔同定CNN モデルは17 の層から成り、112x112 のRGB 画像を入力とします。

Face Identification CNN:
SUMMARY OF OPS
Hardware: 199,784,640 ops (198,019,072 macc; 1,746,752 comp; 18,816 add; 0 mul; 0 bitwise)
Layer 0: 11,239,424 ops (10,838,016 macc; 401,408 comp; 0 add; 0 mul; 0 bitwise)
Layer 1: 29,403,136 ops (28,901,376 macc; 501,760 comp; 0 add; 0 mul; 0 bitwise)
Layer 2: 58,003,456 ops (57,802,752 macc; 200,704 comp; 0 add; 0 mul; 0 bitwise)
Layer 3: 21,876,736 ops (21,676,032 macc; 200,704 comp; 0 add; 0 mul; 0 bitwise)
Layer 4: 7,375,872 ops (7,225,344 macc; 150,528 comp; 0 add; 0 mul; 0 bitwise)
Layer 5: 21,826,560 ops (21,676,032 macc; 150,528 comp; 0 add; 0 mul; 0 bitwise)
Layer 6: 1,630,720 ops (1,605,632 macc; 25,088 comp; 0 add; 0 mul; 0 bitwise)
Layer 7: 14,450,688 ops (14,450,688 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 8: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 9: 12,544 ops (0 macc; 0 comp; 12,544 add; 0 mul; 0 bitwise)
Layer 10: 3,261,440 ops (3,211,264 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 11: 10,888,192 ops (10,838,016 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 12: 912,576 ops (903,168 macc; 9,408 comp; 0 add; 0 mul; 0 bitwise)
Layer 13: 10,838,016 ops (10,838,016 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 14: 809,088 ops (802,816 macc; 6,272 comp; 0 add; 0 mul; 0 bitwise)
Layer 15: 7,225,344 ops (7,225,344 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 16: 22,656 ops (16,384 macc; 0 comp; 6,272 add; 0 mul; 0 bitwise)
Layer 17: 8,192 ops (8,192 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
RESOURCE USAGE
Weight memory: 365,408 bytes out of 442,368 bytes total (82.6%)
Bias memory: 1,296 bytes out of 2,048 bytes total (63.3%)

顔同定CNN の構成、重み、バイアスを読み込む前に、前回のCNN モデル実行からCNN エンジンのステート・マシンとメモリをクリアする必要があります。これを実施する方法の1 つは、cnn_disable()関数を呼び出してCNN エンジンをパワーダウンすることです。

// Power off CNN after unloading result to clear all CNN registers
// It is needed to load and run other CNN models
cnn_disable();
// Enable CNN peripheral, enable CNN interrupt, and turn on CNN clock
// CNN clock: 50MHz div 1
cnn_enable(MXC_S_GCR_PCLKDIV_CNNCLKSEL_PCLK, MXC_S_GCR_PCLKDIV_CNNCLKDIV_DIV1);
/* Configure CNN_2 to recognize a face */
cnn_2_init(); // Bring CNN state machine into consistent state
cnn_2_load_weights_from_SD(); // Load CNN kernels from SD card
cnn_2_load_bias(); // Reload CNN bias
cnn_2_configure(); // Configure CNN state machine

顔同定CNN モデルの出力は、顔画像に対応する長さが64 の埋め込みベクトルです。ドット積モデルに入力として与える前に、その埋め込みベクトルをL2 正規化します。

ドット積

ドット積モデルにはリニア・レイヤが1 つあり、長さ64 の埋め込みベクトルを入力として使用します。

Dot Product CNN:
SUMMARY OF OPS
Hardware: 65,536 ops (65,536 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 0: 65,536 ops (65,536 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
RESOURCE USAGE
Weight memory: 65,536 bytes out of 442,368 bytes total (14.8%)
Bias memory: 0 bytes out of 2,048 bytes total (0.0%)

ドット積CNN の構成、重み、バイアスを読み込む前にも、CNN エンジンのステート・マシンとメモリをクリアする必要があります。

// Power off CNN after unloading result to clear all CNN registers
// It is needed to load and run other CNN models
cnn_disable();
// Enable CNN peripheral, enable CNN interrupt, turn on CNN clock
// CNN clock: 50MHz div 1
cnn_enable(MXC_S_GCR_PCLKDIV_CNNCLKSEL_PCLK, MXC_S_GCR_PCLKDIV_CNNCLKDIV_DIV1);
/* Configure CNN_3 for dot product */
cnn_3_init(); // Bring CNN state machine into consistent state
cnn_3_load_weights(); // Load CNN kernels
cnn_3_load_bias(); // Reload CNN bias
cnn_3_configure(); // Configure CNN state machine

ドット積モデルの出力は1024 個のドット積類似度で、それぞれが与えられた顔とデータベースに記録されている顔の類似度を示します。ドット積類似度の最大値が閾値より大きければ、類似度が最大のサンプルが同定された顔となり、TFT に表示されます。閾値に至らない場合は「Unknown(不明)」と出力されます。

図1. MAX78000 による顔画像認識結果
図1. MAX78000 による顔画像認識結果

MAX78002 による顔画像認識アプリケーション

MAX78002 評価キット(EVKIT)ボード[6]でも顔認識アプリケーション[5]を実行できます。

MAX78000 上のアプリケーションと同様、顔検出CNN モデル、顔同定CNN モデル、ドット積モデルは順次実行されます。ただしMAX78002 には、モデルの重みを全て保存できるほどの大きい内部フラッシュ・メモリがあります。

このアプリケーションでは、重みとレイヤの構成全てを読み込むのは初期化時のみで、推論ごとにはバイアスだけを再読み込みします。このアプローチにより、モデル間での切り替えのオーバーヘッドが減少します。

全てのモデルをCNNメモリ内に共存させるために、レイヤのオフセットを同様に配置し、モデルが順次連続するようにします。この例では、レイヤのオフセットを表1 に示すように配置します。

表1. CNN モデルの構成
CNN Model Start Layer End Layer
Face Identification 0 72
Dot Product 73 73
Face Detection 74 89

この手法を使用するためには、レイヤの総数が、MAX78002 の制限である128 の最大値を超過しないようにする必要があります。

合成時には、レイヤ0 から開始しないモデルについては、network.yaml ファイルでモデルのレイヤの前にパススルー・レイヤを追加する必要があります。AI8x-Synthesis リポジトリ[7]に、network.yaml ファイルの例があります。

このアプリケーションでのもう1 つの考慮事項は、重みのオフセットの調整です。MAX78002 には64 個の並列プロセッサがあり、それぞれには8 ビット精度のパラメータを9 個保持できるCNN カーネルが4096 個あります。重みのオフセットの調整にあたっては、前のモデルのカーネル・メモリの使用量を考慮します。

この例では、重みのオフセットを表2 に示すように配置します。

表2. CNN モデルの重みオフセット
CNN Model Weight Offset Number of Kernels
Face Identification 0 1580
Dot Product 2000 114
Face Detection 2500

合成時には、「–start-layer」と「–weight-start」の引数を使用してパススルー・レイヤと重みのオフセットを追加します。合成スクリプトの例をAI8x-Synthesis リポジトリ[7]に示しています。

初期化時に、モデルの重みと構成を全て読み込みます。

cnn_1_enable(MXC_S_GCR_PCLKDIV_CNNCLKSEL_IPLL,
MXC_S_GCR_PCLKDIV_CNNCLKDIV_DIV4);
cnn_1_init(); // Bring CNN state machine into consistent state
cnn_1_load_weights(); // Load kernels of CNN_1
cnn_1_configure(); // Configure CNN_1 layers
cnn_2_load_weights(); // Load kernels of CNN_2
cnn_2_configure(); // Configure CNN_2 layers
cnn_3_load_weights(); // Load kernels of CNN_3
cnn_3_configure(); // Configure CNN_3 layers

顔検出

顔検出CNN モデルには16 の層があり、168x224 のRGB 画像を入力として使用します。

Face Detection CNN:
SUMMARY OF OPS
Hardware: 589,595,888 ops (588,006,720 macc; 1,589,168 comp; 0 add; 0 mul; 0 bitwise)
Layer 74: 4,327,680 ops (4,064,256 macc; 263,424 comp; 0 add; 0 mul; 0 bitwise)
Layer 75: 11,063,808 ops (10,838,016 macc; 225,792 comp; 0 add; 0 mul; 0 bitwise)
Layer 76: 43,502,592 ops (43,352,064 macc; 150,528 comp; 0 add; 0 mul; 0 bitwise)
Layer 77: 86,854,656 ops (86,704,128 macc; 150,528 comp; 0 add; 0 mul; 0 bitwise)
Layer 78: 86,854,656 ops (86,704,128 macc; 150,528 comp; 0 add; 0 mul; 0 bitwise)
Layer 79: 86,854,656 ops (86,704,128 macc; 150,528 comp; 0 add; 0 mul; 0 bitwise)
Layer 80: 173,709,312 ops (173,408,256 macc; 301,056 comp; 0 add; 0 mul; 0 bitwise)
Layer 81 (backbone_conv8): 86,779,392 ops (86,704,128 macc; 75,264 comp; 0 add; 0 mul; 0 bitwise)
Layer 82 (backbone_conv9): 5,513,088 ops (5,419,008 macc; 94,080 comp; 0 add; 0 mul; 0 bitwise)
Layer 83 (backbone_conv10): 1,312,640 ops (1,290,240 macc; 22,400 comp; 0 add; 0 mul; 0 bitwise)
Layer 84 (conv12_1): 647,360 ops (645,120 macc; 2,240 comp; 0 add; 0 mul; 0 bitwise)
Layer 85 (conv12_2): 83,440 ops (80,640 macc; 2,800 comp; 0 add; 0 mul; 0 bitwise)
Layer 86: 1,354,752 ops (1,354,752 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 87: 40,320 ops (40,320 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 88: 677,376 ops (677,376 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 89: 20,160 ops (20,160 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
RESOURCE USAGE
Weight memory: 275,184 bytes out of 2,396,160 bytes total (11%)
Bias memory: 536 bytes out of 8,192 bytes total (7%)

アプリケーションは顔検出モデルから開始し、各実行の前に対応するバイアス値をCNN エンジンに読み込みます。そして、CNN_1 とFIFO 構成を実行して顔検出を行います。

cnn_1_load_bias(); // Load bias data of CNN_1
// Bring CNN_1 state machine of Face Detection model into consistent state
*((volatile uint32_t *) 0x51000000) = 0x00100008; // Stop SM
*((volatile uint32_t *) 0x51000008) = 0x00004a59; // Layer count
*((volatile uint32_t *) 0x52000000) = 0x00100008; // Stop SM
*((volatile uint32_t *) 0x52000008) = 0x00004a59; // Layer count
*((volatile uint32_t *) 0x53000000) = 0x00100008; // Stop SM
*((volatile uint32_t *) 0x53000008) = 0x00004a59; // Layer count
*((volatile uint32_t *) 0x54000000) = 0x00100008; // Stop SM
*((volatile uint32_t *) 0x54000008) = 0x00004a59; // Layer count
// Disable FIFO control
*((volatile uint32_t *) 0x50000000) = 0x00000000;

MAX78000 のアプリケーションと同様、顔検出CNNモデルの出力は、いくつかのボックスの座標と対応するスコアの組です。非最大抑制(NMS)アルゴリズムで、確信度スコアが最大のバウンディング・ボックスを選択し、それがTFT に表示されます。

顔検出CNN モデルが顔を検出すると、顔を1 つだけ含む長方形の部分画像が選択され、顔同定CNNモデル入力に一致するよう、112x112のRGB 画像にリサイズされます。

顔同定

顔同定CNN モデルには73 の層があり、112x112 のRGB 画像を入力として使用します。

Face Identification CNN:
SUMMARY OF OPS
Hardware: 445,470,720 ops (440,252,416 macc; 4,848,256 comp; 370,048 add; 0 mul; 0 bitwise)
Layer 0: 22,478,848 ops (21,676,032 macc; 802,816 comp; 0 add; 0 mul; 0 bitwise)
Layer 1: 2,809,856 ops (1,806,336 macc; 1,003,520 comp; 0 add; 0 mul; 0 bitwise)
Layer 2: 231,612,416 ops (231,211,008 macc; 401,408 comp; 0 add; 0 mul; 0 bitwise)
Layer 3: 1,404,928 ops (903,168 macc; 501,760 comp; 0 add; 0 mul; 0 bitwise)
Layer 4: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 5: 6,522,880 ops (6,422,528 macc; 100,352 comp; 0 add; 0 mul; 0 bitwise)
Layer 6: 1,003,520 ops (903,168 macc; 100,352 comp; 0 add; 0 mul; 0 bitwise)
Layer 7: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 8: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 9: 50,176 ops (0 macc; 0 comp; 50,176 add; 0 mul; 0 bitwise)
Layer 10: 6,522,880 ops (6,422,528 macc; 100,352 comp; 0 add; 0 mul; 0 bitwise)
Layer 11: 1,003,520 ops (903,168 macc; 100,352 comp; 0 add; 0 mul; 0 bitwise)
Layer 12: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 13: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 14: 50,176 ops (0 macc; 0 comp; 50,176 add; 0 mul; 0 bitwise)
Layer 15: 6,522,880 ops (6,422,528 macc; 100,352 comp; 0 add; 0 mul; 0 bitwise)
Layer 16: 1,003,520 ops (903,168 macc; 100,352 comp; 0 add; 0 mul; 0 bitwise)
Layer 17: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 18: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 19: 50,176 ops (0 macc; 0 comp; 50,176 add; 0 mul; 0 bitwise)
Layer 20: 6,522,880 ops (6,422,528 macc; 100,352 comp; 0 add; 0 mul; 0 bitwise)
Layer 21: 1,003,520 ops (903,168 macc; 100,352 comp; 0 add; 0 mul; 0 bitwise)
Layer 22: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 23: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 24: 50,176 ops (0 macc; 0 comp; 50,176 add; 0 mul; 0 bitwise)
Layer 25: 13,045,760 ops (12,845,056 macc; 200,704 comp; 0 add; 0 mul; 0 bitwise)
Layer 26: 702,464 ops (451,584 macc; 250,880 comp; 0 add; 0 mul; 0 bitwise)
Layer 27: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 28: 6,472,704 ops (6,422,528 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 29: 501,760 ops (451,584 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 30: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 31: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 32: 25,088 ops (0 macc; 0 comp; 25,088 add; 0 mul; 0 bitwise)
Layer 33: 6,472,704 ops (6,422,528 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 34: 501,760 ops (451,584 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 35: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 36: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 37: 25,088 ops (0 macc; 0 comp; 25,088 add; 0 mul; 0 bitwise)
Layer 38: 6,472,704 ops (6,422,528 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 39: 501,760 ops (451,584 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 40: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 41: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 42: 25,088 ops (0 macc; 0 comp; 25,088 add; 0 mul; 0 bitwise)
Layer 43: 6,472,704 ops (6,422,528 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 44: 501,760 ops (451,584 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 45: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 46: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 47: 25,088 ops (0 macc; 0 comp; 25,088 add; 0 mul; 0 bitwise)
Layer 48: 6,472,704 ops (6,422,528 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 49: 501,760 ops (451,584 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 50: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 51: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 52: 25,088 ops (0 macc; 0 comp; 25,088 add; 0 mul; 0 bitwise)
Layer 53: 6,472,704 ops (6,422,528 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 54: 501,760 ops (451,584 macc; 50,176 comp; 0 add; 0 mul; 0 bitwise)
Layer 55: 6,422,528 ops (6,422,528 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 56: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 57: 25,088 ops (0 macc; 0 comp; 25,088 add; 0 mul; 0 bitwise)
Layer 58: 12,945,408 ops (12,845,056 macc; 100,352 comp; 0 add; 0 mul; 0 bitwise)
Layer 59: 351,232 ops (225,792 macc; 125,440 comp; 0 add; 0 mul; 0 bitwise)
Layer 60: 3,211,264 ops (3,211,264 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 61: 1,618,176 ops (1,605,632 macc; 12,544 comp; 0 add; 0 mul; 0 bitwise)
Layer 62: 125,440 ops (112,896 macc; 12,544 comp; 0 add; 0 mul; 0 bitwise)
Layer 63: 1,605,632 ops (1,605,632 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 64: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 65: 6,272 ops (0 macc; 0 comp; 6,272 add; 0 mul; 0 bitwise)
Layer 66: 1,618,176 ops (1,605,632 macc; 12,544 comp; 0 add; 0 mul; 0 bitwise)
Layer 67: 125,440 ops (112,896 macc; 12,544 comp; 0 add; 0 mul; 0 bitwise)
Layer 68: 1,605,632 ops (1,605,632 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 69: 0 ops (0 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 70: 6,272 ops (0 macc; 0 comp; 6,272 add; 0 mul; 0 bitwise)
Layer 71: 809,088 ops (802,816 macc; 6,272 comp; 0 add; 0 mul; 0 bitwise)
Layer 72: 14,464 ops (8,192 macc; 0 comp; 6,272 add; 0 mul; 0 bitwise)
RESOURCE USAGE
Weight memory: 909,952 bytes out of 2,396,160 bytes total (38.0%)
Bias memory: 7,296 bytes out of 8,192 bytes total (89.1%)

顔同定モデルを実行するため、対応するバイアス値を各実行の前にCNN に読み込みます。CNN_2 とFIFO 構成を実行して顔同定を行います。

cnn_2_load_bias(); // Load bias data of CNN_2
// Bring CNN_2 state machine of Face ID model into consistent state
*((volatile uint32_t *) 0x51000000) = 0x00108008; // Stop SM
*((volatile uint32_t *) 0x51000008) = 0x00000048; // Layer count
*((volatile uint32_t *) 0x52000000) = 0x00108008; // Stop SM
*((volatile uint32_t *) 0x52000008) = 0x00000048; // Layer count
*((volatile uint32_t *) 0x53000000) = 0x00108008; // Stop SM
*((volatile uint32_t *) 0x53000008) = 0x00000048; // Layer count
*((volatile uint32_t *) 0x54000000) = 0x00108008; // Stop SM
*((volatile uint32_t *) 0x54000008) = 0x00000048; // Layer count
// Enable FIFO control
*((volatile uint32_t *) 0x50000000) = 0x00001108; // FIFO control

顔同定CNN モデルの出力は、入力の顔画像に対応する長さ64 の埋め込みベクトルです。ドット積モデルに入力として与える前に、その埋め込みベクトルをL2 正規化します。

ドット積

ドット積モデルにはリニア・レイヤが1 つあり、長さ64 の埋め込みベクトルを入力として使用します。

Dot Product CNN:
SUMMARY OF OPS
Hardware: 65,536 ops (65,536 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
Layer 73: 65,536 ops (65,536 macc; 0 comp; 0 add; 0 mul; 0 bitwise)
RESOURCE USAGE
Weight memory: 65,536 bytes out of 2,396,160 bytes total (2.7%)
Bias memory: 0 bytes out of 8,192 bytes total (0.0%)

ドット積モデルを実行するため、各実行の前に対応するバイアス値をCNN エンジンに読み込みます。その後、CNN_3 とFIFO 構成を実行してドット積を行います。

cnn_3_load_bias(); // Load bias data of CNN_3
//Dot product CNN state machine configuration
*((volatile uint32_t *) 0x51000000) = 0x00100008; // Stop SM
*((volatile uint32_t *) 0x51000008) = 0x00004949; // Layer count
*((volatile uint32_t *) 0x52000000) = 0x00100008; // Stop SM
*((volatile uint32_t *) 0x52000008) = 0x00004949; // Layer count
*((volatile uint32_t *) 0x53000000) = 0x00100008; // Stop SM
*((volatile uint32_t *) 0x53000008) = 0x00004949; // Layer count
*((volatile uint32_t *) 0x54000000) = 0x00100008; // Stop SM
*((volatile uint32_t *) 0x54000008) = 0x00004949; // Layer count
// Disable FIFO control
*((volatile uint32_t *) 0x50000000) = 0x00000000;

ドット積モデルの出力は1024 個のドット積類似度で、それぞれが与えられた顔とデータベースに記録されている顔の類似度を示します。ドット積類似度の最大値が閾値より大きければ、類似度が最大のサンプルが同定された顔となり、TFT に表示されます。閾値に至らない場合は「Unknown(不明)」と出力されます。

新しいサンプルの画像の追加

このアプリケーションでは新しいサンプルをデータベースに追加できます。タッチスクリーンの[Record](記録)ボタンを押すと、サンプルの名前を入力できます。

図2. サンプルの名前の入力
図2. サンプルの名前の入力

次のステップは、カメラでサンプルの顔の画像を作ることです。[OK]ボタンを押して取得した画像をデータベースに追加するか、[Retry](再実行)を押して再度取得します。

図3. サンプル顔画像の取得
図3. サンプル顔画像の取得

アプリケーションは新しいサンプルの顔を基に埋め込みベクトルを計算し、それを内部フラッシュ・データベースに保存します。ドット積CNN モデルは埋め込みデータベースを使用してサンプルを認識し、最終判断を下します。

図4. MAX78002 による顔画像認識結果
図4. MAX78002 による顔画像認識結果

まとめ

超低消費電力のCNN推論エンジンであることから、MAX78000/MAX78002 マイクロコントローラはバッテリ駆動のIoT アプリケーションに最適です。MAX78000[1]やMAX78002[2]のAI マイクロコントローラで複数のモデルを使用することにより、非常に複雑なアプリケーションをエネルギー効率良く実装できます。

参考資料

[1] MAX78000 データシート

[2] MAX78002 データシート

[3] MAX78000FTHR 評価用キットのデータシート

[4] MAX78000FTHR による顔画像認識アプリケーション

[5] MAX78002EVKIT による顔画像認識アプリケーション

[6] MAX78002 評価キットのデータシート

[7] AI8x-Synthesis リポジトリ