레이블이 ibm인 게시물을 표시합니다. 모든 게시물 표시
레이블이 ibm인 게시물을 표시합니다. 모든 게시물 표시

2020년 12월 8일 화요일

IBM PowerAI (Watson ML Community Edition)이 설치된 Ubuntu ppc64le 기반의 docker image 만들기

 


먼저 다음 링크를 참조하여 ppc64le (IBM POWER9) nvidia-docker2 환경에서 Ubuntu 기반의 docker image를 만듭니다.  


http://hwengineer.blogspot.com/2019/05/ppc64le-ibm-power9-nvidia-docker2.html


참고로 ppc64le (IBM POWER9)에서의 CUDA 설치는 NVIDIA CUDA download page의 안내와 같이 아래처럼 진행하시면 됩니다.


# wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/ppc64el/cuda-repo-ubuntu1804_10.1.105-1_ppc64el.deb

# dpkg -i cuda-repo-ubuntu1804_10.1.105-1_ppc64el.deb

# apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/ppc64el/7fa2af80.pub

# apt-get update

# apt-get install cuda



또는 이미 만들어둔 docker image를 다음과 같이 pull 해와도 됩니다.


# docker pull bsyu/ubuntu18.04_cuda10-1_ppc64le:v0.1


이렇게 pull 받아온 docker image를 확인합니다.


root@unigpu:/files/docker# docker images

REPOSITORY                          TAG                 IMAGE ID            CREATED             SIZE

bsyu/ubuntu18.04_cuda10-1_ppc64le   v0.1                ef8dd4d654e7        2 hours ago         6.33GB

ubuntu                              18.04               ecc8dc2e4170        4 weeks ago         106MB


이 image를 다음과 같이 구동합니다.  


root@unigpu:/files/docker# docker run --runtime=nvidia -ti --rm bsyu/ubuntu18.04_cuda10-1_ppc64lel:v0.1 bash


이제 그 image 속에서 다음과 같이 IBM PowerAI (IBM Watson ML Community Edition)을 설치합니다.  이는 IBM이 마련한 conda channel을 등록하고 거기에서 conda install 명령을 수행하는 방식으로 설치됩니다.


# conda config --prepend channels https://public.dhe.ibm.com/ibmdl/export/pub/software/server/ibm-ai/conda/


# conda create --name wmlce_env python=3.6


# conda activate wmlce_env


# apt-get install openssh-server


# conda install powerai     


위와 같이 conda install powerai 명령을 내리면 tensorflow 뿐만 아니라 caffe, pytorch 등이 모두 설치됩니다.  가령 Tensorflow 1.14만 설치하고자 한다면 위 명령 대신 conda install tensorflow=1.14를 수행하시면 됩니다.


powerai 전체 package 설치는 network 사정에 따라 1~2시간이 걸리기도 합니다.  설치가 완료되면 다음과 같이 docker commit하여 docker image를 저장합니다.


# docker ps -a

CONTAINER ID        IMAGE                                   COMMAND             CREATED             STATUS              PORTS               NAMES

45fb663f025c        bsyu/ubuntu18.04_cuda10-1_ppc64le:v0.1   "bash"              42 seconds ago      Up 39 seconds                           elastic_gates


이어서 v0.2 등의 새로운 tag로 commit 하시면 됩니다.


[root@ac922 docker]# docker commit 45fb663f025c bsyu/ubuntu18.04_cuda10-1_ppc64le:v0.2



아래는 그렇게 만들어진 docker image들의 사용예입니다.   제가 만든 그런 image들은 https://hub.docker.com/u/bsyu 에 올려져 있습니다.



root@unigpu:~# docker run --runtime=nvidia -ti --rm bsyu/ubuntu18.04_cuda10-1_tf1.15_pytorch1.2_ppc64le:latest 


(wmlce_env) root@bdbf11e90094:/# python

Python 3.6.10 |Anaconda, Inc.| (default, Mar 26 2020, 00:22:27)

[GCC 7.3.0] on linux

Type "help", "copyright", "credits" or "license" for more information.


>>> import torch


>>> import tensorflow as tf

2020-05-29 04:53:09.637141: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudart.so.10.1


>>> sess=tf.Session()

2020-05-29 04:53:20.795027: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcuda.so.1

2020-05-29 04:53:20.825918: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1639] Found device 0 with properties:

name: Tesla V100-SXM2-16GB major: 7 minor: 0 memoryClockRate(GHz): 1.53

pciBusID: 0004:04:00.0

2020-05-29 04:53:20.827162: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1639] Found device 1 with properties:

name: Tesla V100-SXM2-16GB major: 7 minor: 0 memoryClockRate(GHz): 1.53

pciBusID: 0004:05:00.0

2020-05-29 04:53:20.828421: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1639] Found device 2 with properties:

name: Tesla V100-SXM2-16GB major: 7 minor: 0 memoryClockRate(GHz): 1.53

pciBusID: 0035:03:00.0

2020-05-29 04:53:20.829655: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1639] Found device 3 with properties:

name: Tesla V100-SXM2-16GB major: 7 minor: 0 memoryClockRate(GHz): 1.53

pciBusID: 0035:04:00.0

2020년 10월 27일 화요일

tf_cnn_benchmarks를 이용한 GPU 성능 벤치마크 테스트



Deep learning용 GPU 서버의 성능 측정은 역시 deep learning에 가장 많이 사용되는 tensorflow를 이용한 benchmark test를 돌려보는 것입니다.  구체적으로 어떤 GPU에서는 몇 images/sec의 속도가 나와야 한다는 기준은 존재하지 않습니다.  테스트에 사용되는 neural network의 종류와 사소한 parameter, 그리고 어떤 dataset을 이용하느냐에 따라 그 성능은 천차만별이기 때문입니다.  또 테스트를 위해 labeling된 image dataset을 구하는 것도 쉽지 않습니다.


그런데 이런 어려운 문제를 극복하고 GPU를 이용한 tensorflow를 이용한 benchmark test를 수행하는 방법이 있습니다.  Tensorflow github에 공개된 tf_cnn_benchmarks를 이용하는 것입니다.  이 테스트는 더 이상 update되고 있지는 않지만 다음과 같은 장점이 있어서 아직도 널리 쓰이고 있습니다.


1) 사용방법이 간단

2) GPU 개수를 조절해가며 테스트 가능

3) CPU만으로도 테스트하여 CPU 대비 GPU 성능도 평가 가능

4) Test용 image dataset을 별도로 준비하지 않아도 python code에서 합성하여 사용

5) 성능 평가 수치를 images/sec로 간단명료하게 제시


이를 POWER9 processor를 장착한 IBM POWER 서버에서 수행하기 위해서는 먼저 다음과 같이 anaconda package를 download 받아 설치합니다.


[cecuser@p1226-kvm1 ~]$ wget https://repo.anaconda.com/archive/Anaconda3-2020.07-Linux-ppc64le.sh


[cecuser@p1226-kvm1 ~]$ chmod a+x Anaconda3-2020.07-Linux-ppc64le.sh


[cecuser@p1226-kvm1 ~]$ ./Anaconda3-2020.07-Linux-ppc64le.sh


Do you accept the license terms? [yes|no]

[no] >>> yes


[/home/cecuser/anaconda3] >>>


Do you wish the installer to initialize Anaconda3

by running conda init? [yes|no]

[no] >>> yes



Anaconda 설치가 끝난 뒤 profile을 수행하면 conda environment가 가동됩니다.


[cecuser@p1226-kvm1 ~]$ . ~/.bashrc


(base) [cecuser@p1226-kvm1 ~]$


이제 IBM OPEN-CE (구 명칭 IBM PowerAI 또는 Watson Machine Learning Community Edition), 즉 IBM ppc64le 환경에서 쉽게 deep leanring 관련 open source conda package를 설치할 수 있도록 해주는 conda channel을 등록합니다.


(base) [cecuser@p1226-kvm1 ~]$ conda config --prepend channels https://public.dhe.ibm.com/ibmdl/export/pub/software/server/ibm-ai/conda/


이 tf_cnn_benchmarks는 python 3.6 환경에서 수행하므로 다음과 같이 python 3.6용 conda virtual environment를 생성합니다.  여기서는 이름을 wmlce_env로 정했습니다.


(base) [cecuser@p1226-kvm1 ~]$ conda create --name wmlce_env python=3.6


방금 만든 wmlce_env 환경을 activate 합니다.  


(base) [cecuser@p1226-kvm1 ~]$ conda activate wmlce_env


이제 prompt 맨 앞부분이 (wmlce_env)로 바뀐 것을 보실 수 있습니다.  이제 OPEN-CE를 설치합니다.  구명칭인 PowerAI라는 이름의 패키지를 설치하시면 됩니다.  네트워크 환경에 따라 시간이 꽤 걸릴 수 있습니다.  (30분 ~ 몇 시간)


(wmlce_env) [cecuser@p1226-kvm1 ~]$ conda install powerai


그러고 난 뒤, 다음과 같이 tensorflow의 하위 github인 benchmarks를 clone 합니다.


(wmlce_env) [cecuser@p1226-kvm1 ~]$ git clone https://github.com/tensorflow/benchmarks


이제 그 중 tf_cnn_benchmarks로 들어갑니다.


(wmlce_env) [cecuser@p1226-kvm1 ~]$ cd benchmarks/scripts/tf_cnn_benchmarks


이 directory에 들어있는 tf_cnn_benchmarks.py를 수행하면 됩니다.  이때 다음과 같은 parameter를 주고 수행하면 됩니다.


먼저, GPU를 1개 이용한 테스트입니다.   아래 테스트는 NVIDIA P100 GPU를 이용한 것입니다만 공식적인 수치는 아니며 환경에 따라 또 다른 수치가 나올 수 있으니 참고용으로만 쓰십시요.


(wmlce_env) [cecuser@p1226-kvm1 tf_cnn_benchmarks]$ python tf_cnn_benchmarks.py --num_gpus=1 --batch_size=32 --model=resnet50 --variable_update=parameter_server --data_format=NHWC --num_batches=640


Done warm up

Step    Img/sec total_loss

1       images/sec: 224.9 +/- 0.0 (jitter = 0.0)        8.108

10      images/sec: 225.9 +/- 0.2 (jitter = 0.6)        8.122

20      images/sec: 226.0 +/- 0.2 (jitter = 0.4)        7.983

...

620     images/sec: 221.4 +/- 0.6 (jitter = 0.7)        7.772

630     images/sec: 221.4 +/- 0.6 (jitter = 0.7)        7.676

640     images/sec: 221.5 +/- 0.6 (jitter = 0.7)        7.779

----------------------------------------------------------------

total images/sec: 221.40



만약 GPU 2장을 쓰고 싶으시면 아래와 같이 --num_gpus=1 대신 --num_gpus=2를 쓰시면 됩니다.


(wmlce_env) [cecuser@p1226-kvm1 tf_cnn_benchmarks]$ python tf_cnn_benchmarks.py --num_gpus=2 --batch_size=32 --model=resnet50 --variable_update=parameter_server --data_format=NHWC --num_batches=640



GPU의 성능이 제대로 나오고 있는 것인지 보는 가장 직관적이고 좋은 방법은 이 동일한 테스트를 CPU로 돌려보는 것입니다.  아래와 같이 --device=CPU를 쓰시면 CPU로만 수행이 가능합니다.  역시 CPU 성능 및 개수와 밀접한 상관이 있으므로, 아래 수치는 참고로만 쓰십시요.



(wmlce_env) [cecuser@p1226-kvm1 tf_cnn_benchmarks]$ python tf_cnn_benchmarks.py --device=CPU --batch_size=32 --model=resnet50 --variable_update=parameter_server --data_format=NHWC --num_batches=640


Done warm up

Step    Img/sec total_loss

1       images/sec: 3.0 +/- 0.0 (jitter = 0.0)  8.108

10      images/sec: 3.0 +/- 0.0 (jitter = 0.0)  8.122

20      images/sec: 2.9 +/- 0.0 (jitter = 0.0)  7.983

...

620     images/sec: 2.9 +/- 0.0 (jitter = 0.0)  7.750

630     images/sec: 2.9 +/- 0.0 (jitter = 0.0)  7.667

640     images/sec: 2.9 +/- 0.0 (jitter = 0.0)  7.805

----------------------------------------------------------------

total images/sec: 2.91

----------------------------------------------------------------




참고로 위 GPU 테스트를 수행할 떄의 nvidia-smi tool을 보면 아래와 같이 GPU 사용률을 보여줍니다.  



Tue Oct 20 04:23:57 2020

+-----------------------------------------------------------------------------+

| NVIDIA-SMI 440.33.01    Driver Version: 440.33.01    CUDA Version: 10.2     |

|-------------------------------+----------------------+----------------------+

| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |

| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |

|===============================+======================+======================|

|   0  Tesla P100-SXM2...  On   | 00000001:00:01.0 Off |                    0 |

| N/A   51C    P0   240W / 300W |  15677MiB / 16280MiB |     96%      Default |

+-------------------------------+----------------------+----------------------+


+-----------------------------------------------------------------------------+

| Processes:                                                       GPU Memory |

|  GPU       PID   Type   Process name                             Usage      |

|=============================================================================|

|    0     16243      C   python                                     15667MiB |

+-----------------------------------------------------------------------------+



2020년 6월 12일 금요일

tf_cnn_benchmarks.py를 이용한 Tensorflow Large Model Support (LMS)의 demo


IBM Watson Machine Learning Community Edition (WML-CE) 1.6.2 속에 포함된  Tensorflow 1.15를 이용하여 large model support (LMS)에 대한 demo를 해보는 방법입니다.

** 아래 환경은 IBM CECC cloud에서 제공되는 가상화 환경의 P100 GPU를 이용했기 때문에, training 성능 자체는 떨어진다는 점을 인지해주시기 바랍니다.


가장 간단한 것은 WML-CE 속에 들어있는 tf_cnn_benchmarks suite를 이용하는 것입니다.

먼저 아래 명령어를 이용하여 tf_cnn_benchmarks suite를 원하는 directory에 copy합니다.  (이건 optional step이고, 그냥 해당 directory로 직접 찾아 들어가도 됩니다.)

(wmlce_162) [cecuser@p1290-kvm1 ~]$ ./anaconda3/envs/wmlce_162/bin/install_tf_cnn_benchmarks .

(wmlce_162) [cecuser@p1290-kvm1 ~]$ cd tf_cnn_benchmarks

(wmlce_162) [cecuser@p1290-kvm1 tf_cnn_benchmarks]$ ls
all_reduce_benchmark.py                   cnn_util.py                 mlperf_test.py     test_data
all_reduce_benchmark_test.py              cnn_util_test.py            models             test_util.py
allreduce.py                              coco_metric.py              platforms          tf_cnn_benchmarks.py
allreduce_test.py                         constants.py                preprocessing.py   variable_mgr.py
batch_allreduce.py                        convnet_builder.py          __pycache__        variable_mgr_util.py
benchmark_cnn_distributed_test.py         datasets.py                 README.md          variable_mgr_util_test.py
benchmark_cnn_distributed_test_runner.py  flags.py                    run_tests.py
benchmark_cnn.py                          leading_indicators_test.py  ssd_constants.py
benchmark_cnn_test.py                     mlperf.py                   ssd_dataloader.py


다만 여기서 benchmark_cnn.py 에서 일부 source code를 수정해야 합니다.  이는 source code 안에 들어있는 LMS 관련 parameter인 lms_swapout_threshold 관련 bug 때문입니다.   원래 값인 -1을 그대로 놔두면 원래는 auto-tuning이 되어야 하는데, TF 버전 등과의 호환 문제로 거기서 에러가 나므로, 일단은 그냥 1로 수정합니다.

(wmlce_162) [cecuser@p1290-kvm1 tf_cnn_benchmarks]$ vi benchmark_cnn.py
...
#flags.DEFINE_integer('lms_swapout_threshold', -1,
flags.DEFINE_integer('lms_swapout_threshold', 1,
...


그렇게 한 뒤 아래와 같이 tf_cnn_benchmarks.py를 수행해 봅니다.   여기서는 batch_size를 150으로 주고 해봅니다.  일단 잘 수행되는 것을 보실 수 있습니다.

(wmlce_162) [cecuser@p1290-kvm1 tf_cnn_benchmarks]$ python tf_cnn_benchmarks.py --batch_size=150 --num_batches=100 --model=resnet50  --num_gpus=1 --display_every=10
...
I0612 04:14:43.269922 140736229690240 session_manager.py:502] Done running local_init_op.
Running warm up
2020-06-12 04:14:45.534222: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcublas.so.10
2020-06-12 04:14:45.728889: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudnn.so.7
Done warm up
Step    Img/sec total_loss
1       images/sec: 255.8 +/- 0.0 (jitter = 0.0)        7.820
10      images/sec: 255.8 +/- 0.1 (jitter = 0.4)        8.082
20      images/sec: 255.7 +/- 0.1 (jitter = 0.4)        7.856
30      images/sec: 255.6 +/- 0.1 (jitter = 0.3)        7.832
40      images/sec: 255.5 +/- 0.0 (jitter = 0.3)        7.879
50      images/sec: 255.5 +/- 0.0 (jitter = 0.2)        7.701
60      images/sec: 255.5 +/- 0.0 (jitter = 0.2)        7.918
70      images/sec: 255.5 +/- 0.0 (jitter = 0.2)        7.845
80      images/sec: 255.4 +/- 0.0 (jitter = 0.2)        7.750
90      images/sec: 255.3 +/- 0.0 (jitter = 0.2)        7.806
100     images/sec: 255.3 +/- 0.0 (jitter = 0.3)        7.856
----------------------------------------------------------------
total images/sec: 255.22
----------------------------------------------------------------


이때 OS에서 nmon tool을 이용해서 관찰해보면, host RAM의 메모리 사용량이 5GB 정도에 불과하고 tf_cnn_benchmarks의 data size도 32GB 정도, res set size도 2.1GB 정도에 불과한 것을 보실 수 있습니다.


x Memory and Swap qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqx
x PageSize:64KB  RAM-Memory  Swap-Space       High-Memory     Low-Memory         x
x Total (MB)        63392.2      4094.5       - not in use   - not in use        x
x Free  (MB)        58734.8      3518.5                                          x
x Free Percent         92.7%       85.9%                                         x

x Top Processes Procs=365-mode=3-1=Base 3=Perf 4=Size 5=I/O[RootOnly] u=Argsqqqqqx
x  PID    %CPU  Size   Res   Res   Res   Res Shared   Faults  Command            x
x          Used    KB   Set  Text  Data   Lib    KB  Min  Maj                    x
x   13671  42.1 32142m 2153m 3200  2866m    0 633216  12    0 tf_cnn_benchmar    x



이제 batch_size를 200으로 늘려 보겠습니다.  그러면 16GB에 불과한 P100 GPU의 메모리가 꽉 차서 결국 Out-Of-Memory(OOM) error가 발생합니다.

(wmlce_162) [cecuser@p1290-kvm1 tf_cnn_benchmarks]$ python tf_cnn_benchmarks.py --batch_size=200 --num_batches=100 --model=resnet50  --num_gpus=1 --display_every=10
...
tensorflow.python.framework.errors_impl.ResourceExhaustedError: 2 root error(s) found.
  (0) Resource exhausted: OOM when allocating tensor with shape[200,2048,7,7] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc
         [[node tower_0/v/cg/resnet_v113/conv46/conv2d/Conv2D (defined at /home/cecuser/anaconda3/envs/wmlce_162/lib/python3.6/site-packages/tensorflow_core/python/framework/ops.py:1748) ]]
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.

         [[main_fetch_group/_566]]
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.

  (1) Resource exhausted: OOM when allocating tensor with shape[200,2048,7,7] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc
         [[node tower_0/v/cg/resnet_v113/conv46/conv2d/Conv2D (defined at /home/cecuser/anaconda3/envs/wmlce_162/lib/python3.6/site-packages/tensorflow_core/python/framework/ops.py:1748) ]]
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.

0 successful operations.
0 derived errors ignored.
...


하지만 동일한 batch_size를 그대로 주더라도, LMS를 적용하여 --lms=True 옵션을 주고 수행해보면 (비록 많이 느려졌지만) error 없이 수행되는 것을 보실 수 있습니다.


(wmlce_162) [cecuser@p1290-kvm1 tf_cnn_benchmarks]$ python tf_cnn_benchmarks.py --batch_size=200 --num_batches=100 --model=resnet50  --num_gpus=1 --display_every=10 --lms=True
....
I0612 04:27:06.439511 140735558208384 lms.py:1275] [LMS][0] [Simulator] Available memory for simulation: -0.09 GiB (memory ratio: 0.9)
I0612 04:27:06.439677 140735558208384 lms.py:1275] [LMS][0] [Simulator] Available CPU memory for simulation: 64.0 GiB
I0612 04:27:06.440271 140735558208384 lms.py:1275] [LMS][0] LMS will use the latest parameter set found by Simulator for the best performance. However, if you encounter an out-of-memory error, please manually use the previous parameter set found by Simulator.
I0612 04:27:06.440359 140735558208384 lms.py:1275] [LMS][0]   sync_mode: 3 (Synchronous memory copy between host and device)
I0612 04:27:06.440439 140735558208384 lms.py:1275] [LMS][0]   swapout_threshold: 1
I0612 04:27:06.440520 140735558208384 lms.py:1275] [LMS][0]   swapin_ahead: -1 (ignored since sync_mode is 3)
I0612 04:27:06.440600 140735558208384 lms.py:1275] [LMS][0]   swapin_groupby: -1 (ignored since sync_mode is 3)
I0612 04:27:06.869183 140735558208384 lms.py:1275] [LMS][0] Added 425 operations to the model (180 swap-out operations (20.33 GiB) and 245 swap-in operations (31.36 GiB))
I0612 04:27:06.869335 140735558208384 lms.py:1275] [LMS][0] Editing model for LMS, took: 799.3814945220947 ms
...
Running warm up
2020-06-12 04:27:15.098435: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcublas.so.10
2020-06-12 04:27:15.371592: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudnn.so.7
Done warm up
Step    Img/sec total_loss
1       images/sec: 21.1 +/- 0.0 (jitter = 0.0) 7.988
10      images/sec: 21.1 +/- 0.0 (jitter = 0.1) 7.900
20      images/sec: 21.1 +/- 0.0 (jitter = 0.1) 7.914
30      images/sec: 21.1 +/- 0.0 (jitter = 0.0) 8.043
40      images/sec: 21.1 +/- 0.0 (jitter = 0.0) 7.880
50      images/sec: 21.1 +/- 0.0 (jitter = 0.0) 7.903
60      images/sec: 21.1 +/- 0.0 (jitter = 0.0) 7.889
70      images/sec: 21.1 +/- 0.0 (jitter = 0.0) 7.770
80      images/sec: 21.1 +/- 0.0 (jitter = 0.0) 7.906
90      images/sec: 21.1 +/- 0.0 (jitter = 0.1) 7.813
100     images/sec: 21.1 +/- 0.0 (jitter = 0.1) 7.824
----------------------------------------------------------------
total images/sec: 21.13
----------------------------------------------------------------


이때 host의 OS를 관찰해보면 host RAM 사용량이 22GB 정도로 대폭 늘었고, tf_cnn_benchmarks의 data size도 50GB 정도, res set size도 19GB 정도로 대폭 늘어난 것을 보실 수 있습니다.


x Memory and Swap qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqx
x PageSize:64KB  RAM-Memory  Swap-Space       High-Memory     Low-Memory         x
x Total (MB)        63392.2      4094.5       - not in use   - not in use        x
x Free  (MB)        41505.6      3490.5                                          x
x Free Percent         65.5%       85.2%                                         x

x Top Processes Procs=365-mode=3-1=Base 3=Perf 4=Size 5=I/O[RootOnly] u=Argsqqqqqx
x  PID    %CPU  Size   Res   Res   Res   Res Shared   Faults  Command            x
x          Used    KB   Set  Text  Data   Lib    KB  Min  Maj                    x
x   13427  10.4 49577m19322m 3200  3399m    0 176710   0    0 tf_cnn_benchmar    x




2019년 4월 25일 목요일

RAPIDS.ai on IBM POWER9 : ppc64le 환경에서 cuDF를 source로부터 build하기



RAPIDS.ai는 NVIDIA가 요즘 공을 들이고 있는 GPU를 이용한 data science platform입니다.  그 핵심 모듈이 cuDF와 cuML입니다.  이 모듈들은 최근 발표된 IBM PowerAI toolkit에도 포함되어 있습니다.  ( https://www.ibm.com/support/knowledgecenter/en/SS5SF7_1.6.0/navigation/pai_getstarted_rapids.html 참조)

다만 IBM PowerAI는 CUDA 10.1만을 지원하는 등 제약 사항이 일부 있기 때문에 모든 환경에서 유연하게 사용하시기가 곤란한 부분이 있을 수 있습니다.  그래도 어차피 RAPIDS는 open source니까, ppc64le 아키텍처 위에서 그냥 source로부터 build하시면 됩니다.  이번 posting에서는 cuDF를 Ubuntu 18.04 ppc64le에서 build하는 방법을 보시겠습니다.

일단 아래와 같이 cuda 10.0을 설치합니다.

~/files$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/ppc64el/cuda-repo-ubuntu1804_10.0.130-1_ppc64el.deb

~/files$ sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/ppc64el/7fa2af80.pub

~/files$ sudo apt-get update

~/files$ sudo apt-get install cuda

~/files$ sudo tar -xvf ./cudnn-10.0-linux-ppc64le-v7.5.0.56.solitairetheme8 -C /usr/local

~/files$ sudo tar -xvf ./nccl_2.4.2-1+cuda10.0_ppc64le.txz -C /usr/local

Python은 Anaconda3를 설치하여 Python 3.6.8을 사용했습니다. 

~/files$  which python
/home/u0017649/anaconda3/bin/python

먼저 conda install 명령으로 아래 package들을 설치합니다.

~/files$ conda install numpy six setuptools cython pandas pytest cmake flatbuffers rapidjson boost boost-cpp thrift snappy zlib gflags brotli lz4-c zstd arrow -c conda-forge

먼저 유의하실 것은 Ubuntu 18.10의 기본 gcc 버전인 gcc-8은 CUDA 10.0을 지원하지 않습니다.  그런데 또 현재 cudf v0.7.0은 아직 CUDA 10.1을 지원하지 않습니다.  그래서 해결책은 Ubuntu에 gcc-7과 g++-7을 설치해야 합니다.

~/files$ sudo apt-get install -y gcc-7 gcc-7-base gcc-7-powerpc-linux-gnu libgcc-7-dev g++-7

~/files$ sudo rm /usr/bin/gcc /usr/bin/g++

~/files$ sudo ln -s /usr/bin/gcc-7 /usr/bin/gcc

~/files$ sudo ln -s /usr/bin/g++-7 /usr/bin/g++

먼저, RMM을 설치합니다.

~/files$ git clone --recursive  https://github.com/rapidsai/rmm.git

~/files$ cd rmm

~/files/rmm$ rm -rf build

~/files/rmm$ mkdir build && cd build

~/files/rmm/build$ cmake ..

~/files/rmm/build$ make -j2

~/files/rmm/build$ sudo make install

~/files/rmm/build$ cd ../python

~/files/rmm/python$ python setup.py install


다음으로는 custrings를 설치합니다.

~/files$ git clone --recursive https://github.com/rapidsai/custrings.git

~/files$ cd custrings/cpp

~/files/custrings/cpp$ mkdir build && cd build

~/files/custrings/cpp/build$ cmake ..

~/files/custrings/cpp$ make -j2

~/files/custrings/cpp$ sudo make install

다음으로는 thrift를 설치합니다. 

~/files$ git clone --recursive https://github.com/apache/thrift

~/files$ cd thrift/

~/files/thrift$ sudo apt-get install libssl-dev

~/files/thrift$ ./bootstrap.sh

~/files/thrift$ ./configure

~/files/thrift$ cd build

~/files/thrift/build$ cmake ..

~/files/thrift/build$ make -j2

~/files/thrift/build$ sudo make install

다음으로는 Arrow를 설치합니다. 

~/files$ sudo apt-get install libdouble-conversion1 libghc-double-conversion-dev libdouble-conversion-dev libgoogle-glog-dev libgoogle-glog0v5 thrift-compiler libthrift-java

~/files$ git clone https://github.com/apache/arrow.git

~/files$ cd arrow/cpp

~/files/arrow/cpp$ mkdir build && cd build

여기서 특정 header 파일을 아래와 같이 일부 수정해야 합니다.  이 error는 꼭 ppc64le 환경에서만 나는 것은 아니고, 나중에 patch가 될 예정입니다.   ( error: there are no arguments to ‘DCHECK’ that depend on a template parameter, so a declaration of ‘DCHECK’ must be available 이라는 error 방지용.  https://github.com/apache/arrow/issues/4014 참조)

~/files/arrow/cpp/build$ vi ~/files/arrow/cpp/src/arrow/util/sse-util.h
...
#include "logging.h"   # 이 include 문을 삽입해야 함


~/files/arrow/cpp/build$ cmake -DCMAKE_BUILD_TYPE=release -DARROW_PYTHON=on -DARROW_PLASMA=on -DARROW_BUILD_TESTS=OFF  -DARROW_PARQUET=ON ..

~/files/arrow/cpp/build$ make -j2

~/files/arrow/cpp/build$ sudo make install

~/files/arrow/cpp/build$ cd ../../python

~/files/arrow/python$ export ARROW_HOME=/usr/local

기본으로 설치되는 Cython 버전이 맞지 않으므로, 반드시 0.29 버전으로 새로 설치해야 하더라고요.

~/files/arrow/python$ pip install Cython==0.29

~/files/arrow/python$ MAKEFLAGS=-j2 python setup.py build_ext --build-type=release --with-parquet --inplace

~/files/arrow/python$ MAKEFLAGS=-j2 python setup.py build_ext --build-type=release --with-parquet --bundle-arrow-cpp bdist_wheel

위에서 생성되는 wheel file을 아래와 같이 설치하시면 됩니다.

~/files/arrow/python$ pip install dist/pyarrow-0.13.1.dev40+g6907d972.d20190408-cp37-cp37m-linux_ppc64le.whl


이제 비로소 cudf를 설치할 수 있게 되었습니다.

~/files$ git clone --recursive https://github.com/rapidsai/cudf.git

~/files$ cd cudf

~/files/cudf$ git submodule update --init --remote --recursive

여기서 역시 아래의 file 하나를 수정해야 합니다.  이 역시 ppc64le에 국한된 문제는 아니고, 아래 link에서 해결된 것인데, 나중에 patch로 반영될 예정입니다.  ( https://github.com/rapidsai/cudf/issues/1384 참조)

~/files/cudf$ vi cpp/tests/hashing/hash_partition_test.cu
...
  // The indices of the columns that will be hashed to determine the partitions
  constexpr static const std::array<int, sizeof...(cols)> cols_to_hash{{cols...}};
};
 template< typename tuple_of_vectors       # 이하 4줄의 line을 추가하시면 됩니다.
           gdf_hash_func hash,
           int... cols>
 constexpr const std::array<int, sizeof...(cols)> TestParameters<tuple_of_vectors, hash, cols...>::cols_to_hash;


그 다음은 아래와 같이 build하시면 됩니다.

~/files/cudf$ cd cpp

~/files/cudf/cpp$ mkdir build && cd build

~/files/cudf/cpp/build$ cmake .. -DCMAKE_INSTALL_PREFIX=~/anaconda3

~/files/cudf/cpp/build$ make -j2

~/files/cudf/cpp/build$ sudo make install

root@8f2f82cf3e22:/mnt/cudf# cd python

root@8f2f82cf3e22:/mnt/cudf/python# python setup.py build_ext --inplace

root@8f2f82cf3e22:/mnt/cudf/python# python setup.py install
...
Best match: numpy 1.16.2
Adding numpy 1.16.2 to easy-install.pth file
Installing f2py script to /opt/anaconda3/bin
Installing f2py3 script to /opt/anaconda3/bin
Installing f2py3.6 script to /opt/anaconda3/bin

Using /opt/anaconda3/lib/python3.6/site-packages
Finished processing dependencies for cudf==0.7.0.dev0+679.g97833593.dirty

2019년 3월 18일 월요일

H2O Driverless AI를 통한 인물별 의료비 예측


H2O Driverless AI (이하 H2O DAI)의 또다른 유력한 use case인 보험 업무에 대해 살펴보겠습니다.   보험사에게 있어 의료비가 많이 들 것 같은 사람을 골라내는 것은 보험사의 수익과 직결되는 무척 중요한 일입니다.  아래 Kaggle site에서 얻은 환자 기본 정보 및 각 환자에게 든 의료비에 대한 dataset을 이용하여 H2O DAI가 예상 의료비를 얼마나 정확히 측정하는지 테스트 해보겠습니다.

https://www.kaggle.com/mirichoi0218/insurance

이 dataset에는 다음과 같은 칼럼들이 있습니다. 

age  나이
sex  성별
bmi  비만도
children  자녀수
smoker  흡연여부
region  사는 지역
charges  의료비

보험사에서 예측하고 싶은 것은 물론 맨 마지막 칼럼인 charges 부분일 것입니다.  이제 H2O DAI를 이용하여 어떻게 이 dataset으로부터 특정 조건을 가진 인물의 예상 의료비를 뽑아낼 수 있는지 step by step으로 알아보시도록 하겠습니다.

1) 웹 브라우저를 통해 H2O DAI에 접속합니다.   맨 처음 menu는 'DATASET'이며, 여러가지 입력 방법 중에서 저는 제 laptop으로부터 upload하는 menu를 택하겠습니다.



2) 저는 위의 Kaggle dataset (insurance.csv)에서 미리 일부 row들을 떼어내어 insurance_test.xlsx를 만들었고, 그 나머지를 insurance_training.xlsx로 저장해놓았습니다.  이것들을 선택하여 H2O DAI에 dataset으로 등록합니다.



3) insurance_training.xlsx와 insurance_test.xlsx가 dataset으로 등록되었습니다.   우측의 'Click for Actions' 부분을 눌러 나오는 sub-menu 중 'DETAILS' 부분을 클릭해 봅니다.



4) 이 DETAILS' 메뉴에서는 이 dataset이 어떤 정보를 담고 있는지 보실 수 있습니다.  각 칼럼별 평균/최대/최소/편차 등의 기본 정보와 최초 20개 row의 값 등을 보실 수 있습니다. 



5) Dataset 우측의 'Click for Actions' 부분을 눌러 나오는 sub-menu 중 'VISUALIZATION'을 클릭하면 여러가지 다양한 graph가 자동으로 생성됩니다.   가령 'OUTLIERS PLOT'을 보면 전체 data 중 일부가 표준편차에서 크게 벗어난 것을 보실 수 있습니다.  그런 부분은 표에서 보는 것보다는 이렇게 그래프로 시각화해서 보면 직관적으로 이해하기가 쉽지요.  그렇게 크게 벗어난 오렌지색 점을 클릭해보면 해당 row의 상세 정보를 보실 수도 있습니다.






6) H2O DAI에서 가장 중요한 것은 역시 'PREDICT' 메뉴입니다.  이 메뉴를 통해서 예측 모델을 자동 생성하게 됩니다. 



7) 'PREDICT' 메뉴에 들어가면 꼭 하셔야 할 일은 단 하나 밖에 없습니다.  어느 칼럼에 대한 예측 모델을 만드느냐에 대한 선택입니다.  여기서는 당연히 charges 칼럼을 택합니다.





8) 추가로 선택하실 수 있는 메뉴는 중앙 하단의 3개의 라디오 다이얼입니다.  각각의 의미와 강약 조절은 아래와 같습니다.   여기서는 default로 제시된 8-3-8을 그대로 적용하겠습니다.



Accuracy : 어떤 알고리즘들을 몇 개나 적용할지 정합니다.  물론 다이얼 숫자가 높을 수록 더 많은 알고리즘을 적용합니다.
Time : 머신러닝에서 반복 훈련, 즉 iteration을 몇 회나 수행할지 정합니다.  물론 다이얼 숫자가 높을 수록 더 많은 회수가 적용됩니다.
Interpretability : 머신러닝으로 만들어진 모델에 대한 해석의 강도 조절 부분입니다.  다이얼 숫자가 높을 수록 더 단순화해서 해석해줍니다.


9) Launch를 누르면 자동 모델 생성이 시작되고 모델이 training 되는 과정을 보시게 됩니다.  중앙 상단을 보면 그 단계에서 하고 있는 작업과 적용되는 알고리즘 등이 실시간으로 업데이트 되면서 보여집니다.  중앙 하단에는 그 시점까지의 분석 단계에서 판단할 때 가장 중요한 변수/feature, 즉 입력된 dataset의 칼럼 중 어느 칼럼이 가장 중요한 역할을 하더라는 것이 실시간으로 분석되어 보여집니다.   가령 3% 경과된 시점에서는 LIGHTGBM 알고리즘을 처리 중이고, 흡연여부-비만지수-나이 순으로 병원비에 중요한 영향을 끼친다고 나옵니다. 






10) 그러나 auto feature engineering이 본격적으로 시작되면서 경과%가 진행되면서 그 값들은 계속 변화합니다.  가령 79% 경과 진행 중일 때는 무려 497개의 feature에 대해 1582개의 model에 대해서 평가 중이라고 나오지요.  원래 dataset의 칼럼 수, 즉 feature 수가 7개 밖에 없었다는 점을 생각하면 H2O DAI가 정말 다양한 조합의 feature engineering을 자동으로 수행하고 있다는 점을 아실 수 있습니다.  그 결과로 나오는 중앙 하단의 'Variable Importance', 즉 어떤 변수/feature가 병원비 지출액에 가장 중요한 영향을 끼치더라는 점도 비만도와 성별, 그리고 흡연여부가 결합되어 새로 생성된 변수를 가장 중요시하는 것을 보실 수 있습니다.  그 항목들을 자세히 보시면, 정말 모든 경우에 흡연여부가 가장 중요한 영향을 끼친다는 것을 보실 수 있습니다.  흡연인 여러분, 아무래도 담배는 끊으셔야 할 것 같습니다.



11) 모델 생성이 완료되면 우측 하단에 요약 설명이 나옵니다.  그러나 가장 중요한 것은 중앙 상단 메뉴의 3번쨰 항목, 즉 'SCORE ON ANOTHER DATASET' 입니다.  여기에 우리가 원하는 charges 값을 뺀 다른 값들 (연령, 사는 곳, 성별, 흡연 여부 등)이 들어있는 표를 입력하면, 해당 사람들이 얼마나 병원비를 쓸지 예측한 값을 출력해주거든요.   여기서는 미리 입력해둔 insurance_test.xlsx를 test dataset으로 선택하겠습니다.  그러면 곧장 해당 사람들의 병원비(charges) 값을 예측하여 그 결과를 csv 파일로 download 시켜줍니다.





12) 그렇게 해서 얻은 해당 환자들의 예상 병원비와 실제 병원비의 결과는 아래 그래프와 같습니다.  파란 곡선이 실제값이고, 오렌지색 곡선이 H2O DAI가 예측한 값입니다.  놀랍도록 잘 맞춘 것을 보실 수 있습니다.   다만 중간 정도에 H2O DAI는 7천4백불 정도를 예상했는데 실제로는 2만8천불을 사용하여 H2O DAI의 예상이 크게 틀린 환자가 있습니다.  이 환자의 상태를 보면, BMI 지수가 높은 비흡연자입니다.  아마도 H2O DAI가 만든 모델에서는 BMI 지수는 그다지 중요하지 않고 흡연 여부가 가장 중요했는데, 이 환자의 경우는 그 예측이 빗나간 것 같습니다.



13) 위에서 BMI 지수니 흡연여부니 하는 것은 어디까지나 저 개인의 짐작에 불과할 뿐 수학적인 모델로 계산한 결과는 아닙니다.  왜 이 머신러닝 모델이 이런 예측값을 내놓았는지 해석하는 것이 바로 MLI (Machine Learning Interpretation)입니다.  H2O는 K-LIME과 Decision Tree, Random Forest 등 다양한 MLI 기능을 제공합니다.  그런 MLI는 모델 생성 완료시의 메뉴 맨 상단의 'Interpret This Model'을 클릭함으로써 생성할 수 있습니다. 



14) 이런 MLI 해석 결과도 어느 정도 data science에 대한 소양이 있어야 볼 수 있는 것이 사실입니다.  가령 LIME이 무엇인지 알아야 이해를 할 수 있으니까요.  (참고로 LIME은 Locally Interpretable Model-agnostic Explainations을 뜻하는 말로서, 어떤 모델을 생성할 때 사용된 변수 값을 하나씩 바꿔보고 그 모델의 결과에 얼마나 변화가 생기는지 봄으로써 어느 변수가 가장 중요한 역할을 하는지 해석하는 기법입니다.)  하지만 H2O DAI는 일반인들도 이해하기 쉬운 설명도 제시합니다.





15) 가령 Summary 부분의 맨 아래는 원래 dataset의 칼럼 중에서 어느 칼럼이 가장 중요한 역할을 하는지 보여줍니다. 



16) KLIME에서는 각각의 예측값에 대해, 어떤 변수가 어느 정도의 영향을 끼쳤는지를 수식화해서 보여줍니다.



17) 가장 쉬운 설명은 KLIME 메뉴 중 중앙상단의 'Explanations' 버튼을 클릭하면 볼 수 있습니다.   여기서는 흡연여부, BMI 지수 등의 변수의 증감에 따라 우리가 알고자 하는 target (여기서는 병원비)의 증감이 어떻게 변화하는지 최대한 단순화하여 제시합니다.  여기에 제시된 설명에 따르면 흡연여부가 가장 중요하고, 자녀가 있는지 여부가 그 다음이며, 사는 곳이 어디인지도 꽤 큰 영향을 미치는 것 같습니다.  아마 부유한 동네인지 또는 그 지방의 식습관 등이 영향을 주는 것일까요 ?  왜 그런지 모르겠습니다만 이 예측 모델에서는 의외로 BMI 지수, 즉 비만 여부는 상대적으로 그다지 큰 영향을 주지는 않는다고 판단하고 있습니다.



이 포스팅의 결론은 다음과 같습니다.

1. H2O DAI는 무척 정확한 예측 모델을 정말 쉽게 만들어낼 수 있을 뿐만 아니라, 왜 그런 예측을 했는지도 매우 쉽게 풀어서 설명해줍니다.  
2. 흡연자 여러분, 금연 합시다.


2019년 2월 22일 금요일

ppc64le 환경에서 tensorflow 1.12를 source로부터 build 하기


Tensorflow v1.12는 IBM PowerAI toolkit v1.5.4에 포함되어 있습니다.  그러나 그건 CUDA 10.0 환경을 위해 만들어진 것이라서, CUDA 9.2 환경을 그대로 쓰고자 하는 고객분들께서는 사용하실 수 없습니다.  하지만 github의 source code로부터 직접 build하시면 간단합니다.

제가 build한 환경은 Anaconda3 5.2 (python 3.6.8) + CUDA 9.2 + NCCL 2.2 + CUDNN 7.4.1 + Redhat 7.4 ppc64le 입니다. 

먼저 아래와 같이 기초적으로 필요한 OS package들을 yum으로 설치하십시요.

[bsyu@redhat74 files]$ which python
~/anaconda3/bin/python

[bsyu@redhat74 files]$ python
Python 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:38:54)
[GCC 7.2.0] on linux

[bsyu@redhat74 files]$ sudo yum install java-1.8.0-openjdk-devel.ppc64le zip unzip automake autoconf make gcc patch

[bsyu@redhat74 files]$ conda install protobuf wheel numpy six

Tensorflow v1.12 build를 위해서는 bazel v0.15 이상이 필요합니다.  Bazel v0.15를 bootstrap 방식으로 먼저 build합니다.  예전에는 ppc64le 환경에서 bazel을 build하는 것이 매우 힘들었는데, 이젠 x86_64 환경에서와 똑같이 그냥 build하시면 됩니다.

[bsyu@redhat74 files]$ wget https://github.com/bazelbuild/bazel/releases/download/0.15.0/bazel-0.15.0-dist.zip

[bsyu@redhat74 files]$ mkdir bazel-0.15 && cd bazel-0.15

[bsyu@redhat74 bazel-0.15]$ unzip ../bazel-0.15.0-dist.zip

[bsyu@redhat74 bazel-0.15]$ export EXTRA_BAZEL_ARGS="--host_javabase=@local_jdk//:jdk"

[bsyu@redhat74 bazel-0.15]$ export PROTOC=~/anaconda3/bin/protoc

[bsyu@redhat74 bazel-0.15]$ ./compile.sh
....
INFO: Build completed successfully, 2371 total actions
WARNING: --batch mode is deprecated. Please instead explicitly shut down your Bazel server using the command "bazel shutdown".
Build successful! Binary is here: /home/bsyu/files/bazel-0.15/output/bazel

이제 bazel build가 완료되었습니다.  이렇게 만든 bazel 실행파일을 아래와 같이 /usr/local/bin에 옮겨놓고 쓰시면 됩니다.

[bsyu@redhat74 bazel-0.15]$ sudo cp output/bazel /usr/local/bin

그리고 tensorflow build에 들어가기 전에, 아래와 같이 cudnn.h의 soft link를 /usr/include 밑에 만들어 줍니다.  이것이 없으면 자꾸 cudnn.h를 못 찾는다는 error("Cannot find cudnn.h under /usr/local/cuda-9.2/targets/ppc64le-linux/lib")가 나니까, 그걸 막기 위한 것입니다. 

[bsyu@redhat74 files]$ sudo ln -s /usr/local/cuda/include/cudnn.h /usr/include/cudnn.h

이제 tensorflow source code를 받습니다.

[bsyu@redhat74 files]$ git clone https://github.com/tensorflow/tensorflow.git

[bsyu@redhat74 files]$ cd tensorflow/

우리가 원하는 버전인 v1.12.0으로 checkout 합니다.

[bsyu@redhat74 tensorflow]$ git checkout tags/v1.12.0

./configure를 수행하되, 다음 몇 줄 이외에는 모두 default 값을 쓰면 됩니다.

[bsyu@redhat74 tensorflow]$ ./configure

Do you wish to build TensorFlow with CUDA support? [y/N]: y
Please specify the CUDA SDK version you want to use. [Leave empty to default to CUDA 9.0]: 9.2
Please specify the location where cuDNN 7 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]: /usr/local/cuda/lib64
Please note that each additional compute capability significantly increases your build time and binary size. [Default is: 3.5,7.0]: 6.0,7.0

그리고 temp file을 쓸 directory를 별도로 지정해두기 위해 다음과 같이 환경변수 TMP를 넉넉한 disk 공간이 있는 directory로 지정해두는 것이 좋습니다.

[bsyu@redhat74 tensorflow]$ export TMP=/data/tmp

이제 bazel을 이용하여 tensorflow build에 들어갑니다.  이 과정은 시간이 오래 걸리니까 nohup & 을 쓰시는 것이 좋습니다.   그리고 의외로 system memory를 많이 잡아먹습니다.  저는 16GB memory가 있는 POWER8 가상머신에서 했는데, active memory를 거의 9GB 쓰는 것 같습니다.   4GB memory만 있는 가상머신에서 build하려니 killed 되던데, 아마 메모리 부족으로 죽는 것 같았어요.

[bsyu@redhat74 tensorflow]$ bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
...
INFO: Build completed successfully, 1180 total actions

성공적으로 완료되었습니다.  이제 wheel file을 생성합니다.

[bsyu@redhat74 tensorflow]$ ./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
...
Fri Feb 22 22:05:17 KST 2019 : === Output wheel file is in: /tmp/tensorflow_pkg

이제 wheel file이 /tmp/tensorflow_pkg 밑에 생성되었습니다.   다음과 같이 확인합니다.

[bsyu@redhat74 tensorflow]$ ls -l /tmp/tensorflow_pkg
-rw-rw-r-- 1 bsyu bsyu 171252634 Feb 22 22:05 tensorflow-1.12.0-cp36-cp36m-linux_ppc64le.whl

이제 이 wheel file을 pip 명령으로 설치하면 됩니다.  이 과정 중에서 tensorflow에 필요한 grpcio 등의 python package들을 추가로 internet에서 download 하여 설치하므로, 만약 internet이 없는 환경이라면 intranet에 있는 PYPI repository에서 그런 package들을 download 할 수 있도록 설정이 필요합니다.

[bsyu@redhat74 tensorflow]$ pip install /tmp/tensorflow_pkg/tensorflow-1.12.0-cp36-cp36m-linux_ppc64le.whl

Processing /tmp/tensorflow_pkg/tensorflow-1.12.0-cp36-cp36m-linux_ppc64le.whl
Requirement already satisfied: numpy>=1.13.3 in /home/bsyu/anaconda3/lib/python3.6/site-packages (from tensorflow==1.12.0) (1.15.4)
Requirement already satisfied: keras-applications>=1.0.6 in /home/bsyu/anaconda3/lib/python3.6/site-packages (from tensorflow==1.12.0) (1.0.7)
Requirement already satisfied: keras-preprocessing>=1.0.5 in /home/bsyu/anaconda3/lib/python3.6/site-packages (from tensorflow==1.12.0) (1.0.9)
Requirement already satisfied: six>=1.10.0 in /home/bsyu/anaconda3/lib/python3.6/site-packages (from tensorflow==1.12.0) (1.12.0)
Requirement already satisfied: protobuf>=3.6.1 in /home/bsyu/anaconda3/lib/python3.6/site-packages (from tensorflow==1.12.0) (3.6.1)
Collecting termcolor>=1.1.0 (from tensorflow==1.12.0)
  Downloading https://files.pythonhosted.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz
Collecting astor>=0.6.0 (from tensorflow==1.12.0)
  Downloading https://files.pythonhosted.org/packages/35/6b/11530768cac581a12952a2aad00e1526b89d242d0b9f59534ef6e6a1752f/astor-0.7.1-py2.py3-none-any.whl
Collecting grpcio>=1.8.6 (from tensorflow==1.12.0)
  Downloading https://files.pythonhosted.org/packages/90/2e/f432e69f86961393c22a6c4490aafdbb94533deba33f5ea2d5651770aa21/grpcio-1.18.0.tar.gz (14.6MB)
    100% |████████████████████████████████| 14.6MB 3.4MB/s
Collecting absl-py>=0.1.6 (from tensorflow==1.12.0)
  Downloading https://files.pythonhosted.org/packages/31/bc/ab68120d1d89ae23b694a55fe2aece2f91194313b71f9b05a80b32d3c24b/absl-py-0.7.0.tar.gz (96kB)
    100% |████████████████████████████████| 102kB 11.7MB/s
Collecting tensorboard<1.13.0,>=1.12.0 (from tensorflow==1.12.0)
  Downloading https://files.pythonhosted.org/packages/07/53/8d32ce9471c18f8d99028b7cef2e5b39ea8765bd7ef250ca05b490880971/tensorboard-1.12.2-py3-none-any.whl (3.0MB)
    100% |████████████████████████████████| 3.1MB 8.6MB/s
Collecting gast>=0.2.0 (from tensorflow==1.12.0)
  Downloading https://files.pythonhosted.org/packages/4e/35/11749bf99b2d4e3cceb4d55ca22590b0d7c2c62b9de38ac4a4a7f4687421/gast-0.2.2.tar.gz
Requirement already satisfied: wheel>=0.26 in /home/bsyu/anaconda3/lib/python3.6/site-packages (from tensorflow==1.12.0) (0.32.3)
Requirement already satisfied: h5py in /home/bsyu/anaconda3/lib/python3.6/site-packages (from keras-applications>=1.0.6->tensorflow==1.12.0) (2.7.1)
Requirement already satisfied: setuptools in /home/bsyu/anaconda3/lib/python3.6/site-packages (from protobuf>=3.6.1->tensorflow==1.12.0) (39.1.0)
Requirement already satisfied: werkzeug>=0.11.10 in /home/bsyu/anaconda3/lib/python3.6/site-packages (from tensorboard<1.13.0,>=1.12.0->tensorflow==1.12.0) (0.12.2)
Collecting markdown>=2.6.8 (from tensorboard<1.13.0,>=1.12.0->tensorflow==1.12.0)
  Downloading https://files.pythonhosted.org/packages/7a/6b/5600647404ba15545ec37d2f7f58844d690baf2f81f3a60b862e48f29287/Markdown-3.0.1-py2.py3-none-any.whl (89kB)
    100% |████████████████████████████████| 92kB 14.6MB/s
Building wheels for collected packages: termcolor, grpcio, absl-py, gast
  Running setup.py bdist_wheel for termcolor ... done
  Stored in directory: /home/bsyu/.cache/pip/wheels/7c/06/54/bc84598ba1daf8f970247f550b175aaaee85f68b4b0c5ab2c6
  Running setup.py bdist_wheel for grpcio ... done
  Stored in directory: /home/bsyu/.cache/pip/wheels/e5/22/5a/fa5c03beb66ecc2658e73673175e748ac37385614d52430877
  Running setup.py bdist_wheel for absl-py ... done
  Stored in directory: /home/bsyu/.cache/pip/wheels/90/db/f8/2c3101f72ef1ad434e4662853174126ce30201a3e163dcbeca
  Running setup.py bdist_wheel for gast ... done
  Stored in directory: /home/bsyu/.cache/pip/wheels/5c/2e/7e/a1d4d4fcebe6c381f378ce7743a3ced3699feb89bcfbdadadd
Successfully built termcolor grpcio absl-py gast
jupyter 1.0.0 requires qtconsole, which is not installed.
distributed 1.21.8 requires msgpack, which is not installed.
gevent 1.3.0 has requirement greenlet>=0.4.13, but you'll have greenlet 0.4.12 which is incompatible.
Installing collected packages: termcolor, astor, grpcio, absl-py, markdown, tensorboard, gast, tensorflow
Successfully installed absl-py-0.7.0 astor-0.7.1 gast-0.2.2 grpcio-1.18.0 markdown-3.0.1 tensorboard-1.12.2 tensorflow-1.12.0 termcolor-1.1.0

이제 보시는 바와 같이 tensorflow가 설치되었습니다.

[bsyu@redhat74 tensorflow]$ pip list | grep tensor
tensorboard                        1.12.2
tensorflow                         1.12.0

이걸 GPU가 있는 서버에서 테스트하는 방법은 다음과 같습니다.

[bsyu@redhat74 tensorflow]$ cd ..

[bsyu@redhat74 files]$ python
Python 3.6.8 |Anaconda, Inc.| (default, Dec 30 2018, 01:34:02)
[GCC 7.3.0] on linux

>>> import tensorflow as tf
/home/bsyu/anaconda3/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  from ._conv import register_converters as _register_converters

>>> sess=tf.Session()
2019-02-22 22:14:15.250972: E tensorflow/stream_executor/cuda/cuda_driver.cc:300] failed call to cuInit: CUDA_ERROR_UNKNOWN: unknown error
2019-02-22 22:14:15.251021: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:150] kernel driver does not appear to be running on this host (redhat74): /proc/driver/nvidia/version does not exist

제가 GPU가 없는 서버에서 이걸 수행했기 때문에 위에서는 error가 났습니다만, GPU가 장착된 서버에서는 error가 없어야 하고 nvidia-smi로 보았을 때 python이 GPU를 점거하는 것으로 보일 것입니다.

여기서 build된 tensorflow wheel 파일과 site-packages directory 전체를 tar로 말아서 아래의 google drive에 올려두겠습니다.

tensorflow wheel 파일 : https://drive.google.com/open?id=1plqSuw9WnWuOPJCPEiVYSp3uK3IilQMy

2019년 1월 30일 수요일

IBM POWER8/9 (ppc64le) 환경에서의 Darknet 설치 및 test



Darknet은 C로 구현된 open source neural network famework입니다.  IBM POWER8 또는 POWER9, 즉 ppc64le 환경에서도 당연히 잘 설치됩니다.  여기서는 CentOS 7 on POWER8에서 구현했습니다.

설치는 source를 받아서 다음과 같이 compile 하기만 하면 됩니다.  Source를 수정할 필요 전혀 없습니다.

[bsyu@centos01 files]$ git clone https://github.com/pjreddie/darknet.git

[bsyu@centos01 files]$ cd darknet

[bsyu@centos01 darknet]$ make -j8

[bsyu@centos01 darknet]$ ./darknet
usage: ./darknet <function>

다만 혹시 GPU를 사용하고자 할 때는 아래와 같이 CUDA로 build되도록 Makefile을 살짝 수정해주시면 됩니다.  이 또한 ppc64le 환경에서도 build는 잘 됩니다만, 제가 가난하여 GPU가 없기 때문에 테스트는 이것으로 못했습니다.

[bsyu@centos01 darknet]$ vi Makefile
GPU=1   # default 0
CUDNN=1   # default 0
...

[bsyu@centos01 darknet]$ make -j8

[bsyu@centos01 darknet]$ ./darknet
usage: ./darknet <function>


CUDA 없이, 처음에 build한 CPU-only 버전으로도 darknet을 통해 YOLO를 테스트해볼 수 있습니다.   이 darknet 속에는 이미 YOLO를 위한 cfg 파일과 샘플용 멍멍이 사진이 들어있거든요.

[bsyu@centos01 darknet]$  ls -l cfg/yolov3.cfg data/dog.jpg
-rw-r--r-- 1 bsyu bsyu   8342 Jan 30 15:19 cfg/yolov3.cfg
-rw-r--r-- 1 bsyu bsyu 163759 Jan 30 15:19 data/dog.jpg

이 dog.jpg를 download 받아보면 아래와 같습니다.



이제 테스트를 위해, 미리 멍멍이를 감지하도록 YOLO v3로 pre-train된 weight file을 download 합니다.

[bsyu@centos01 darknet]$ wget https://pjreddie.com/media/files/yolov3.weights

이것으로 data/dog.jpg 사진 속의 object를 'detect' 하는 명령을 내려보겠습니다.

[bsyu@centos01 darknet]$ ./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
layer     filters    size              input                output
    0 conv     32  3 x 3 / 1   608 x 608 x   3   ->   608 x 608 x  32  0.639 BFLOPs
    1 conv     64  3 x 3 / 2   608 x 608 x  32   ->   304 x 304 x  64  3.407 BFLOPs
    2 conv     32  1 x 1 / 1   304 x 304 x  64   ->   304 x 304 x  32  0.379 BFLOPs
    3 conv     64  3 x 3 / 1   304 x 304 x  32   ->   304 x 304 x  64  3.407 BFLOPs
    4 res    1                 304 x 304 x  64   ->   304 x 304 x  64
    5 conv    128  3 x 3 / 2   304 x 304 x  64   ->   152 x 152 x 128  3.407 BFLOPs
    6 conv     64  1 x 1 / 1   152 x 152 x 128   ->   152 x 152 x  64  0.379 BFLOPs
...
  104 conv    256  3 x 3 / 1    76 x  76 x 128   ->    76 x  76 x 256  3.407 BFLOPs
  105 conv    255  1 x 1 / 1    76 x  76 x 256   ->    76 x  76 x 255  0.754 BFLOPs
  106 yolo
Loading weights from yolov3.weights...Done!
data/dog.jpg: Predicted in 27.192135 seconds.
dog: 100%
truck: 92%
bicycle: 99%

우리가 OpenCV로 darknet을 build하지 않았기 때문에 직접 사진이 나오지는 않지만 darknet은 predictions.jpg로 그 결과를 저장합니다.

[bsyu@centos01 darknet]$ ls -ltr | tail -n 3
-rwxr-xr-x 1 bsyu bsyu    719872 Jan 30 15:29 libdarknet.so
-rwxr-xr-x 1 bsyu bsyu    841976 Jan 30 15:29 darknet
-rw-r--r-- 1 bsyu bsyu    119208 Jan 30 15:41 predictions.jpg

이 predictions.jpg을 PC로 download 받아보면 그 결과는 아래와 같습니다.



2019년 1월 16일 수요일

IBM PowerAI Vision 사용법 demo : Image classification/object detection


IBM의 이미지 및 동영상을 위한 classification/object detection용 솔루션인 PowerAI Vision의 사용법을 정리했습니다.

먼저, image dataset에 대해 labeling을 해야 합니다.  이는 인터넷 상에서 쉽게 구할 수 있는 무료 tool인 labelimg, imageio 등을 이용하셔도 되고, 아예 처음부터 PowerAI Vision (이하 PAIV) 속에서 수행하셔도 됩니다.   아래의 예는 labelimg를 이용하여 사진 속의 object에 사각형을 그리고 labeling을 하는 장면입니다.



이런 식으로 labeling을 하면 그 결과가 해당 파일 하나마다 한개씩 xml 파일이 생성되어 저장됩니다.  이렇게 사진마다 labeling xml 파일이 생성되면 파일들을 PAIV에 upload할 준비가 된 것입니다.   이 사진 및 xml 파일들을 PAIV에 upload할 때 더 간편하게 할 수 있도록 아예 zip 파일로 묶어놓으면 더 좋습니다.



참고로 이 labeling xml 파일의 내용은 아래와 같습니다.



이제 web browser를 통해 PAIV에 접속하겠습니다.   기본 userid/passwd는 admin/passw0rd입니다.   접속하고나면 맨 먼저 'Data sets' 항목으로 갑니다.  기존에 다른 분들이 upload하신 dataset들이 있고 수지씨의 아름다운 사진도 보입니다만 한눈 팔지 마시고 우리는 'Create New Data Set'을 클릭합니다.



'Data Set Name'에 적절한 이름을 붙이십시요. 



그러고나면 우리가 만든 fighter라는 dataset이 생성된 것을 보실 수 있습니다.  그러나 여기에는 아직 사진이 한장도 들어있지 않습니다.   이제 여기에 사진을 넣어야 합니다.



우리가 만든 fighter라는 dataset을 클릭하면 '파일을 여기에 끌어놓으라'는 메시지와 'Import files'라는 사각버튼이 보입니다.  여기서는 이 사각버튼을 눌러 보겠습니다. 



이건 평범하게, 우리가 쓰고 있는 PC의 directory로부터 파일을 upload할 수 있는 메뉴를 불러옵니다.  여기서는 아까 zip으로 압축해놓았던 fighter.zip을 선택합니다.




이제 보면 fighter.zip 속에 들어있는 사진들과 xml 파일을 PAIV가 읽어들여 dataset으로 포맷한 것으로 보실 수 있습니다.  다만 사진들을 보면 작은 글씨로 f16, f15 등이 아까 우리가 labeling해놓은 대로 표시되어 있으나, 사진 위에는 큰 글씨로 'Uncategorized' 라고 분류된 것을 보실 수 있습니다.  이는 위에서 우리가 했던 label은 사진 속의 object에 붙여놓은 것이고, 사진 전체에 대해 f15, f16 등으로 분류하는 label을 붙여놓은 것은 아니기 때문입니다.  즉, 이 사진들은 classification을 위해서 label이 된 것이 아니라 object detection을 위해서 label이 된 것입니다.

여기서 잠깐 classification과 object detection을 구분하자면 아래와 같습니다.

Classification : 사진 1장 전체를 미리 지정한 category 중 어느 하나로 분류 
Object detection : 사진 내에 미리 지정된 object에 해당하는 것이 있는지 감지하여 사각형으로 표시

우리의 dataset에는 크기 f15, f16, f14의 3가지 object들이 들어있습니다.  이것들을 모두 택하시고, 이제 'Train'이라는 사각버튼을 눌러 training에 들어가겠습니다. 



Train 메뉴에서는 먼저 'Type of training'을 'Image classification'과 'Object detection' 둘 중 하나에서 선택해야 합니다.  물론 이 dataset labeling 특성에 맞게 우리는 'Object detection'을 택해야 합니다.  ('Image classification'을 택하려면 먼저 사진의 labeling을 그에 맞게 해야 하는데, 그건 뒤에서 다시 보시겠습니다.)  이어서 그 아래의 'Model selection'을 해야 하는데, 여기서는 'Optimized for accuracy (faster R-CNN)'을 택했습니다.



그 아래의 'Advanced options' 메뉴는 max interation이나 learning rate 같은 hyperparameter를 지정하는 곳입니다.  여기서는 아무 수정 없이 그냥 train 하겠습니다.  아래의 'Train' 사각버튼을 누르면 train이 시작됩니다. 



Train이 시작되면 이 과정이 얼마나 더 걸리는지가 대략 계산되어 display 됩니다.



그 아래 화면에서는 iteration이 진행됨에 따라 감소하는 loss graph가 display 됩니다.



Training이 완료되면 'Model details'와 'Deploy'의 2가지 사각버튼이 보입니다.  이 중 먼저 'Model details'를 클릭하겠습니다.



여기서는 train된 model에 대한 간단한 정보들이 display됩니다.   Accuracy와 Precision, mAP 등이 무엇을 뜻하는지는 아래 URL을 참조하시기 바랍니다.

https://www.ibm.com/support/knowledgecenter/SSRU69_1.1.2/base/vision_metrics.html#vision_metrics__detection_gpu




이제 맨 위의 'Deploy model' 사각버튼을 눌러보겠습니다.  아래와 같이 model의 이름을 정하고 엔터를 누르면 'Deployed models'에 방금 생성한 model의 이름이 나타나게 됩니다. 




우리가 방금 생성한 model 이름을 클릭해 봅니다.   그러면 이 모델이 Image classification을 위한 것인지 Object detection을 위한 것인지가 표시되면서, 외부에서 이 model을 불러쓸 수 있도록 API endpoint도 display됩니다.   여기서는 그 밑에 있는 'Tes Model' 메뉴에 별도의 사진을 넣어 제대로 object를 탐지하는지 시험해보겠습니다.  시험 방법은 간단합니다.  그냥 PC의 파일관리자에서 원하는 사진을 끌어다 'Drop files here'라고 쓰인 흰색 상자에 넣기만 하면 됩니다.




보셨다시피 training dataset에 사진이 몇장 없었기 때문에, 이 모델의 실제 정확도는 매우 낮습니다.  그래서 F14 전투기를 F16으로 분류하기도 합니다만, 겉으로 꽤 비슷해 보이는 F14와 F15를 훌륭하게 제대로 구분해서 보여주기도 합니다. 





이번에는 처음에 만들었던 'fighter' dataset으로 되돌아가보겠습니다.  메뉴 화면 중에 'Augment data'라는 것이 보일 것입니다.  그걸 클릭해보면, blur/color/sharpen/rotate/crop/noise 등과 같은 기법을 통해 1장의 사진을 여러장으로 가공하여 사진 수를 늘리는 메뉴임을 아실 수 있습니다.  여기서는 blur와 color 빼고 모든 기법을 다 택하고 'Continue'를 눌러보겠습니다.




아래와 같이 새로 추가될 증강 dataset에 'fighter_augmented'라고 이름을 붙여주고나면, 그 이름으로 새로운 dataset이 추가된 것을 보실 수 있습니다.  그리고 그 속의 사진 개수는 원래 24장이던 것이 무려 528장으로 늘어나 있습니다.  이제 그 'fighter_augmented' dataset을 클릭해보겠습니다.




실제로 하나의 사진이 blur라든가 rotate 등의 기법으로 여러 장으로 복제된 것을 보실 수 있습니다.  이 528장의 사진을 가지고 이번에는 object detection이 아닌 classification을 수행해보도록 하겠습니다. 



위의 사진들 중 f16에 해당하는 사진들을 click한 뒤, 사진 위의 메뉴 중 'Assign category'를 클릭하십시요.  그리고 거기에 category 이름을 f14, f15, f16 등으로 지정하면 됩니다.




이제 아래 dataset과 같이 각 사진마다 f14, f15, f16 중 하나의 category가 지정되었습니다.  이제 'Train model' 사각버튼을 눌러 train을 시작합니다.



'Type of training' 항목에서는 아까와는 달리 'Object detection' 대신 'Image Classification'을 선택합니다.  그 아래의 'Model selection'에서는 시스템에서 제공하는 기본 neural network인 'GoogleNet'을 선택합니다.  아직은 Caffe에서의 GoogleNet만 기본 지원되지만, 그 밑의 'Custom Model'을 선택하면 외부에서 가져온 tensorflow의 다른 neural network도 import 하여 사용할 수 있습니다.



그 밑의 'Advanced options'에서는 'Base model'을 선택하게 되어 있습니다.  대부분의 경우엔 'General'을 택하겠습니다만, 혹시 우리가 지금 train하려는 dataset이 PAIV에서 기본으로 제공되는 trained model인 '풍경, 얼굴, 자동차' 등에 해당하는 것이라면, 이 기본 model에 대해 추가 dataset으로 추가 train 하는 형태로 진행할 수 있습니다.  그 경우 더 높은 정확도를 얻을 수 있겠지요.  불행히도 우리는 여기서 전투기 사진을 사용하고 있으므로 해당 사항이 없고, 따라서 'General'을 택해야 합니다. 



나머지 부분은 learning rate 등의 hyper parameter setting입니다.  여기서는 변경하지 않고 'Train' 사각버튼을 눌러 train을 시작합니다.



그 다음 부분은 위에서 한번 해본 object detection과 동일합니다.  Model training이 끝나면 해당 model을 적당한 이름으로 save하고, 이어서 deploy하면 그 이름이 Deployed models 목록에 나타나는 것을 보실 수 있습니다.






방금 deploy한 'fighter_augmented_model_deployed'를 클릭하여 들어가보면, 아까의 object detection 모델과 같이 'API endpoint' 정보 등과 함께, 'Test Model' 메뉴가 나옵니다.  여기에 별도로 준비한 전투기 사진을 drag & drop으로 넣어서 제대로 classification을 하는지 보겠습니다.



이 classification model은 아까의 object detection model에 비해 (비록 실제로 다양한 사진을 넣은 것이 아니라 augmented dataset에 불과하지만) 훨씬 많은 dataset을 사용해서 train했기 때문인지, 아까의 object detection보다는 훨씬 더 나은 정확도를 보여줍니다.  비록 도중에 F14를 F16이라고 분류한 것이 있긴 합니다만, 전투기에 별 관심 없는 사람이라면 구별하기 힘든 F14와 F15를 매우 잘 분류하고 있습니다.








이번에는 PAIV가 자랑하는 특수 기능인 'Auto labeling'을 시도해보겠습니다.  이는 기존에 train해둔 model을 이용하여, 새로 추가된 dataset에 대해 object label을 자동으로 수행해주는 기능입니다.  많은 일손과 시간이 들어가는 label 수작업을 크게 줄여주는 고마운 기능입니다.  다만 이 기능에 대해서는 2가지를 염두에 두셔야 합니다. 

1) Classification은 지원하지 않으며, Object detection을 위한 labeling만 지원합니다.
2) Auto labeling에 사용한 기존 model의 accuracy가 좋지 않으면, 당연히 auto labeling의 품질도 떨어집니다.

Auto labeling을 수행하기 위해, 먼저 추가의 전투기 사진들로 새로운 dataset 'more_fighters'를 만듭니다. 





이제 메뉴 바 중의 'Auto label'을 클릭합니다.  그러면 아래와 같이 기존 deployed model 중에서 auto label에 사용할 model을 선택하게 되어 있습니다.  우리는 아까 만들어두었던 fighter_model1_deployed를 선택합니다. 



이어서 'Auto label' 사각버튼을 누르면 auto label이 시작됩니다.



사진이 34장 밖에 안 되므로 auto label도 순식간에 끝납니다.  그러나, 기억하시다시피 우리가 사용한 'fighter_model1_deployed' model은 정확도가 별로 높지 않았습니다.  그래서인지, 34장의 사진 중 고작 10개의 object만 label했습니다.



그나마 아래와 같이 F14에 F16이라는 label을 붙여놓았습니다.



원래 어떤 model이라도 100% 정확할 수는 없으며, 따라서 auto label된 dataset은 결국 사람이 눈으로 검토하고 잘못된 label은 손으로 수정해야 합니다.  이제 위의 잘못 label된 것을 수정하겠습니다.  해당 사진을 클릭하면 아래와 같이 pop up 되는데, 여기서 나온 'Label objects' 사각버튼을 클릭합니다.



사진 오른쪽 위에 f16(1) X 라는 표시가 보입니다.  그 X 표시에 클릭하면 f16이라는 사각형으로 둘러싸인 label이 삭제됩니다.



이제 사진 오른쪽 위에 있는 f14(0) 이라는 표시를 선택한 뒤, 마우스를 전투기 사진 옆에서 click & drag 하여 사각형을 그려주면 이 전투기가 f14로 label됩니다.



이제 위쪽의 하얀 사각버튼 'Done editing'을 클릭하면 label 수정이 완료됩니다.



기존에 없던 object label을 이 메뉴에서 새로 추가하는 것도 가능합니다.  가령 아래 사진에는 F15와 F16 외에도, 머스탱(P51D) 프로펠러 전투기와 F22 스텔스 전투기도 보입니다.  이것들에 대해서는 아래와 같이 사진 오른쪽 위의 '+ Add New'를 클릭하여 즉석에서 새로운 label을 입력해주면 됩니다.







PowerAI Vision의 좀더 자세한 정식 manual은 아래 URL을 참조하세요.

https://www.ibm.com/support/knowledgecenter/en/SSRU69_1.1.2/navigation/welcome.html