FPGAに学習済みニューラルネットワークを実装して推論を実行する:FPGAにニューラルネットワークを実装する(3)(1/3 ページ)
FPGAにニューラルネットワークを実装するプロセスを学ぶ本連載。第3回では、PC上で生成した学習済みニューラルネットワークをFPGAに実装して推論を実行する。
はじめに
前回は、ニューラルネットワークの基本であるホップフィールドネットワークについて押さえつつPC上で学習済みデータを生成しました。今回はいよいよ、この学習済みデータをFPGAに渡して推論を行わせてみます。
⇒連載「FPGAにニューラルネットワークを実装する」バックナンバーはこちら
学習済みデータの生成
今回使用する、学習済みデータをFPGAに渡すためのプログラム「makelinks.c」は以下のリポジトリから参照できます。リストに示す行番号は、執筆時にリポジトリにアップロードした時のもので、その後リポジトリのファイルが更新されるとここで示した行番号とずれる可能性がありますので、その点はご了承ください。
⇒makelinks.cのあるGitHubのリポジトリはこちら
作業はPCで行います。PCのハードウェア環境と用いるCコンパイラについては、前回の記事を参照してください。
まずは、学習済みデータをFPGAの開発に用いるハードウェア記述言語(HDL)の一つであるVerilogHDLに取り込める形式にする必要があります。
リスト1を見ながら以降をお読みください。学習済みデータをFPGAに渡すためのプログラムのソースコードがmakelinks.cですが、これはC言語で書かれています。これをコンパイルするとa.exeという実行ファイルが生成されます。a.exeを実行し、リダイレクションでlinks.txtを指定するとFPGAにデータを持っていける形式のファイルが生成されます。
>gcc makelinks.c >a.exe>links.txt
学習済みデータを生成するプログラムのコンパイルと実行例
それでは、学習済みデータをFPGAに渡すためのプログラムの中身を見ていきましょう(リスト2)。
40: void listlinks(void){ 41: for (int i=0;i<25;i++) 42: for(int j=0;j<25;j++) 43: printf("links[%d]=%d;\n",i*25+j,links[i*25+j]); 44: } 45: 46: void main(void){ 47: learn2(); 48: listlinks(); 49: }
今回初登場の関数はlistlinksです(40〜44行まで)。これは、前回も登場した学習関数learn2が生成した学習済みデータの配列linksの値を、FPGAに渡すためにVerilogHDL形式でFPGAのレジスター(次回以降で解説)に値を代入するために成形する関数です。学習済みデータが格納されているlinksはグローバル変数の配列として定義されています。
ちょっと思い出したので、ここで筆者の持論を記しておきましょう。計算機科学を専門で修めた方々は、モジュールの独立性を保つために大域変数(グローバル変数)を使うべきではないというのが大半かと思います。しかし、われわれが取り扱うコードは50行足らずの行数です。少なくともA4用紙に印刷しても1枚に収まる程度です。
そのくらいであれば一目でみてコードの意味を理解することはそれほど大変ではないでしょう。むしろモジュールの細分化や独立性を重視することによる弊害の方が大きいかと思います。
何が言いたいかというと、分かりやすいコードを書くのであれば短いコードを書くべきだし、ライブラリなどで再利用してもらいたいコードであればモジュールの細分化や独立性を考慮したコードを書くべきだと思います。しかし、筆者としては最低限のコードで動くものをこの連載記事では紹介したいと考えています。
さて、話をVerilogHDLの解説に戻します。
main関数内となる47〜48行ですが、学習関数のlearn2で蓄えた学習済みデータのlinks配列を、listlinks関数によりVerilogHDLで読める形式で出力しています。
これは、printfを使って出力形式を整形していますが、ほしいのはFPGAの開発環境に受け渡しできるファイルなので、リダイレクションでlinks.txtを生成します。リスト3は、生成したlinks.txtの一部です。これは最初の6行のみですが実際には625行あります。
links[0]=4; links[1]=0; links[2]=0; links[3]=0; links[4]=0; links[5]=-2;
Copyright © ITmedia, Inc. All Rights Reserved.