1-04 入力、重み、バイアスなどすべて整数化してみる

■Pythonのプログラムを整数化する

 パソコンで計算するぶんには小数でよいのですが、FPGAで小数の演算は行えません。したがってneuralnet_mnist.py内の変数をすべて「
整数化」します。


●入力データを整数化する

 まずは入力されるテスト画像を整数化します。リスト1-01のようにload_mnistの引数normalizeをTrueからFalseに変更すると、画像データはリスト1-02のように0〜255までの整数になります。

 リスト1-02のカッコ内は整数化する前の値です。これは(0.0〜1.0)の範囲が[0〜255]の範囲に写像されたことを意味します。




●重みとバイアスを整数化する

 またリスト1-03のように重みの行列W1〜3、バイアスの配列b1〜3を256倍し(*1)、型をintにするとそれらはリスト1-04のように整数になります。

(*1)整数化後の絶対値を255以下に収めるために255.9を乗算している。またW2とW3は絶対値が1.0を超えるものがあるのでリミッタをかける

 リスト1-04のカッコ内は整数化する前の値です。(-1.0〜+1.0)の範囲が[-256〜+255]の範囲に写像されています。




●積和演算の直後に8ビット右シフトさせる

 上述のように
(-1.0〜+1.0)は整数化によって[-256〜+255]に写像されます。これは重みやバイアスの値が整数化によって256倍になることを意味します。

 また入力データの値も整数化によって256倍になります。それは重みと乗算されるので、その結果の値は65,536倍になってしまいます(図1-10)。バイアスの値は256倍のままなので、そのまま加算するとバイアスの影響力が1/256になってしまいます。したがってリスト1-05のように
8ビット右シフトさせてからバイアスを加算します。




シグモイド関数を変更する

 
シグモイド関数は数式で表すと式1-01になります。グラフで表すと図1-11の破線のようになります。

 h (x) = 1 / ( 1 + exp (-x) )   式1-01 シグモイド関数

 FPGA向きの特性ではないため、図1-11のように-2.0で0に飽和、+2.0で+1.0に飽和する直線的な関数で近似します。(-1.0〜+1.0)が[-256〜+255]に写像されることを鑑みると図1-12のような特性の関数になります。

 リスト1-06に変更した関数(sigmoid_int)を示します。-512で0に飽和、+511で255に飽和します。






●整数化した値をファイルに落とす

 リスト1-07のように変更すると入力(テスト画像の最初の1枚)、重み(行列3個)、バイアス(配列3個)をファイルに書き出すことができます。後々EXCELに貼り付けるので
CSVファイルでセーブします。


●正解率はほとんど落ちていない!

 図1-13は整数化したプログラムを実行した結果で、正解率(Accuracy)は0.9325(
93.25%)になります。整数化前は93.52%だったので1%も劣化していないことになります。



 図1-13 実行結果(
整数で計算)


●PythonとEXCELを確実に一致させるために

 リスト1-08のように演算の結果や途中経過をファイルに落としておくと、後々EXCEL化やVHDL化の際、データの比較、つき合わせに役立ちます。


整数化すると推論に3秒程度かかる?

 私はWindowsパソコンにAnacondaのJupyter Labをインストールしています。Pythonを整数化してテスト画像10,000枚を推論させると、
3秒程度かかるようです。皆さんの環境ではどうでしょうか。

目次へ戻る