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시간 남짓 걸릴 것입니다.)

댓글 없음:

댓글 쓰기