FC2カウンター FPGAの部屋 2017年06月04日
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

マウスコンピューターのパソコンにHDDとGPUを追加してUbuntuをインストールした

マウスコンピューターのパソコンにHDDとGPU(NVidia の GTX1060)を追加して、追加したHDD の 1.4TB のパーティションに Ubuntu 16.04 をインストールしたのだが、とっても大変だったのでブログに書いておく。

マウスコンピューターのパソコンを購入した記録だ。
マウスコンピューターにパソコンを注文しました” ”FPGAコンパイルマシンが届きました(新しいパソコン)
ちなみに、メモリは16GB に増設されている。

HDDとGPU を追加した写真を示す。
Ubuntu_GPU_1_170604.jpg

まずは、Windows の高速起動をOFF にしないと、パソコン起動時のBIOS の設定が難しいので、高速起動をOFFにした。

Windows 上から 「 BIOS 設定 」 画面を表示する方法 ( Windows10 )”を参照にしてBIOS 画面を表示した。

BIOS 設定が肝だった。これを間違うといろいろな不具合が生じた。
まずは、Boot 設定。
Fast Boot をDisabled にしないと、下のUEFI Hard Disk Drive Priorities が出てこない。
Boot 画面が見えるようにQuiet Boot をDisabled に設定した。
Hard Disk のブートはWindows Boot Manager になっているのが分かる。これをUbuntu に設定しないとGRUBの画面が出てこなかった。
Ubuntu_GPU_2_170604.jpg

UEFI Hard Disk Drive Priorities に入って、’-’ボタンを押して、ubuntu をBoot Option #1 に持ってきた。
Ubuntu_GPU_3_170604.jpg

Hard Disk のブートが ubuntu になっているのが分かる。これでGRUBが起動して、Ubuntu やWindows の起動を選ぶことできるようになった。
Ubuntu_GPU_4_170604.jpg

これでUbuntu を起動することができるようになった。
ちなみに、Ubuntu 16.04 のインストールは、USBメモリにUnetbootin を使用して、Ubuntu 16.04 のイメージを書きこんで、USBブートでインストールした。

ところが、USB ブートして、インストールメニューは出るのだが、どうしてインストールを選ぶとその後の画面が表示されない。とっても悩んだが、”nVidiaのGPU搭載PCにUbuntuを入れようとしてハマった”をやってみると画面が表示されるようになった。
結局、メニューが出たら e キーを押してコマンドの編集モードにして、”quiet splash を nomodeset に書き換える”をやれば、その後の画面が見えた。

NVidiaのドライバをインストールしないと 800 x 600 の画面しか表示できなかったので、インストールを行った。
GTX-1080 など GeForce を Ubuntu 16.04 LTS で CUDA-8.0RC と共に使う”を参考に、GPU のGTX1060 のドライバをインストールしたのだが、どうやってもドライバをインストール後にUbuntu を再起動した後にログインすることができなかった。2回ほどインストールのし直しをしてしまった。
原因は、BIOS のSecure Boot だった。これをDisabled にすると、GTX1060 のドライバを問題なくインストールすることができた。
Ubuntu_GPU_5_170604.jpg

BNN-PYNQ/bnn/src/training/ の設定を行って、mnist をトレーニングしてみた。
その結果、Epochが 6.5 秒程度だった。以前にVirtualBox 上にインストールしたUbuntu 16.04 のCPUでやった時は、約125 秒だったので、約19.2 倍にスピードアップしていることになる。
つまり、33時間20分が1時間44分で終了するということになる。計測してなかったが実際に速かった。Ubntu_GPU_6_170604.png

(2017/06/05:追記)
マウスホイールの移動量が少ないので、”「imwheel」でマウスホイールのスクロール移動量(スピード)を大きく”を参考にして、設定したら、快適になりました。
UPを7、DOWNを6に設定しました。
  1. 2017年06月04日 04:38 |
  2. パソコン関連
  3. | トラックバック:0
  4. | コメント:0