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

2018년 9월 10일 월요일

ILSVRC2012 dataset 중 강아지 사진만을 이용한 짧은 TF inception v3 테스트 방법



다음과 같이 benchmark/tensorflow 디렉토리에 들어가서, exec_img.sh를 수행하시면 됩니다.  이때 아래와 같이 nohup으로 수행하시면 도중에 연결 세션이 끊어져도 백그라운드로 job은 계속 수행될 뿐만 아니라, 수행 기록이 nohup.out에도 기록되므로 편리하실 것입니다.

[root@ac922 tensorflow]# pwd
/home/files/ilsvrc12/tensorflow

[root@ac922 tensorflow]# ls
benchmark  exec_img.sh  models  nohup.out.final.tf  output_final

[root@ac922 tensorflow]# nohup ./exec_img.sh &

위와 같이 exec_img.sh를 한번 수행하시면 그 속에서 아래와 같이 ./models/run_model.sh 스크립트가 batch_size=128로 순차적으로 GPU 개수 4, 2, 1에 대해서 각각 1번씩 총 3번을 수행합니다.  각 수행이 끝날 때마다 time 명령에 의해 수행 시간에 걸린 시간이 nohup.out에 기록됩니다.   원래 NVIDIA에서 준 script를 수행해보니, 매번 exec을 수행할 때마다 output directory를 새로 만들어야 제대로 수행되는 것 같아 아래와 같이 exec 수행시마다 ouput directory를 다른 이름으로 옮기고 새로 output을 만드는 문장을 추가했습니다.

mkdir output
time  exec  tf inception3  128  4  0
mv output output4gpu
mkdir output
time  exec  tf inception3  128  2  0
mv output output2gpu
mkdir output
time  exec  tf inception3  128  1  0
mv output output1gpu


결과 확인은 ouput directory에 쌓이는 아래의 log를 보셔도 되고, nohup.out을 보셔도 됩니다.  이 script에서는 total images/sec이 python 자체적으로 합산되어 표시되므로 그것을 기록하시면 됩니다.   단, python에서 계산되는 Elapsed Time은 일부 로직이 잘못되어 분:초 단위만 맞고 시간 단위는 9시간으로 나오니 그건 무시하십시요. 

이 테스트를 위해 필요한 python code 및 model file을 아래 google drive에 올려 놓았습니다.

https://drive.google.com/open?id=1DNn-Nv4rlOiv2NLqk6Y0j2ANlJjw9VP6

그리고 이 테스트를 위해 필요한 종류별로 labeling된 강아지 사진을 tfrecord 포맷으로 만든 dataset을 아래 google drive에 올려 놓았습니다.

https://drive.google.com/open?id=1rQcxAWeNbByy0Yooj6IbROyVRsdQPn5-

위 dataset을 추출하고 tfrecord로 포맷하는 과정은 아래에 정리되어 있습니다.

http://hwengineer.blogspot.com/2018/04/ilsvrc2012imgtraint3tar-training-dataset.html


** 별첨 :  tfrecord file들의 이름과 size

[root@ac922 ilsvrc12]# cd tfrecord/

[root@ac922 tfrecord]# ls -l | head
total 1509860
-rw-rw-r--. 1 1001 1001  6920780 Apr 11 19:20 train-00000-of-00120
-rw-rw-r--. 1 1001 1001  6422535 Apr 11 19:20 train-00001-of-00120
-rw-rw-r--. 1 1001 1001  6959007 Apr 11 19:21 train-00002-of-00120
-rw-rw-r--. 1 1001 1001  6885268 Apr 11 19:21 train-00003-of-00120
-rw-rw-r--. 1 1001 1001  5969364 Apr 11 19:21 train-00004-of-00120
-rw-rw-r--. 1 1001 1001  6143260 Apr 11 19:21 train-00005-of-00120
-rw-rw-r--. 1 1001 1001  6123517 Apr 11 19:21 train-00006-of-00120
-rw-rw-r--. 1 1001 1001  8585788 Apr 11 19:21 train-00007-of-00120
-rw-rw-r--. 1 1001 1001  6149957 Apr 11 19:21 train-00008-of-00120

[root@ac922 tfrecord]# ls -l | tail
-rw-rw-r--. 1 1001 1001 24124729 Apr 11 19:20 validation-00022-of-00032
-rw-rw-r--. 1 1001 1001 23741822 Apr 11 19:20 validation-00023-of-00032
-rw-rw-r--. 1 1001 1001 24759230 Apr 11 19:20 validation-00024-of-00032
-rw-rw-r--. 1 1001 1001 25225023 Apr 11 19:20 validation-00025-of-00032
-rw-rw-r--. 1 1001 1001 25273559 Apr 11 19:20 validation-00026-of-00032
-rw-rw-r--. 1 1001 1001 26820464 Apr 11 19:20 validation-00027-of-00032
-rw-rw-r--. 1 1001 1001 24115323 Apr 11 19:20 validation-00028-of-00032
-rw-rw-r--. 1 1001 1001 24459085 Apr 11 19:20 validation-00029-of-00032
-rw-rw-r--. 1 1001 1001 25246485 Apr 11 19:20 validation-00030-of-00032
-rw-rw-r--. 1 1001 1001 23561132 Apr 11 19:20 validation-00031-of-00032

[root@ac922 tfrecord]# du -sm .
1475    .


2017년 12월 12일 화요일

Caffe를 이용하여 ILSVRC2012 dataset을 alexnet으로 training하기

먼저 작업 환경을 PowerAI에 포함된 caffe-nv로 하기 위해 PATH 등 각종 환경 변수를 설정해주는 다음 script를 수행합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ source /opt/DL/caffe-nv/bin/caffe-activate

다음과 같이 caffe가 caffe-nv로 잡히는지 확인합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ which caffe
/opt/DL/caffe-nv/bin/caffe

PowerAI에 포함된 caffe-nv 밑의 example과 data를 GPFS 파일시스템 쪽으로 copy해옵니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ cp -r /opt/DL/caffe-nv/examples examples
b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ cp -r /opt/DL/caffe-nv/data data

거기서 아래와 같이 get_ilsvrc_aux.sh를 수행하여 ilsvrc2012 dataset 생성에 필요한 label 파일 등을 download 받습니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ cd data/ilsvrc12
b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/data/ilsvrc12$ ./get_ilsvrc_aux.sh

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/data/ilsvrc12$ ls -ltr
total 37888
-rw-r----- 1 b7p286za IBM1  3200000 Feb 25  2014 test.txt
-rw-r----- 1 b7p286za IBM1    10000 Feb 25  2014 synsets.txt
-rw-r----- 1 b7p286za IBM1   786446 Feb 25  2014 imagenet_mean.binaryproto
-rw-r----- 1 b7p286za IBM1  1644500 Feb 25  2014 val.txt
-rw-r----- 1 b7p286za IBM1 43829433 Feb 25  2014 train.txt
-rw-r----- 1 b7p286za IBM1    31675 Apr  8  2014 synset_words.txt
-rw-r----- 1 b7p286za IBM1     3787 Jun  8  2014 det_synset_words.txt
-rw-r----- 1 b7p286za IBM1 14931117 Jul 11  2014 imagenet.bet.pickle
-rwxr-x--- 1 b7p286za IBM1      585 Dec 12 02:12 get_ilsvrc_aux.sh

이제 imagenet data, 즉 ILSVRC2012를 download 받습니다.  Training dataset은 앞선 posting에서 사용한 tensorflow resnet training에서 사용했던 raw-data를 이용하면 됩니다.  다만, 거기서는 validation dataset도 label명에 따른 디렉토리로 분산해서 넣었는데, 이 alexnet에서는 val이라는 디렉토리에 한꺼번에 풀어놓아야 합니다.  따라서 다음과 같이 val만 새로 풀어놓습니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/data/ilsvrc12$ cd ../..

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ mkdir raw-data/val && cd raw-data/val

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/raw-data/val$ tar -xf ../../ILSVRC2012_img_val.tar

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/raw-data/val$ cd ../..

이제 raw-data 밑의 train과 val 속의 JPEG 파일들을 LMDB 포맷으로 변환해야 합니다.  다음과 같이 create_imagenet.sh 스크립트를 수정해서 사용합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ vi ./examples/imagenet/create_imagenet.sh
...
export CAFFE_BIN=/opt/DL/caffe-nv/bin   (추가)
...
TRAIN_DATA_ROOT=/gpfs/gpfs_gl4_16mb/b7p286za/raw-data/train/
VAL_DATA_ROOT=/gpfs/gpfs_gl4_16mb/b7p286za/raw-data/val/
...
#RESIZE=false
RESIZE=true

수정을 마치고 다음과 같이 수행합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ time ./examples/imagenet/create_imagenet.sh

이 과정도 200GB가 넘는 data를 LMDB format으로 변환하는 것이므로 스토리지 상황에 따라 6~7시간 가량 걸립니다.   위의 script가 다 돌고나면 examples/imagenet/ilsvrc12_train_lmdb와 examples/imagenet/ilsvrc12_val_lmdb에 LMDB format으로 변환된 dataset이 생깁니다.

이제 생성된 LMDB로부터 전체 imagenet data의 평균값을 구하기 위해 make_imagenet_mean.sh를 수행합니다.  여기서도 script 맨 앞에 다음과 같이 CAFFE_BIN을 정의해줍니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ vi ./examples/imagenet/make_imagenet_mean.sh
source /opt/DL/caffe-nv/bin/caffe-activate
export CAFFE_BIN=/opt/DL/caffe-nv/bin
...

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ time ./examples/imagenet/make_imagenet_mean.sh

다음으로는 solver.prototxt를 수정합니다.  먼저 /opt/DL/caffe-nv/models에 있는 bvlc_alexnet 디렉토리를 GPFS 파일시스템으로 copy해옵니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ cp -r /opt/DL/caffe-nv/models/bvlc_alexnet .

그리고나서 다음과 같이 solver.prototxt 속의 디렉토리 이름들과 max_iter 등을 적절히 수정해줍니다.
여기서는 나중에 batch_size를 2048로 할 것이므로, max_iter를 1250으로 하면 대략 1250 x 2048 / 1280000 = 20 epochs의 training을 완료하게 됩니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ vi bvlc_alexnet/solver.prototxt
#net: "models/bvlc_alexnet/train_val.prototxt"
net: "bvlc_alexnet/train_val.prototxt"
...
#display: 20
display: 500
#max_iter: 100000
max_iter: 1250
...
#snapshot_prefix: "models/bvlc_alexnet/caffe_alexnet_train"
snapshot_prefix: "bvlc_alexnet/caffe_alexnet_train"

다음으로는 bvlc_alexnet/train_val.prototxt를 필요시 수정하여 train data의 batch_size를 늘이거나 줄이고, 각종 path도 적절히 변경합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ vi bvlc_alexnet/train_val.prototxt
...
    source: "examples/imagenet/ilsvrc12_train_lmdb"
#    batch_size: 1024
    batch_size: 2048
...

이제 다음과 같은 train_alexnet.sh를 만들어 수행합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ vi ./examples/imagenet/train_alexnet.sh
source /opt/DL/caffe-nv/bin/caffe-activate
export CAFFE_BIN=/opt/DL/caffe-nv/bin
set -e
$CAFFE_BIN/caffe train -gpu all --solver=bvlc_alexnet/solver.prototxt

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ nohup time ./examples/imagenet/train_alexnet.sh &

결과 log는 nohup.out에서 보실 수 있습니다.   위와 같이 20 epochs를 수행하는데는 12분 정도 밖에 안 걸립니다. 


b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ grep iter nohup.out
test_iter: 1000
max_iter: 1250
I1212 14:15:42.151552 82131 solver.cpp:242] Iteration 0 (0 iter/s, 24.031s/500 iter), loss = 6.91103
I1212 14:22:10.507652 82131 solver.cpp:242] Iteration 500 (1.28749 iter/s, 388.352s/500 iter), loss = 6.37464
I1212 14:26:19.506183 82131 solver.cpp:242] Iteration 1000 (2.00806 iter/s, 248.996s/500 iter), loss = 5.34417
I1212 14:27:50.453514 82131 solver.cpp:479] Snapshotting to binary proto file bvlc_alexnet/caffe_alexnet_train_iter_1250.caffemodel
I1212 14:27:51.540899 82131 sgd_solver.cpp:273] Snapshotting solver state to binary proto file bvlc_alexnet/caffe_alexnet_train_iter_1250.solverstate


Tensorflow로 ILSVRC2012 dataset을 이용하여 resnet101 training하기

먼저, 다음과 같이 anaconda2를 설치합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ wget https://repo.continuum.io/archive/Anaconda2-5.0.0-Linux-ppc64le.sh

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ chmod a+x ./Anaconda2-5.0.0-Linux-ppc64le.sh

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ ./Anaconda2-5.0.0-Linux-ppc64le.sh
--> 설치 directory는 여기서는 user home directory인 /gpfs/gpfs_gl4_16mb/b7p286za/anaconda2 로 합니다만, 환경에 따라서 다른 곳에 하셔도 됩니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ export PATH=/gpfs/gpfs_gl4_16mb/b7p286za/anaconda2/bin:$PATH

이제 python이 OS의 기본 python이 아니라 anaconda에 딸린 python으로 설정되었는지 확인합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ which python
/gpfs/gpfs_gl4_16mb/b7p286za/anaconda2/bin/python

이제 다음 명령으로 tensorflow 1.2.1을 설치합니다.

혹시 tensorflow 1.3이 꼭 필요한 경우엔 이 URL(http://hwengineer.blogspot.kr/2017/10/minsky-tensorflow-r13-source-build.html)을 참조하여 직접 build 하셔야 합니다.  빌드 및 수행은 ppc64le에서도 잘 됩니다.  다만 tensorflow 1.2.1로도 충분하므로 굳이 1.3을 build하실 필요까지는 없습니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ conda install tensorflow tensorflow-gpu

그 다음으로 benchmark용 resnet model 등이 들어있는 다음의 git repository를 다음과 같이 clone 하십시요.  이는 원래 https://github.com/tensorflow/models.git 에 들어 있는 내용에 일부 script를 추가한 것입니다.  원래의 script는 imagenet training dataset을 download하는 것부터 시작하는데, 그건 시간이 너무 오래 걸리므로, 이미 download 받은 dataset을 이용하여 TFrecord로 변환하는 등의 script를 추가했습니다.  이 script 작성은 IBM 이보란님께서 수고해주셨습니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ git clone https://github.com/brlee08/models.git

여기에서 사용할 ILSVRC2012 imagenet dataset들은 다음과 같으며, 이는 미리 download 받으두셔야 합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ ls -l ILSVRC2012*
-rw-r----- 1 b7p286za IBM1     20861852 Aug 12  2012 ILSVRC2012_bbox_train_v2.tar.gz
-rw-r----- 1 b7p286za IBM1 147897477120 Nov  5 07:02 ILSVRC2012_img_train.tar
-rw-r----- 1 b7p286za IBM1   6744924160 Nov  5 07:03 ILSVRC2012_img_val.tar

이를 다음과 같이 적절한 위치에 풀어두셔야 합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ mkdir -p raw-data/bounding_boxes

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ mv ILSVRC2012_bbox_train_v2.tar.gz raw-data/bounding_boxes/annotations.tar.gz
b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ mv ILSVRC2012_img_train.tar raw-data/
b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ mv ILSVRC2012_img_val.tar raw-data/

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ cd models/research/inception/inception/data/

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/models/research/inception/inception/data$  ./T2_ibm_uncompress_imagenet.sh /gpfs/gpfs_gl4_16mb/raw-data/ /gpfs/gpfs_gl4_16mb/b7p286za/models/research/inception/inception/data/imagenet_lsvrc_2015_synsets.txt

--> 여기서 앞의 directory 이름 끝에 반드시 /를 붙이셔야 합니다.  (안그러면 error 납니다.)  이 script에 의해 앞에 쓴 directory 밑에 raw image (JPEG)들이 풀리면서 label명인 sub-directory로 분산되어 들어갑니다.   뒤에 쓴 imagenet_lsvrc_2015_synsets.txt 파일은 이 ILSVRC2012 data의 label 이름입니다.

위 script가 다 수행되고 나면 다음과 같이 이 JPEG 파일들을 TFrecord 포맷으로 변환합니다.  그를 위해, models/research/inception/inception/data 밑에 있는 T2_ibm_preprocess.sh 에서 아래 부분을 수정합니다.

  #source /opt/DL/tensorflow/bin/tensorflow-activate  (맨 위의 tensorflow-activate 부분을 comment-out 처리.  PowerAI에 있는 TF 1.0 대신 conda install로 설치한 TF 1.2.1을 사용하기 위한 것임)
   WORK_DIR="<models 디렉토리가 위치한 경로>/models/research/inception/inception"
   python <models 디렉토리가 위치한 경로>/models/research/inception/inception/data/build_imagenet_data.py

여기서는 아래와 같이 고쳤습니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/models/research/inception/inception/data$ vi ./T2_ibm_preprocess.sh
#source /opt/DL/tensorflow/bin/tensorflow-activate
...
WORK_DIR="/gpfs/gpfs_gl4_16mb/b7p286za/models/research/inception/inception"
...
python /gpfs/gpfs_gl4_16mb/b7p286za/models/research/inception/inception/data/build_imagenet_data.py \
...

수정이 끝나면 다음과 같이 수행합니다.  T2_ibm_preprocess.sh 뒤에 적어주는 directory 밑에 ilsvrc_tf라는 sub-directory가 생기면서 TFrecord 파일들이 생성됩니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/models/research/inception/inception/data$ time ./T2_ibm_preprocess.sh /gpfs/gpfs_gl4_16mb/b7p286za/

위 script는 200GB가 넘는 파일들을 처리하므로 시간이 꽤 오래, 약 4시간 정도 걸립니다.  다 끝마치면 다음과 같이 train-xxxx과 validation-xxxx 등의 TFrecord 파일들이 생깁니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/ilsvrc_tf$ ls -l | more
total 62635520
-rw-r----- 1 b7p286za IBM1 149402267 Dec 12 00:17 train-00000-of-01024
-rw-r----- 1 b7p286za IBM1 150240608 Dec 12 00:19 train-00001-of-01024
-rw-r----- 1 b7p286za IBM1 141760185 Dec 12 00:20 train-00002-of-01024
-rw-r----- 1 b7p286za IBM1 152134069 Dec 12 00:22 train-00003-of-01024
-rw-r----- 1 b7p286za IBM1 141508613 Dec 12 00:24 train-00004-of-01024
-rw-r----- 1 b7p286za IBM1 148320681 Dec 12 00:25 train-00005-of-01024
-rw-r----- 1 b7p286za IBM1 146087263 Dec 12 00:27 train-00006-of-01024
...

이제 다음과 같이 benchmark script들이 들어있는 git repo를 clone 합니다.  역시 이 script 작성은 IBM 이보란님께서 수고해주셨습니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ git clone https://github.com/brlee08/benchmark.git

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za$ cd benchmark/tensorflow

이중 bench_ibm_single.sh을 이용하여 수행하되, 먼저 일부를 다음과 같이 수정합니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/benchmark/tensorflow$ vi bench_ibm_single.sh
...
DATA_DIR=/gpfs/gpfs_gl4_16mb/b7p286za/ilsvrc_tf    (tfrecord 위치한 디렉토리)
LOG_DIR=/gpfs/gpfs_gl4_16mb/b7p286za/benchmark/tensorflow/output_single  (log를 쌓을 디렉토리)
...
TRAIN_DIR=/gpfs/gpfs_gl4_16mb/b7p286za/benchmark/tensorflow/train_log   (tensorboard용 log 쌓을 디렉토리)
...
NUM_EPOCHS=10
NUM_GPU=4
INPUT_BATCH=64
INPUT_MODEL="resnet101"
...
#TRAIN_LOG_DIR="${TRAIN_DIR}/googlenet-10e-128b-4G"  (쓰지 않는 것이므로 comment-out으로 막으십시요.)
...
#source /opt/DL/tensorflow/bin/tensorflow-activate  (역시 PowerAI에 있는 TF 1.0 대신 conda install로 설치한 TF 1.2.1을 사용하기 위해 comment-out)
export PATH=/gpfs/gpfs_gl4_16mb/b7p286za/anaconda2/bin:$PATH
export PYTHONPATH=/gpfs/gpfs_gl4_16mb/b7p286za/anaconda2/lib/python2.7/site-packages   (원래 source에는 anaconda3를 쓰고 있으나 여기서는 anaconda2의 site-packages를 PYTHONPATH로 설정해야 함)
...
#        --data_name=imagenet --train_dir=${TRAIN_LOG_DIR} --data_dir=${DATA_DIR} --variable_update=${VARIABLE_UPDATE} \
        --data_name=imagenet --train_dir=${TRAIN_DIR} --data_dir=${DATA_DIR} --variable_update=${VARIABLE_UPDATE} \
(원본에 오타가 있었습니다.  --train_dir=${TRAIN_LOG_DIR}를 --train_dir=${TRAIN_DIR}로 수정해야 합니다.)


이제 다음과 같이 resent training을 수행하면 됩니다.

b7p286za@p10login1:/gpfs/gpfs_gl4_16mb/b7p286za/benchmark/tensorflow$ nohup time /gpfs/gpfs_gl4_16mb/b7p284za/benchmark/tensorflow/bench_ibm_single.sh &

처음에는 몇몇 warning message와 함께 tensorflow 기동하는데 10분 정도 걸리므로 당황하지 마십시요.  대략 다음과 같은 결과가 나옵니다.

50010   images/sec: 485.7 +/- 0.1 (jitter = 3.8)        4.943
50020   images/sec: 485.7 +/- 0.1 (jitter = 3.8)        4.716
50030   images/sec: 485.7 +/- 0.1 (jitter = 3.8)        4.847
50040   images/sec: 485.6 +/- 0.1 (jitter = 3.8)        4.639
----------------------------------------------------------------
total images/sec: 485.42
----------------------------------------------------------------
Training Finish - 2017-12-12 13:59:14
Elapsed Time - 02:31:31


2017년 7월 24일 월요일

Minsky 서버에서 ImageNet Contest 2012 data로 Caffe AlexNet training 해보기

# 먼저, ILSVRC2012 data를 고성능 filesystem(NVMe SSD 또는 ESS 등)에 download 받습니다

b6p318za@p10a109:~/nvme/ilsvrc2012$ wget http://www.image-net.org/challenges/LSVRC/2012/nnoupb/ILSVRC2012_img_train.tar  # 138GB
b6p318za@p10a109:~/nvme/ilsvrc2012$ wget http://www.image-net.org/challenges/LSVRC/2012/nnoupb/ILSVRC2012_img_train_t3.tar  # 728MB
b6p318za@p10a109:~/nvme/ilsvrc2012$ wget http://www.image-net.org/challenges/LSVRC/2012/nnoupb/ILSVRC2012_img_val.tar   #  6.3GB
b6p318za@p10a109:~/nvme/ilsvrc2012$ wget http://www.image-net.org/challenges/LSVRC/2012/nnoupb/ILSVRC2012_img_test.tar  # 13GB

b6p318za@p10a109:/nvme/ilsvrc2012$ ls -ltr
total 165357316
-rw-r----- 1 b6p318za IBM1   6744924160 Jun 14  2012 ILSVRC2012_img_val.tar
-rw-r----- 1 b6p318za IBM1 147897477120 Jun 14  2012 ILSVRC2012_img_train.tar
-rw-r----- 1 b6p318za IBM1    762460160 Jul  4  2012 ILSVRC2012_img_train_t3.tar
-rw-r----- 1 b6p318za IBM1  13685811200 Jul  9  2012 ILSVRC2012_img_test.tar

# 이렇게 download 받은 image tar file들을 각각의 directory에 풀어놓습니다.  단, train용 image tar file을 풀면 그 속에 다시 1000개의 tar file이 나오니, 그것들을 또 한번 더 풀어주어야 합니다.

b6p318za@p10a109:/nvme/ilsvrc2012$ mkdir val
b6p318za@p10a109:/nvme/ilsvrc2012$ mkdir test
b6p318za@p10a109:/nvme/ilsvrc2012$ mkdir train
b6p318za@p10a109:/nvme/ilsvrc2012$ mkdir train_t3

b6p318za@p10a109:/nvme/ilsvrc2012$ cd val
b6p318za@p10a109:/nvme/ilsvrc2012/val$ tar -xvf ../ILSVRC2012_img_val.tar

b6p318za@p10a109:/nvme/ilsvrc2012$ cd train
b6p318za@p10a109:/nvme/ilsvrc2012/train$ tar -xvf ../ILSVRC2012_img_train.tar
b6p318za@p10a109:/nvme/ilsvrc2012/train$ for i in `ls`
> do
> dir=`echo $i | cut -d. -f1`
> mkdir $dir
> cd $dir
> tar -xf ../$i
> cd ..
> done

b6p318za@p10a109:/nvme/ilsvrc2012$ cd test
b6p318za@p10a109:/nvme/ilsvrc2012/test$ tar -xvf ../ILSVRC2012_img_test.tar

b6p318za@p10a109:/nvme/ilsvrc2012$ cd train_t3
b6p318za@p10a109:/nvme/ilsvrc2012/train_t3$ tar -xvf ../ILSVRC2012_img_train_t3.tar
b6p318za@p10a109:/nvme/ilsvrc2012/train_t3$ for i in *.tar
> do
> tar -xvf $i
> done


# 기본 시스템 성능 튜닝입니다.   GPU의 autoboost도 on 시켜 놓습니다.

b6p318za@p10a109:~$ sudo apt-get install linux-tools-common cpufrequtils
b6p318za@p10a109:~$ sudo cpupower frequency-set --governor performance

b6p318za@p10a109:~$ sudo nvidia-smi -pm ENABLED

b6p318za@p10a109:~$ sudo nvidia-smi -ac 715,1480


# 이미 설치된 PowerAI 중 NV-caffe를 사용합니다.  이를 위해서는 아래와 같은 명령을 수행하여 PATH 환경 변수 등을 NV-caffe를 기본으로 하도록 합니다.   PowerAI 설치에 대해서는 지난 posting ( http://hwengineer.blogspot.kr/2017/05/minsky-cuda-powerai-tuning.html )을 참조하십시요.

b6p318za@p10a109:/opt/DL$ source /opt/DL/caffe-nv/bin/caffe-activate

b6p318za@p10a109:/opt/DL$ which caffe
/opt/DL/caffe-ibm/bin/caffe


# 아래와 같이 caffe-test를 수행했을 때 혹시 error가 난다면 다음과 같이 LD_LIBRARY_PATH를 제대로 설정해주시면 됩니다.

b6p318za@p10a109:/opt/DL$ caffe-test
caffe-test: symbol lookup error: /opt/DL/caffe-ibm/test/../lib/libcaffe.so.1.0.0-rc3: undefined symbol: _ZNK6google8protobuf7Message11GetTypeNameB5cxx11Ev

b6p318za@p10a109:~$ export LD_LIBRARY_PATH=/usr/lib/powerpc64le-linux-gnu:/usr/local/lib:$LD_LIBRARY_PATH

b6p318za@p10a109:~$ sudo vi /etc/ld.so.conf.d/DL.conf
/opt/DL/openblas/lib

b6p318za@p10a109:~$ sudo ldconfig

b6p318za@p10a109:/opt/DL$ caffe-test
...
[----------] Global test environment tear-down
[==========] 2081 tests from 277 test cases ran. (664293 ms total)
[  PASSED  ] 2081 tests.


# Alexnet 수행 준비를 위해, 먼저 get_ilsvrc_aux.sh를 수행합니다.  그리고 download된 train.txt의 내용을 실제 file 위치에 맞도록 수정합니다.

b6p318za@p10a109:/opt/DL/caffe-ibm/data/ilsvrc12$ ./get_ilsvrc_aux.sh

b6p318za@p10a109:/opt/DL/caffe-ibm$ vi data/ilsvrc12/train.txt
n01440764/n01440764_10026.JPEG 0
n01440764/n01440764_10027.JPEG 0
...
---->
/nvme/ilsvrc2012/train/n01440764/n01440764_10026.JPEG 0
/nvme/ilsvrc2012/train/n01440764/n01440764_10027.JPEG 0
...

# 전체 image 준비를 위해 create_imagenet.sh를 수행합니다.  단, 수행 전에 이 script에서 RESIZE=true로 바꾸고, 기타 TRAIN_DATA_ROOT 등의 각종 path 등을 수정합니다.   특히, 기본적으로 $EXAMPLE 밑에 생성되도록 되어 있는 ilsvrc12_train_lmdb과 ilsvrc12_val_lmdb 이 고성능 filesystem(NVMe 혹은 ESS)에 생성되도록 path를 바꿔 줍니다.

b6p318za@p10a109:/opt/DL/caffe-ibm$ vi ./examples/imagenet/create_imagenet.sh
...
RESIZE=true
#RESIZE=false

b6p318za@p10a109:/opt/DL/caffe-ibm$ time ./examples/imagenet/create_imagenet.sh
Creating train lmdb...
...
I1116 08:56:31.806813  8234 convert_imageset.cpp:147] Processed 49000 files.
I1116 08:56:37.932953  8234 convert_imageset.cpp:147] Processed 50000 files.
Done.

(약 2시간 넘게 걸립니다.)

# 그 결과로 LMDB file들이 제대로 생성되었는지 확인합니다.

b6p318za@p10a109:/opt/DL/caffe-ibm$ ls -l /nvme/ilsvrc2012/ilsvrc12_train_lmdb
total 287040648
-rw-r----- 1 b6p318za IBM1 293929582592 Nov 16 08:51 data.mdb
-rw-r----- 1 b6p318za IBM1         8192 Nov 16 08:59 lock.mdb
b6p318za@p10a109:/opt/DL/caffe-ibm$ ls -l /nvme/ilsvrc2012/ilsvrc12_val_lmdb
total 11203084
-rw-r----- 1 b6p318za IBM1 11471945728 Nov 16 08:56 data.mdb
-rw-r----- 1 b6p318za IBM1        8192 Nov 16 08:56 lock.mdb


# 생성된 LMDB로부터 전체 imagenet data의 평균값을 구하기 위해 make_imagenet_mean.sh를 수행합니다.  (약 6시간 가까이 걸립니다.)

b6p318za@p10a109:/opt/DL/caffe-ibm$ nohup time ./examples/imagenet/make_imagenet_mean.sh &



# models/bvlc_alexnet/solver.prototxt을 적절한 위치로 copy 한 뒤 수정하여 stepsize를 20000으로 바꾸고, 각종 path도 적절한 위치로 바꿉니다.

b6p318za@p10a109:/tmp$ vi /nvme/bsyu/solver.prototxt
net: "/nvme/bsyu/train_val.prototxt"
test_iter: 1000
test_interval: 1000
base_lr: 0.01
lr_policy: "step"
gamma: 0.1
stepsize: 20000
display: 20
max_iter: 25000
momentum: 0.9
weight_decay: 0.0005
snapshot: 25000
snapshot_prefix: "/nvme/bsyu/models/caffe_alexnet_train"
solver_mode: GPU

# models/bvlc_alexnet/train_val.prototxt를 적절한 위치로 copy 한 뒤 수정하여 train data의 batch_size를 256으로, val data의 batch_size는 64로 바꾸고, 각종 path도 적절히 변경합니다.

b6p318za@p10a109:/tmp$ vi "/nvme/bsyu/train_val.prototxt"
name: "AlexNet"
layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    mirror: true
    crop_size: 227
    mean_file: "/nvme/ilsvrc2012/imagenet_mean.binaryproto"
  }
  data_param {
    source: "/nvme/ilsvrc2012/ilsvrc12_train_lmdb"
    batch_size: 256
    backend: LMDB
  }
}
layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TEST
  }
  transform_param {
    mirror: false
    crop_size: 227
    mean_file: "/nvme/ilsvrc2012/imagenet_mean.binaryproto"
  }
  data_param {
    source: "/nvme/ilsvrc2012/ilsvrc12_val_lmdb"
    batch_size: 64
    backend: LMDB
  }
}
...


# 다음과 같은 train_alexnet.sh를 만들어 수행합니다.

b6p318za@p10a109:/opt/DL/caffe-nv$ vi ./examples/imagenet/train_alexnet.sh
#!/usr/bin/env sh
set -e
#./bin/caffe train -gpu 0,1 --solver=models/bvlc_alexnet/solver.prototxt
./bin/caffe train -gpu all --solver=models/bvlc_alexnet/solver.prototxt


b6p318za@p10a109:/opt/DL/caffe-nv$ nohup time ./examples/imagenet/train_caffenet.sh &
[1] 9820


# 결과로 생기는 nohup.out에서 grep accuracy를 수행하여, accuracy가 0.5 이상으로 올라갈 때까지 걸린 시간을 계산합니다.

b6p318za@p10a109:/opt/DL/caffe-ibm$ grep accuracy ~/nohup.out
I1118 06:55:19.538242 48597 solver.cpp:442]     Test net output #0: accuracy = 0.000999999
I1118 07:41:13.278080 48597 solver.cpp:442]     Test net output #0: accuracy = 0.18552
I1118 07:50:19.552739 48597 solver.cpp:442]     Test net output #0: accuracy = 0.26228
...
I1118 08:27:07.605918 48597 solver.cpp:442]     Test net output #0: accuracy = 0.405379
I1118 08:36:16.722012 48597 solver.cpp:442]     Test net output #0: accuracy = 0.42512
...
I1118 11:36:23.555583 48597 solver.cpp:442]     Test net output #0: accuracy = 0.50274
I1118 20:38:10.207644 48597 solver.cpp:442]     Test net output #0: accuracy = 0.52026

(약 1시간 남짓 걸릴 것입니다.)