2020年7月30日木曜日

AlphaGoをやってみた。

AlphaGoは、数年前にGoogleの子会社のDeepMindが作った最強の囲碁プログラムです。
http://augmentingcognition.com/assets/Silver2017a.pdf



オリジナルはPythonで書かれているのですが、なんとC++版を実装してくれた人がいます。

https://github.com/leela-zero/leela-zero

おじさん、前からAlphaGoで遊んでみたかったんだよねぇ。
C++のコードはそんな大きくないので、頑張って,GPUがないおじさんのマシンでも動くように改良してビルドしてみました。
bootstを使っているのですが、おじさんboost嫌いなので、booastをとってこなくても動くようにしました。

ソースコードはこちら
https://drive.google.com/file/d/1JYpTM4r9i-KihoK_tVxzQoTNCrC7K4gr/view?usp=sharing


学習をするのに1700年かかるそうです。
おじさん暇なんですが、そんなに待ってる余裕ねーよ。
ということで学習済みデータを取ってきます。

学習済みデータが300Mバイトもある。
びょえー。


leelazを起動して

genmove w
genmove b

などのコマンドを打てば、AIが考えてくれるらしい。

-----------------------------
Leela: genmove w
Thinking at most 36.0 seconds...
NN eval=0.969207
Playouts: 12, Win: 81.57%, PV: Q4 D16 pass
Playouts: 83, Win: 61.85%, PV: pass Q4 D16 D4 Q16 R14 C3
Playouts: 187, Win: 59.55%, PV: pass Q4 D16 Q16 D4 F17 R3 R4
Playouts: 289, Win: 59.46%, PV: pass Q4 D16 Q16 D4 F17 R3 R4 Q3
Playouts: 410, Win: 59.52%, PV: pass Q4 D16 Q16 D4 F17 R3 R4 Q3
Playouts: 557, Win: 59.33%, PV: pass Q4 D16 D4 Q16 R14 C3 D3 C4
Playouts: 724, Win: 58.85%, PV: pass Q4 D16 Q16 D4 F17 R3 R4 Q3 O3
Playouts: 899, Win: 58.53%, PV: pass Q4 D16 Q16 D4 F17 R3 R4 Q3 O3
Playouts: 1036, Win: 58.33%, PV: pass Q4 D16 D4 Q16 C17 C16 D17 E16
Playouts: 1252, Win: 58.11%, PV: pass Q4 D16 Q16 D4 F17 R3 R4 Q3 O3
Playouts: 1405, Win: 58.07%, PV: pass Q4 D16 Q16 D4 F17 R3 R4 Q3 O3
Playouts: 1683, Win: 57.91%, PV: pass Q4 D16 Q16 D4 C3 D3 C4 D5 B6
Playouts: 1878, Win: 57.85%, PV: pass Q4 D16 Q16 D4 C3 D3 C4 D5 B6 O17
Playouts: 1989, Win: 57.84%, PV: pass Q4 D16 C17 D17 C16 D15 B14 R16 C4 E3 D5

  Q4 ->     269 (V: 59.61%) (LCB: 57.13%) (N:  1.29%) PV: Q4 D4 pass R3 Q3 R4 Q5 S6 Q16 D16 F17 R7 C14
pass ->    1440 (V: 57.18%) (LCB: 57.12%) (N: 89.81%) PV: pass Q4 D16 Q16 D4 C3 D3 C4 D5 B6 O17
 D16 ->     214 (V: 59.35%) (LCB: 56.67%) (N:  1.04%) PV: D16 Q16 pass C17 D17 C16 D15 B14 D4 Q4 O3 C13
  D4 ->     101 (V: 59.02%) (LCB: 55.24%) (N:  1.26%) PV: D4 Q16 pass Q4 D16 C3 D3 C4 D5 B6 O17 C7
8.2 average depth, 14 max depth
1586 non leaf nodes, 1.28 average children
2026 visits, 718331 nodes, 2024 playouts, 56 n/s

= Q4

NN eval=0.094774

  D3 ->    1707 (V: 21.96%) (LCB: 19.96%) (N:  3.07%) PV: D3 C5 D16 Q16 F4 C17 C16 D17 F17 E17 E16 F18
 R16 ->    1459 (V: 21.94%) (LCB: 19.78%) (N:  2.55%) PV: R16 D17 D3 P17 C15 Q15 R15 Q14 R13 D5 C5 C6 C4 D6 F4 H3
  C4 ->     982 (V: 22.09%) (LCB: 19.45%) (N:  0.49%) PV: C4 Q16 D17 E3 D5 D15 C15 C14 C16 D14 F17 D10 R3 R4
 Q17 ->     946 (V: 22.03%) (LCB: 19.35%) (N:  0.71%) PV: Q17 D4 C16 R15 P16 E16 E17 F17 D17 F16 C14 K16 R3 Q3
 C16 ->     461 (V: 21.73%) (LCB: 17.87%) (N:  1.71%) PV: C16 Q16 D3 C5 F4 E16 E17 F17 D17 F16 D14
 D16 ->    1420 (V: 19.99%) (LCB: 17.78%) (N: 29.75%) PV: D16 C17 D17 C16 C14 C15 D15 B14 D4 C13 D14 Q16 C18 B12 B17 B16 A16 B15 R3 R4 Q3
 D17 ->     346 (V: 21.57%) (LCB: 17.10%) (N:  1.74%) PV: D17 D4 R16 P16 P17 O17 Q17 O16 Q14 R12 R13 Q12 O14
  D4 ->     482 (V: 19.87%) (LCB: 16.06%) (N: 10.57%) PV: D4 D16 R16 P17 Q15 M17 R3 R4 Q3 P3 P2 O2 O3 P4 N2 Q2
 Q16 ->     401 (V: 18.65%) (LCB: 14.50%) (N: 13.88%) PV: Q16 D16 C4 E3 D5 H3 C17 C16 D17 E17 E18 F18 F17 E16 G18 D18
  R3 ->     233 (V: 18.36%) (LCB: 12.87%) (N:  8.57%) PV: R3 D16 Q3 P4 P3 O4 S5 D4 Q16 O3
  R6 ->      16 (V: 10.38%) (LCB:  0.00%) (N:  1.93%) PV: R6 Q16 D4 D16 C17 C16 D17 E17
  O3 ->       7 (V:  8.99%) (LCB:  0.00%) (N:  0.99%) PV: O3 D4 Q16 D16 C17 D17
 R17 ->       1 (V:  2.32%) (LCB:  0.00%) (N:  0.28%) PV: R17
  C3 ->       1 (V:  2.32%) (LCB:  0.00%) (N:  0.24%) PV: C3
 Q15 ->       1 (V:  2.25%) (LCB:  0.00%) (N:  0.29%) PV: Q15
 D15 ->       1 (V:  2.16%) (LCB:  0.00%) (N:  0.29%) PV: D15
 E16 ->       1 (V:  2.16%) (LCB:  0.00%) (N:  0.24%) PV: E16
 C17 ->       1 (V:  2.10%) (LCB:  0.00%) (N:  0.36%) PV: C17
10.0 average depth, 29 max depth
6794 non leaf nodes, 1.25 average children

8468 visits, 2977365 nodes


Passes: 0            Black (X) Prisoners: 0
Black (X) to move    White (O) Prisoners: 0

   a b c d e f g h j k l m n o p q r s t
19 . . . . . . . . . . . . . . . . . . . 19
18 . . . . . . . . . . . . . . . . . . . 18
17 . . . . . . . . . . . . . . . . . . . 17
16 . . . + . . . . . + . . . . . + . . . 16
15 . . . . . . . . . . . . . . . . . . . 15
14 . . . . . . . . . . . . . . . . . . . 14
13 . . . . . . . . . . . . . . . . . . . 13
12 . . . . . . . . . . . . . . . . . . . 12
11 . . . . . . . . . . . . . . . . . . . 11
10 . . . + . . . . . + . . . . . + . . . 10
 9 . . . . . . . . . . . . . . . . . . .  9
 8 . . . . . . . . . . . . . . . . . . .  8
 7 . . . . . . . . . . . . . . . . . . .  7
 6 . . . . . . . . . . . . . . . . . . .  6
 5 . . . . . . . . . . . . . . . . . . .  5
 4 . . . + . . . . . + . . . . .(O). . .  4
 3 . . . . . . . . . . . . . . . . . . .  3
 2 . . . . . . . . . . . . . . . . . . .  2
 1 . . . . . . . . . . . . . . . . . . .  1
   a b c d e f g h j k l m n o p q r s t

Hash: 4764FDB76CFE8FAC Ko-Hash: 7CBB65687BFB484F

Black time: 01:00:00
White time: 00:59:23
-----------------------------

できたけど、なんか一手打つのに10分くらいかかる・・・・・。
こういうのもGPUがないマシンでもいちおう動かせるんですね。


2020年7月28日火曜日

monodepthをやってみる

前回、最小のTensorflow2をつくることができたました。
そこで今回はこれを使って深度推定のmododepthをやってみたいと思います。

https://arxiv.org/pdf/1609.03677.pdf

monodepthは、深度推定のアルゴリズムの中では高速で正確らしいです。
最近はCPPのコードも充実してきています。
https://github.com/yan99033/monodepth-cpp
これはさっそく試さなくては。

python版のtensorflowはバージョンがちょっとでも違うと動かないですが、c++版の方は多少バージョンが違ってもきちんと動きます。
なので、おじさんはc++で頑張ります。

さくっと最小のtensorflow2で動くように改良。
ソースコードはこちら
https://drive.google.com/file/d/1_pxE6jmjXABKvtZgHkiJTu6aIzuJRTPv/view?usp=sharing

-----------------------
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN

#include <monodepth.h>

//#include <opencv2/opencv.hpp>
#include "opencv2_core.hpp"
#include "opencv2_imgproc.hpp"
#include "opencv2_imgproc_imgproc_c.h"
#include "opencv2_imgcodecs.hpp"

#ifdef _MSC_VER
#pragma comment(lib,"ws2_32.lib")
#endif

int main()
{
  int image_width = 1241;
  int image_height = 376;

  image_width = 1242;
  image_height = 375;

  monodepth::MonoDepth m(image_width, image_height, "model_city2kitti_vgg.pb");
  cv::Mat depth;

  std::string img_path = "/path/to/image/folder/";

  int number_of_images = 1000;

  //for (int i=0; i<number_of_images; i++)
  {
    //char index_buf[7]; sprintf(index_buf, "%06d", i); std::string index_s(index_buf);
    //cv::Mat image(cv::imread(img_path + index_s + ".png"));
    // std::cout << "read image in test monodepth" << std::endl;
    cv::Mat image(cv::imread("000027.png"));
      assert(!image.empty());

    m.inference(image, depth);

    // convert disparity to depth
    depth = 0.3128f / (depth + 0.00001f);

    double min_val, max_val;
    cv::Mat depthmap_visual;
    cv::threshold(depth, depthmap_visual, 50.0, 50.0, cv::THRESH_TRUNC); // apply threshold
    cv::minMaxLoc(depthmap_visual, &min_val, &max_val);
    depthmap_visual = 255 * (depthmap_visual - min_val) / (max_val - min_val);
    depthmap_visual.convertTo(depthmap_visual, CV_8U);
    cv::applyColorMap(depthmap_visual, depthmap_visual, 2); //COLORMAP_JET

    cv::Size img_size = image.size();
    int height = img_size.height * 2;
    int width = img_size.width;
    cv::Mat full(height, width, CV_8UC3);
    cv::Mat top(full, cv::Rect(0, 0, img_size.width, img_size.height));
    image.copyTo(top);
    cv::Mat bottom(full, cv::Rect(0, img_size.height, img_size.width, img_size.height));
    depthmap_visual.copyTo(bottom);

    cv::imwrite("top.png", top);
    cv::imwrite("bottom.png", bottom);
    cv::imwrite("full.png", full);
    //cv::namedWindow("FULL", CV_WINDOW_AUTOSIZE);
    //cv::imshow("FULL", full);
    //cv::waitKey(1);
  }

  return 0;
}
-----------------------

vggとresnetの学習済みデータが合わせて500Mバイトもあるけど、それ以外はなんか何事もなく簡単に作れてしまった。
結果はいかのとおり。


GPUがあると13fpsでると書いてあるけど、おじさんのCPUだけマシンだと1枚の画像を解析するだけでも数分間かかる・・・。
monodepthはCPUだけでも遅いけどどうにかできそうってことがわかった。
monodepthの日本語の記事がひとつしかない。日本の自動車メーカーとか大丈夫なんでしょうか?

Tensorflow2をビルドする

いつのまにかTensorflowのバージョンが2に上がっている。
以前はVisualStudioでビルドできなかったのですが、バージョンアップに伴いWindowsでも簡単にビルドできるようになったっぽいのでおじさんもビルドしてみました。

bazelでビルドするとビルド途中でエラーが・・・
なんでだよ。

なのでbazelを使わないでビルドしてみました。
VisualStudio2019に以下のファイル追加すればbazelを使わないほかのビルドシステムでビルドできるっぽいですね。

・tensorflow/core以下の全ファイル
・tensorflow/core/kernelsは必要なものだけをビルド
・double-conversion
・farmhash
・protocolbuffer
・eigen
・giflib
・turbojpeg
・libpng
・sqlite3
・grpc
・nsync
・absl
・re2
・zlib
・snappy
・json-cpp
・bazelによって自動生成されるops_xxxxx.cpp
・gentoolによって自動生成されるxxxxx.pb_text.cc、xxxxx.pb_text.h、xxxxx_pb_text-impl.h
・protocによって自動生成されるxxxxx.pb.cc、xxxxx.pb.h

基本的にはtensorflow/coreをどうにかビルドできればtensorflowは動きます。
gpuとかtpuとかrpcとかがファイル名に入っているものは、gpuとかtpuとかrpcを使わないのであればいらないっぽいです。
これらのファイルを全部VisualStudio2019に追加すれば、bazelを使わなくてもtensorflowをビルドすることができます。

tensorflow/core/kerners内のファイルをたくさんビルドしようとすると、コンパイル時にヒープ領域が足りなくなるようで、
その時は以下の設定をするとよいそうです。
https://kenkyu-note.hatenablog.com/entry/2019/11/01/193301

ファイル名を「tensorflow/core/hoge.cc」から「tensorflow_core_hoge.cc」のように名前を変えれば、全部のファイルを一つのディレクトリに入れてビルドすることもできます。

tensorflowはopencvとよく併用されるので、ついでにopencvのソースも一部入れます。

いつものようにtensorflow2でmnistをやってみます。
https://qiita.com/iwatake2222/items/d7cb2bd10a8bbb81cd8b
mnistはこのサイトを参考にします。

これをベースに最小のtensorflow2を作ってみました。
https://drive.google.com/file/d/1UzCRcFLTe-VF8LDn1jP2hZumXNOYfmFR/view?usp=sharing


いつものようにこの画像を認識させてみます。


-----------------------
prob of 0: 0.000
prob of 1: 0.001
prob of 2: 0.013
prob of 3: 0.043
prob of 4: 0.929
prob of 5: 0.003
prob of 6: 0.001
prob of 7: 0.006
prob of 8: 0.001
prob of 9: 0.003
-----------------------

できた!