えいあーるれいの技術日記

ROS2やM5 Stack、Ubuntuについて書いています

Darknet(本家)をLog収集可能にしてみた(プログラム改造)

 Darknetは偉大です。速いし、性能いいし、すぐ試せる。欠点を挙げるなら学習にちょっとクセがあるくらいです。使用方法は単純なのにディープなニューラルネットワークを構成するYOLO v3はコンピュータビジョン関連の研究をする大学生で知らない人はいない(?)くらい有名なアルゴリズムです。ROSにも組み込まれていて簡単に使えるからびっくり。

 しかし、研究で使うときに少し不都合があります。それは、ログの取り方が分からないことです。機械学習・深層学習の学習は基本は損失などのデータを貼り付けて学習回数の根拠とすることが多い気がしますが、Darknet(本家)ではデフォルトで実装されていません。(論文をあまり読んでいない上に、読んでいるプログラムも一部なので、もしかしたらほかに方法があるかもしれませんが…)

 学習進捗をweightsの結果以外で知りたい!と思ったので、darknet.cに追記する形で実装しました。

実装

 収集対象は学習コマンドを打ち込んだターミナルに出力される文字列(選択して白くなっている部分)です。

f:id:Ray_ar:20201209121133p:plain
収集対象のログ

 書き換えるプログラムはdarknet/examples/detector.cの130行目付近です。アルゴリズムは、ログが出力される→csvを新規作成or開く→同じ文字列でcsvに書き込む→ファイルを閉じる で、これを学習回数分だけ繰り返します。保存場所はbackupで指定したフォルダと同じ場所です。追記するソースコードを示します。

//直前の行:printf("%ld: %f, %f avg, %f rate, %lf seconds, %d images\n", get_current_batch(net), loss, avg_loss, get_current_rate(net), what_time_is_it_now()-time, i*imgs);
        
//Write log -------------------------------------------------
FILE *fp;
char log_name[100] = {};
sprintf(log_name, "%s/%s", backup_directory, "train_log.csv");
if(i == 1)
    fp=fopen(log_name, "w");
else
    fp=fopen(log_name, "a+b");
 
fprintf(fp,"%ld,%f,%f,%f,%lf,%d\n",get_current_batch(net), loss, avg_loss, get_current_rate(net), what_time_is_it_now()-time, i*imgs);
fclose(fp);


//直後の行:if(i%100==0){

 普通にコンパイルします。darknetディレクトリでmakeを実行

 1回目の学習時にファイルは消えるので、新たに学習を開始する場合は注意してください。これで生成されたcsvファイルを適当なアプリで開いてグラフを作成すれば、損失グラフを作ることができます!

f:id:Ray_ar:20201209122858p:plain
csvExcelで開いてグラフ描画

 グラフを表示することができました。Gnuplotとかでリアルタイムでグラフ表示するとかでもよさそうですね。

それにしても、C言語ニューラルネットワーク構築するとか自分だったら頭狂いそう…

またちまちまと改造して使いやすいようにしていきたいと思います。