darknetとかyoloで顔認識したい。失敗

 

■顔学習環境の作成

 

 core i5 のメモリ16GB搭載のマシンが余っていたので
 これに Geforce GT 1030 を入れて
 学習環境を作成する

 https://qiita.com/k_ikasumipowder/items/5e88ec45f958c35e05ed
 これのページどおりに実施すればOK

 

□OSインストール

 

 https://www.ubuntu.com/download/desktop
 から
 Ubuntu 18.04TLSをダウンロード。
 DVDに焼いて普通にインストール。全部デフォルトでOK

 

□いろいろインストール

 

sudo apt-get update
sudo apt-get upgrade

最新になるまで何度か行う。

 

sudo apt-get install -y vim csh flex gfortran libgfortran3 g++ ¥
                 cmake xorg-dev patch zlib1g-dev libbz2-dev ¥
                 libboost-all-dev openssh-server libcairo2 ¥
                 libcairo2-dev libeigen3-dev lsb-core ¥
                 lsb-base net-tools network-manager ¥
                 git-core git-gui git-doc xclip gdebi-core libffi-dev ¥
                 make build-essential libssl-dev zlib1g-dev libbz2-dev ¥
                 libreadline-dev libsqlite3-dev wget curl llvm ¥
                 libncurses5-dev libncursesw5-dev ¥
                 xz-utils tk-dev libffi-dev liblzma-dev python-openssl


□G++-7とBoostLibが動作しているか確認

 

・以下のファイルを作成
test_boost.cpp

 

#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>

int main()
{
    using namespace boost::lambda;
    typedef std::istream_iterator<int> in;

    std::for_each(
        in(std::cin), in(), std::cout << (_1 * 3) << " " );
}

 

・コンパイルして実行
g++-7 test_boost.cpp -o test_boost
echo 3 6 9 | ./test_boost

9 18 27と出力されればOK

 

□nvidia-driver のインストール

 

https://www.nvidia.com/Download/index.aspx

 

グラボに合っているドライバーを確認
(ダウンロードするわけではない)

 

sudo apt-get purge nvidia-*
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update

sudo apt-get install nvidia-driver-415
※nvidia-driver-415の部分をあなたのグラボと合わせる

 

□再起動

 

reboot
再起動を待つ

 

□GPUの状況を確認
 
nvidia-smi

 

こんな感じで出るっす。

 

miha@linux:~/test_boost$ nvidia-smi 
Sun Mar  3 09:58:14 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 415.27       Driver Version: 415.27       CUDA Version: 10.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GT 1030     Off  | 00000000:01:00.0 Off |                  N/A |
| 38%   35C    P0    N/A /  30W |    420MiB /  2000MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0       892      G   /usr/lib/xorg/Xorg                           182MiB |
|    0      1111      G   /usr/bin/gnome-shell                         157MiB |
|    0      1540      G   ...uest-channel-token=15854222783359571361    78MiB |
+-----------------------------------------------------------------------------+

 

miha@linux:~/test_boost$ 

GPU使っていればVolatile GPU-Utilの所の数字が上がるっす。
ちなみに、自分の環境ではGT1030が1枚ですが複数のGPU搭載の場合はここに何行か出てきます。

 

□CUDAのインストール

 

参考にしたページ
https://qiita.com/k_ikasumipowder/items/5e88ec45f958c35e05ed
に色々書いてあるが、
CUDA10.0はTensorFlowで動かないとか
2018/11/30時点でのTensorFlow 1.12.0での Software requirementsに従って
CUDAは9を採用する。

これ駄目。sudo apt-get install cudaをするとnvidia-driverが削除されるとの事。

sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub

wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_9.1.85-1_amd64.deb

sudo apt install ./cuda-repo-ubuntu1604_9.1.85-1_amd64.deb

wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64/nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb

sudo apt install ./nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb

sudo apt update

sudo apt install cuda9.0 cuda-cublas-9-0 cuda-cufft-9-0 cuda-curand-9-0 ¥
    cuda-cusolver-9-0 cuda-cusparse-9-0 libcudnn7=7.2.1.38-1+cuda9.0 ¥
    libnccl2=2.2.13-1+cuda9.0 cuda-command-line-tools-9-0

 

□cuDNNのインストール

 

https://developer.nvidia.com/rdp/form/cudnn-download-survey
にサインアップして

cuDNN Library for Linuxをダウンロード

cudnn-9.2-linux-x64-v7.5.0.56.tgz

 

□libcuptiをインストール

 

sudo apt-get install libcupti-dev

 

□ファイルを展開して所定の位置にコピー

 

tar -zxvf cudnn-9.2-linux-x64-v7.5.0.56.tgz
sudo cp -P cuda/lib64/libcudnn* /usr/local/cuda-9.0/lib64/
sudo cp cuda/include/cudnn.h /usr/local/cuda-9.0/include/
sudo chmod a+r /usr/local/cuda-9.0/include/cudnn.h /usr/local/cuda/lib64/libcudnn*

 

□pyenvを入れてpython環境を切り替えできるようにする

 

git clone https://github.com/yyuu/pyenv.git ~/.pyenv

 

・パスを通す

 

vi ~/.bashrc

以下の行を追加
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

 

□python3.6.8をインストール

 

pyenv install 3.6.8
pyenv global 3.6.8
pyenv rehash
python -V

 

□venvで仮想環境を作成する

 

cd
mkdir workspace
cd workspace
sudo apt-get install python3-venv
python3 -m venv TensorFlow
source TensorFlow/bin/activate

 

□tensorflowをインストールする

 

pip install tensorflow-gpu==1.12.0

 

□minstが動作するか確認する

 

vi test_mnist.py

 

以下の内容で作成

 

import tensorflow as tf
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)

 

・実行

 

python test_mnist.py

 

・こんな感じで実行される

 

(TensorFlow) miha@linux:~/workspace$ python test_mnist.py
Epoch 1/5
2019-03-03 10:21:47.707416: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2019-03-03 10:21:47.793110: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:964] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-03-03 10:21:47.793568: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1432] Found device 0 with properties: 
name: GeForce GT 1030 major: 6 minor: 1 memoryClockRate(GHz): 1.468
pciBusID: 0000:01:00.0
totalMemory: 1.95GiB freeMemory: 1.48GiB
2019-03-03 10:21:47.793587: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1511] Adding visible gpu devices: 0
2019-03-03 10:21:48.036911: I tensorflow/core/common_runtime/gpu/gpu_device.cc:982] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-03-03 10:21:48.036946: I tensorflow/core/common_runtime/gpu/gpu_device.cc:988]      0 
2019-03-03 10:21:48.036953: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1001] 0:   N 
2019-03-03 10:21:48.037173: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 1230 MB memory) -> physical GPU (device: 0, name: GeForce GT 1030, pci bus id: 0000:01:00.0, compute capability: 6.1)
   32/60000 [..............................] - ETA: 20:08 - loss: 2.4107 - acc:   544/60000 [..............................] - ETA: 1:16 - loss: 1.5640 - acc: 0 1056/60000 [..............................] - ETA: 41s - loss: 1.1520 - acc: 0. 1568/60000 [..............................] - ETA: 29s - loss: 0.9480 - acc: 0. 2080/60000 [>.............................] - ETA: 23s - loss: 0.8366 - acc: 0. 2592/60000 [>.............................] - ETA: 20s - loss: 0.7556 - acc: 0. 3104/60000 [>.............................] - ETA: 17s - loss: 0.6932 - acc: 0. 3616/60000 [>.............................] - ETA: 15s - loss: 0.6532 - acc: 0. 4096/60000 [=>............................] - ETA: 14s - loss: 0.6160 - acc: 0. 4544/60000 [=>............................] - ETA: 13s - loss: 0.5943 - acc: 0. 5024/60000 [=>............................] - ETA: 12s - loss: 0.5691 - acc: 0. 5536/60000 [=>............................] - ETA: 11s - loss: 0.5550 - acc: 0. 6016/60000 [==>...........................] - ETA: 11s - loss: 0.5339 - acc: 0. 6560/60000 [==>...........................] - ETA: 10s - loss: 0.5168 - acc: 0. 7072/60000 [==>...........................] - ETA: 10s - loss: 0.5001 - acc: 0. 7552/60000 [==>...........................] - ETA: 9s - loss: 0.4895 - acc: 0.8 8032/60000 [===>..........................] - ETA: 9s - loss: 0.4772 - acc: 0.8 8544/60000 [===>..........................] - ETA: 9s - loss: 0.4635 - acc: 0.8 9024/60000 [===>..........................] - ETA: 8s - loss: 0.4544 - acc: 0.8 9504/60000 [===>..........................] - ETA: 8s - loss: 0.4432 - acc: 0.810048/60000 [====>.........................] - ETA: 8s - loss: 0.4348 - acc: 0.810528/60000 [====>.........................] - ETA: 8s - loss: 0.4251 - acc: 0.811040/60000 [====>.........................] - ETA: 7s - loss: 0.4166 - acc: 0.811552/60000 [====>.........................] - ETA: 7s - loss: 0.4097 - acc: 0.8


・GPUの使用状況を確認

 

実行中に以下のコマンドで

 

nvidia-smi -l

 

GPUの使用状況を確認

Volatile GPU-Utilが73%になっているのでOK

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 415.27       Driver Version: 415.27       CUDA Version: 10.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GT 1030     Off  | 00000000:01:00.0 Off |                  N/A |
| 38%   37C    P0    N/A /  30W |   1811MiB /  2000MiB |     73%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0       892      G   /usr/lib/xorg/Xorg                           182MiB |
|    0      1111      G   /usr/bin/gnome-shell                         180MiB |
|    0      1540      G   ...uest-channel-token=15854222783359571361    76MiB |
|    0     21830      C   python                                      1361MiB |
+-----------------------------------------------------------------------------+


ここまででGPUが使用できる環境が整った

 

■顔の学習の元になる顔の写真と顔の座標のファイルを整備

 

学習させるには顔の写真と、その写真の中の何処が顔なのかを入力する必要があり。
その元になるファイルは色んなサイトで公開してもらっているようなので
これを使用する。

参考にしたページ
https://qiita.com/ha9kberry/items/1bc113cfcd9892a9ddbd
いつも助かっています。

 

□顔の学習のもとになる顔の写真と顔の座標のファイルをダウンロード

 

http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/

WIDER Face Training Images

Face annotations
をダウンロードして解凍する

こんな感じで
.
├── WIDER_train展開されます
│   └── images
│       ├── 0--Parade
│       │   ├── 0_Parade_Parade_0_1014.jpg
│       │   ├── 0_Parade_Parade_0_1019.jpg
│       │   ├── 0_Parade_Parade_0_1040.jpg
│       │   ├── 0_Parade_Parade_0_1041.jpg
  省略
│       ├── 1--Handshaking
│       │   ├── 1_Handshaking_Handshaking_1_102.jpg
│       │   ├── 1_Handshaking_Handshaking_1_105.jpg
│       │   ├── 1_Handshaking_Handshaking_1_113.jpg
 省略
│           ├── 9_Press_Conference_Press_Conference_9_944.jpg
│           ├── 9_Press_Conference_Press_Conference_9_946.jpg
│           └── 9_Press_Conference_Press_Conference_9_97.jpg
├── wider_face_split
    ├── readme.txt
    ├── wider_face_test.mat
    ├── wider_face_test_filelist.txt
    ├── wider_face_train.mat
    ├── wider_face_train_bbx_gt.txt
    ├── wider_face_val.mat
    └── wider_face_val_bbx_gt.txt

で、中を見ると集合写真とかのjpgが沢山と
 wider_face_train_bbx_gt.txtが顔の座標が入っている模様。

 

□Annotationファイル作成

 

参考ページを参考にして。
参考ページの人はJupyter Notebookを使用しているようなんですが
自分は違うので自分で環境整備します。

 

pip install opencv-python

 

で、ファイルを作成

 

vi generator.py

 

import os
import cv2
import math
import random

txt_file = 'wider_face_split/wider_face_train_bbx_gt.txt'
with open(txt_file) as f:
    num = f.read().count('jpg')
print('number of images:',num)

 

そのまま実行すると
number of images: 12880
となるんです。

参考ページによるとなんでかはわかりませんけど
「予め0--Parade〜20--Family_Groupのみ抽出」となっていますんで

wider_face_train_bbx_gt.txtを開いて
0--Parade〜20--Family_Groupだけ残す。

ちなみに、このファイルの番号が曲者で
普通に20--Family_Groupの後ろを削除すればOKと思うじゃないですが。
しかーし、よく見ると
20--Family_Groupのあとには21--Festival/21_Festival_Festival_21_14.jpgが有って
その後ろは22→23→・・・・と続きますが
29の次が3--Riot/3_Riot_Riot_3_189.jpgになるので注意です。

それと、もう一つ。
Ubuntuに最初から入っていたテキストエディターなんですが、
これでやると、セーブしたときにファイルが崩れます。
適当に他の行とくっついて以下のような行が発生して後ろの工程でエラーになりますので注意です。
「264--Dancing/4_Dancing_Dancing_4_71.jpg」

もう一回実行

(TensorFlow) miha@linux:~/workspace/test$ python generator.py 
number of images: 5451
(TensorFlow) miha@linux:~/workspace/test$ 

参考ページと同じでok


□Annotationファイル構成

 

0_Parade_marchingband_1_45.txt
0 0.68017578125 0.9162995594713657 0.0400390625 0.07342143906020558
0 0.02978515625 0.8127753303964758 0.0185546875 0.027900146842878122

- 各バウンディングボックスごとにクラス x座標 y座標 ボックス幅 ボックス高さ
- 座標はバウンディングボックスの中心座標
- 座標、幅・高さともに、画像の幅・高さに対する相対値
- Annotationファイルは、画像ファイルと同じディレクトリ内に保存

 

generator2.py

 

以下の内容で作成

 

import cv2

def generator():
    num = 4152
    with open("wider_face_train_bbx_gt.txt") as f:
        img_paths=[]

        for i in range(num):
            # 両端の空白や改行を除去して1行ずつ読み込む
            img_path=f.readline().strip()
            # 画像パス一覧取得
            img_paths.append(img_path)
            # 画像を読み込み幅・高さ取得
            im = cv2.imread(img_path)
            im_h, im_w, im_c = im.shape
            # '/'で分割
            split=img_path.split('/')
            # Annotationファイルを格納するディレクトリ取得
            dir_name=split[0]
            # Annotationファイル名作成
            file_name=split[1].replace('.jpg', '.txt')
            # ボックス数取得
            count = int(f.readline())
            readline=[]
            readlines=[]

            for j in range(count):
                readline=f.readline().split()
                # ボックスの左上座標を取得
                xmin=int(readline[0])
                ymin=int(readline[1])
                # ボックスの幅・高さを取得
                w=int(readline[2])
                h=int(readline[3])
                # ボックスの中央座標(相対値)を作成
                xcenter=str((xmin+w/2)/im_w)
                ycenter=str((ymin+h/2)/im_h)
                # ボックスの幅・高さを相対値に変換
                w=str(w/im_w)
                h=str(h/im_h)

                class_num='0'
                # クラス x座標 y座標 ボックス幅 ボックス高さを半角スペースで結合
                string=' '.join([class_num, xcenter, ycenter, w, h])
                readlines.append(string)
            # 改行で結合    
            readlines_str='¥n'.join(readlines)
            # 該当するディレクトリ内にAnnotationファイルを保存
            with open(dir_name+'/'+file_name, 'w') as j:
                j.write(readlines_str)

    # 画像パス一覧を出力
    return img_paths

img_paths = generator()

 

これを動かすのにディレクトリ構成を以下のように変更

.
├── 0--Parade
│   ├── 0_Parade_Parade_0_1014.jpg
│   ├── 0_Parade_Parade_0_1019.jpg
│   ├── 0_Parade_Parade_0_1040.jpg
 省略
├── 1--Handshaking
│   ├── 1_Handshaking_Handshaking_1_102.jpg
│   ├── 1_Handshaking_Handshaking_1_105.jpg
│   ├── 1_Handshaking_Handshaking_1_113.jpg
 省略
│   ├── 9_Press_Conference_Press_Conference_9_946.jpg
│   └── 9_Press_Conference_Press_Conference_9_97.jpg
├── generator2.py
└── wider_face_train_bbx_gt.txt

 

generator2.pyとwider_face_train_bbx_gt.txtをimagesの中に移動して

そこで
python generator2.py を実行。

結果はjpgファイルのjpg部分をtxtにしたファイルが作成される
.
├── 0--Parade
│   ├── 0_Parade_Parade_0_1014.jpg
│   ├── 0_Parade_Parade_0_1014.txt
│   ├── 0_Parade_Parade_0_1019.jpg
│   ├── 0_Parade_Parade_0_1019.txt
│   ├── 0_Parade_Parade_0_1040.jpg
│   ├── 0_Parade_Parade_0_1040.txt
 省略
├── 1--Handshaking
│   ├── 1_Handshaking_Handshaking_1_102.jpg
│   ├── 1_Handshaking_Handshaking_1_102.txt
│   ├── 1_Handshaking_Handshaking_1_105.jpg
│   ├── 1_Handshaking_Handshaking_1_105.txt
│   ├── 1_Handshaking_Handshaking_1_113.jpg
│   ├── 1_Handshaking_Handshaking_1_113.txt
 省略
│   ├── 9_Press_Conference_Press_Conference_9_946.jpg
│   ├── 9_Press_Conference_Press_Conference_9_946.txt
│   ├── 9_Press_Conference_Press_Conference_9_97.jpg
│   └── 9_Press_Conference_Press_Conference_9_97.txt
├── generator2.py
└── wider_face_train_bbx_gt.txt

 

□trainデータ、testデータそれぞれで使う画像のパス一覧テキストファイルを作成

プログラムを見るとfaceというディレクトリの中のファイル一覧を取ってくるようになっているようなのと、0--Parade〜20--Family_Group以外が有るとうまく行かないようなんで
以下の構成に変更

 

.
├── face
│   ├── 0--Parade
│   │   ├── 0_Parade_Parade_0_1014.jpg
│   │   ├── 0_Parade_Parade_0_1014.txt
│   │   ├── 0_Parade_Parade_0_1019.jpg
│   │   ├── 0_Parade_Parade_0_1019.txt
 省略
│   ├── 1--Handshaking
│   │   ├── 1_Handshaking_Handshaking_1_102.jpg
│   │   ├── 1_Handshaking_Handshaking_1_102.txt
│   │   ├── 1_Handshaking_Handshaking_1_105.jpg
│   │   ├── 1_Handshaking_Handshaking_1_105.txt
 省略
│       ├── 9_Press_Conference_Press_Conference_9_97.jpg
│       └── 9_Press_Conference_Press_Conference_9_97.txt
├── generator3.py
└── wider_face_split
    └── wider_face_train_bbx_gt.txt

 

・実行
 python generator3.py

 

以下のファイルができる

 

test.txt

face/18--Concerts/18_Concerts_Concerts_18_505.jpg
face/18--Concerts/18_Concerts_Concerts_18_973.jpg
face/18--Concerts/18_Concerts_Concerts_18_1008.jpg
face/18--Concerts/18_Concerts_Concerts_18_833.jpg
省略

test.txt
face/9--Press_Conference/9_Press_Conference_Press_Conference_9_550.jpg
face/9--Press_Conference/9_Press_Conference_Press_Conference_9_554.jpg
face/9--Press_Conference/9_Press_Conference_Press_Conference_9_10.jpg
face/9--Press_Conference/9_Press_Conference_Press_Conference_9_873.jpg
face/9--Press_Conference/9_Press_Conference_Press_Conference_9_639.jpg
face/9--Press_Conference/9_Press_Conference_Press_Conference_9_226.jpg

・結果的に以下のディレクトリ構成になる
.
├── face
│   ├── 0--Parade
│   │   ├── 0_Parade_Parade_0_1014.jpg
│   │   ├── 0_Parade_Parade_0_1014.txt
│   │   ├── 0_Parade_Parade_0_1019.jpg
│   │   ├── 0_Parade_Parade_0_1019.txt
 省略
│   ├── 1--Handshaking
│   │   ├── 1_Handshaking_Handshaking_1_102.jpg
│   │   ├── 1_Handshaking_Handshaking_1_102.txt
│   │   ├── 1_Handshaking_Handshaking_1_105.jpg
│   │   ├── 1_Handshaking_Handshaking_1_105.txt
 省略
│       ├── 9_Press_Conference_Press_Conference_9_97.jpg
│       └── 9_Press_Conference_Press_Conference_9_97.txt
├── generator3.py
├── test.txt
├── train.txt
└── wider_face_split
    └── wider_face_train_bbx_gt.txt


■DARKNETで学習させる

 

□DARKNERをインストール

 

git clone https://github.com/AlexeyAB/darknet.git

cd darknet

vi Makefile
以下の箇所を修正
 GPU=1
 CUDNN=1

make

 

□トラブル発生。

 

よくわからんがね。

makeでエラーって出るのさー。

cuda_runtime.hが無いと言われ。
findで探したパスを-Iに追加すると

 

今度は
curand.hが無いと言われ。
findでcurand.hを探しても見つからないのさー

ちょっと、わからないので
アプローチの方法を変更して
また今度だね。