lisz-works

技術系だけど関係ないこと多い系ブログ

「darknet」C言語で機械学習!とりあえずインストールとmake、エラーの対処をしてみた

【スポンサーリンク】

darknetロゴ

巷で話題の「人工知能」、「AI」、「機械学習」、「ディープラーニング」なんてワード。

いやいや、他人事でしょ。勝手にみんな便利なもの作ってくれるんでしょ?

とか思っていたら、C言語でできるフレームワークを知ってしまった……

しかもインストール簡単。

ということで、まずはインストールして、ビルドを通してみました。

darknetのインストール

まずはこの3行を実行すればよいらしいです。
ということで、コマンドプロンプトを立ち上げて実行です!

git clone https://github.com/pjreddie/darknet.git
darknet
make

と、すんなりいく予定が、エラー。

コマンドプロンプト エラー

ここから問題が続々と発生していくのであった……

「make」が認識できないコマンドとなっている

makeを実行!と意気揚々と実行するも、このようなエラーが。

> make
‘make’ は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

……ほぉぅ?

調べてみると、このような記述を見つけました。

make コマンドについて

最後に make コマンドについてちょっと書いておきます *4。 MinGW で提供されている make コマンドには “mingw32-make.exe” という名前が付いており、コマンドプロンプトから使用する場合は “mingw32-make” とコマンドを打たなければいけません。 なぜこのような名前が付いているのかは以下に書いてあります。

MinGW について頻繁に尋ねられる質問と回答 (なぜ make には mingw32-make.exe という名前が付けられているのですか?) つまり、MSYS にも make が含まれており、名前の衝突を防ぐために MinGW の make の名前を変更した、ということのようです。 MSYS をインストールして make を使うのであればこのままでいいと思いますが、MSYS をインストールしないのであれば mingw32-make.exe をコピーして make.exe にリネームしてもいいかと思います。
引用:Windows 上に C/C++ 開発環境を構築する #1 (MinGW のインストール方法) - vivid memo

要約すると……

  1. MSYSもMinGWもmakeってもの使うから、MinGWのmakeは「mingw32-make.exe」って名前にしてあるよ。
  2. MSYS使わないなら「mingw32-make.exe」を「make」にリネームしてもいいと思うよ。

ということです。

現状、MSYS使ってないので、「make」に変更です。

MinGWのインストールフォルダに移動です。
(デフォルトは恐らく、C:\MinGW)

この中の「bin」に入りましょう。

MinGWのbinフォルダ

すると「mingw32-make.exe」というファイルがあります。
念のためバックアップを取ります。

makeのバックアップ

「make」にリネームします。

make.exe

これでOK!

サブディレクトリまたはファイル -p は既に存在します。

make問題を解決したぼくは、改めて「make」実行!

としましたが、またエラーです。

>make
mkdir -p obj
mkdir -p backup
サブディレクトリまたはファイル -p は既に存在します。
処理中にエラーが発生しました: -p
Makefile:74: recipe for target ‘backup’ failed
make: *** [backup] Error 1

どうやらMakefileのこの箇所が問題のようです。

obj:
    mkdir -p obj
backup:
    mkdir -p backup
results:
    mkdir -p results

mkdirのオプションとして、「-p」を設定しているように見受けられます。

しかしDOS(Windowsのコマンド)のmkdirには、-pオプションはありません。

Linuxのコマンドを調べてみると、オプションに「-p」がありました。

-p, –parents    指定したディレクトリをサブディレクトリごと作成する。ツリー状のディレクトリも作成可能

とのこと。

……ていうかMakefile上の3つは、単発のフォルダしかしていしてないから、これ不要なのでは……?

ということで、Makefileからこのように「-p」を消します。

obj:
    mkdir obj
backup:
    mkdir backup
results:
    mkdir results

いざ実践……!

動いたー!

>make
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/gemm.c -o obj/gemm.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/utils.c -o obj/utils.o
./src/utils.c: In function ‘fgetl’:
./src/utils.c:274:24: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘size_t {aka unsigned int}’ [-Wformat=]
                 printf(“%ld\n”, size);
                        ^
./src/utils.c: In function ‘rand_size_t’:
./src/utils.c:587:36: warning: left shift count >= width of type [-Wshift-count-overflow]
     return  ((size_t)(rand()&0xff) << 56) |
                                    ^
./src/utils.c:588:36: warning: left shift count >= width of type [-Wshift-count-overflow]
             ((size_t)(rand()&0xff) << 48) |
                                    ^
./src/utils.c:589:36: warning: left shift count >= width of type [-Wshift-count-overflow]
             ((size_t)(rand()&0xff) << 40) |
                                    ^
./src/utils.c:590:36: warning: left shift count >= width of type [-Wshift-count-overflow]
             ((size_t)(rand()&0xff) << 32) |
                                    ^
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/cuda.c -o obj/cuda.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/deconvolutional_layer.c -o obj/deconvolutional_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/convolutional_layer.c -o obj/convolutional_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/list.c -o obj/list.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/image.c -o obj/image.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/activations.c -o obj/activations.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/im2col.c -o obj/im2col.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/col2im.c -o obj/col2im.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/blas.c -o obj/blas.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/crop_layer.c -o obj/crop_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/dropout_layer.c -o obj/dropout_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/maxpool_layer.c -o obj/maxpool_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/softmax_layer.c -o obj/softmax_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/data.c -o obj/data.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/matrix.c -o obj/matrix.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/network.c -o obj/network.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/connected_layer.c -o obj/connected_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/cost_layer.c -o obj/cost_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/parser.c -o obj/parser.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/option_list.c -o obj/option_list.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/darknet.c -o obj/darknet.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/detection_layer.c -o obj/detection_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/captcha.c -o obj/captcha.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/route_layer.c -o obj/route_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/writing.c -o obj/writing.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/box.c -o obj/box.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/nightmare.c -o obj/nightmare.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/normalization_layer.c -o obj/normalization_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/avgpool_layer.c -o obj/avgpool_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/coco.c -o obj/coco.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/dice.c -o obj/dice.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/yolo.c -o obj/yolo.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/detector.c -o obj/detector.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/layer.c -o obj/layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/compare.c -o obj/compare.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/regressor.c -o obj/regressor.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/classifier.c -o obj/classifier.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/local_layer.c -o obj/local_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/swag.c -o obj/swag.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/shortcut_layer.c -o obj/shortcut_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/activation_layer.c -o obj/activation_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/rnn_layer.c -o obj/rnn_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/gru_layer.c -o obj/gru_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/rnn.c -o obj/rnn.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/rnn_vid.c -o obj/rnn_vid.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/crnn_layer.c -o obj/crnn_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/demo.c -o obj/demo.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/tag.c -o obj/tag.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/cifar.c -o obj/cifar.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/go.c -o obj/go.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/batchnorm_layer.c -o obj/batchnorm_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/art.c -o obj/art.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/region_layer.c -o obj/region_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/reorg_layer.c -o obj/reorg_layer.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/lsd.c -o obj/lsd.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/super.c -o obj/super.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/voxel.c -o obj/voxel.o
gcc  -Wall -Wfatal-errors  -Ofast -c ./src/tree.c -o obj/tree.o> gcc  -Wall -Wfatal-errors  -Ofast obj/gemm.o obj/utils.o obj/cuda.o obj/deconvolutional_layer.o obj/convolutional_layer.o obj/list.o obj/image.o obj/activations.o obj/im2col.o obj/col2im.o obj/blas.o obj/crop_layer.o obj/dropout_layer.o obj/maxpool_layer.o obj/softmax_layer.o obj/data.o obj/matrix.o obj/network.o obj/connected_layer.o obj/cost_layer.o obj/parser.o obj/option_list.o obj/darknet.o obj/detection_layer.o obj/captcha.o obj/route_layer.o obj/writing.o obj/box.o obj/nightmare.o obj/normalization_layer.o obj/avgpool_layer.o obj/coco.o obj/dice.o obj/yolo.o obj/detector.o obj/layer.o obj/compare.o obj/regressor.o obj/classifier.o obj/local_layer.o obj/swag.o obj/shortcut_layer.o obj/activation_layer.o obj/rnn_layer.o obj/gru_layer.o obj/rnn.o obj/rnn_vid.o obj/crnn_layer.o obj/demo.o obj/tag.o obj/cifar.o obj/go.o obj/batchnorm_layer.o obj/art.o obj/region_layer.o obj/reorg_layer.o obj/lsd.o obj/super.o obj/voxel.o obj/tree.o -o darknet -lm -pthread

地味に警告が5件くらい出てるけど、make成功したー!

他の環境でやった時に発生したエラー

実はここ最近で、別の環境でも同じようにdarknetの環境構築をしていたんですが……

この時は、別のエラーが発生しました。

しかし今回このすんなりいった感じを見ると、MinGWのバージョン(というかそこからインストールした、C関連のファイルとか)が古いバージョンのせいで発生したのかもしれません。

その環境では、MinGWを結構前に入れて、そのままだったので。

念のため、その時発生したエラーと、解決方法を書いていきます。

同じようなものが出た方は、ご参考までに。

pthreadがないと言われた

「pthreadがない」と言われた場合の対処法です。

pthreadを入れて上げればOKです。

Pthread関係で必要なファイルをsourceforgeのmingwプロジェクトpthreadのページから次のファイルをダウンロードする.
・libpthread-2.8.0-3-mingw32-dll-2.tar.lzma
・pthreads-w32-2.8.0-3-mingw32-dev.tar.lzma
引用:demura.net | Windows用Pthreadインストール用メモ

ということで、pthreadのページからファイルをダウンロードします。

これらを解凍し、bin,lib,includeの中身を同名のフォルダにコピーする。

ファイルは、7zipなどを使えば解凍できます。

ダウンロード | 7-Zip

pid_tがないと言われた

sched.hを修正すればOKです。

この部分を探し出します。
「pid_t」で検索していれば出てくると思います。

#if defined(__MINGW32__) || defined(_UWIN)
#if PTW32_LEVEL >= PTW32_LEVEL_MAX
/* For pid_t */
#  include <sys/types.h>
/* Required by Unix 98 */
#  include <time.h>
#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
#else
typedef int pid_t;
#endif

それをこのように修正。

#if defined(__MINGW32__) || defined(_UWIN)
#if PTW32_LEVEL >= PTW32_LEVEL_MAX
/* For pid_t */
#  include <sys/types.h>
/* Required by Unix 98 */
#  include <time.h>
#else
typedef int pid_t;
#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
#else
typedef int pid_t;
#endif

具体的には「#  include <time.h>」の下に、この2行を追加する。

#else
typedef int pid_t;

解決方法は、こちらのサイトを参考にしました。

猫科研究所 - Pthreads-w32 2.8.0のバグ

timespec構造体が再定義されている(重複定義)

「timespec構造体が再定義されている」と言われた場合です。

c:\mingw\include\parts\time.h:65:8: error: redefinition of ‘struct timespec’
 struct timespec
        ^

「time.h」と「pthread.h」の両方で、timespec構造体が定義されているのが問題のようです。

なのでそれぞれの構造体の再定義ブロックに使っているdefineを、定義後にONしてあげるように変更しました。

・time.h

#if defined __need_struct_timespec && ! __struct_timespec_defined
/*
 * Structure timespec is mandated by POSIX, for specification of
 * intervals with the greatest precision supported by the OS kernel.
 * Although this allows for specification to nanosecond precision, do
 * not be deluded into any false expectation that such short intervals
 * can be realized on Windows; on Win9x derivatives, the metronome used
 * by the process scheduler has a period of ~55 milliseconds, while for
 * WinNT derivatives, the corresponding period is ~15 milliseconds; thus,
 * the shortest intervals which can be realistically timed will range
 * from 0..55 milliseconds on Win9x hosts, and from 0..15 ms on WinNT,
 * with period values normally distributed around means of ~27.5 ms
 * and ~7.5 ms, for the two system types respectively.
 */
struct timespec
{
  /* Period is sum of tv_sec + tv_nsec; use fundamental integer types
   * to avoid 32-bit vs. 64-bit time_t ambiguity.
   */
  long long    tv_sec;     /* seconds */
  long      tv_nsec;    /* nanoseconds */
};
# define __struct_timespec_defined  1
#define HAVE_STRUCT_TIMESPEC 1    /* 2017.03.28 y add > copy pthread.h redefinition block */
#endif

・pthread.h

#ifndef HAVE_STRUCT_TIMESPEC
#define HAVE_STRUCT_TIMESPEC 1
# define __struct_timespec_defined  1    /* 2017.03.28 y add > copy time.h redefinition block */
struct timespec {
        long tv_sec;
        long tv_nsec;
};
#endif /* HAVE_STRUCT_TIMESPEC */

……あとあとになって、tv_secが、long longとlongだからなんか問題出そうだな……と思いました。

ここは別の解決方法を考えたほうがいいかもしれません……

あとがき

darknetの環境構築についてでした。

正直MinGWのアプデ後のすんなりさを鑑みると、

  1. MinGWのアップデート
  2. darknetのインストール

という手順を踏んだほうが良いですね。

簡単にできるので、みなさんも是非やってみてくださいー!

とりあえず今回はビルド成功まで行ったので、次はお試し実行してみようと思います。

2017/04/08 追記:画像認識試してみました!

www.lisz-works.com