FC2カウンター FPGAの部屋 PYNQ
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Kerasを使用したMNIST CNNで手書き文字認識11(特徴マップが10個のMNISTのCNNを再学習3)

Kerasを使用したMNIST CNNで手書き文字認識10(特徴マップが10個のMNISTのCNNを再学習2)”の続き。

前回は、Vivado HLS 2018.2 で mnist_conv_nn10_hlss_ko_dma プロジェクトを作成して、IP 化を行い、PYNQ_MNIST_CNN10_182 フォルダのVivado 2018.2 プロジェクトを作成し、論理合成、インプリメンテーション、ビットストリームの生成を行った。今回は、SDK を起動して、PYNQボードをコンフィギュレーションし、アプリケーションソフトを起動して、手書き数字の認識を行った。

まずは、PYNQ_MNIST_CNN10_182 フォルダのVivado 2018.2 プロジェクトで、ハードウェアをエクスポートし、SDK を起動した。
keras_minst_cnn_67_180702.png

PYNQボードの電源ON、SDK からビットファイルをダウンロードし、SDK で mnist_conv_soft_test.c を起動した。
手書き数字の画像を示す。
keras_minst_cnn_18_180629.jpg

まずは、1 を認識させた。
keras_minst_cnn_54_180702.png

正常に認識できた。ハードウェアの認識時間は、約 2.05 ms だった。ソフトウェアの認識時間は、約 35.0 ms だった。約 17 倍ハードウェアの方が高速ということになる。

2 を認識させた。
keras_minst_cnn_55_180702.png

正常に認識できた。

3 を認識させた。
keras_minst_cnn_56_180702.png

正常に認識できた。

4 を認識させた。
keras_minst_cnn_57_180702.png

正常に認識できた。

5 を認識させた。
keras_minst_cnn_58_180702.png

正常に認識できた。

6 を認識させた。
keras_minst_cnn_59_180702.png

正常に認識できた。

7 を認識させた。
keras_minst_cnn_60_180702.png

正常に認識できた。

8 を認識させた。
keras_minst_cnn_61_180702.png

正常に認識できた。

9 を認識させた。
keras_minst_cnn_62_180702.png

正常に認識できたが、少し上にスペースを空ける必要があった。

0 を認識させた。
keras_minst_cnn_63_180702.png

正常に認識できた。

すべての数字が正常に認識できた。ただし、9 は少し字が大きかったのか?すこし上にスペースを空ける必要があったくらいで、気持ちよく認識できた。MNISTの手書き数字のデータを学習して、カメラで撮影した自分の手書き数字の画像を認識させる実験では、特徴マップが 10 個のCNN を使う必要があった。カメラで撮影した自分の手書き数字の画像を使用して学習すれば、もう少し小さい特徴マップ数でも行けるかもしれない?
なお、特徴マップ 5 個の時は 3 個の時よりも間違っていた。
  1. 2018年07月07日 04:58 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

Kerasを使用したMNIST CNNで手書き文字認識10(特徴マップが10個のMNISTのCNNを再学習2)

Kerasを使用したMNIST CNNで手書き文字認識9(特徴マップが10個のMNISTのCNNを再学習1)”の続き。

前回は、MNIST のCNN の特徴マップが10個の場合を再学習してVivado HLS で精度を確認した。今回は、Vivado HLSで精度を確認できたので、Vivado HLS 2018.2 で mnist_conv_nn10_hlss_ko_dma プロジェクトを作成して、IP 化を行い、PYNQ_MNIST_CNN10_182 フォルダのVivado 2018.2 プロジェクトを作成し、論理合成、インプリメンテーション、ビットストリームの生成を行った。

まずは、Vivado HLS 2018.2 で mnist_conv_nn10_hlss_ko_dma プロジェクトを作成した。
各パラメータは前回の値と同じとした。
keras_minst_cnn_64_180702.png

C シミュレーションを行った。エラーになってしまった。どこが原因でエラーになったのか?は分からない?
keras_minst_cnn_81_180705.png

C コードの合成を行った。
keras_minst_cnn_65_180702.png

Latency の最大値は 2.05 ms 程度だった。約 487 fps になる。
リソース使用量はBRAM_18K が 116 個、DSP48E が 169 個、FF が 10273 個、LUT が 17881 個だった。

次に Export RTL を行った。なお、Vivado synthesis, place and route にチェックを入れてある。
keras_minst_cnn_80_180705.png

LUT は 6564 個、FF が 6128 個、DSP が 172 個、BRAM が 115 個、SRL が 111 個となった。

これでIP 化ができた。
次に、PYNQ_MNIST_CNN10_182 フォルダのVivado 2018.2 プロジェクトを作成というか、特徴マップが 3 個の時のPYNQ_MNIST_CNN3_182 フォルダをPYNQ_MNIST_CNN10_182 フォルダと名前を変えた。

PYNQ_MNIST_CNN10_182 フォルダの下の hls_all_layers フォルダに特徴マップが 3 個のCNN のIP が入っているので、それを今回の特徴マップが 10 個のIP と入れ替えた。
Vivado 2018.2 プロジェクトを示す。
keras_minst_cnn_66_180702.png

ブロックデザインを示す。
keras_minst_cnn_78_180705.png

Address Editor 画面を示す。
keras_minst_cnn_79_180705.png

論理合成、インプリメンテーション、ビットストリームの生成を行った。結果を示す。
keras_minst_cnn_68_180702.png

DSP の使用量が 78 % で多くなっている。
  1. 2018年07月06日 04:48 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

Kerasを使用したMNIST CNNで手書き文字認識9(特徴マップが10個のMNISTのCNNを再学習1)

Kerasを使用したMNIST CNNで手書き文字認識8(特徴マップが3個のMNISTのCNNを再学習2)”の続き。

前回は、MNIST のCNN の特徴マップが3個の時に過学習が手書き数字の誤認識に影響しているのか?を確かめるために、Epoch 数を変更して再学習を行った時の重みやバイアスをVivado HLS のC ヘッダ・ファイルとして代入した時の結果を示した。今回は、特徴マップが3個の時には、あまり精度の向上が見られなかったため、MNIST のCNN の特徴マップが10個の場合を再学習してVivado HLS で精度を確認してみようと思う。

まずは、MNIST のCNN の特徴マップが10個の場合をKeras で再度学習した。epoch = 3 とした。
keras_mnist_cnn_76_180704.png

keras_mnist_cnn_77_180704.png

np.std(conv_output) = 0.49935710430145264
np.max(conv_output) = 2.8642632961273193
np.min(conv_output) = -3.466301202774048

np.std(dence_layer1_output) = 2.0340144634246826
np.max(dence_layer1_output) = 9.999906539916992
np.min(dence_layer1_output) = -10.721842765808105

np.std(dence_layer2_output) = 6.04936408996582
np.max(dence_layer2_output) = 24.52584457397461
np.min(dence_layer2_output) = -21.551403045654297

重みとバイアスをC のヘッダ・ファイルとして出力してVivado HLS 2017.4 でC シミュレーションを行った。
keras_mnist_cnn_73_180703.png

mnist_conv_nn10_hlss.h の AFFINE_INTEGER_LEN は 5 ビットだったが、np.max(dence_layer2_output) と np.min(dence_layer2_output) を見ると、約 24.5 と約 -21.6 なので、整数部は 6 ビット必要なので、AFFINE_INTEGER_LEN を 6 とした。
keras_mnist_cnn_74_180703.png

これで、もう一度 C シミュレーションを行ったが、ハードウェアのエラーが増えてしまった。
keras_mnist_cnn_75_180703.png

小数点以下の精度が足りなかったのだろうということで、AFFINE_INTEGER_LEN を 5 ビットに戻した。

(2018/07/05 : 追記)
全結合層 2 層目の最大値が 24 程度なのに、全結合層の整数部が 5 ビットではまずい気がしてきたので、全結合層の整数部を 6 ビットにすると同時に、全結合層の総ビット数も 15 ビットから 16 ビットに変更した。
keras_mnist_cnn_82_180705.png

C シミュレーションを行ったところ、ハードウェアとソフトウェアの誤差は共に 20 個になった。
keras_mnist_cnn_83_180705.png

HW_ERROR_COUNT = 20, SW_ERROR_COUNT = 20


これで行こうと思う。
  1. 2018年07月04日 03:51 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

Kerasを使用したMNIST CNNで手書き文字認識8(特徴マップが3個のMNISTのCNNを再学習2)

Kerasを使用したMNIST CNNで手書き文字認識7(特徴マップが3個のMNISTのCNNを再学習)”の続き。

前回は、過学習が手書き数字の誤認識に影響しているのか?を確かめるために、Epoch 数を変更して再学習を行って、PYNQボードに実装して手書き数字の認識を確認した。今回は、その過程でVivado HLS で行った、精度の確認を書けなかったので、それを書いておく。

学習した重みとバイアスをC ヘッダ・ファイルとして出力し、Vivado HLS の mnist_conv_nn3_hlss_k_org の同じファイル名のヘッダ・ファイルと入れ替えた。
C シミュレーションを行った。結果を示す。
keras_mnist_cnn_69_180703.png

HW_ERROR_COUNT = 26, SW_ERROR_COUNT = 25


ハードウェアの間違いが 26 個なので、精度は (1000 - 26) / 1000 x 100 = 97.4 % で、ソフトウェアの間違いは 25 個なので、精度は (1000 - 25) / 1000 x 100 = 97.5 % だった。

MNIST のCNN の各層の値域を見ると、全結合層 2 層目の最大、最小値が 21.3 と -23.7 程度なので、現在の 5 ビットでは足りない。5 ビットの範囲は +16 弱から -16 なので、値の範囲が足りない。
keras_mnist_cnn_70_180703.png

#define AFFINE_INTEGER_LEN 5

だが、

#define AFFINE_INTEGER_LEN 6

に変更した。こうすれば、 +32 弱から -32 までの値の範囲になる。
keras_mnist_cnn_71_180703.png

これで、C シミュレーションを行った。結果を示す。
keras_mnist_cnn_72_180703.png

HW_ERROR_COUNT = 22, SW_ERROR_COUNT = 25

でハードウェアの間違いが 22 個になった。ハードウェアの精度は (1000 - 22) / 1000 x 100 = 97.8 % となった。これで良いだろう。

今日はブログを 2 つ書く予定だったが、ワールドカップ・サッカーの日本 ー ベルギー戦が 2 - 0 で日本が勝っているので、応援するため、コレで終わりにする。日本頑張れ。。。後半22分。。。

(追記)
2 - 3 で負けました。残念ですが、善戦しました。。。
  1. 2018年07月03日 04:26 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

Kerasを使用したMNIST CNNで手書き文字認識7(特徴マップが3個のMNISTのCNNを再学習)

Kerasを使用したMNIST CNNで手書き文字認識6(実機確認3)”の続き。

前回は、考えられる 2 つの原因の内の量子化の精度、および飽和演算について検証を行ったが、浮動小数点数による特徴マップが3個のMNISTのCNN の演算でも手書き数字を誤認識していたので、量子化の精度、および飽和演算の問題ではないという結論になった。今回は、過学習が手書き数字の誤認識に影響しているのか?を確かめるために、Epoch 数を変更して再学習を行った。

まずは、jupyter notebook で特徴マップが3個のMNISTのCNN の学習を行った。前の結果からトレーニング・データの精度とテスト・データの精度が一致するEpoch 数は 4 程度だというのが分かったので、最大Epoch 数は 4 とした。学習結果を示す。
keras_minst_cnn_51_180702.png

Epoch = 4 の時のトレーニング・データでの精度は0.9744 でテスト・データでに精度は 0.9745 だった。
グラフを示す。
keras_minst_cnn_52_180702.png

学習した重みとバイアスのC ヘッダファイルを生成して、Vivado HLS 2018.2 の mnist_conv_nn3_hlss_ko_dma プロジェクトの重みとバイアスのC ヘッダファイルと交換した。
この状態で、C コードの合成を行った。結果を示す。
keras_minst_cnn_53_180702.png

Export RTLを行って、できたIP をPYNQ_MNIST_CNN3_182 フォルダのVivado 2018.2 のプロジェクトと入れ替えた。
論理合成、インプリメンテーション、ビットストリームの生成を行った。結果を示す。
keras_minst_cnn_50_180702.png

ハードウェアをエクスポートして、SDK を立ち上げた。
浮動小数点数によるMNISTのCNN のC ヘッダファイルも新しい学習した重みとバイアスに変更した。
これで、FPGA をコンフィギュレーションし、アプリケーションソフトの mnist_conv_soft_test.elf を起動した。

最初に手書き数字の 1 を認識させた。
keras_minst_cnn_40_180701.png

1 のはずなのに、ハードウェア、ソフトウェア共に 8 と誤認識された。

2 を認識させた。
keras_minst_cnn_41_180701.png

ハードウェア、ソフトウェア共に 2 で、正解だ。

3 を認識させた。
keras_minst_cnn_42_180701.png

3 もハードウェア、ソフトウェア共に 3 で、正解だった。

4 を認識させた。
keras_minst_cnn_43_180701.png

4 のはずなのに、ハードウェア、ソフトウェア共に 8 と誤認識された。

5 を認識させた。
keras_minst_cnn_44_180701.png

5 はハードウェア、ソフトウェア共に 5 で、正解だった。

6 を認識させた。
keras_minst_cnn_45_180701.png

6 のはずなのに、ハードウェア、ソフトウェア共に 8 と誤認識された。

7 を認識させた。
keras_minst_cnn_46_180701.png

7 のはずなのに、ハードウェア、ソフトウェア共に 3 と誤認識された。

8 を認識させた。
keras_minst_cnn_47_180701.png

ハードウェア、ソフトウェア共に 8 で正解だ。

9 を認識させた。
keras_minst_cnn_48_180701.png

9 のはずなのに、ハードウェア、ソフトウェア共に 8 と誤認識した。

0 を認識させた。
keras_minst_cnn_49_180701.png

ハードウェア、ソフトウェア共に 0 で正解だ。

どうやら、過学習もカメラで撮影した私の手書き数字の認識をミスる原因ではないようだ。
  1. 2018年07月02日 04:23 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

Kerasを使用したMNIST CNNで手書き文字認識6(実機確認3)

Kerasを使用したMNIST CNNで手書き文字認識5(実機確認2)”の続き。

前回は、アプリケーションソフトを動作させて、自分で書いた手書き数字を認識させたが、1, 4, 6, 7 が誤認識してしまった。以前の 10 個の特徴マップのCNN では、正常に認識しているので、量子化の精度、および飽和演算に問題があるのか?はたまた過学習になっているのかを検証することになった。今回は、考えられる 2 つの原因の内の量子化の精度、および飽和演算について検証を行った。

量子化の精度、および飽和演算について検証方法は、現在、以前の 10 個の特徴マップのCNN で行っている浮動小数点数によるCNN の演算を今回の特徴マップが 3 個のCNN で行うことだ。こうすれば、量子化の精度、および飽和演算がまずいのであれば、今回の特徴マップが 3 個のCNN の浮動小数点数による演算では、正常に手書き数字が認識できるはずである。

早速、mnist_conv_soft_test.c を特徴マップの個数を指定できるように書き換えた。そして、今回の特徴マップが 3 個の浮動小数点数用の重みのヘッダファイルを用意して、mnist_conv_soft_test.elf をRun した。
keras_minst_cnn_39_180630.png

最初に 1 にピンクの四角枠を合わせて 1 を認識させた。
keras_minst_cnn_29_180630.png

ハードウェアのCNN の認識時間は約 1.03 ms でソフトウェアでは、10.87 ms だった。ハードウェアの方はVivado HLS 2018.2 でのレイテンシとほぼ同じだった。ハードウェアの方が約 10 倍速い。
認識は 1 のはずが、固定小数点のハードウェア、浮動小数点のソフトウェア共に 3 に間違えた。

次に、2 を認識させた。
keras_minst_cnn_30_180630.png

ハードウェアでは、2 と判定され正解だったが、ソフトウェアでは、3 と判定された。

3 を認識させた。
keras_minst_cnn_31_180630.png

ハードウェア、ソフトウェア双方とも 3 で正解だ。

4 を認識させた。
keras_minst_cnn_32_180630.png

ハードウェアは 4 で正解だが、ソフトウェアは 3 で間違っている。ハードウェアも位置をシビアに調整する必要があった。

5 を認識させた。
keras_minst_cnn_33_180630.png

ハードウェアは 5 で正解dが、ソフトウェアは 3 で間違っている。

6 を認識させた。
keras_minst_cnn_34_180630.png

ハードウェア、ソフトウェア共に 8 で間違っている。

7 を認識させた。
keras_minst_cnn_35_180630.png

ハードウェアでは 7 で正解だが、ソフトウェアは 3 で間違っている。ハードウェアも位置をシビアに調整する必要があった。

8 を認識させた。
keras_minst_cnn_36_180630.png

8 はハードウェア、ソフトウェア共に正解だ。

9 を認識させた。
keras_minst_cnn_37_180630.png

9 はハードウェア、ソフトウェア共に正解だが、人間の目で上よりの位置に四角枠を設定する必要があった。

0 を認識させた。
keras_minst_cnn_38_180630.png

0 もハードウェア、ソフトウェア共に正解で問題ない。

特徴マップが 3 個の CNN の演算に浮動小数点演算を使用した結果は、1, 2, 4, 5, 6, 7 を間違えた。特徴マップが 3 個の CNN の演算に固定小数点演算を用いた結果は、1, 6 を間違えた。浮動小数点演算のほうが間違えが多いので、量子化の精度、および飽和演算が原因ではないと思う。
  1. 2018年07月01日 05:46 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0

Kerasを使用したMNIST CNNで手書き文字認識5(実機確認2)

”Kerasを使用したMNIST CNNで手書き文字認識4(実機確認)”の続き。

前回は、SDK でPYNQボードをコンフィギュレーションし、アプリケーションソフトの mnist_conv_soft_test.elf を起動してPYNQボードで動作を確認した。今回はアプリケーションソフトを動作させて、自分で書いた手書き数字を認識させてみよう。

SDK で Xilinx メニューから Program FPGA を選択して、FPGA をコンフィギュレーションして、mnist_conv_soft_test.elf を右クリックし、右クリックメニューからRun As -> 1 Launch on Hardware (System Debugger) を選択して、アプリケーションソフトをRun するとHMDI out にカメラ画像が出力された。
keras_minst_cnn_18_180629.jpg

一番下の段の手書き数字を認識させよう。
最初に 1 にピンクの四角枠を合わせて 1 を認識させる。
keras_minst_cnn_19_180629.png

ハードウェアのCNN の認識時間は約 1.03 ms でソフトウェアでは、35.00 ms だった。ハードウェアの方はVivado HLS 2018.2 でのレイテンシとほぼ同じだった。ただし、四角枠の位置を調整してもどうしても 1 のはずが 3 と誤認されてしまう。ソフトウェアは以前のCNN で特徴マップが 10 個のものを使用している。こちらは、きちんと 1 と認識されている。

次に 2 を認識させよう。
keras_minst_cnn_20_180629.png

こちらは 2 と認識した。

3 を認識させる。
keras_minst_cnn_21_180629.png

3 も認識できた。

4 を認識させた。
keras_minst_cnn_22_180629.png

4 もどう位置を調整しても 8 と誤認されてしまう。

5 を認識させた。
keras_minst_cnn_23_180629.png

5 は問題無く認識できている。

6 を認識させた。
keras_minst_cnn_24_180629.png

6 は 8 と誤認された。

7 を認識させた。
keras_minst_cnn_25_180629.png

7 は 3 と誤認された。

8 を認識させた。
keras_minst_cnn_26_180629.png

8 は問題無く認識された。

9 を認識させた。
keras_minst_cnn_27_180629.png

9 は問題無く認識された。

0 を認識させた。
keras_minst_cnn_28_180629.png

0 も問題なく認識できた。

1, 4, 6, 7 が誤認してしまう。以前の 10 個の特徴マップのCNN では、正常に認識しているので、手書き数字は大丈夫だと思うのだが。。。量子化の精度、および飽和演算に問題があるのか?はたまた過学習になっているのかを検証するために、今回の特徴マップが 3 個の時の float 演算のCNN を動作させてみよう。これが問題無く認識できているようならば、量子化の精度、および飽和演算に問題があるということになる。
  1. 2018年06月30日 05:19 |
  2. PYNQ
  3. | トラックバック:0
  4. | コメント:0
»