FC2カウンター FPGAの部屋 2017年05月
fc2ブログ

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

FPGAの部屋

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

Vivado HLSのCoSim がNorton Endpointの検疫に引っかかる

Vivado HLSのCoSim がNorton Endpointの検疫に引っかかってしまった。
Vivado HLS のバージョンは2017.1 だが、2016.4 も同様に引っかかっている。

あるVivado HLS のプロジェクトを作成した。
C-Simulation を行ったら通った。
Endpoint_Cosim_3_170531.png

けれどもC コードの合成を行って、CoSim を行ったらエラー発生。
Endpoint_Cosim_4_170531.png

同時にNorton Endpoint の検疫に引っかかっていた。
Endpoint_Cosim_1_170531.png

詳しいダイアログを表示した。
Endpoint_Cosim_2_170531.png

CoSim 時に自動生成されたcosim.pc.exe が検疫されているではないか。。。

このファイルはCoSim 時に自動生成されているので、これがウィルスということはないと思うのだが。。。怪しい動きをしていたのだろうか?
ちなみに検出結果は”SONAR.SuspScript!g3”ということだった。

Norton Endpoint を立ち上げて、「設定の変更」ボタンをクリックし、
「ウイルス対策とスパイウェアの設定」ダイアログの「グローバル設定(G)」タブで「例外:」の「リスト表示(L)」ボタンをクリックし、
「例外」ダイアログの「追加(A)...」ボタンをクリックして、「SONAR例外」→「フォルダ」を選択して、Vivado HLS のプロジェクトのあるフォルダを指定したところ、CoSim が通った。
Endpoint_Cosim_5_170531.png


  1. 2017年05月31日 15:00 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

ニューラルネットワークの推論のハードウェア化1(概要編)

ニューラルネットワークの推論のハードウェア化をやってみようと思う。
original_NN_1_170530.png

以前、ニューラルネットワークのハードウェア化をやっていたが、それは、2層のニューラルネットワークをその形のままFPGAにハードウェア化していた。ニューラルネットワークを画像フィルタとして使用していたが、パイプライン化されたニューラルネットワークから 1 クロックごとに出力することができていた。そして、積和演算をDSPで行ったのでは、DSPが足りなかった。そこで、ニューラルネットワークの形のまま実装するということは、重みは固定で良いので、乗算をシフト+加算の形に変換した。そして、シフト+加算の形でVHDLを書くのはとっても大変なので、重みの表からシフト+加算の形のVHDL を出力するRuby スクリプトを作成した。これによって、FPGAの使用リソースを削減することができた。また、DSPは使わずにロジックだけで実装することができた。

この方式の欠点は、演算器が片方の定数入力に対して最適化されていて重みが変更できないことだ。ディープなニューラルネットワークで、FPGAに入らない場合はどうするか?ということになる。この場合はFPGAのコンフィギャラブルという最大の利点を生かすソリューションを使うと良い。つまりパーシャルリコンフィギュレーションを使うのだ。パーシャルリコンフィギュレーションを使用すると、層単位または複数層でも良いが、適当な区切りで回路を入れ替えて実行することができる。
例えば、10層のニューラルネットワークだったら、2層ごとにパーシャルリコンフィギュレーションで回路を入れ替えながら、5回やれば良い。各層の重みは定数で良いので、DSPを使用する必要もなく、回路も削減できる。パーシャルリコンフィギュレーションを使えるのはFPGAだけの特権だと思う。ただし、パーシャルリコンフィギュレーションの速度が問題になると思うが、これから検証していこうと思う。

これから、オライリーの本「ゼロから作る Deep Learning」の「5章 誤差逆伝播法」のPython コードを元に、量子化をソフトウェアで行って、結果を確認しながらニューラルネットワークのハードウェア化を行っていきたいと思う。なお、「ゼロから作る Deep Learning」のPython コードはオライリー・ジャパンのoreilly-japan/deep-learning-from-scratch にあって、MITライセンスなので改変したものを公表することができる。
重みやバイアスの統計データを「「ゼロから作る Deep Learning」をやってみる4(4章 ニューラルネットワークの学習)」の「W1, W2, b1, b2の統計データ」に書いておいたが、適当な値に分布しているので、使いやすそうだった。
  1. 2017年05月31日 04:38 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

Vivado HLS の符号付 C++の任意精度固定小数点型について

Vivado HLS の符号付 C++の任意精度固定小数点型について疑問があったので調べてみた。
Vivado HLS の C++の任意精度固定小数点型は、C++のテンプレートを使用して、ap_[u]fixed で宣言される。(Xilinx社のUser Guide 高位合成 UG902 (v2016.4) 2016年11月30日 192 ページ「C++ の任意精度固定小数点型」参照)

W :ワード長(ビット数)
I :整数部のビット長
Q :量子化モード
O :オーバーフローモード
N :折り返しモードでの飽和ビット数


符号なしC++の任意精度固定小数点型 ap_ufixed<> は問題ないが、符号付C++の任意精度固定小数点型 ap_fixed<>で整数部を1ビットにした場合は符号ビットを含むのか含まないのか?が疑問だった。
そこで、Vivado HLS 2017.1 で ap_fixed_test プロジェクトを作成して、テストしてみた。
ap_fixed_test プロジェクトを示す。
ap_fixed_test_1_170529.png

テストベンチの ap_fixed_test_tb.cpp を示す。

// ap_fixed_test_tb.cpp
// 2017/04/29
//

#include <stdio.h>
#include <ap_fixed.h>

int main(){
    ap_fixed<91, AP_TRN_ZERO, AP_SAT> a;
    float f;

    a = 0.5;
    f = a;
    printf("0.5: %f\n", f);
    a = 1.0;
    f = a;
    printf("1.0: %f\n", f);
    a = -1.0;
    f = a;
    printf("-1.0: %f\n", f);
    a = -0.5;
    f = a;
    printf("-0.5: %f\n", f);
    a = 2.0;
    f = a;
    printf("2.0: %f\n", f);
    a = -1.5;
    f = a;
    printf("-1.5: %f\n", f);
    a = -0.9;
    f = a;
    printf("-0.9: %f\n", f);
}


このテストベンチのC シミュレーション結果はすでにVivado HLS のプロジェクトの図に表示されているが、下に示す。

0.5: 0.500000
1.0: 0.996094
-1.0: -1.000000
-0.5: -0.500000
2.0: 0.996094
-1.5: -1.000000
-0.9: -0.898438


この結果から、整数部のビット長を 1 とすると、1.0 - 量子化ステップ値 ~ -1.0 までの値を取れるようだ。つまり整数部は符号を表すビットのみの 1 ビットだけということになる。
  1. 2017年05月29日 15:05 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

BNN-PYNQ のトレーニングを試してみる2

BNN-PYNQ のトレーニングを試してみる1”の続き。

前回は、Theano やpylearn2 をインストールして、mnist のトレーニングを行った。33時間20分かかってトレーニングが終了した。
今回は、その結果を見ていこう。

~/BNN-PYNQ/bnn/src/training ディレクトリに mnist_parameters.npz ができていた。

トレーニングされたmnist の重みをバイナリにしてみよう。
python mnist-gen-binary-weights.py
を実行した。
BNN-PYNQ_58_170528.png
BNN-PYNQ_59_170528.png

表示出力の全文を示す。

masaaki@masaaki-VirtualBox2:~/BNN-PYNQ/bnn/src/training$ python mnist-gen-binary-weights.py
Extracting FCBN complex, ins = 784 outs = 1024
Layer 0: 1024 x 832, SIMD = 64, PE = 32
WMem = 416 TMem = 32
Extracting FCBN complex, ins = 1024 outs = 1024
Layer 1: 1024 x 1024, SIMD = 32, PE = 64
WMem = 512 TMem = 16
Extracting FCBN complex, ins = 1024 outs = 1024
Layer 2: 1024 x 1024, SIMD = 64, PE = 32
WMem = 512 TMem = 32
Extracting FCBN complex, ins = 1024 outs = 10
Layer 3: 16 x 1024, SIMD = 8, PE = 16
WMem = 128 TMem = 1
Config header file:



#define L0_SIMD 64
#define L0_PE 32
#define L0_WMEM 416
#define L0_TMEM 32
#define L0_MW 832
#define L0_MH 1024

#define L1_SIMD 32
#define L1_PE 64
#define L1_WMEM 512
#define L1_TMEM 16
#define L1_MW 1024
#define L1_MH 1024

#define L2_SIMD 64
#define L2_PE 32
#define L2_WMEM 512
#define L2_TMEM 32
#define L2_MW 1024
#define L2_MH 1024

#define L3_SIMD 8
#define L3_PE 16
#define L3_WMEM 128
#define L3_TMEM 1
#define L3_MW 1024
#define L3_MH 16

masaaki@masaaki-VirtualBox2:~/


すると、binparam-lfc-pynq ディレクトリができていた。
BNN-PYNQ_60_170528.png

binparam-lfc-pynq ディレクトリの中身を示す。
BNN-PYNQ_61_170528.png

これはちょうど ~/BNN-PYNQ/bnn/params/mnist ディレクトリと同じだ。
BNN-PYNQ_62_170529.png

CIFAR-10 ConvNet は、どれだけ時間がかかるか恐ろしい。今、GPU のGTX1060を購入したので、Ubuntu とWindowsのデュアルブートにして、Ubuntu でどのくらいトレーニングに時間がかかるか?調べてみたいと思う。
  1. 2017年05月29日 04:47 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

BNN-PYNQ のトレーニングを試してみる1

BNN-PYNQ以前もやったのだが、今回はトレーニングを試してみることにした。

BNN-PYNQ/bnn/src/training/ を参考にしてやってみることにした。
ただし、GPU は持っていないので、CPU のみでやってみる。
早速、やってみよう。
とりあえず、Installing the Training Environment: からやってみた。
VirtualBox 上のUbuntu 16.04 でやっているので、Install Nvidia Drivers, CUDA and cuDNN はやらなかった。

Install Python Packages から行った。
まずは、必要なツールをインストールした。
sudo apt-get install git python-dev libopenblas-dev liblapack-dev gfortran -y
BNN-PYNQ_40_170526.png

pip は既にインストールしていあるので省略

Theano をインストール。
pip install --user git+https://github.com/Theano/Theano.git@rel-0.9.0beta1
BNN-PYNQ_41_170526.png

Lasagne をインストール。
pip install --user https://github.com/Lasagne/Lasagne/archive/master.zip
BNN-PYNQ_42_170526.png

./theanorc を作成した。GPUの代わりにCPUを使用するように変更した。
echo "[global]" >> ~/.theanorc
echo "floatX = float32" >> ~/.theanorc
echo "device = cpu" >> ~/.theanorc
echo "openmp = True" >> ~/.theanorc
echo "openmp_elemwise_minsize = 200000" >> ~/.theanorc
echo "" >> ~/.theanorc
echo "[nvcc]" >> ~/.theanorc
echo "fastmath = True" >> ~/.theanorc
echo "" >> ~/.theanorc
echo "[blas]" >> ~/.theanorc
echo "ldflags = -lopenblas" >> ~/.theanorc

BNN-PYNQ_43_170526.png

.theanorc ができた。
BNN-PYNQ_44_170527.png
BNN-PYNQ_45_170527.png

pylearn2 のインストール。
pip install --user numpy==1.11.0 # Pylearn2 seems to not work with the latest version of numpy
git clone https://github.com/lisa-lab/pylearn2
cd pylearn2

BNN-PYNQ_46_170527.png

python setup.py develop --user

BNN-PYNQ_47_170527.png

cd ..

Download Datasets を実行した。
export PYLEARN2_DATA_PATH=~/.pylearn2
mkdir -p ~/.pylearn2
cd pylearn2/pylearn2/scripts/datasets

BNN-PYNQ_48_170527.png

mnist と cifar10 をダウンロード。
python download_mnist.py
./download_cifar10.sh

BNN-PYNQ_49_170527.png

BNN-PYNQ_50_170527.png

”export PYLEARN2_DATA_PATH=~/.pylearn2”を.bashrc に追加。
BNN-PYNQ_51_170527.png

BNN-PYNQ が古くなっていたので、消去して、git clone しなおした。
BNN-PYNQ_52_170527.png

BNN-PYNQ/bnn/src/training/ ディレクトリに移動した。
cd BNN-PYNQ/bnn/src/training/
BNN-PYNQ_53_170527.png

mnist のトレーニングをスタートした。
python mnist.py
BNN-PYNQ_54_170527.png

スタートしたのが、2017/05/27 5時10分頃だ。
現在、8時13分だが Epoch 92 だ。
BNN-PYNQ_55_170527.png

1 つのEpoch を実行するのに、約 125 秒かかっているので、1000 Epoch では、34時間43分くらいかかることになる。
ネイティブのUbuntu とGPU がとっても欲しくなった。。。

(追記)
次の日の14時30分頃、Epoch 1000 が終了しました。約33時間20分かかりました。
BNN-PYNQ_56_170528.png

best epoch: は 824 でした。それを示します。
BNN-PYNQ_57_170528.png
  1. 2017年05月27日 08:18 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

DnnWeaverをやってみる6(Windows 10 のVivado 2016.2でやってみた2)

DnnWeaverをやってみる5(Windows 10 のVivado 2016.2でやってみた1)”の続き。

前回は、ZYNQ7 Processing System を含むブロックデザインをPYNQボード用に変更した。今回は、ビットファイルを生成して、SDKでPYNQボードにビットファイルを書き込んで、アプリケーションソフトをコンパイルして試してみたい。

Generate Bitstream をクリックして、ビットファイルの生成を行う。
DnnWeaver_65_170523.png

論理合成、インプリメント、ビットファイルの生成を行った。Project Summary を示す。
DnnWeaver_66_170523.png

critical warning が 1 個ある。これを表示してみよう。
ROM.v で読んでいる norm_lut.vh が無いという critical warning だった。
DnnWeaver_67_170523.png

norm_lut.vh は、dnnweaver.public/fpga/hardware/include にあった。
DnnWeaver_68_170523.png

norm_lut.vh を持ってきて、Vivado のプロジェクトに追加した。
DnnWeaver_69_170523.png

論理合成、インプリメント、ビットファイルの生成を行ったところ、critical warning は無くなった。
DnnWeaver_70_170523.png

ビットファイル付きで、ハードウェアをエクスポートして、SDK を立ち上げた。
DnnWeaver_72_170524.png

standalone アプリケーション・プロジェクトを作成した。
DnnWeaver_75_170524.png

DnnWeaver_74_170524.png

dnnweaver.public/fpga/aram_software/src から platform.c と standalone.c を standalone アプリケーション・プロジェクトの src フォルダにコピーした。
DnnWeaver_75_170524.png

DnnWeaver_76_170524.png

同様に、dnnweaver.public/fpga/aram_software/lib から platform.h と platform_config.h を standalone アプリケーション・プロジェクトの src フォルダにコピーした。
DnnWeaver_77_170524.png

DnnWeaver_76_170524.png

standalone.elf ができた。
DnnWeaver_78_170524.png

PYNQボードの電源を入れて、JTAG モードにし、SDK でビットファイルをダウンロードした。(Xilinx Tools メニューからProgram FPGA を選択)
standalone.elf をデバックモードで起動して、ステップオーバーでアプリケーションソフトを実行していった。
wr_address にアドレスを読み込むところで 0xdeadbeef が読み込まれている。
DnnWeaver_79_170524.png

そのため、次にステップオーバーすると、DataAbortHandler に飛んでしまう。
DnnWeaver_80_170524.png

と言う訳で、PYNQボード用のDnnWeaver を動作させることができなかった。
  1. 2017年05月25日 05:05 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

DnnWeaverをやってみる5(Windows 10 のVivado 2016.2でやってみた1)

DnnWeaverをやってみる4(「PYNQ祭り」延長戦の成果)”の続き。

今まで、DnnWeaver のVivado 2016.2 のGUI では、トップレベルにいろいろなソースコードが入っていたので、これをスクリプトでまとめてビットファイルを生成していたのかと思っていた。しかしよく見てみると、zynq_wrapper.v の下に階層構造ができている。
DnnWeaver_71_170524.png

これで、ビットファイルを作ればOKじゃないか?ということで、Vivado 2016.2 単体でやってみた。
Windows 10 でやってみたいということで、Ubuntu から移行することにした。
Ubuntu 16.04 上で、File メニューからArchive Project ... を選択する。
Archive Project ダイアログが表示された。今回のコンパイル結果は、ZC702 のものなので、include run results のチェックを外してOK ボタンをクリックする。
DnnWeaver_42_170523.png

すると、dnnwever.xpr.zip が生成された。
DnnWeaver_43_170523.png

USB メモリ経由でWindows 10 に持ってきて見ているが、dnnwever.xpr.zip の中には、dnnweaver フォルダがある。
DnnWeaver_44_170523.png

dnnweaver フォルダを dnnweaver_162 として、PYNQ フォルダにコピーした。
DnnWeaver_45_170523.png

Windows 10 上のVivado 2016.2 で開いてみた。
DnnWeaver_46_170523.png

トップの zynq_wrapper.v を開いてみると、DDR とFIXED_IO だけの配線で、これだと配線位置が決まっているので、制約ファイルも要らない。
DnnWeaver_47_170523.png

さて、ZC702 からPYNQ ボード用に変更しよう。Project part のZYNQ-7 ZC702 Evaluation Board (xc7z020clg484-1) をクリックする。
DnnWeaver_48_170523.png

Project device: の… ボタンをクリックして、FPGAを変更しよう。
DnnWeaver_49_170523.png

Select Device ダイアログで、Select: を Parts にして、下の図のようにFilter を選択し、xc7z020clg400-1 を選択した。
DnnWeaver_50_170523.png

Project Settings のProject device にxc7z020clg400-1 が入った。
DnnWeaver_51_170523.png

Project Summary を見ても、Project part にxc7z020clg400-1 が入っているのが分かる。
DnnWeaver_52_170523.png

これで、ブロックデザインのzc702.bd を開くと、FPGA パーツを変更したので、IP をアップグレードする必要がある。Upgrade Selected ボタンをクリックして、IP をアップグレードする。
DnnWeaver_53_170523.png

IP をアップグレードしても、ZYNQ7 Processing System はZC702 用のままなので、いったん削除する。
DnnWeaver_54_170523.png

削除した状態を示す。
DnnWeaver_55_170523.png

新しくZYNQ7 Processing System をAdd IP した。
DnnWeaver_56_170523.png

ZYNQ7 Processing System をダブルクリックして、設定画面を開く。
Presets をクリックして、Apply Configuration を選択する。
DnnWeaver_57_170523.png

Digilent 社のPYNQ サイトのZynq Presets をダウンロードして解凍した pynq_revC.tcl を選択する。
DnnWeaver_58_170523.png

すると、PYNQ の設定がZynq Block Design に反映されているのが分かる。
DnnWeaver_59_170523.png

ついでに設定を行う。
PS-PL Configuration で、M AXI GP0 interface と S AXI HP0 interface にチェックを入れた。
DnnWeaver_60_170523.png

Clock Configuration で PL Fabric Clocks の FCLK_CLK0 を 150 MHz に設定した。
DnnWeaver_61_170523.png

配線をやり直して、ブロックデザインが完成した。
DnnWeaver_62_170523.png

次に、Address Editor で、M_AXI_GP0 を右クリックして、Assign Address を選択して、アドレスをマップした。
S_AXI_HP0 も同様にアドレスをマップした。
DnnWeaver_63_170523.png

アドレス・マップ後。
DnnWeaver_64_170523.png

これで、zc702.bd (PYNQボード用に変更はしたが名前はそのまま)は、PYNQボード用になった。
  1. 2017年05月24日 04:54 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

DnnWeaverをやってみる4(「PYNQ祭り」延長戦の成果)

DnnWeaverをやってみる3”の続き。

「PYNQ祭り」延長戦 : FPGAディープラーニング実践懇親会”では、DnnWeaver のARTY-Z7-20 への実装をやってみるというお題でやってみた。6 時間という時間の制限があったので、五里霧中だったときは苦しかったが、徐々に気が楽になり、気分が乗ってきた。それでも家でリラックスしてやっているときより気が付かない。やはり、私はハッカソンよりも家で家事をやりながら、やったほうがひらめくようだ。しかし、いろいろな方とお知り合いになれて、いろいろなお話ができたし、実りは多かったと思う。そうそれに、研究室の卒業生が来ていて、同じ班で、以前と同じように協力して課題に取り組めたのは良かった。昔を思い出した。彼がソフトウェアで、私がハードウェア担当でいろいろと実験コードを書いてもらいながら、協力してバグフィックスしていたのを思い出した。

そうそう、彼が、私のノートパソコンがarm-xilinx-eabi-gcc が動作しなかったので、直してくれた。64 ビットLinux から 32 ビットのアプリケーションが動作しない問題だと言っていたので、”64bit-Linuxで32bitバイナリ実行環境を構築”の辺りの解決策を試してくれたのだと思う。

さて、PYNQ祭り延長戦で分かったDnnWeaver の構成とその後、私が解明した事実を書いておく。

まずは、~/dnnweaver.public/fpga ディレクトリにある Makefile について。

Makefile
オプションについて書いておく。
test : iverilog でシミュレーションを行う。
ELF : ソフトウェアのコンパイルを行う。
launch : XMD でZynq に standalone.elf をダウンロードし、起動する。
つまり、DnnWeaver を動かすときは、make launch を実行すると動作させられるはずだったが、どこが悪かったのか?PYNQ祭り延長戦では、Arty-Z7-20 で動作しなかった。
Vivado での処理は、tcl/vivado_2016_2.tcl を呼び出して処理を行っている。

vivado_2016_2.tcl
PYNQ祭り延長戦では、DnnWeaver はXilinx 社のZC702 ボード用なので、Arty-Z7-20 に移行することを考えてみた。
vivado_2016_2.tcl の最初の部分で、FPGAの型番とボード・ファイルを指定している。Arty-Z7-20 に移行するには、ここを書き換える必要がある。
更に、ここを書き換えただけではだめで、その下で、

source tcl/zynq_1AXIHP0_1AXIGP0.tcl

でzynq_1AXIHP0_1AXIGP0.tcl を実行している。
これは、ブロックデザインを開いて、File メニューから Export -> Export Block Design... を選択したときに、出力される tcl ファイルそのものなので、ここで、Zynq のProcessing System がそのまま入ってしまう。よって、ここも書き換える必要があった。
DnnWeaver の tcl/vivado_2016_2.tcl を引用する。
DnnWeaver_34_170522.png

上の vivado_2016_2.tcl から下へ書き換えた。
まずは、FPGA はZC702 の484 ピンから 400 ピンに書き換える必要がある。
次に、Arty-Z7-20 のボード・ファイルをDigilent から持ってきて、Vivado 2016.2 にインストールした。それで、ボード・ファイルの行を書き換えている。ポイントは xilinx.com から digilentinc.com に書き換えて、バージョン番号を 1.0 にすることだった。
次に、zynq_1AXIHP0_1AXIGP0.tcl の代わりに、Arty-Z7-20 用の zc702.tcl を作ったので、それを実行するように書き換えた。zc702.tcl の出力方法については後述する。
DnnWeaver の tcl/vivado_2016_2.tcl を引用してArty-Z7-20 用に書き換えた。
DnnWeaver_35_170522.png

zc702.bd
zc702.bd を Arty-Z7-20 用に変更する。すでにDigilent 社のボード・ファイルをVivado 2016.2 に入れてあるものする。
Vivado 2016.2 を起動して、~/dnnweaver.public/fpga/vivado/dnnweaver.xpr を読み込ませる。
Vivado のGUI 画面を示す。ZC702 用に設定されている。
DnnWeaver_36_170522.png

Preject part の ZYNQ-7 ZC702 をクリックして、Arty-Z7-20 に変更しよう。
クリックすると、Project Settings ダイアログが表示される。右の・・・ボタンをクリックして、Arty-Z7-20 に変更した。これでOK ボタンをクリックする。
DnnWeaver_37_170522.png

これでボード・ファイルをArty-Z7-20 に変更できた。IP のアップグレードを求められるので、行う。
それでもZynq のProcessing System は更新されていない。更新するためには、いったん削除して、もう一度、Add IP する必要がある。
DnnWeaver_38_170522.png

Arty-Z7-20 用のZynq のProcessing System を追加したら、S_AXI_HP0 interface のチェックボックスにチェックを入れる。
DnnWeaver_39_170522.png

次に、PL Fabric Clocks の FCLK_CLK0 にチェックを入れる。
DnnWeaver_40_170522.png

これでブロックデザインが完成した。
次に、このブロックデザインを生成するためのTCL スクリプトを生成しよう。
File メニューから Export -> Export Block Design... を選択すると、Export Block Design ダイアログが表示される。この際に、ブロックデザイン名の TCL スクリプトが生成される。名前が気に入らなければ、名前を変更する。
DnnWeaver_41_170522.png

このように、Arty-Z7-20 用に変更されたブロックデザイン生成用 tcl ファイルを得ることができた。
tcl/vivado_2016_2.tcl はすでに zc702.tcl が動作するように書き換えてある。

これで、もう一度、make を行うと Arty-Z7-20 用に変更されてビルドを行うことができた。
PYNQ祭り延長戦では、VirtualBox 上のUbuntu 16.04 から make launch を行って、接続されたArty-Z7-20 を動作させようとしたが、うまく動作しなかった。
そこで、/fpga/synthesis-output ディレクトリをUSB メモリにコピーして、Windows 10 のVivado SDK でプロジェクトを作成した。
.hdf ファイルを読み込むと SDK のハードウェア・プラットフォームが生成できる。詳しくは、FPGAプログラミング大全 Xilinx編の巻末の説明を参照のこと。
SDK のプラットフォームに standalone プロジェクトを作成して、~/dnnweaver.public/fpga/arm_software/src/standalone.c, platform.c と ~/dnnweaver.public/fpga/arm_software/lib の platform.h, platform_config.h などをコピー & ペーストをしてアプリケーション・プロジェクトを作成した。それをデバックモードで動作させたが、どこかのレジスタが 0xdeadbeef で動作しなかった。残念。
SDK は他の人に任せたので、詳しい説明になっていない。
次は、Vivado のGUI でインプリメントできたので、それをブログに書いておこうと思う。
  1. 2017年05月22日 05:28 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

DnnWeaverをやってみる3

DnnWeaverをやってみる2”の続き。

前回は、エラーで終了してしまったので、今回はそのエラーの解消を図る。

実は、コメント欄で解決方法を教えてもらったのだ。管理人のみ閲覧できますコメントだったのでお名前は書かないがありがとうございます。
教えてもらったことをやってみよう。それは、ディレクトリを作ろうということだった。
~/dnnweaver.public/fpga/arm_software ディレクトリの下に、obj ディレクトリを作って、その下に、standalone 、linux ディレクトリを作る。
cd ~/dnnweaver.public/fpga/arm_software
ls
mkdir obj
ls
cd obj
mkdir standalone
mkdir linux
ls

DnnWeaver_28_170520.png

次に、~/dnnweaver.public/fpga ディレクトリに戻って、make を行った。
cd ~/dnnweaver.public/fpga
make

DnnWeaver_29_170520.png
DnnWeaver_30_170520.png

成功した。
synthesis-output ディレクトリを見てみよう。
DnnWeaver_31_170520.png

zynq_wrapper.bit、 zynq_wapper.hdf、 standalone.elf、 linux.elf がある。

vivado ディレクトリに行ってみた。dnnweaver.xpr がある。
DnnWeaver_32_170520.png

vivado 2016.2 を起動してdnnweaver.xpr を開いてみたが、トップのファイルがないな。。。GUIはこのままでは使えないね。
DnnWeaver_33_170520.png

今日は、「PYNQ祭り」延長戦 : FPGAディープラーニング実践懇親会に行くのでこれまでとします。
  1. 2017年05月20日 04:39 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

DnnWeaverをやってみる2

DnnWeaverをやってみる1”の続き。

Vengineer さんにDnnWeaver は、TensorFlow をインストールすると make できるというのを教えて頂いたので、VirtualBox 上のUbuntu 16.04 にTensorFlow をインストールすることができた。
今回は、~/dnnweaver.public/fpga ディレクトリで make してみよう。
Vivado 2016.2 は2016.2 と2016.3 の間に壁があるので、インストールすることにして、インストールを行った。

~/dnnweaver.public/fpga ディレクトリに cd して、make を行った。
DnnWeaver_25_170519.png

途中省略

DnnWeaver_26_170519.png

「Fatal error: can't create arm_software/obj/standalone/standalone.o: そのようなファイルやディレクトリはありません」というエラーが出て止まってしまった。

make 後の全表示を貼っておく。

(tensorflow) masaaki@masaaki-VirtualBox2:~/dnnweaver.public/fpga$ make
Generating instructions for DnnWeaver
Config = 8 PEs, 1 PUs
Initializing DW Network
Network Name:        CIFAR10_full_deploy
Input Dimensions:    32 x 32 x 3
Number of Layers:    13

Layer Name:        conv1
Layer Type:        Convolution 5x5 - s1
Macro Layer Name:        conv1

Layer Name:        pool1
Layer Type:        Pooling 3x3 - s2

Layer Name:        relu1
Layer Type:        ReLU

Layer Name:        norm1
name: "norm1"
type: "LRN"
bottom: "pool1"
top: "norm1"
lrn_param {
  local_size: 3
  alpha: 4.99999987369e-05
  beta: 0.75
  norm_region: WITHIN_CHANNEL
}

Layer Type:        Normalization 3x3

Layer Name:        conv2
Layer Type:        Convolution 5x5 - s1

Layer Name:        relu2
Layer Type:        ReLU

Layer Name:        pool2
Layer Type:        Pooling 3x3 - s2

Layer Name:        norm2
name: "norm2"
type: "LRN"
bottom: "pool2"
top: "norm2"
lrn_param {
  local_size: 3
  alpha: 4.99999987369e-05
  beta: 0.75
  norm_region: WITHIN_CHANNEL
}

Layer Type:        Normalization 3x3

Layer Name:        conv3
Layer Type:        Convolution 5x5 - s1

Layer Name:        relu3
Layer Type:        ReLU

Layer Name:        pool3
Layer Type:        Pooling 3x3 - s2

Layer Name:        ip1
Layer Type:        FullyConnected 

Layer Name:        prob

Connecting Prev:conv1 and Next:pool1
Connecting Prev:pool1 and Next:relu1
Connecting Prev:relu1 and Next:norm1
Connecting Prev:norm1 and Next:conv2
Connecting Prev:conv2 and Next:relu2
Connecting Prev:relu2 and Next:pool2
Connecting Prev:pool2 and Next:norm2
Connecting Prev:norm2 and Next:conv3
Connecting Prev:conv3 and Next:relu3
Connecting Prev:relu3 and Next:pool3
Connecting Prev:pool3 and Next:ip1
Connecting Prev:ip1 and Next:prob
Head: conv1
Curr layer = pool1
Appending: pool1
Curr layer = relu1
Appending: relu1
Curr layer = norm1
New macro node norm1
Macro Layer Name:        norm1
Curr layer = conv2
New macro node conv2
Macro Layer Name:        conv2
Curr layer = relu2
Appending: relu2
Curr layer = pool2
Appending: pool2
Curr layer = norm2
New macro node norm2
Macro Layer Name:        norm2
Curr layer = conv3
New macro node conv3
Macro Layer Name:        conv3
Curr layer = relu3
Appending: relu3
Curr layer = pool3
Appending: pool3
Curr layer = ip1
New macro node ip1
Macro Layer Name:        ip1
Curr layer = prob
PE   : conv1 5x5 s1     |     Pool : pool1 3x3 s2     |     Act  : relu1 ReLU      
PE   : norm1 3x3        |     Pool : None             |     Act  : None            
PE   : conv2 5x5 s1     |     Pool : pool2 3x3 s2     |     Act  : relu2 ReLU      
PE   : norm2 3x3        |     Pool : None             |     Act  : None            
PE   : conv3 5x5 s1     |     Pool : pool3 3x3 s2     |     Act  : relu3 ReLU      
PE   : ip1 64x10        |     Pool : None             |     Act  : None            
**************************************************
Generating Compute Binary : hardware/include/pu_controller_bin.vh
**************************************************
Layer conv1+pool1+relu1 weight size 6144
Layer norm1 weight size 0
Layer conv2+relu2+pool2 weight size 65536
Layer norm2 weight size 0
Layer conv3+relu3+pool3 weight size 131072
Layer ip1 weight size 32800



**************************************************
generating instructions for macro layer conv1+pool1+relu1
Layer name = conv1+pool1+relu1
Layer input  Dim = <google.protobuf.pyext._message.RepeatedScalarContainer object at 0x7fd4a19cc8b8>
Layer output Dim = [1, 32, 16, 16]



**************************************************
generating instructions for macro layer norm1
Layer name = norm1
Layer input  Dim = [1, 32, 16, 16]
Layer output Dim = [1, 32, 16, 16]



**************************************************
generating instructions for macro layer conv2+relu2+pool2
Layer name = conv2+relu2+pool2
Layer input  Dim = [1, 32, 16, 16]
Layer output Dim = [1, 32, 8, 8]



**************************************************
generating instructions for macro layer norm2
Layer name = norm2
Layer input  Dim = [1, 32, 8, 8]
Layer output Dim = [1, 32, 8, 8]



**************************************************
generating instructions for macro layer conv3+relu3+pool3
Layer name = conv3+relu3+pool3
Layer input  Dim = [1, 32, 8, 8]
Layer output Dim = [1, 64, 4, 4]



**************************************************
generating instructions for macro layer ip1
Layer name = ip1
Layer input  Dim = [1, 64, 4, 4]
Layer output Dim = [1, 10, 1, 1]
**************************************************
Generating Memory Read Binary : hardware/include/rd_mem_controller.vh
**************************************************
generating memory instructions
Layer name = conv1+pool1+relu1
Layer input  Dim = <google.protobuf.pyext._message.RepeatedScalarContainer object at 0x7fd4a19cc8b8>
Layer output Dim = [1, 32, 32L, 32L]
generating memory instructions
Layer name = norm1
Layer input  Dim = [1, 32, 16, 16]
Layer output Dim = [1, 32, 16, 16]
generating memory instructions
Layer name = conv2+relu2+pool2
Layer input  Dim = [1, 32, 16, 16]
Layer output Dim = [1, 32, 16, 16]
generating memory instructions
Layer name = norm2
Layer input  Dim = [1, 32, 8, 8]
Layer output Dim = [1, 32, 8, 8]
generating memory instructions
Layer name = conv3+relu3+pool3
Layer input  Dim = [1, 32, 8, 8]
Layer output Dim = [1, 64, 8, 8]
generating memory instructions
Layer name = ip1
Layer input  Dim = [1, 64, 4, 4]
Layer output Dim = [1, 10, 1, 1]
**************************************************
Generating Memory Write Binary : hardware/include/wr_mem_controller.vh
**************************************************
generating memory instructions
Layer name = conv1+pool1+relu1
Layer output Dim = [1, 32, 16, 16]
generating memory instructions
Layer name = norm1
Layer output Dim = [1, 32, 16, 16]
generating memory instructions
Layer name = conv2+relu2+pool2
Layer output Dim = [1, 32, 8, 8]
generating memory instructions
Layer name = norm2
Layer output Dim = [1, 32, 8, 8]
generating memory instructions
Layer name = conv3+relu3+pool3
Layer output Dim = [1, 64, 4, 4]
generating memory instructions
Layer name = ip1
Layer output Dim = [1, 10, 1, 1]
**************************************************
Generating DnnWeaver Parameters : hardware/include/dw_params.vh
**************************************************
**************************************************
Generating DnnWeaver MMAP : hardware/include/mmap.txt
**************************************************
**************************************************
Generating DnnWeaver Testbench MMAP : hardware/include/tb_mmap.vh
**************************************************
#@python ../compiler/compiler.py -prototxt ../compiler/sample_prototxts/cifar10_full.prototxt -b hardware/include -fpga zynq
Synthesizing DnnWeaver
DnnWeaver: Creating Project
DnnWeaver: Top module is : zynq_wrapper
DnnWeaver: Frequency is : 150 MHz
DnnWeaver: Verilog Path is : hardware
DnnWeaver: Generating Zynq block
DnnWeaver: Generating Zynq block - done
DnnWeaver: Running Synthesis
DnnWeaver: Generating utilization report
DnnWeaver: Running Placement
DnnWeaver: Checking for Timing violations after placement
DnnWeaver: No timing violations found
DnnWeaver: Running Routing
DnnWeaver: Generating Bitfile ./synthesis-output/zynq_wrapper
DnnWeaver: Generating HDF
DnnWeaver: Generating utilization report
DnnWeaver: Done!
Compiling arm_software/src/standalone.c ...arm_software/src/standalone.c: In function 'main':
arm_software/src/standalone.c:7:34: warning: initialization from incompatible pointer type
 #define AXI_GP0_MASTER_BASE_ADDR (u16*)0x43C00000
                                  ^
arm_software/src/standalone.c:20:34: note: in expansion of macro 'AXI_GP0_MASTER_BASE_ADDR'
  volatile u32 * control_master = AXI_GP0_MASTER_BASE_ADDR;
                                  ^
arm_software/src/standalone.c:21:32: warning: initialization makes pointer from integer without a cast
  volatile u16 * rd_address   = *(control_master + 2);
                                ^
arm_software/src/standalone.c:22:32: warning: initialization makes pointer from integer without a cast
  volatile u16 * wr_address   = *(control_master + 3);
                                ^
Assembler messages:
Fatal error: can't create arm_software/obj/standalone/standalone.o: そのようなファイルやディレクトリはありません
Makefile:126: ターゲット 'arm_software/obj/standalone/standalone.o' のレシピで失敗しました
make: *** [arm_software/obj/standalone/standalone.o] エラー 1


~/dnnweaver.public/fpga ディレクトリは、Vivado のログを除くと、synthesis-output, vivado ディレクトリが新規作成されて、fsm_encoding.os, get-pip.py が増えている。
DnnWeaver_27_170519.png
  1. 2017年05月19日 05:19 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:1

VirtualBox 上のUbuntu 16.04 にTensorFlow をインストールする

Vengineer さんにDnnWeaver は、TensorFlow をインストールすると make できるというのを教えて頂いたので、VirtualBox 上のUbuntu 16.04 にTensorFlow をインストールすることにした。

Installing TensorFlow on Ubuntu”を参考にした。

まずは、
sudo apt-get update
DnnWeaver_18_170519.png

python-pip python-dev python-virtualenv をインストール。
sudo apt-get install python-pip python-dev python-virtualenv
DnnWeaver_19_170519.png

Python のバージョンを確認すると、2.7.12 だった。
python -V
DnnWeaver_20_170519.png

tensorflow ディレクトリを作成して、virtualenv 環境を生成し、virtualenv 環境をアクティベートした。
mkdir tensorflow
virtualenv --system-site-packages tensorflow/
source ~/tensorflow/bin/activate

DnnWeaver_21_170519.png

Python のバージョンに合ったTensorFlow Python package をこのWeb ページから選んで、pip でインストールする。
pip install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.1.0-cp27-none-linux_x86_64.whl
DnnWeaver_22_170519.png
DnnWeaver_23_170519.png

このWeb ページから「動作確認」のPython コードを引用した。
DnnWeaver_24_170519.png

正常にインストールできたようだ。
  1. 2017年05月19日 04:51 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

DnnWeaverをやってみる1

DnnWeaver をやってみようと思う。
DnnWeaver は、「FPGA上でディープニューラルネットワーク(DNN)を加速するための最初のオープンソースのフレームワーク」(Google 翻訳使用)だそうだ。

DnnWeaver のダウンロードページを見ると、git で clone するようなので、Windows 10 上のVirtualBox でインストールしたUbuntu 16.04 を使用することにした。

まずは、Ubuntu 16.04 のホームで git clone を行った。
git clone https://bitbucket.org/hsharma35/dnnweaver.public.git
すると、dnnweaver.public ディレクトリができた。
DnnWeaver_1_170516.png

DnnWeaver のダウンロードページでは、python 2.7 と Vivado 2016.2 が必須だが、Python 2.7.12 がインストールされているし、Vivado も 2016.4 だが、インストールされているので、これでやってみることにする。

DnnWeaver のダウンロードページでは、fpga ディレクトリに行って、「make PROTOTXT=your_prototxt_here」するようにとのことだった。
dnnweaver.public/fpga に行ってみるとMakefile があった。
DnnWeaver_2_170516.png

しかし、Makefile を見ると、すでに PROTOTXT が定義されているようなので、make だけでやってみることにする。
DnnWeaver_3_170516.png

make すると、google.protobuf.internal の enum_type_wrapper が無いと言われてしまった。
caffe_pb2.py を見ると、、google.protobuf.internal や、google.protobuf からのインポートがたくさんある。
DnnWeaver_5_170516.png

これらはどうやら、googleのprotobuf というものらしい?
DnnWeaver_6_170516.png

googleのprotobufから protobuf-python-3.3.0.tar.gz をダウンロードしてホームディレクトリに解凍した。

caffe_pb2.py のインポートするべきファイルがあった。
DnnWeaver_8_170516.png

今回、protobuf のインストールは行わないで、ファイルだけを利用してみようと思う。
ファイルを利用するためにPYTHONPATH にprotobuf-3.3.0/python を追加する。
export PYTHONPATH="/home/masaaki/protobuf-3.3.0/python:$PYTHONPATH"
そして、もう一度、make を行った。
DnnWeaver_9_170516.png

やはり、エラーで今度は six モジュールが無いとのことだった。
six モジュールは pip でインストールするということで、まずは pip をインストールする。
wget https://bootstrap.pypa.io/get-pip.py
get-pip.py が取得できた。
DnnWeaver_10_170516.png

スーパーユーザー・モードで get-pip.py を起動した。
sudo python get-pip.py
DnnWeaver_11_170516.png

six モジュールをインストールする。
sudo pipinstall six
DnnWeaver_12_170516.png

make すると、今度は、descripter_pb2.py が足りないらしい。
DnnWeaver_13_170517.png

descripter_pb2.py はどうやってゲットするのか?調べていたら、「Why do I see “cannot import name descriptor_pb2” error when using Google Protocol Buffers?」がヒット。それによると、descripter_pb2.py はコンパイルして生成するものらしい?
(注:このWebサイトには、protobuf をインストールするように書いてあったが、インストールしないでやっている。結局うまく行っていないので、インストールしてみようと思う)

続きます。
  1. 2017年05月18日 05:38 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

「ゼロから作る Deep Learning」をやってみる8(8章 ディープラーニング)

引き続き、オライリーの本「ゼロから作る Deep Learning」をやってみよう。コードはオライリー・ジャパンのoreilly-japan/deep-learning-from-scratch にあって、MITライセンスなので、これをjupyter notebook ででやりながらやってみることにした。この本はとっても良い本なので、購入されて勉強することをお勧めする。

今回は、ディープラーニングについて学習する。この辺りになると、論文の紹介が多くなる。概要が見れてうれしい。
演習は畳み込みニューラルネットワーク2層、プーリング1層、畳み込みニューラルネットワーク2層、プーリング1層、畳み込みニューラルネットワーク2層、プーリング1層、全結合1層、ドロップアウト1層、全結合1層、ドロップアウト1層の合計13層のディープラーニング・ニューラルネットワークをdeep_convert.py で実装している。それを train_deepet.py で訓練すると、99.39 |% の正確さでMnist の数字を認識できた。
最後には、64ビット長の浮動小数点数を使ったときと、16 ビット長の浮動小数点数を使ったときの認識精度は変化が無かった。(half_float_network.py)

DLNN_106_170517.png
DLNN_107_170517.png
DLNN_108_170517.png
DLNN_109_170517.png
DLNN_110_170517.png
DLNN_111_170517.png
DLNN_112_170517.png
DLNN_113_170517.png
  1. 2017年05月17日 04:01 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

「ゼロから作る Deep Learning」をやってみる7(7章 畳み込みニューラル ネットワーク)

引き続き、オライリーの本「ゼロから作る Deep Learning」をやってみよう。コードはオライリー・ジャパンのoreilly-japan/deep-learning-from-scratch にあって、MITライセンスなので、これをjupyter notebook ででやりながらやってみることにした。この本はとっても良い本なので、購入されて勉強することをお勧めする。

今回は畳み込みニューラルネットワーク をやってみた。説明は分かりやすかった。
Convolution レイヤやPooling レイヤの実装を学習したが、いまいち頭に入っていないので、あとでもう一度、やってみることにする。
今までの全結合ニューラルネットワークと同様にPython で書けるのは素晴らしい。
畳み込みニューラルネットワークでMnist を学習したときのテストデータの正確さは 98.76 % だった。

DLNN_96_170516.png
DLNN_97_170516.png
DLNN_98_170516.png
DLNN_99_170516.png
DLNN_100_170516.png
DLNN_101_170516.png
DLNN_102_170516.png
DLNN_103_170516.png
DLNN_104_170516.png
DLNN_105_170516.png
  1. 2017年05月16日 04:50 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

「ゼロから作る Deep Learning」をやってみる6(6章 学習に関するテクニック)

引き続き、オライリーの本「ゼロから作る Deep Learning」をやってみよう。コードはオライリー・ジャパンのoreilly-japan/deep-learning-from-scratch にあって、MITライセンスなので、これをjupyter notebook ででやりながらやってみることにした。この本はとっても良い本なので、購入されて勉強することをお勧めする。

今回は学習に関するテクニックを学習した。
パラメータの更新方法で、SGD, Momentum, AdaGrad, Adm を学習した。重みの初期値についてや、Batch Nomalization。
正則化では、過学習に陥る条件やその解消方法としてWeight decay, Dropout を学習した。またハイパーパラメータの最適化について学習した。すべて実際のコードを見て、結果も見られるのが良いと思う。
なお、結果が長い場合は、途中を省略している。

DLNN_55_170514.png
DLNN_56_170514.png
DLNN_57_170514.png
DLNN_58_170514.png
DLNN_59_170514.png
DLNN_60_170514.png
DLNN_61_170514.png
DLNN_62_170514.png
DLNN_63_170514.png
DLNN_64_170514.png
DLNN_65_170514.png
DLNN_66_170514.png
DLNN_67_170514.png
DLNN_68_170514.png
DLNN_69_170514.png
DLNN_70_170514.png
DLNN_71_170514.png
DLNN_72_170514.png
DLNN_73_170514.png
DLNN_74_170514.png
DLNN_75_170514.png
DLNN_76_170514.png
DLNN_77_170514.png
DLNN_78_170514.png
DLNN_79_170514.png
DLNN_80_170514.png
DLNN_81_170514.png
DLNN_82_170514.png
DLNN_83_170514.png
DLNN_84_170514.png
DLNN_85_170514.png
DLNN_86_170514.png
DLNN_87_170514.png
DLNN_88_170514.png
DLNN_89_170514.png
DLNN_90_170514.png
DLNN_91_170514.png
DLNN_92_170514.png
DLNN_93_170514.png
DLNN_94_170514.png
DLNN_95_170514.png
  1. 2017年05月14日 05:40 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

「ゼロから作る Deep Learning」をやってみる5(5章 誤差逆伝播法)

引き続き、オライリーの本「ゼロから作る Deep Learning」をやってみよう。コードはオライリー・ジャパンのoreilly-japan/deep-learning-from-scratch にあって、MITライセンスなので、これをjupyter notebook ででやりながらやってみることにした。この本はとっても良い本なので、購入されて勉強することをお勧めする。

今回は誤差逆伝播法だ。4 章では、数値微分で重みの学習を行ったが、この章では、誤差逆伝播法でニューラルネットワークの学習を行っている。数値微分法の方が誤差逆伝播法よりも約2万倍遅いという結果が出た。衝撃的だった。その位の差があるようだ。。。

DLNN_42_170513.png
DLNN_43_170513.png
DLNN_44_170513.png
DLNN_45_170513.png
DLNN_46_170513.png
DLNN_47_170513.png
DLNN_48_170513.png
DLNN_49_170513.png
DLNN_50_170513.png
DLNN_51_170513.png
DLNN_52_170513.png
DLNN_53_170513.png
DLNN_54_170513.png
  1. 2017年05月13日 04:26 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

「ゼロから作る Deep Learning」をやってみる4(4章 ニューラルネットワークの学習)

引き続き、オライリーの本「ゼロから作る Deep Learning」をやってみよう。コードはオライリー・ジャパンのoreilly-japan/deep-learning-from-scratch にあって、MITライセンスなので、これをjupyter notebook ででやりながらやってみることにした。この本はとっても良い本なので、購入されて勉強することをお勧めする。

今度はニューラルネットワークの学習だ。
ここでは、誤差逆伝播法を使ってなくて、すべての層の重みに関する損失関数の偏微分を行って傾きを求めて損失関数が小さくなる方向に重みを更新しているようだ。これでも求められるが計算時間がかかるという欠点があるようだ。
DLNN_24_170511.png
DLNN_25_170511.png
DLNN_26_170511.png
DLNN_27_170511.png
DLNN_40_170511.png
DLNN_28_170511.png
DLNN_29_170511.png
DLNN_30_170511.png
DLNN_31_170511.png
DLNN_32_170511.png
DLNN_33_170511.png
DLNN_34_170511.png
DLNN_35_170511.png
DLNN_36_170511.png
DLNN_37_170511.png
DLNN_38_170511.png
DLNN_39_170511.png
DLNN_41_170511.png
  1. 2017年05月11日 05:35 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

「ゼロから作る Deep Learning」をやってみる3(3章 ニューラルネットワーク)

引き続き、オライリーの本「ゼロから作る Deep Learning」をやってみよう。コードはオライリー・ジャパンのoreilly-japan/deep-learning-from-scratch にあって、MITライセンスなので、これをjupyter notebook ででやりながらやってみることにした。この本はとっても良い本なので、購入されて勉強することをお勧めする。

いよいよ3章のニューラルネットワークをやってみる。この章ではニューラルネットワークの推論を簡単なコードで実行することがで来ている。Python って for が要らないことが多いので、コードも短い。
最初に活性化関数のステップ関数、シグモイド関数、ReLU関数をやってみた。
多元配列の練習をしてから、softmax関数を試してた。
その後、MNISTデータセットを使った3層ニューラルネットワークを実装した。
最後に、MNISTデータセットを使った3層ニューラルネットワークのバッチ処理を実装した。
DLNN_8_170509.png
DLNN_9_170509.png
DLNN_10_170509.png
DLNN_23_170509.png
DLNN_11_170509.png
DLNN_12_170509.png
DLNN_13_170509.png
DLNN_14_170509.png
DLNN_15_170509.png
DLNN_16_170509.png
DLNN_17_170509.png
DLNN_18_170509.png
DLNN_19_170509.png
DLNN_20_170509.png
DLNN_21_170509.png
DLNN_22_170509.png
  1. 2017年05月09日 05:03 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

「ゼロから作る Deep Learning」をやってみる2(パーセプトロンでゲートを作る)

引き続き、オライリーの本「ゼロから作る Deep Learning」をやってみよう。コードはオライリー・ジャパンのoreilly-japan/deep-learning-from-scratch にあって、MITライセンスなので、これをjupyter notebook ででやりながらやってみることにした。この本はとっても良い本なので、購入されて勉強することをお勧めする。

今日は、2章のパーセプトロンだ。ゲートをパーセプトロンで作っている。AND、NAND、OR
XOR は閾値が線形だと表せないので、パーセプトロンをつないで作っている。
DLNN_5_170508.png
DLNN_6_170508.png
DLNN_7_170508.png
  1. 2017年05月08日 04:46 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

「ゼロから作る Deep Learning」をやってみる1(Numpyと matplotlib の使い方)

「PYNQ祭り」延長戦 : FPGAディープラーニング実践懇親会」に参加するためにDeep Learning Nerual Network (DLNN) を勉強することにした。
勉強するために「ゼロから作る Deep Learning」の本をやってみることにしたのだが、老眼で本を読むのがつらいので、オライリーの「ゼロから作る Deep Learning」のPDFを購入して、それを見ながらやってみることにした。
コードはオライリー・ジャパンのoreilly-japan/deep-learning-from-scratch にあって、MITライセンスなので、これをjupyter notebook ででやりながらやってみることにした。この本はとっても良い本なので、購入されて勉強することをお勧めする。

最初に第1章からやってみる。Python は大体わかっていたので、Numpyと matplotlib の使い方を学習した。
売り物の本の内容なので、jupyter notebook を貼るだけにする。ちなみにjupyter notebook は本の通りにAnacondaをインストールして、そこから起動している。
DLNN_1_170507.png
DLNN_2_170507.png
DLNN_3_170507.png
DLNN_4_170507.png
  1. 2017年05月07日 04:32 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

Vivado HLSで stdint.h を使用する

FPGAマガジンNo16 のAXI4 Master のソースコードと、FPGAマガジン No.17 のAXI4-Stream のソースコードを公開しているが、taksei さんから「ソースコードを64bit Linux版VivadoでC-Sim実行してみたのですが、long型が8バイトとして確保されるため、BMPファイルのリード・ライトに失敗するようです。」との報告があった。long型で4バイトのところ、8バイトになっていたようだ。
そこで、taksei さんに教えて頂いたように、stdint.h を使用して、uintX_t や intX_t を使用することにした。taksei さん、ありがとうございました。

私もVirtualBox 上に64ビット版のUbuntu 16.04 をインストールしてあって、その上にVivado 2016.4 をインストールしてある。よって、それ上のVivado HLS 2016.4 で確かめてみよう。

まずは、64ビット版Ubuntu 16.04 の Vivado HLS 2016.4 を起動した。
まずは、以前のままの bitmap_header.h でやってみよう。
stdint_1_170505.png

これで C シミュレーションを行った。
stdint_2_170505.png

”Can't allocate rd_bmp memory”エラーになってしまった。
taksei さんによると、”stdint.h” を使えば良いらしい。
”stdint.h”は、少なくとも 8, 16, 32, 64 ビット長の intN_t, uintN_t という型を宣言してるようだ。つまり、ビット長が明確に定義されている。
これを使用して、BMPのフォーマットに関しての資料を参考に、 intN_t, uintN_t で bitmap_header.h を書き直してみよう。実際には、taksei さんのコードを検証しながら、コピー&ペーストを行った。
更に、lap_filter_tb.c にもBMPのフォーマットがあるので、それも同様に、 intN_t, uintN_t に修正した。
stdint_3_170505.png

stdint_4_170505.png

修正後に C シミュレーションを行ったところ、今度は成功した。
stdint_5_170505.png

C コードの合成結果を示す。Windows 10 での結果と同じレイテンシだった。
stdint_6_170505.png

C/RTL協調シミュレーション結果を示す。これも、Windows 10 での結果と同じだった。
stdint_7_170505.png

lap_filter0_axim/solution1/sim/wrap_pc ディレクトリを見ると、test_lap.bmp が出来て、正常にラプラシアンフィルタ処理が行われているのが分かる。
stdint_8_170505.png

Export RTL も正常に行うことができた。
stdint_9_170505.png

更新した bmp_header.h, lap_filter_tb.c を Windows 10 のVivado HLS 2017.1 に持って行っても正常にシミュレーション、合成を行うことができた。
stdint_10_170505.png

OS によって、int, long の型のビット長は変化するので、ビット長が決まっている変数を宣言する場合は、stdint.h の intN_t, uintN_t を使用して書いたほうが良い。

(2017/07/24: 追記)
新しい bmp_header.h を貼っておきます。

// bmp_header.h
// BMP ファイルフォーマットから引用させて頂きました
// http://www.kk.iij4u.or.jp/~kondo/bmp/
//
// 2017/05/04 : takseiさんのご指摘によりintX_tを使った宣言に変更。takseiさんありがとうございました
//              変数の型のサイズの違いによってLinuxの64ビット版では動作しなかったためです
//              http://marsee101.blog19.fc2.com/blog-entry-3354.html#comment2808
//

#include <stdio.h>
#include <stdint.h>

// BITMAPFILEHEADER 14bytes
typedef struct tagBITMAPFILEHEADER {
    uint16_t bfType; 
    uint32_t bfSize; 
    uint16_t bfReserved1; 
    uint16_t bfReserved2; 
    uint32_t bfOffBits;
} BITMAPFILEHEADER;

// BITMAPINFOHEADER 40bytes
typedef struct tagBITMAPINFOHEADER{
    uint32_t biSize; 
    int32_t biWidth; 
    int32_t biHeight; 
    uint16_t biPlanes; 
    uint16_t biBitCount; 
    uint32_t biCompression; 
    uint32_t biSizeImage; 
    int32_t biXPixPerMeter; 
    int32_t biYPixPerMeter; 
    uint32_t biClrUsed; 
    uint32_t biClrImporant;
} BITMAPINFOHEADER;

typedef struct BMP24bitsFORMAT {
    unsigned char blue;
    unsigned char green;
    unsigned char red;
} BMP24FORMAT;

  1. 2017年05月05日 16:25 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

「美女と野獣」(映画)を見ました

美女と野獣」(映画)を奥さんと見てきました。
アニメは子供たちのお供で何度も見ていたので、歌や映像に見覚えがあって懐かしかったです。
なかなか良かったです。女性受けすると思います。エマ・ワトソンは綺麗で素敵でしたね。
  1. 2017年05月03日 20:14 |
  2. 日記
  3. | トラックバック:0
  4. | コメント:0

Vivado 2017.1 の新機能8(Zynq-7000 VIP)

今回は、Zynq-7000 VIP について書いてみようと思う。

Vivado 2017.1 からZynq-7000 VIP のライセンスが無料になって、Zynq のPS 込みでシミュレーションできるようになったようだ。(Vivado 2016.4 でPS 込みのシミュレーションをしたところ、AXI BFM のライセンスエラーになってしまった)

Zynq-7000 VIP の資料で見つかったのは唯一”AR# 69031 Zynq-7000 All Programmable SoC VIP - リリース ノートおよび既知の問題”だった。
それによると、「Zynq-7000 All Programmable SoC VIP は Processing System7 IP からのみアクセスできます。」だそうだ。

サンプル・デザインで、Zynq-7000 VIP が試せるという情報があったので、File メニューから Open Examples Project... を選択して、サンプル・プロジェクトを作成した。サンプル・プロジェクトのテンプレートは、Base Zynq を選択した。
Vivado_2017-1_68_170501.png

Base Zynq プロジェクトが開いたところだ。
Vivado_2017-1_62_170501.png

ブロックデザインを示す。
Vivado_2017-1_63_170501.png

Address Editor の画面を示す。
Vivado_2017-1_64_170501.png

Flow Navigator のSIMULATION -> Run Simulation -> Run Behavioral Simulation を選択して、シミュレーションを行った。
Vivado_2017-1_65_170501.png

シミュレーションの波形が示された後に、”run all”を行ったときのVivado画面を示す。
Vivado_2017-1_69_170501.png

AXI VIP Test PASSED が表示された。

まずは、シミュレーションの階層を示す。
Vivado_2017-1_70_170501.png

シミュレーション用のテストベンチ・ファイルのzynq_tb.v にPS からPL へのアクセス方法が書いてあった。zynq_tb.v の一部を画像で引用する。
Vivado_2017-1_71_170501.png

tb.zynq_sys.base_zynq_i.processing_system7_0.inst.write_data(32'h40000000,4, 32'hDEADBEEF, resp);

で0x40000000 番地に 0xDEADBEEF を書いて、

tb.zynq_sys.base_zynq_i.processing_system7_0.inst.read_data(32'h40000000,4,read_data,resp);

で 0x40000000 番地のデータを read_data に読んでくることができる。階層はシミュレーション階層の図の通りだ。
その前にLED を点灯するために 0x41200000 に 0xFFFFFFFF を書いている。

さて、シミュレーション波形を見てみよう。全体の波形は省略するが、Read /Write する場面の波形を示す。
Vivado_2017-1_66_170501.png

0x41200000 に 0xFFFFFFFF を書いているのが分かると思う。その後のトランザクションはよく見えないので、もう少し拡大してみよう。
Vivado_2017-1_67_170501.png

上の波形を見ると、0x40000000 番地に 0xdeadbeef を書いて、0x40000000 を読むと 0xdeadbeef なのが分かる。

これで、PS のままのプロジェクトでもシミュレーションを行うことができた。これは便利だ。今まで、わざわざシミュレーション用にAXI4-Lite のMaster モジュールを付けた専用のプロジェクトを作る必要が無くなった。
  1. 2017年05月02日 04:23 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0

Vivado 2017.1 の新機能7(AXI Verification IPの使い方の覚書3)

Vivado 2017.1 の新機能6(AXI Verification IPの使い方の覚書2)”の続き。

前回、AXI Verification IPのWrite トランザクションについて記事を書いたが、どうしてもWVALID をディアサートする方法が分からなかった。本当はランダムにできれば良かったのだが、WVALID を変化させる方法が分かったので、覚書を書いておく。

AXI Verification IP v1.0 LogiCORE IP Product Guide Vivado Design Suite PG267 April 5, 2017”の60 ページの”Figure C-2: Write Command and Data Flow”の一部を引用する。
Vivado_2017-1_59_170501.png

ここでピンクの四角で囲ってある”Data Inter-Beat Delay (Transaction)”がWVILD に当たることができるDelay のようだ。
ここで、”AR# 68234 AXI Verification IP - AXI VIP のリリース ノートおよび既知の問題”のXILINX_AXI_VIP_2017_1.zip を展開した資料を見てみる。
Vivado_2017-1_60_170501.png

上の図でもわかるように set_beat_delay() があった。これを使用してみたが、updated の設定の仕方が分からない。
set_beat_delay() を使って、2番目のWrite トランザクションのバースト転送の2番目、4番目、6番目を遅らせてみた。2番目のWrite トランザクションのSystemVerilog のコードを示す。

  task wr_tran_method_two();
    axi_transaction              wr_transaction;     //Declare an object handle of write transaction
    xil_axi_uint                 mtestID;            // Declare ID  
    xil_axi_ulong                mtestADDR;          // Declare ADDR  
    xil_axi_len_t                mtestBurstLength;   // Declare Burst Length   
    xil_axi_size_t               mtestDataSize;      // Declare SIZE  
    xil_axi_burst_t              mtestBurstType;     // Declare Burst Type  
    xil_axi_data_beat [255:0]    mtestWUSER;         // Declare Wuser  
    xil_axi_data_beat            mtestAWUSER;        // Declare Awuser  
    /***********************************************************************************************
    * A burst can not cross 4KB address boundry for AXI4
    * Maximum data bits = 4*1024*8 =32768
    * Write Data Value for WRITE_BURST transaction
    * Read Data Value for READ_BURST transaction
    ***********************************************************************************************/
    bit [32767:0]                 mtestWData;         // Declare Write Data 

    mtestID = 0;
    mtestADDR = 'h100;
    mtestBurstLength = 15;
    mtestDataSize = xil_axi_size_t'(xil_clog2(32/8));
    mtestBurstType = XIL_AXI_BURST_TYPE_INCR; 
    wr_transaction = agent.wr_driver.create_transaction("write transaction in API");
    WR_TRANSACTION_FAIL: assert(wr_transaction.randomize());
    wr_transaction.set_write_cmd(mtestADDR,mtestBurstType,mtestID,mtestBurstLength,mtestDataSize);
    mtestWData[31:0] = 32'h12345678; 
    mtestWData[63:32] = 32'h9abcdef0;
    wr_transaction.set_data_block(mtestWData);
    wr_transaction.set_beat_delay(2,8);
    wr_transaction.set_beat_delay(4,8);
    wr_transaction.set_beat_delay(6,8);
    agent.wr_driver.send(wr_transaction);
  endtask :wr_tran_method_two


ここで、

    wr_transaction.set_beat_delay(2,8);
    wr_transaction.set_beat_delay(4,8);
    wr_transaction.set_beat_delay(6,8);

が今回書き加えた部分だ。
このシミュレーション波形を示す。
Vivado_2017-1_61_170501.png

2番目のWrite トランザクションでWVALID がトグルしているのが分かるが、同じ updated の値にしたのに、それぞれのWVALID がディアサートされている間隔が違っているのはなぜだかわからない?
2番目のWVALID のディレイの長さは 40 ns 、4番目のWVALID のディレイの長さは120 ns 、6番目のWVALID のディレイの長さは140 ns だった。
  1. 2017年05月01日 05:01 |
  2. Vivado
  3. | トラックバック:0
  4. | コメント:0