アプリとサービスのすすめ

アプリやIT系のサービスを中心に書いていきます。たまに副業やビジネス関係の情報なども気ままにつづります

強化学習で三目並べ版の「AlphaZero」を作ったのでその仕組みまとめ【機械学習】

DeepMindが作った世界最強のゲームAIに使われているアルゴリズムが「AlphaZero」の仕組みを利用して、今回は「三目並べ」というゲーム版のAlphaZeroを作ってみた。

今回は備忘録として「三目並べ版-AlphaZero」の仕組みを淡々とまとめていく。


目次
1.AlphaZeroの仕組み
2.「三目並べ」の環境
3.AlphaZeroで使うニューラルネットワーク
4.自己対戦(Self-Playing)部分
5.パラメータ更新部分
6.パラメータ評価部分
7.パフォーマンス


1.AlphaZeroの仕組み


1.はじめに「best player」(いわゆるAgent)を作る

2.戦略と価値を更新するニューララネットワーク(Dual NN)でモンテカルロ法を使いながら自己対戦を繰り返して、学習データを貯めていく

3.その学習データをもとに「latest player」という、この時点で最強のpalyerをもう一つ作る。

4.「best player」と「latest player」を対戦させ、より強い方を「best player」として採用し、また自己対戦をさせる~

5.2〜4を繰り返す


というサイクルを繰り返して強くなっていく。

f:id:trafalbad:20200408173249j:plain


三目並べは単純なのでGPUが1つでも半日もあれば、十分に強くなる。





2.「三目並べ」の環境

ここでは三目並べ用の環境(Environment)を定義するコードが必要で適宜関数とかクラスを用意する。


「三目並べ」というゲームの詳細な説明は参考サイトを参照。
いわば。超simpleな簡易版の対戦ゲーム。






3.AlphaZeroで使うニューラルネットワーク

AlphaZeroで使うニューラルネットワーク(Dual NN)は

入力:「相手と自分の状態(S)」

出力戦略(Policy)と価値(Value)

の出入力構成で「戦略と価値」の2つ出力するDual NN。

まずDual NNを動かして一番はじめの「best player」を作る。

optimizerはDeepmind本家のはSGDだけど、今回はスピード重視なのでAdamにした。

def dual_network():
 # if trained model, nothing to do
 if os.path.exists('./model/best.h5'):
     return

 input = Input(shape=DN_INPUT_SHAPE)
 x = conv(DN_FILTERS)(input)
 x = BatchNormalization()(x)
 x = Activation('relu')(x)

 # resblock x 19
 for i in range(DN_RESIDUAL_NUM):
     x = residual_block()(x)

 x = GlobalAveragePooling2D()(x)
 p = Dense(DN_OUTPUT_SIZE, kernel_regularizer=l2(0.0005),
             activation='softmax', name='pi')(x)

 v = Dense(1, kernel_regularizer=l2(0.0005))(x)
 v = Activation('tanh', name='v')(v)
 model = Model(inputs=input, outputs=[p,v])


4.自己対戦(Self-Playing)部分

best player(Dual NN)同士を戦わせて互いに腕を上げていく部分。GANの仕組みとほぼ同じ。

戦わせながら1 playごとに学習データに

・相手と自分の盤上の駒の状態:累積s(累積状態)

・1 playの戦略のscore:policy score

・1 playの価値の合計:累積v(累積価値)

の3つをlist形式で貯めていく。


f:id:trafalbad:20200408174339j:plain


SELFPLAY_GAME_COUNT = 500
def self_play():
 # train data list
 history = []

 # load best player
 model = load_model('./model/best.h5')

 # multi play
 for i in range(SELFPLAY_GAME_COUNT):
     # 1 play
     h = one_episode_play(model)
     history.extend(h)

     print('\rSelfPlay {}/{}'.format(i+1, SELFPLAY_GAME_COUNT), end='')
 print('')

 # save train data
 save_state_policy_value(history)

 K.clear_session()
 del model



5.パラメータ更新部分

自己対戦(Self-Playing)で貯めた学習データを使って、Dual NNを学習。

・説明変数が「状態s」

・ターゲット変数が「戦略(p)」と「価値(s)」

def create_latest_player():
 def train_dual_network():
     # load train data
     xs, y_policies, y_values = load_policy_value()

     # load best player
     model = load_model(best_weight)
 
     model.compile(loss=['categorical_crossentropy', 'mse'], optimizer='adam')

     lr_decay, print_callback = call_back()


     # train
     model.fit(xs, [y_policies, y_values], batch_size=128, epochs=RN_EPOCHS,
             verbose=0, callbacks=[lr_decay, print_callback])
     print('')

     # save latest player
     model.save('./model/latest.h5')

     # delete model 
     K.clear_session()
     del model
 return train_dual_network


最後に「latest player」として学習済みモデルを保存する。
「latest player」は500戦した学習データをもとに、報酬(勝率)が最大になるように作り上げた一番強いplayer。

これではじめの「best player」と「latest player」という2人のplayer(正確にはAgent)ができた。






6.パラメータ評価部分

「best player」と「latest player」を10回戦わせて、一番強いplayerを新たな「best player」として採用し、弱い方は捨てる。

def total_episode_play():
 # load latest player
 model0 = load_model('./model/latest.h5')

 # load best layer 
 model1 = load_model('./model/best.h5')

 # select action by PV MCTS
 next_action0 = select_action_by_pv_mcts(model0, BOLTZMAN_TEMP)
 next_action1 = select_action_by_pv_mcts(model1, BOLTZMAN_TEMP)
 next_actions = (next_action0, next_action1)

 # multi play
 total_point = 0
 for i in range(GAME_COUNT):
     # 1 play
     if i % 2 == 0:
         total_point += one_episode_play(next_actions)
     else:
         total_point += 1 - one_episode_play(list(reversed(next_actions)))

     print('\rEvaluate for update player {}/{}'.format(i + 1, GAME_COUNT), end='')
 print('')

 # caluculate average point
 average_point = total_point / GAME_COUNT
 print('AveragePoint', average_point)

 # delete models
 K.clear_session()
 del model0
 del model1

 if average_point > 0.5:
     print('change best player')
     update_best_player()
     return True
 else:
     return False

これでまた始めに戻り、自己対戦(Self-Playing)~パラメータ評価を繰り返してplayerの強さを上げていく。





7.パフォーマンス

以下がAlphaZeroのサイクルを回してplayerを強くしていくアルゴリズムのコード。

途中の「新パラメータ評価部」で、別のアルゴリズムと対戦させて、best playerを評価(強さを確かめてる)してる。

train_network = create_latest_player()

# create dual NN
dual_network()

for i in range(10):
 print('Train',i,'====================')
 # セルフプレイ部
 self_play()

 # パラメータ更新部
 train_network()

 # 新パラメータ評価部
 update_best_player = total_episode_play()

 # ベストプレイヤーの評価
 if update_best_player:
     evaluate_best_player()

>>>>>

Train 0 ====================
SelfPlay 500/500
Train 100/100
Evaluate for update player 10/10
AveragePoint 0.95
Change BestPlayer

Evaluate 10/10
VS_Random 1.0
VS_AlphaBeta 0.25
VS_MCTS 0.5
<略>
Train 10 ====================
SelfPlay 500/500
Train 100/100
Evaluate for update player 10/10
AveragePoint 0.95
Change BestPlayer

Evaluate 10/10
VS_Random 1.0
VS_AlphaBeta 0.55
VS_MCTS 0.6


三目並べでほぼ最強のアルゴリズム「alpha-beta法」に互角以上の成績を叩き出した。




AlphaZeroはかなり汎用性がある、対戦用のメカニズムになっているなと感じた。

ハイエンド脳無もこんな感じで作れたらなとか思う今日この頃。

f:id:trafalbad:20200408173342j:plain

Vitis IDEでultra96向けplatform作成と、ultra96v2で動作確認するまで【avnet,hardware】VitisPlatform作りpart4

今回は

Vitisプラットフォーム(Vitis IDE)でultra96向けプラットフォームを作成

ultra96v2で実際に動作確認する

ところまでやってみたいと思う。

本家サイトのラストの部分まで。


今回のpart4でこの部分ができる。
f:id:trafalbad:20200404110016p:plain


目次
1.ultra96向けプラットフォームの作成
2.テストアプリケーションの作成
3.ultra96v2のSDカードにコピー
4.wifiを接続後にultra96v2で動作確認
5.次にやりたいこと




1.ultra96向けプラットフォームの作成

# vitis起動
cd /home/[user]/ultra96base/pfm
vitis -workspace wksp1


  • [Create platform project]からプラッフォフォーム作成

  • プラッフォフォーム名(今回は[ultra96base])を入力。
    f:id:trafalbad:20200404110625p:plain


    XSAファイルから作成するので、[Create from hardware specification (XSA)] => [Next]


  • Vivadoで作成した、XSAファイルを指定
  • Operating system は Linux

    Processorpsu_cortexa53

    足りないファイルは追加していくので、ビックリマークは赤いままでOK、[Finish]をクリック。
    f:id:trafalbad:20200404111101j:plain


    ファイル一覧に

    linux

    ・zynqmp_fsbl

    ・zynqmp_pmufw

    があることを確認。



  • [linux on psu_cortexa53]を選択
  • Bifファイルは 「linux.bif」

    Boot ComponentDirectoryは「bootディレクトリー」

    Linux imageのDirectoryは 「bootディレクトリー」

    Sysrootディレクトリーには、「sysroots/aarch64-xilinx-linux

    をそれぞれ指定。
    f:id:trafalbad:20200404110822j:plain





  • 下図のトンカチアイコンをクリックして、ビルド

  • インデックスファイルを作っているらしく、時間がかかる。


    少し待つとビルドがおわり、コンソールに[Bulid Finished]が表示される。
    f:id:trafalbad:20200404110738j:plain

    exportフォルダーにプラットフォームのデータ[ultra96base.xpfm]が作成されてる。

    # 確認
    $ ls /home/[host-name]/ultra96base/pfm/wksp1/ultra96base/export/ultra96base
    hw  sw  ultra96base.xpfm
    


    これでultra96向けのプラットフォームができた。






    2.テストアプリケーションの作成

    ultra96v2用のファイルを作成してく。

  • Vitis IDEのメニューから File→New→Application Projectを選択して、
    プロジェクトネーム(今回は「alternative_xsa」)を適当に入れて[Next]をクリック
  • f:id:trafalbad:20200404110554j:plain



    プラットフォームを選択できるので、[ultra96base]を選択して、Nextをクリック。
    f:id:trafalbad:20200404111209p:plain



  • 次はsysroot等を聞いてくるので、デフォルトで[Next]
  • その後、ultra96v2で試す用のExampleファイルを作成。

    今回は[Hello World]しかないので、Exampleとして取り込んでダウンロード。


  • 上のトンカチアイコンから、ハードウェアの[Debug]を選択してビルド

  • ビルド後、SDcardのハードウェアフォルダ(Debug)の中に必要なファイルが作成される。

    # Debugフォルダが出来てるか確認
    $ ls
    Debug  _ide  alternative_xsa.prj  src
    





    3.ultra96v2のSDカードにコピー

    ここでVitis IDEの操作は終わり。


    後はultra96v2のSDカードにコピーしていく。
    ultra96v2付属のSDカード
    f:id:trafalbad:20200404110110j:plain



    マウントフォルダのパス

    ・ホストOS側「Volumes/BUFFALO/mount」

    ・ゲストOS側「/media/sf_mount」


    Debugファルダ内のファイルを外付けHDDのマウントファルダ(Volumes/BUFFALO/mount)にコピーする。
    それからGUIでultra96v2のSDカードのFAT領域(/Volumes/boot/boot)に移動。

    # 外吹けHDDマウントフォルダにbootファルダを作成
    $ sudo mkdir /media/sf_mount/boot
    
    # マウントフォルダにコピー
    $ sudo cp -r /home/[host-name]/ultra96base/pfm/wksp1/alternative_xsa/Debug/* /media/sf_mount/boot
    

    コピーした後、GUIでSDカード内に移動。




    次に、Petalinuxで作ったrootfs.tar.gzをSDカードのEXTフォルダー(/Volumes/boot/rootfs)に入れる。
    その後、GUIでultra96v2のSDカードのEXTフォルダー(/Volumes/boot/rootfs)に移動。

    # マウントフォルダにrootfsファルダを作成
    $ sudo mkdir /media/sf_mount/rootfs
    
    # Petalinuxで作ったrootfs.tar.gzをrootfsファルダにコピー
    $ sudo cp /home/[host-name]/ultra96base/petalinux/images/linux/rootfs.tar.gz /media/sf_mount/rootfs/
    
    # ホストOS側で解凍してSDカードのEXTフォルダーにコピー
    $ sudo tar xzvf /Volumes/BUFFALO/mount/rootfs.tar.gz -C /Volumes/boot/rootfs
    

    同じくコピーした後、GUIでSDカード内に移動






    4.wifiを接続後にultra96v2で動作確認

    ultra96v2で動作確認のため、まずPCと


    ultra96v2を接続
    f:id:trafalbad:20200404110133j:plain

    ultra96v2の接続・ログイン記事はこちらを参照
    trafalbad.hatenadiary.jp



    # sshでログイン
    $ ssh -l root 192.168.2.1
    $ cd /run/media/mmcblk0p1 && export XILINX_XRT=/usr
    $ cd boot 
    
    # 動作確認
    $ ./alternative_xsa.elf vadd.xclbin
    >>>
    Hello World
    

    f:id:trafalbad:20200404110259p:plain


    動作してるのが確認できた!





    5.次にやりたいこと

    part1~4でultra96v2の動作の全体像のこの領域ができた。
    f:id:trafalbad:20200404110044p:plain




    次は

    ・実際にultra96v2で学習済みAIを動かす(Vitis AIの作成とか)

    ・リアルに論理回路をいじったりするガチなところまで触れる

    PYNQの構築

    とかもっとガチのAI部分まで触れてみたい。その前にこの低スペックPCを買い換えなきゃな。


    f:id:trafalbad:20200404111717j:plain



    追記:メモ


    一回作ったプロジェクトまたは、bspファイルから作成したプロジェクトで、回路デザインのプログラマロジック(PL)回路を変更する際の、変更手順を簡単にまとめ。



    プログラマロジックの回路変更手順

    1.vivadoでPL回路変更
    2.BitStream生成
    3.Export Hardware
    4.petalinux-config
    5.petalinux-build
    6.petalinux-package


    f:id:trafalbad:20200407104154j:plain


    参考サイト回路情報のエクスポート




    参考サイト



    How to create Ultra96v2 Linux-based Platform in Xilinx Vitis 2019.2

    ultra96v2の動作に必要な「BIFファイル」作成、vitis IDEの立ち上げまで【FPGA】- VitisPlatform作りpart3

    前回の続編のpart3。Vivadoでultra96のデザインブロックとかXSAファイルを作成した後、PetaLinuxでVitisプラットフォーム(vitis IDE)立ち上げまでやっていく。

    part3の作業で完了するのは「vitis IDE」構築のvitisの部分。
    f:id:trafalbad:20200314065320p:plain



    メインでにやること

    ・ultra96の動作に必要な「BIFファイル」の作成

    ・vitis IDEの立ち上げ


    手順はほぼ本家のサイト「Ultra96用Vitisプラットフォームの作り方(BASE編)」通り作業していく。



    ただVivadoで作成するXSAファイルは本家サイト通りやってもエラーが出て作成できなかったので、Xilinxgithubのファイルで代用した。
    Alternative XSA file at GitHub


    目次
    1.Vivadoでのハードウェア設計
    2.PetalinuxでLinuxシステムの設計
    3.Vitis IDEを立ち上げてみる





    1.Vivadoでのハードウェア設計

    Vivadoでultra96v2で動作させるハードウェアを設計。
    今回は参考サイトのだと何故かうまくいかないので、Xilinxgithubから代用のXSAファイルを使う。

    一応、ultra96で使うまでのハードウェア設計の手順だけまとめていく。ここはほぼ本家と同じ



    1.新規プロジェクトと新規ブロックデザインの作成



  • 「Create Project」からProject作成
  • ・Project name:ultra96base
    ・Project location: /home/[host-name]/ultra96base
    ・Project type:RTL Project
    (「Do not specify sources at this time」のブロックにチェックを入れた)


  • [Add Sources]と[Add Constraints]ページはデフォルトのまま[next]ボタン。

  • 次のページで右の「Board」クリックから「Ultra96」をsearchで「Ultra96v2 Evaluation Platform」を選択 => next&finishでNew Project完成。

  • ***Project再開方法
    Open ProjectからProjectを作ったフォルダの[プロジェクト名.xpr]を選択し、再開。



  • 次にブッロクデザインの作成

  • 右の[Flow Navigator]でIP INTEGRATOR => Create Block Design => ブロックデザイン名を決める。
    デフォルでいいのでOKで作成。




    2.Blockの配置・配線



    デザインを作成すると、キャンパスが出てくるのでブロック追加・配線をする。ここは本家サイトと同じなので
    ・簡単な流れ
    ・エラーになる箇所のポイント
    をまとめた。


  • +のアイコンから[Add IP]でブロックを追加していく

  • [Search]からzynqを入力して[Zynq UltraScale+ MPSoC]を選択・配置して、[Run Block Automation]をクリックし、デフォルト値のままOK。
    f:id:trafalbad:20200403001151j:plain



  • ZYNQ7 Processing Systemをダブルクリックし、PS-PL Configuration -> AXI Non Secure Enablement -> GP Master AXI Interface -> M_AXI_GP0 interface のチェックを外し、OKをクリック
  • Clocking Wizardを追加し、その後同IPの設定のOutput Clocksタブより、clk_out2~Nまで追加して、適切なHzに変更(例:clk_out2を200Hz, clk_out3を300MHz)。 Reset TypeをActive Lowにする
  • Processor System ResetとConcatを配置
  • Concatは[Number of Port]を1にする。

  • 下図のように配線
    f:id:trafalbad:20200403001244p:plain





    配線実行例

  • 1.右クリックからの[Add IP]
  • 2.resetで検索してから[Processer System Reset]を選択
  • 3.上の丸アイコン押すと、ブロックがアップになる
  • 4.連結したい配線部分をクリック(オレンジに染まる)
  • 5.右クリックから[Make Connection]

  • f:id:trafalbad:20200403001341j:plain


  • 6.連結したい導線部分を選択しOKで配線完了



  • 完全に慣れなので一つずつ確実に配線してく。







    3.プラットフォーム(PFM)インターフェースとプロパティの定義



  • [Window]から[Platform Interface] => [Enable platform Interfaces]をクリックインターフェイス作成。
  • Board名を「ultra96v2」に変更
  • [Source]から必要なポートをダブルクリックで[Enable]で有効化
  • clk_out1 (100 MHz) をクリック後、[Platform Interface Properties] の中の Optionsのタブをクリックして、[is_default]を選択して、idを0に変更。(id変更したら必ずエンターキーをクリック)


  • ***ここ大事
    ・clk_outのidをclk_out1から順にidを0, 1, 2にする(clk_out2, 3はidを1, 2に変更)


    18- Select the enabled clk_out1 and in the Options window change the id to 0 and select the is_default. Note, to change the id filed you must press the Enter key on your keyboard. Change ids of clk_out2, clk_out3, and clk_out4 to 1, 2, and 3, respectively.

    引用元:How to create Ultra96v2 Linux-based Platform in Xilinx Vitis 2019.2



    4.XRT用の設定から[BitStream]まで



  • 下のほうにTclコンソールがあるので次コマンドを入力。1行ずつ入れてく
  • set_property platform.design_intent.embedded true [current_project]
    set_property platform.design_intent.server_managed false [current_project]
    set_property platform.design_intent.external_host false [current_project]
    set_property platform.design_intent.datacenter false [current_project]
    set_property platform.default_output_type "sd_card" [current_project]
    

  • 上部にある[Validate Design]アイコンをクリック、OKなら問題なし

  • f:id:trafalbad:20200403001428j:plain


  • [Source]タブの中のデザインファイル[ultra96base(ultra96base.bd)]を右クリック、メニューから、[Create HDL Wrapper]を選択してOK
  • =>オレンジから青のファイル(ultra96base_wrapper(ultra96base_wrapper.v))に変わる
    f:id:trafalbad:20200403001741p:plain



  • [Flow Navigator]の[Generate Bitstream]をクリックで、ビットストリームを作成。2つほどダイアログが出て、Save=>Yes=>Okの順でクリックすればOK。

  • f:id:trafalbad:20200403001524j:plain


  • 数十分後、Bitstream Generation Completed ダイアログが表示されるので、Cancel ボタンをクリックする。



  • 5.XSAファイルの作成



    Vivadoのメニューから [File] → [Export]→[Export Hardware]
    をクリック。

    [include bitstream]にチェックをいれて、デザインの名前を[ultra96base](プロジェクト名と同じ)に変更
    f:id:trafalbad:20200403001806j:plain


    XSAファイルの名前をプロジェクト名と同じ「ultra96base.xsa」にするのは下の理由から。

    ハードウェア・コンポーネント(XSAファイル)とソフトウェア・コンポーネント(SPFMファイル)の名前を一致させる必要あるから

    アクセレーション・プラットフォームとVitisに認識させるにはハードとソフトの名前の一致が重要な要件だから



  • Tclコンソールから、出力したファイルのチェック以下コマンドで確かめる。
  • ちゃんとできてるなら、エラーが出ないで成功

    $ validate_hw_platform <Write Path>/ultra96base.xsa
    >>>
    INFO: [Vivado 12-6074] Validating Hardware Platform: ‘/home/[host-name]/ultra96base/ultra96base.xsa’
    〜略〜
    INFO: [Vivado 12-6067] Found file 'ultra96base.bit' of type 'FULL_BIT' in the Hardware Platform.
    INFO: [Vivado 12-6066] Finished running validate_dsa for file: '/home/[host-name]/ultra96base/ultra96base.xsa'
    




    2.PetalinuxでLinuxシステムの設計

    PetaLinuxシステムで、Ultra96の動作に必要なBIFファイルと、Vitis IDEに必要なSDKファイルを作成してく。

    メインでやること
    ・ultra96の動作に必要なBIFファイルの作成

    ・vitis IDE立ち上げ





    1.Petalinux用のプロジェクトの作成



    プロジェクトのファルダ内(/home/[host-name]/ultra96base)で実行。

    # ディレクトリ構成
    $ tree
    /home/[host-name]/ultra96base
               └── <>
               └──ultra96base.xpr
               └──ultra96base.xsa
    
    
    # git cloneしてきたものなので権限付与
    $  sudo chmod 777 ultra96base.xsa
    
    # プロジェクト作成
    $ petalinux-create -t project -n petalinux --template zynqMP
    >>>
    INFO: Create project: petalinux
    INFO: New project successfully created in /opt/petalinux/petalinux
    




    2.Vivadoで作成したXSAファイルの取り込み


    $ cd petalinux
    $ petalinux-config ―get-hw-description=/home/[host-name]/ultra96base
    

    コンソールによるメニュー形式が出てくるので本家の通り操作。
    DTG Settngs → MACHINE_NAMEを[avnet-ultra96-rev1]

    [Exit]で戻り、Subsystem AUTO Hardware Settings → Serial Settings を設定、その後、[psu_uart_1]に設定
    f:id:trafalbad:20200403002305j:plain


    f:id:trafalbad:20200403002324j:plain



    次にシステムを増やすために、SDカードの記録方法を指定。

    2回[Exit]でトップメニューから、[Image Packageing Configuration] => [Root filesystem type] から[EXT(SD/eMMC/QSPI/STAT/USB)]を[select]で選択。

    選択して[Exit]を2回。その後、「保存しますか」を聞いてくるので、Yesをクリック。

    完了まで時間がかかるのでコーヒーブレイク。

    出力ログ

    INFO: Getting hardware description...
    INFO: Rename ultra96base.xsa to system.xsa
    [INFO] generating Kconfig for project
    [INFO] menuconfig project
    configuration written to /home/[host-name]/ultra96base/petalinux/project-spec/configs/config
    
    *** End of the configuration.
    *** Execute 'make' to start the build or try 'make help'.
    〜略〜
    [INFO] silentconfig rootfs
    [INFO] generating petalinux-user-image.bb
    
    # ファルダ状況確認
    $ ls
    >>>
    build  components  config.project  project-spec
    



    3.ファイルの追加・編集



    # XRTを使えるようにするため追記
    $ sudo vi /home/[host-name]/ultra96base/petalinux/project-spec/meta-user/conf/user-rootfsconfig
    
    #Note: Mention Each package in individual line
    #These packages will get added into rootfs menu entry
    
    CONFIG_gpio-demo
    CONFIG_peekpoke
    CONFIG_xrt
    CONFIG_xrt-dev
    CONFIG_zocl
    CONFIG_opencl-clhpp-dev
    CONFIG_opencl-headers-dev
    CONFIG_packagegroup-petalinux-opencv
    # Zynqシリーズで、XRTドライバーが使えるようにする
    $ sudo vi /home/[host-name]/ultra96base/petalinux/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
    
    /include/ "system-conf.dtsi"
    / {
    };
    &amba {
      zyxclmm_drm {
          compatible = "xlnx,zocl";
          status = "okay";
      };
    };

    上の設定したファイルを有効可するため下コマンドを実行。

    コンソールによるメニュー形式が出てくるので[user packages]を選択。

    出ているプログラムでスペースキーをクリックしてすべて有効にする。
    f:id:trafalbad:20200403003528j:plain


    2回[Exit]で、セーブして、Yesで保存。

    $ cd && cd ultra96base/petalinux
    $ petalinux-config -c rootfs
    
    >>>
    [INFO] sourcing bitbake
    [INFO] generating plnxtool conf
    〜略〜
    [INFO] menuconfig rootfs
    configuration written to /home/[host-name]/ultra96base/petalinux/project-spec/configs/rootfs_config
    
    *** End of the configuration.
    *** Execute 'make' to start the build or try 'make help'.
    
    [INFO] generating petalinux-user-image.bb
    [INFO] successfully configured rootfs
    




    4.カーネルの操作でDMA転送用のメモリーの確保



    ここも本家通り操作。

    $ petalinux-config -c kernel
    >>>
    [INFO] generating Kconfig for project
    ~略~
    NOTE: Source tree extracted to /home/[host-name]/ultra96base/petalinux/components/plnx_workspace/sources/linux-xlnx
    WARNING: SRC_URI is conditionally overridden in this recipe, thus several devtool-override-* branches have been created, one for each override that makes changes to SRC_URI. It is recommended that you make changes to the devtool branch first, then checkout and rebase each devtool-override-* branch and update any unique patches there (duplicates on those branches will be ignored by devtool finish/update-recipe)
    NOTE: Recipe linux-xlnx now set up to build from /home/[host-name]/ultra96base/petalinux/components/plnx_workspace/sources/linux-xlnx
    ~略~
    NOTE: Updating config fragment /home/[host-name]/ultra96base/petalinux/components/plnx_workspace/sources/linux-xlnx/oe-local-files/devtool-fragment.cfg
    [INFO] successfully configured kernel
    

    ここでコンソールによるメニュー形式が出てくるので本家の通り操作。

    [Device Drivers]→ [Generic Driver Options]→ [DMA Contiguous Memory Allocator] → [Size in Mega Bytes]をクリックして、256を1024に変更。

    f:id:trafalbad:20200403003629j:plain

    f:id:trafalbad:20200403003645j:plain


    [Exit]=>[Save]で保存して終わり。

    ここまでで、コンフィグレーションの設定は終わり。




    5.ビルドしてSDKファイルの作成


    2箇所ビルドをします。かなり時間がかかるところなので、気長に。

    1回目のbuildが終わった時点で、Petalinux-packgeを使って、BOOT.BINファイルを作成して、SDカードにコピーすれば、Ultra96が動作可能。(今回はしない)

    # 1回目のビルド
    $ petalinux-build
    >>>
    [INFO] building project
    ~略~
    NOTE: Resolving any missing task queue dependencies
    WARNING: /opt/petalinux/components/yocto/source/aarch64/layers/meta-xilinx/meta-xilinx-bsp/recipes-kernel/linux/linux-xlnx_2019.2.bb.do_compile is tainted from a forced run
    ~略~
    NOTE: linux-xlnx: compiling from external source tree /home/[host-name]/ultra96base/petalinux/components/plnx_workspace/sources/linux-xlnx
    ~略~
    INFO: Creating /home/[host-name]/ultra96base/petalinux/images/linux directory
    NOTE: Failed to copy built images to tftp dir: /tftpboot 
    [INFO] successfully built project
    
    # ファルダ状況確認
    $ ls
    >>>
    build  components  config.project  images  project-spec
    
    # 2回目のビルド
    $ cd images/linux
    $ petalinux-build --sdk
    >>>
    [INFO] building project
    ~略~
    WARNING: /opt/petalinux/components/yocto/source/aarch64/layers/meta-xilinx/meta-xilinx-bsp/recipes-kernel/linux/linux-xlnx_2019.2.bb.do_compile is tainted from a forced run
    Initialising tasks: 100% 
    ~略〜
    [INFO] Copying SDK Installer...
    [INFO] successfully built project
    
    # sdk.shが出来てるか確認
    $ ls
    ~~~
    pxelinux.cfg      sdk.sh                 zynqmp-qemu-multiarch-pmu.dtb
    rootfs.cpio       system.bit             zynqmp_fsbl.elf
    


    sdk.shは自己解凍ファイルなので解凍して、Vitis IDEのsysrootにする。

    $ cd ../../..  && mkdir pfm
    $ ./petalinux/images/linux/sdk.sh
    


    出力する場所のパスを聞いてくるので、パス(今回は/home/[host-name]/ultra96base/pfm)を指定。

    PetaLinux SDK installer version 2019.2
    ======================================
    Enter target directory for SDK (default: /opt/petalinux/2019.2): /home/[host-name]/ultra96base/pfm
    
    You are about to install the SDK to "/home/[host-name]/ultra96base/pfm". 
    SDK............................................................done
    Setting it up...done
    SDK has been successfully set up and is ready to be used.
    Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
    $ . /home/[host-name]/ultra96base/pfm/environment-setup-aarch64-xilinx-linux
    
    # 確認
    $ ls pfm
    >>>
    environment-setup-aarch64-xilinx-linux  sysroots
    site-config-aarch64-xilinx-linux        version-aarch64-xilinx-linux
    


    最後にVitis IDE作成時にブートするファイルのコピー

    $ mkdir boot && cd petalinux/images/linux
    $ cp image.ub zynqmp_fsbl.elf pmufw.elf bl31.elf u-boot.elf ../../../boot
    $ cd ../../..
    



    6.BIFファイルの作成



    BIFファイルはSDカードを作るときに必要。作成には下のテキストファイルをboot/linux.bif としてそのまま作成

    $ sudo vi boot/linux.bif
    
    /* linux */
    the_ROM_image:
    {
      [fsbl_config] a53_x64
      [bootloader] <zynqmp_fsbl.elf>
      [pmufw_image] <pmufw.elf>
      [destination_device=pl] <bitstream>
      [destination_cpu=a53-0, exception_level=el-3, trustzone] <bl31.elf>
      [destination_cpu=a53-0, exception_level=el-2] <u-boot.elf>
    }



    3.Vitis IDEを立ち上げてみる

    Vitis IDEを起動してみる。

    $ cd /home/[host-name]/ultra96base/pfm
    $ vitis -workspace wksp1
    

    f:id:trafalbad:20200403000935p:plain


    無事立ち上がった。
    PCが低スペックすぎるので、Petalinuxのビルドのところでとんでもなく時間かかった。2017年以降のMacなら割と早く終わるはず。



    参考サイト



    Ultra96-V2 の Vitis アクセラレーション・プラットフォームの作り方(ハードウェア・コンポーネント編)

    FPGAの部屋

    Running Ubuntu on Ultra96v2 Using Petalinux 2019.2, with Networking

    Xlinx-2018.3 SDSoC™ Development Environment Tutorials

    How to create Ultra96v2 Linux-based Platform in Xilinx Vitis 2019.2

    Xilinxサポートフォーラム

    Vitis,Petalinuxのインストールから、Vivadoの起動まで【FPGA, avnet】-VitisPlatform作りpart2

    今回はVitisPlatfrom構築に必要な「Vitis、Petalinux、その他関連ツール」のインストール。
    Ultra96の開発環境(Vitis2019.2版)」をメインに参考にした。


    Vitisプラットフォーム(vitis IDE)はVivado起動後に、「Ultra96用Vitisプラットフォームの作り方(BASE編)」を参考に次記事でやる予定。


    前回作った仮想環境用ネットワークを少し改良して、外付けHDDの中にVirtualBoxをいれて仮想環境を作った。


    そこにUbuntu Linux 18.04.2 LTS (64 ビット)を入れて、vitisとPetaLinuxとかをインストールして、Vivadoを起動するまで。

    VirtualBoxで作ったubuntuの仮想環境のストレージ容量は、VitisとPetaLinuxを入れるために500GBくらいのを作った。



    改良ネットワーク図f:id:trafalbad:20200319090235j:plain



    目次
    1.ゲストOS側でライブラリの準備
    2.Vitisのインストール
    3.その他必要なツールのインストール
    4.ゲストOS側からVivadoの起動


    1.ゲストOS側で必要なライブラリの準備

    Vitisプラットフォーム構築に必要なライブラリをゲストOS側でインストール。

    $ sudo dpkg --add-architecture i386 && sudo apt update && sudo apt install apt-utils libc6:i386 libncurses5:i386 libstdc++6:i386 g++-multilib libgtk2.0-0:i386 dpkg-dev:i386 libxtst6:i386 default-jre unzip net-tools libtext-csv-perl libcanberra-gtk-module libcanberra-gtk3-module lsb-core opencl-headers ocl-icd-opencl-dev ocl-icd-libopencl1 wget -y && sudo ln -s /usr/bin/make /usr/bin/gmake
    
    $ sudo apt install tofrodos iproute2 gawk make net-tools locales cpio libncurses5-dev libssl-dev flex bison libselinux1 gnupg wget diffstat chrpath socat xterm autoconf libtool tar unzip texinfo zlib1g-dev gcc-multilib build-essential libsdl1.2-dev libglib2.0-dev screen pax gzip xvfb tftpd tftp libtool-bin default-jre -y lsb-release zlib1g:i386 git python-dev 
    
    $ sudo apt-get install -y binutils ncurses-dev u-boot-tools file iproute2 tftpd-hpa diffstat x11-apps less etckeeper jed
    $ sudo locale-gen en_US.UTF-8
    
    # 有効なインストール可能なパッケージの一覧を更新(update) & 有効なパッケージ一覧を元にインストール済みパッケージの更新 (upgrade)
    $ sudo apt-get update && sudo apt-get upgrade
    $ sudo apt autoremove
    

    参考記事xilinx2017.2_dep.sh(github)  




    2.Vitisのインストール


    1.Vitisのダウンロード


    Vitisはこのページからダウンロード。

    ダウンロードするものは、

    ザイリンクス統合インストーラ アップデート 1 - 2019.2 (TAR/GZIP - 9.03 GB)

    ザイリンクス統合インストーラー 2019.2: Linux 用自己解凍型ウェブインストーラー(BIN - 115.4MB)




    2.ウェブインストーラーの実行




    ホストOS側でダウンロード後、ゲストOS側(ubuntu側)に移動して、ウェブインストーラーを実行。

    # ゲストOS側で実行
    $ sudo chmod 777 Xilinx_Unified_2019.2_1106_2127_Lin64.bin
    $ ./Xilinx_Unified_2019.2_1106_2127_Lin64.bin
    

    注意事項を聞かれるのでOKした後に、インストール開始画面になる。
    f:id:trafalbad:20200311235452j:plain



    途中でXlinxのアカウント入力が必要。
    f:id:trafalbad:20200311235536j:plain

    インストール対象に「Vitis」を選択をした後、保存先を聞かれる。

    ホストOS内のVivadoフォルダのパス「/media/[host-name]/Vivado」を指定。500GBもあるので十分足りる。
    f:id:trafalbad:20200319020816p:plain



    インストール開始画面
    f:id:trafalbad:20200319020843p:plain




    インストール中
    f:id:trafalbad:20200311235714j:plain


    インストール完了
    f:id:trafalbad:20200311235735p:plain

    インストール完了までは気長に待つだけ。


    licenseの取得


    次にvivadoで必要になるxilinxのlicenseの取得。


    ページからvivado HLSのライセンスを取得。(これをしないと高位合成のときSynthesis errorになる)。
    Obtain Licenseを選び、ラジオボックスを上から2番目(Get Vivado or IP〜)に合わせ、Connect Nowを起動。
    f:id:trafalbad:20200805125246p:plain


    Xilinxのサインインを済ませ、Product Licensingのページに移動し、したの画面の基本licenseに全部チェックして取得。
    f:id:trafalbad:20200805125605p:plain


    するとXilinxからメールが届いて、「Xilinx.lic」が添えつけられているので、適当な場所に配置

    # Xilinx.licをVivadoファルダに移動
    $ mv /media/[マウントフォルダ]/Xilinx.lic Vivado/
    $ sudo chmod 777 Xilinx.lic
    

    あとはLicence ManagerのLoad Licenseを起動し、Copy Licenseをクリック。
    f:id:trafalbad:20200805125658p:plain

    Xilinx.licを選べば完了。
    f:id:trafalbad:20200805125738p:plain

    f:id:trafalbad:20200805125745p:plain





    3.その他必要なツールのインストール

    ・Petalinux



    1.Petalinuxのインストール


    このサイトから下のをdownload。


    PetaLinux 2019.2 インストーラ(TAR/GZIP - 7.92GB)


    ちなみにrootユーザーではインストーラの実行ができない。
    ホストOS側でダウンロードしたものを、マウント共有フォルダでゲストOS内移動して、実行した。

    # check user name
    $ whoami   # user
    $ export USER=user
    $ sudo mkdir -p /opt/petalinux/
    $ sudo chmod -R 777 /opt/petalinux/
    $ sudo chown $USER:$USER /opt/petalinux
    # /home/userのところでinstallの実行
    $ sudo chmod 777 petalinux-v2019.2-final-installer.run 
    $ ./petalinux-v2019.2-final-installer.run /opt/petalinux
    
    >>>>>
    INFO: Checking installation environment requirements...
    INFO: Checking free disk space
    INFO: Checking installed tools
    INFO: Checking installed development libraries
    INFO: Checking network and other services
    INFO: Checking installer checksum...
    INFO: Extracting PetaLinux installer...
    
    LICENSE AGREEMENTS
    〜
    INFO: Installing PetaLinux...
    *********************************************
    WARNING: PetaLinux installation directory: /opt/petalinux/. is not empty!
    *********************************************
    Please input "y" to continue to install PetaLinux in that directory?[n]y
    INFO: Checking PetaLinux installer integrity...
    INFO: Installing PetaLinux SDK to "/opt/petalinux/."
    INFO: Installing aarch64 Yocto SDK to "/opt/petalinux/./components/yocto/source/aarch64"...
    INFO: Installing arm Yocto SDK to "/opt/petalinux/./components/yocto/source/arm"...
    INFO: Installing microblaze_full Yocto SDK to "/opt/petalinux/./components/yocto/source/microblaze_full"...
    INFO: Installing microblaze_lite Yocto SDK to "/opt/petalinux/./components/yocto/source/microblaze_lite"...
    INFO: PetaLinux SDK has been installed to /opt/petalinux/.
    


    インストール後、PetaLinuxツール(components, doc, etc, tools, settings.csh, settings.sh)の確認。

    $ ls
    components  doc  etc  settings.csh  settings.sh  tools
    


    ・XRTライブラリ(ザイリンクスランタイム)


    XRTはライブラリなので、実行してもフォルダは出現しない。

    # xilinxツール用ディレクトリ作成(sshでログインして実行)
    $ mkdir xilinx_drivers && cd xilinx_drivers
    $ wget https://www.xilinx.com/bin/public/openDownload?filename=xrt_201920.2.3.1301_18.04-xrt.deb -O xrt_201920.2.3.1301_18.04-xrt.deb
    # 実行
    $ sudo apt install ./xrt_201920.2.3.1301_18.04-xrt.deb -y
    
    >>>>
    DKMS: install completed.
    Finished DKMS common.postinst
    Loading new XRT Linux kernel modules
    Installing MSD / MPD daemons
    〜
    Collecting pyopencl
      Downloading https://files.pythonhosted.org/packages/a1/b5/c32aaa78e76fefcb294f4ad6aba7ec592d59b72356ca95bcc4abfb98af3e/pyopencl-2020.2.tar.gz (351kB)
        100% |████████████████████████████████| 358kB 2.6MB/s 
        Complete output from command python setup.py egg_info:
    〜
     create mode 100644 OpenCL/vendors/xilinx.icd
     create mode 100644 bash_completion.d/dkms
    〜
     create mode 100644 systemd/system/mpd.service
     create mode 100644 systemd/system/msd.service
     create mode 100644 udev/rules.d/10-xclmgmt.rules
     create mode 100644 udev/rules.d/10-xocl.rules
    





    ・ボードファイル



    # sshでログインして実行
    $ cd xilinx_drivers
    # wget https://github.com/Avnet/bdf/archive/master.zip && unzip master.zip
    
    # new board copy
    $ unzip -o vivado-boards-master.zip
    $ sudo cp -rf vivado-boards-master/new/board_files/* /home/user/Vivado/2019.2/data/boards/board_files/
    $ sudo rm -rf vivado-boards-master
    
    # copy usual board 
    $ unzip -o bdf-master.zip
    $ sudo cp -rf bdf-master/* /home/user/Vivado/2019.2/data/boards/board_files/
    $ sudo rm -rf bdf-master
    




    ・ケーブルドライバー



    $ cd Vivado/2019.2/data/xicom/cable_drivers/lin64/install_script/install_drivers
    $ sudo ./install_drivers
    
    >>>>>
    INFO: Installing cable drivers.
    INFO: Script name = ./install_drivers
    INFO: HostName = hagi-VirtualBox
    INFO: Current working dir = /home/[host-name]/Vivado/Vivado/2019.2/data/xicom/cable_drivers/lin64/install_script/install_drivers
    INFO: Kernel version = 5.3.0-42-generic.
    INFO: Arch = x86_64.
    Successfully installed Digilent Cable Drivers
    --File /etc/udev/rules.d/52-xilinx-ftdi-usb.rules does not exist.
    --File version of /etc/udev/rules.d/52-xilinx-ftdi-usb.rules = 0000.
    --Updating rules file.
    --File /etc/udev/rules.d/52-xilinx-pcusb.rules does not exist.
    --File version of /etc/udev/rules.d/52-xilinx-pcusb.rules = 0000.
    --Updating rules file.
    
    INFO: Digilent Return code = 0
    INFO: Xilinx Return code = 0
    INFO: Xilinx FTDI Return code = 0
    INFO: Return code = 0
    INFO: Driver installation successful.
    CRITICAL WARNING: Cable(s) on the system must be unplugged then plugged back in order for the driver scripts to update the cables.
    




    環境変数の設定



    # LD_LIBRARY_PATH の設定
    $ export GID=`id -g`
    $ sudo chown ${UID}:${GID} /home/$USER/.bashrc
    
    # ゲストOSの環境変数の設定
    $ sudo echo "source /home/〜/Vivado/2019.2/settings64.sh" >> ~/.bashrc
    $ sudo echo "source /home/〜/Vitis/2019.2/settings64.sh" >> ~/.bashrc
    $ sudo echo "source /opt/xilinx/xrt/setup.sh  " >> ~/.bashrc
    $ sudo echo "source /opt/petalinux/settings.sh " >> ~/.bashrc
    

    あとは念のためGUIで再起動(CUI:$sudo reboot)




    4.ゲストOS側からVivadoの起動

    # Vivadoコマンドを起動
    $ /home/〜/Vivado/2019.2/bin/vivado
    


    起動できた。
    f:id:trafalbad:20200311235852p:plain





    後は以下の図の流れでVitisPlatformを構築していく。

    f:id:trafalbad:20200311235916p:plain



    参考サイト



    ・[https://qiita.com/georgioush/items/1e19ecd9a9ef8be886d7:title=Vivado License Error [17-345]]

    Vitis 2019.2 をインストールした(FPGAの部屋)

    PetaLinux Tools Documentation

    PetaLinux 2017.3 をインストールする(FPGAの部屋)

    ultra96v2の環境の構築。仮想環境のubuntuとMacの外付けHDDをマウントするまで -VitisPlatform作りpart1【fpga, avnet】

    ・1.ultra96-v2動作に必要なもの
    はじめてのUltra96 必要なもの」によると、Ultra96-v2に必要なものは、買った付属品以外に、
    「Vitisプラットフォーム(vitis IDE)」という開発環境の構築

    環境構築用OS ubuntu

    が必要らしい。



    ・2.まず自分がやること
    Ultra96-v2でAIを動かすことための「GPUが必要、仮想環境はダメっぽい」など面倒な課題はあとでなんとかするとして、

    ・大容量の外付けHDD

    ubuntu環境

    を用意して、とにかく「vitisプラットフォーム」を外付けHDDの中に構築することにした




    ・3.この記事でやること
    そのために、自分がこの記事でやることは下の通り(仮想環境と外付けHDDをマウントするまでの流れ)。

    mac上でVirtualBoxの仮想環境を構築

    仮想環境にubuntuをインストール

    mac側の大容量の外付けHDDとubuntuをマウント

    (次記事で外付けHDDの中に「vitisプラットフォーム」を構築する)

    この作業の備忘録をまとめてく。




    作成するネットワーク全体像f:id:trafalbad:20200308114134j:plain



    *注:Macを以下「ホストOS」、ubuntuの仮想環境を「ゲストOS」と表記。




    目次
    1.VirtualBoxの仮想環境にubuntuをインストールする

    2.ホストOSからsshでログインするため、ゲストOS内でネットワーク設定

    3.ホストOS側の外付けHDDをゲストOS側とマウント





    1.VirtualBoxの仮想環境にubuntuをインストールする

    ほぼ「MacにVirtualBoxでUbuntuを立てる方法【画像での解説つき】」の通りにやった。




    1.VirtualBoxのインストール & ubuntuをダウンロード


    VirtualBoxMac用のubuntu for desktopは以下からdownload。

    ubuntuのバージョンは「Ubuntu Linux 16.04.5 LTS, 16.04.6 LTS, 18.04.1 LTS, 18.04.2 LTS (64 ビット)」のどれか。
    ここでは18.04.2 LTS (64 ビット)を選択。

    VirtualBox
    VirtualBox

    ubuntuの18.04.2 LTS (64 ビット)





    2.VirtualBoxのネットワーク(ホストオンリーネットワーク)の作成


    サイトを参考に、virtualboxでネットワーク設定(ホストオンリーネットワークで「vboxnet0」を作成)。

    VirtualBox起動=>「ファイル」=>「ホストネットワークマネージャー」=>「vboxnet0」の作成と有効化。


    f:id:trafalbad:20200308114212p:plain



    次にVirtualBoxからネットワークの設定。「ネットワーク」のアダプター1と2を以下の図のように設定。

    f:id:trafalbad:20200504230849p:plain


    f:id:trafalbad:20200504230907p:plain


    3.VirtualBox起動してubuntuのインストール



    ubuntuのインストール画面では、容量を節約するため「最小のインストール」を選択した。

    ・「通常のインストール」:オフィスソフトウェアやミュージックプレイヤーなどが合わせてインストールされる

    ・「最小のインストール」:ソフトウェアのみがインストール


    後はサイト通りにインストールすればOK。



    ubuntuをインストール中
    f:id:trafalbad:20200308114251p:plain

    # 例:ubuntuアカウント
    Your name: Ls
    PC name: Ls-VirtualBox
    User name: Ls
    Pasward: Ls11


    2.ホストOSからsshでログインするため、ゲストOS内でネットワーク設定


    1.ubuntu内のターミナルでネットワーク設定


    # vimとopenssh-serverのインストール
    $ sudo apt-get install vim openssh-server
    
    # ubuntuでadressの確認
    $ ip address show
    
    
    # /etc/network/interfacesの編集
    $ sudo vi /etc/network/interfaces
    
    # 下のように書き込んで、「esc+:wq」
    auto enp0s3
    iface enp0s3 inet static
    address 192.168.56.104
    netmask 255.255.255.0
    


    その後、GUIで再起動

    参考サイト:Ubuntu18.04だとifconfigコマンドが標準で使えない?






    2.ホストOS側ターミナルからゲストOSにsshでログイン


    さっきのubuntuアカウントのYour nameと、/etc/network/interfacesの編集で使ったaddressでログイン。

    # ssh [アカウント名]@[address]
    $ ssh Ls@192.168.56.104
    
    >>>
    Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 5.3.0-28-generic x86_64)
    
    * Documentation:  https://help.ubuntu.com
    * Management:     https://landscape.canonical.com
    * Support:        https://ubuntu.com/advantage
    
    * Canonical Livepatch is available for installation.
      - Reduce system reboots and improve kernel security. Activate at:
        https://ubuntu.com/livepatch
    
    70 個のパッケージがアップデート可能です。
    57 個のアップデートはセキュリティアップデートです。
    
    Your Hardware Enablement Stack (HWE) is supported until April 2023.
    
    The programs included with the Ubuntu system are free software;
    the exact distribution terms for each program are described in the
    individual files in /usr/share/doc/*/copyright.
    
    Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
    applicable law.
    


    ログインできた。


    ここまでのネットワーク全体像f:id:trafalbad:20200308124910j:plain







    3.ホストOS側の外付けHDDをゲストOS側とマウント


    ホストOS側で大容量の外付けHDDを差し込んで、vitisをインストールする場所にした。

    vitisのインストールには110GBくらい必要なので、大容量の外付けHDDを選択。



    自分が選んだのは1TBある、BUFFALOの外付けHDD
    f:id:trafalbad:20200308114408j:plain




    最終的に「vitisプラットフォーム」構築は、

    ・ホストOS側とゲストOSをマウントする共有フォルダに外付けHDDを指定

    ・ゲストOS側(ubuntu環境)から外付けHDDの中に「vitisプラットフォーム」を作成する

    という流れ。





    1.ホストOS上でマウント用フォルダの作成


    ホストOS上で、外付けHDDを差込み、中にマウント用ファルダ「ubuntu_mount」を作成。



    外付けHDDの中身
    f:id:trafalbad:20200308114441p:plain






    2.VirtualBoxで外付けHDDの「ubuntu_mount」を「共有フォルダー」に設定




    ubuntu_mount」のパスを確認。(外付けHDDのパスはディスクユーティリティから確認)

    $ cd /Volumes/BuFFALO && ls
    
    Xlinx        other        ubuntu_mount
    
    $ cd ubuntu_mount && pwd
    /Volumes/BuFFALO/ubuntu_mount
    


    VirtualBox仮想マシンを選択=>「設定」=>「共有フォルダー」
    =>右のフォルダマークをクリック=>下のようにパスとかを入れる


    f:id:trafalbad:20200308114518p:plain

    =>「"読み込み専用"のチェックを外す」=>「OK」クリック


    f:id:trafalbad:20200308131749p:plain






    3.「Guest addtions」をubuntuにインストール


    ubuntuでマウントを完了するには「Guest addtions」のインストールが必要。


    VirtualBoxからubuntuを起動して、上の「Decices」=>「Insert Guest Addition CD Image~」をクリック。


    次に、ubuntu上の画面に表示された「Guest addtions」のソフトウェアを実行。

    f:id:trafalbad:20200308114621j:plain


    Returnをクリックしてインストール完了。
    その後、GUIで再起動。


    再起動した後に、ubuntuの「/media」に移動したところ、マウント用に作成されたフォルダ(sf_[マウントするフォルダ名])があって、ちゃんとマウントされてる。

    $ cd /media && ls
    sf_ubuntu_mount
    

    ***「Guest addtions」が入らない場合
    ターミナルでこのコマンドを実行すれば、同じのが入る

    sudo apt-get install virtualbox-guest-utils
    

    参考:Unable to Install Guest Additions CD Image on Virtual Box



    これで、ホストOS側の外付けHDDをゲストOS側とマウントするネットワークができた




    完成図f:id:trafalbad:20200308124802j:plain




    次記事でこの外付けHDDの「ubuntu_mount」の中に、ゲストOS側から「vitisプラットフォーム」を作ってく予定。





    メイン参考サイト


    VirtualboxのUbuntu ServerにOSXホストのフォルダをマウントする 

    MacにVirtualBoxでUbuntuを立てる方法【画像での解説つき】

    FPGAのultra96v2で「unboxingからLチカまで」の操作手順【avnet, hardware】

    AIをカメラとかのハードウェア上で動かすために、ラズパイと同じFPGAField Programmable Gate Array)のUltra96-v2を購入した。

    目的はハードでAIを使いたいから(≒ヒロアカのハイエンド脳無に惚れたから)。



    FPGAでAIを動かすために必要な作業は下の図のようになり、今回は「SDカード作りの部分」をまとめた。


    FPGAでAIを動かすために必要な作業f:id:trafalbad:20200229150230p:plain



    SDカード作りは「unboxing(開封)してから、一通りUltra96-v2を動作させる(Lチカ)まで」で、その手順には


    ・ライセンス取得
    ・Micro SD cardイメージをSDカードに書き込む
    wifiを通し、Lチカで動作確認


    などが必要で、とりあえず作業で手順をまとめてく。

    ultra96v2の構造



    目次
    1,ライセンス取得
    2. Micro SD cardイメージをSDカードに書き込む
    3.wifiを通し、Lチカで動作確認
    4.linux上での一通りの操作


    1,ライセンス取得

    Ultra96-v2を買うと、XILINXのライセンス取得用の紙があるので用意。



    XILINXのページにアクセスして、ユーザー名とパスワードを作成して、ログイン。


    「Create New license」からvoucher code(ライセンス取得用紙の下のコード)を入力

    f:id:trafalbad:20200229144631p:plain


    そして、「OEM Zynq Ultra96 Vivado Design~Voucher pack」のライセンスを取得。

    取得する際に、HostnameHost value idが必要。


    ・Hostname


    linux上で

    $ hostname
    

    で確認



    ・Host value id


    環境設定→「ネットワーク環境」で「内蔵Ethernet」を作成。

    その後下の「詳細」→ハードウェア→で「MACアドレス」の12桁の英数字がhost value id

    f:id:trafalbad:20200229144706j:plain

    参考:MACアドレスの確認・IPアドレスの設定

    またはこのコマンドを打てば、host IDがわかる。

    $ /usr/sbin/netstat -I en0
    

    ライセンスを取得するとライセンス確認用メールが届く。


    再度ログイン後に、さっきのページで「Manege Licenseでlicense」から取得したライセンスを確認できてる。

    f:id:trafalbad:20200229144740p:plain







    2. Micro SD cardイメージをSDカードに書き込む


    まず、MicroSDカードにイメージを書き込むために「etcher」をdownload。


    次にMicro SD cardイメージのdownload

    $ wget http://www.fpga.co.jp/AI-EDGE/ultra96v2_oob.img.zip 
    

    etcherを起動後にinstall &解凍した「ultra96v2_oob.img」を開く。
    MicroSD カードへのイメージの書き込みstart

    f:id:trafalbad:20200229144838p:plain



    書き込み完了

    f:id:trafalbad:20200229144859j:plain







    3. wifiを通し、Lチカで動作確認

    Ultra96-v2の構成は以下のようになってる。


    f:id:trafalbad:20200229144918p:plain




    まず、microSDカードを取り出しultra96-v2に差し込む。
    そしてSW4のスイッチを押す。

    f:id:trafalbad:20200229144950j:plain



    wifi名「ultra96-v2_ ~」が出てることを確認。


    f:id:trafalbad:20200229145009j:plain

    アクセスして、ブラウザから「http://192.168.2.1」にアクセス。



    ultra96-v2の接続画面に入れた。

    f:id:trafalbad:20200229145032j:plain


    ここからのLチカの動作はこちらのyoutube動画を参照。

    youtu.be






    4.linux上での一通りの操作

    とりあえず、例としてscpで必要なファイル転送が可能にしてみる。
    パスワードは「root」を入力

    $ ssh -l root 192.168.2.1
    >>>
    root@192.168.2.1's password: 
    mount: /mnt: /dev/mmcblk0p1 already mounted on /run/media/mmcblk0p1.
    mount: /mnt: /dev/mmcblk0 already mounted or mount point busy.
    attempting to run /mnt/init.sh
    /mnt
    root@ultra96v2-oob-2019_2:~# 
    

    これでUltra96-v2を購入してからLチカまでできるようになる。



    次の記事ではコードを書いたり、FPGAを操作するIDEの「vitisプラットフォーム」を構築でき次第、記事にまとめようと思う。

    f:id:trafalbad:20200229145519j:plain

    Efficient-Unetで天気画像の予測(パターン認識)リベンジ【機械学習】

    今回はこの前の記事で書いた「signateの天気コンペ」の優勝者(天気の専門家ガチ勢)が実装したモデルを、既存のデータでも予測できる構成で個人的に作ってみた。


    convLSTMを使わずにUnetにしたのは「予測」タスクではなく、「パターン認識」タスクにしたかったから。


    特定の気象条件なら、次の24時間はこういう画像になる」というパターン認識の形で次の24枚の天気画像を生成(予測)する。


    目次
    1.ネットワーク構成
    2.ネットワークに使った技術
    3.予測した画像
    4.他の上位入賞者のテクの備忘録




    1. ネットワーク構成


    優勝者の使ったモデル



    ・自分で天気の特徴量を350こ作った

    ・ハイスペックマシンで計算可能な環境を持っていた

    efficient-Netという最高精度の画像分類ネットワークを使ったencoderを2つ使ったUnet

    hypercolumnの使用

    Feature Pyramid Attention(FPA)の使用


    という点が特徴で下のネットワーク構成
    f:id:trafalbad:20200223012634j:plain




    自分が作ったモデル




    自分が目をつぶったポイント

    ・特別な特徴量を作成しない(面倒くさい、ガチ勢ちゃうから)

    gooogle colabで計算できる計算量(金かけたくない)



    上のポイントでケチったため、自分なりにかなり近い形の、下図のネットワークを作成した(encoderのinputは予測する一時間前の画像(直前の画像))

    f:id:trafalbad:20200223012544j:plain

    encoder input予測直前の画像(前日の23時の画像)
    met input前日の3時間ごとの風の特徴量8こ
    sat input前日の3時間ごとの天気画像8枚







    2. ネットワークに使った技術

    1.最後の出力層のoutput channelを24にして、セグメントタスクと同じ形式にした



    out_channels = 24
    o = Conv2D(out_channels, (1, 1), padding='same', kernel_initializer=conv_kernel_initializer)(o)
    




    2. sigmoidを入れて、生成画像のブレをなくす


    met-inputとsat-inputをdecoderに注入してるので、sigmoidで単位を合わせてあげなければ、画像がチャけた白黒テレビのようにブレブレになる。


    f:id:trafalbad:20200223013111j:plain


    sigmoidとhypercolumnの組み合わせで、ぶれを解消





    3. PSP moduleの使用


    PSP moduleはセグメントで有名なPSPNetで使われているモジュール。


    PSPNetはEncoderにResNet101を使い、EncoderとDecoderの間にPyramid Pooling Module(PSP module)を追加している。

    f:id:trafalbad:20200223012742p:plain


    PSP moduleはhypercolmunと、注入したデータ(met-input, sat-Input)に適用したら、全てのケースで精度があがった。





    4. 天気の特徴量(met-input, sat-input)をdecoderに挿入


    met-input(風の特徴量), sat-input(天気画像)を全DecoderのConvtranspose層に挿入

    # LambdaでreshapeしないとNonetypeエラーが出る
    def psp_layer(inputs, skip_h, skip_w):
        inputs = PyramidPoolingModule()(inputs)
        output = Lambda(lambda x:tf.image.resize_images(x, size=(skip_h, skip_w), method=tf.image.ResizeMethod.BILINEAR))(inputs)
        return output
    
    
    
    # encoderで挿入するより、直接Decoderに挿入の方がいい(やりやすい、早い、便利)。
    def Conv2DTranspose_block(filters, kernel_size=(3, 3), transpose_kernel_size=(2, 2), upsample_rate=(2, 2),
                              initializer='glorot_uniform', skip=None, met_input=None, sat_input=None):
        def layer(input_tensor):
            x = Conv2DTranspose(filters, transpose_kernel_size, strides=upsample_rate, padding='same')(input_tensor)
            
            if skip is not None and met_input is not None:
                h, w = skip.get_shape().as_list()[1:3]
                met_output = psp_layer(met_input, h, w)
                sat_output = psp_layer(sat_input, h, w)
                x = Concatenate()([x, skip, met_output, sat_output])
            elif skip is not None and met_input is None:
                x = Concatenate()([x, skip])
    
            x = channel_spatial_squeeze_excite(x)
            return x
    
        return layer
    






    5. FPA(Feature Pyramid Attention)


    FPAはCNNで抽出した汎用特徴量の細かい部分まで補ってくれる。

    セグメンテーションタスクだと細かい部分のピクセルまで再現できるので、セグメンテーションタスクでも使ってる例は多い。

    f:id:trafalbad:20200223093005j:plain




    FPAを使うときは以下の点に注意

    ・FPAを使うときは 画像サイズは shape=(256, 256)かそれ以上のshapeの必要がある

    計算量が多くなる

    今回は計算量の関係で使わなかったが、試しに使ってみると精度はかなり良くなった。




    FPAのセグメンテーション使用例
    f:id:trafalbad:20200223012840p:plain






    6. SCSE(Concurrent Spatial and Channel Squeeze & Excitation)



    SCSEはすでに出回ってる既存モデル(resnet50とかその他多数)に計算量をそこまで増やさず & 簡単に組み込むことができる。

    f:id:trafalbad:20200223012859p:plain

    特にセグメンテーション系などのタスクで性能を向上させることができる。


    実際、DecoderのConvolution層の代わりに、SCSEを使ったら、計算量が減り、精度が上がった。






    7. hypercolumn


    hypercolumn」はConvolution層の出力を組み合わせて精度を上げる手法。

    f:id:trafalbad:20200223012923p:plain


    ベターな組み合わせは「Convolutional hypercolumns in Python」に詳しく載ってる。


    今回のベストプラクティスは「decoder1とdecoder5」だった。

    なるべく対照的な位置のlayerを組み合わせると良いらしい。

    def interpolation(inputs, interpolation_shape):
        patch_size = np.multiply(inputs.get_shape().as_list()[1:3], interpolation_shape)
        inputs = PyramidPoolingModule()(inputs)
        output = Lambda(lambda x: tf.image.resize_images(x, size=patch_size, method=tf.image.ResizeMethod.BILINEAR))(inputs)
        return output
    
    # decoder のhypercolumnの部分
    if hypercolumn:
            o = Lambda(lambda x: tf.concat([x, d5], axis=3))(o)
    



    8.精度指標


    精度指標はなるべく多く使い(MSE, PSNR, SSIM)、多角的にモデルの性能を判断した。

    from sklearn.metrics import mean_absolute_error
    from skimage.measure import compare_ssim, compare_psnr
    def measurement(func, **kwargs):
        val = func(kwargs["img1"], kwargs["img2"])
        return val
    
    maes= 0
    psnrs = 0
    ssims = 0
    for idx, (pr, im) in enumerate(zip(y_pred, test)):
      maes += mean_absolute_error(pr, im)
      psnrs += measurement(compare_psnr, img1=im, img2=pr)
      ssims += measurement(compare_ssim, img1=im, img2=pr)
    
    print('total mae', maes/24)
    print('total psnr', psnrs/24)
    print('total ssim', ssims/24)
    


    参考:MSE/PSNR vs SSIM の比較画像紹介






    予測した画像

    前回のと比べるとかなり良くなった

    【GroundTruth】
    f:id:trafalbad:20200223013020g:plain




    【自分が予測した画像】
    f:id:trafalbad:20200223013037g:plain

    total mae 0.04931812573362152
    total psnr 22.823581818309222
    total ssim 0.7469266660346182
    



    4. 他の上位入賞者のテクの備忘録


    ・好奇心でやってる人がほぼ全員、義務感でやってる奴はほぼ下位

    画像サイズを変更して、同じネットワークでアンサンブル学習する。

    efficient-Netのb4とかb5とかでうまくネットワーク変えながら、アンサンブルしてた。

    metaデータからうまく天気と関連した特徴量を作成(マイナスの値を0に置換して、風の向きをうまくプラスのベクトルのみで表現してた)

    論文から実装が多く、特にネットワークに変更は加えてない(PredRNN++とか)

    ・セグメントタスクみたいにチャンネルを24にして予測する手法はみんなしてた。

    データ量は少なくして(1 batchとか)、爆速でPDCA回す。

    精度指標は多めにして多角的視点から精度評価してた




    参考サイト


    hypercolumn参考GitHub

    FPAを使用したUnetの参考GitHub