FC2カウンター FPGAの部屋 「ゼロから作るDeep Learning」の2層ニューラルネットワークのハードウェア化3
FC2ブログ

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

FPGAの部屋

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

「ゼロから作るDeep Learning」の2層ニューラルネットワークのハードウェア化3

「ゼロから作るDeep Learning」の2層ニューラルネットワークのハードウェア化2”の続き。

前回は、Python コードを公開した。今回は、Vivado HLSに持っていくための重みとバイアスのC の配列を生成するPython コードを紹介する。更に、Vivado HLSのテストベンチに必要なMNISTデータセットの一部をC の配列に変換するPython コードも紹介する。最後にMNISTデータセットを画像として見るためのPython コードも紹介する。

全てのPython コードはJupyter Notebook で書いてあるので、画像を貼ることにする。
重みをC のヘッダファイルに書き込むメソッドは fwrite_weight で使い方も書いてあるので参照のこと。
バイアスをC のヘッダファイルに書き込むメソッドは fwrite_bias で同様に使い方も書いてあるので参照のこと。
MNISTのデータをCの配列に出力し、ファイルに書き込みするプログラムも作ってある。これでVivado HLSのテストベンチで使用するテストデータを作成することができる。
最後の view_mnist() は指定された範囲のMNISTデータセットを画像として表示する。これで、どのくらい間違いやすい画像だったか?を見ることができる。
nn_fpga_ch5_5_170604.png
nn_fpga_ch5_6_170604.png
nn_fpga_ch5_7_170604.png
nn_fpga_ch5_8_170604.png
nn_fpga_ch5_9_170604.png

重みのファイル af1_weight.h の一部を示す。
nn_fpga_ch5_10_170604.png

af1_bias.h を示す。
nn_fpga_ch5_11_170604.png

MNISTデータセットの一部、mnist_data.h を示す。
nn_fpga_ch5_12_170604.png

これらのデータはPython コードを実行すれば出力できるので、全部を貼っておくことはしない。
Python コードを貼っておく。

def fwrite_weight(weight, wfile_name, float_wt_name, fixed_wt_name, MAGNIFICATION, row_size, column_size):
    import datetime
    import numpy as np
    
    f = open(wfile_name, 'w')
    todaytime = datetime.datetime.today()
    f.write('// '+wfile_name+'\n')
    strdtime = todaytime.strftime("%Y/%m/%d %H:%M:%S")
    f.write('// {0} by marsee\n'.format(strdtime))
    f.write("\n")
    
    f.write('const float '+float_wt_name+'['+str(row_size)+']['+str(column_size)+'] = {\n')
    for i in range(weight.shape[0]):
        f.write("\t{")
        for j in range(weight.shape[1]):
            f.write(str(weight[i][j]))
            if (j==weight.shape[1]-1):
                if (i==weight.shape[0]-1):
                    f.write("}\n")
                else:
                    f.write("},\n")
            else:
                f.write(", ")
    f.write("};\n")

    f.write("\n")
    f.write('const ap_fixed<'+str(int(np.log2(MAGNIFICATION))+1)+', 1, AP_TRN_ZERO, AP_SAT> '+fixed_wt_name+'['+str(row_size)+']['+str(column_size)+'] = {\n')
    for i in range(weight.shape[0]):
        f.write("\t{")
        for j in range(weight.shape[1]):
            w_int = int(weight[i][j]*MAGNIFICATION+0.5)
            if (w_int > MAGNIFICATION-1):
                w_int = MAGNIFICATION-1
            elif (w_int < -MAGNIFICATION):
                w_int = -MAGNIFICATION
            f.write(str(w_int/MAGNIFICATION))
            if (j==weight.shape[1]-1):
                if(i==weight.shape[0]-1):
                    f.write("}\n")
                else:
                    f.write("},\n")
            else:
                f.write(", ")
    f.write("};\n")

    f.close()


MAGNIFICATION = 2 ** (9-1)
fwrite_weight(network.params['W1'], 'af1_weight.h', 'af1_fweight', 'af1_weight', MAGNIFICATION, 784, 50)


fwrite_weight(network.params['W2'], 'af2_weight.h', 'af2_fweight', 'af2_weight', MAGNIFICATION, 50, 10)


def fwrite_bias(bias, wfile_name, float_b_name, fixed_wt_name, MAGNIFICATION, size):
    import datetime
    import numpy as np
    
    f = open(wfile_name, 'w')
    todaytime = datetime.datetime.today()
    f.write('// '+wfile_name+'\n')
    strdtime = todaytime.strftime("%Y/%m/%d %H:%M:%S")
    f.write('// {0} by marsee\n'.format(strdtime))
    f.write("\n")

    f.write('const float '+float_b_name+'['+str(size)+'] = {\n\t')
    for i in range(bias.shape[0]):
        f.write(str(bias[i]))
        if (i < bias.shape[0]-1):
            f.write(", ")
    f.write("\n};\n")

    f.write("\n")
    f.write('const ap_fixed<'+str(int(np.log2(MAGNIFICATION))+1)+', 1, AP_TRN_ZERO, AP_SAT> '+fixed_wt_name+'['+str(size)+'] = {\n\t')
    for i in range(bias.shape[0]):
        b_int = int(bias[i]*MAGNIFICATION+0.5)
        if (b_int > MAGNIFICATION-1):
            b_int = MAGNIFICATION-1
        elif (b_int < -MAGNIFICATION):
            b_int = -MAGNIFICATION
        f.write(str(b_int/MAGNIFICATION))
        if (i < bias.shape[0]-1):
            f.write(", ")
    f.write("\n};\n")

    f.close()


fwrite_bias(network.params['b1'], 'af1_bias.h', 'af1_fbias', 'af1_bias', MAGNIFICATION, 50)


fwrite_bias(network.params['b2'], 'af2_bias.h', 'af2_fbias', 'af2_bias', MAGNIFICATION, 10)


# MNISTのデータをCの配列に出力し、ファイルに書き込み

# coding: utf-8
import sys, os
sys.path.append(os.pardir)

import numpy as np
from dataset.mnist import load_mnist
import datetime

OUTPUT_DATA_NUM = 100 # 出力するMNISTのテストデータ数 10000までの数

# データの読み込み
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)

f = open("mnist_data.h", 'w')
todaytime = datetime.datetime.today()
f.write('// mnist_data.h\n')
strdtime = todaytime.strftime("%Y/%m/%d %H:%M:%S")
f.write('// {0} by marsee\n'.format(strdtime))
f.write("\n")

f.write('ap_ufixed<8, 0, AP_TRN_ZERO, AP_SAT> t_train['+str(OUTPUT_DATA_NUM)+'][784] = {\n')
for i in range(OUTPUT_DATA_NUM):
    f.write("\t{")
    for j in range(x_test.shape[1]):
        f.write(str(x_test[i][j]))
        if (j==x_test.shape[1]-1):
            if (i==OUTPUT_DATA_NUM-1):
                f.write("}\n")
            else:
                f.write("},\n")
        else:
            f.write(", ")
f.write("};\n")

f.write('int t_train_256['+str(OUTPUT_DATA_NUM)+'][784] = {\n')
for i in range(OUTPUT_DATA_NUM):
    f.write("\t{")
    for j in range(x_test.shape[1]):
        f.write(str(int(x_test[i][j]*256)))
        if (j==x_test.shape[1]-1):
            if (i==OUTPUT_DATA_NUM-1):
                f.write("}\n")
            else:
                f.write("},\n")
        else:
            f.write(", ")
f.write("};\n")

f.write("\n")
f.write('float t_test['+str(OUTPUT_DATA_NUM)+'][784] = {\n')
for i in range(OUTPUT_DATA_NUM):
    f.write("\t{")
    for j in range(t_test.shape[1]):
        f.write(str(t_test[i][j]))
        if (j==t_test.shape[1]-1):
            if (i==OUTPUT_DATA_NUM-1):
                f.write("}\n")
            else:
                f.write("},\n")
        else:
            f.write(", ")
f.write("};\n")
f.close() 


def view_mnist(first_offset, last_offset):
    # MNISTデータセットのfirst_offset(画像の配列の番号)からlast_offset-1までの画像を表示する
    # 「ゼロから作るDeep_Learning」第8章のコードを一部引用しています
    
    # coding: utf-8
    import sys, os
    sys.path.append(os.pardir)

    import numpy as np
    from dataset.mnist import load_mnist
    import matplotlib.pyplot as plt

    # データの読み込み
    (x_train, t_train), (x_test, t_test) = load_mnist(normalize=False, one_hot_label=True)

    fig = plt.figure()
    fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.2, wspace=0.2)
    
    current_view = 1
    for i in range(first_offset, last_offset):
        ax = fig.add_subplot(4, 5, current_view, xticks=[], yticks=[])
        ax.imshow(x_test[i].reshape(28, 28), cmap=plt.cm.gray_r, interpolation='nearest')
        current_view += 1
    
    plt.show()


view_mnist(0, 10)


  1. 2017年06月04日 17:34 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog.fc2.com/tb.php/3819-fb416aa8
この記事にトラックバックする(FC2ブログユーザー)