이 튜토리얼은 리버트론에서 교육하는 Vitis-AI 튜토리얼을 진행하며 작성하였습니다.
caffe를 사용하기 위해 이미지를 build할 때 생성되었던 conda 가상환경에 접속한다.
conda activate vitis-ai-caffe
구글 드라이브에서 받아온 파일을 포맷에 맞게 변경시켜줘야 하는데, 이를 자동화해주는 파이썬 코드가 첨부되어있다. 자동화 코드를 사용해도 좋지만 이미 생성된 Annotation File이 zsk_face_detection/densebox_face-detection/train_list.txt 경로에 존재하므로, 이를 사용한다. 해당 파일을 Vitis-AI 폴더의 이미지 데이터와 같은 폴더에 복사해준다.
lmdb를 생성하기 위해 data 폴더에서 아래와 같이 입력한다.
명령어 포맷은 아래와 같다.
convert_face <TRAIN_IMG_DIR> <OUT_TRAIN_ANNO_FILE> <LMDB_PATH>
symbol lookup error가 났다. 해결하기위해 구글링한 결과
https://github.com/Xilinx/Vitis-AI/issues/419
위 글에서 glog 패키지가 충돌이 났으므로, 버전을 낮춰야함을 알았다.
sudo env PATH=/opt/vitis_ai/conda/bin:$PATH CONDA_PREFIX=/opt/vitis_ai/conda/envs/vitis-ai-caffe/ conda install --force --yes glog=0.4.0
위 명령어를 입력하여 glog 버전을 0.4.0으로 낮춘다.
다시 실행해 성공적으로 수행함을 확인했다.
libnccl.so.1 라이브러리가 없다는 에러가 나왔다.
nccl 1버전이 필요한게 아닐까 생각하고 nccl을 새로 받는다.
현재 가상환경인 vitis-ai-caffe를 빠져나온 뒤 nccl을 새로 받는다.
conda deactivate
conda install -c anaconda nccl
설치를 시작하면 다음과 같이 권한이 없다고 나온다.
CPU 버전에서 사용했던 명령어처럼 환경변수를 설정해주면 해결된다.
sudo env PATH=/opt/vitis_ai/conda/bin:$PATH CONDA_PREFIX=/opt/vitis_ai/conda/envs/vitis-ai-caffe/ conda install --force --yes -c anaconda nccl
또 이렇게 해결하고 실행하면 CPU버전에서와 마찬가지로 symbol lookup error가 발생한다. 이를 해결하기 위해 glog 버전을 0.4.0으로 낮춘다.
sudo env PATH=/opt/vitis_ai/conda/bin:$PATH CONDA_PREFIX=/opt/vitis_ai/conda/envs/vitis-ai-caffe/ conda install --force --yes glog=0.4.0
성공적으로 실행됨을 확인했다.
lmdb를 모두 생성한 모습.
다음 단계부터는 더 빠른 학습을 위해 GPU 버전 컨테이너에서 진행한다.
lmdb를 모두 생성하고나면 celeba.lmdb 폴더가 생성되어있다. 이 폴더에 snapshot 이라는 이름의 폴더를 생성한다.
또, zsk_face_detection/densebox_face-detection/float 경로에 있는 solver.prototxt 파일과 train.prototxt 파일을 celeba.lmdb 폴더에 복사한다.
최종 lmdb 폴더의 상태는 아래와 같다.
아래와 같은 포맷으로 실행한다.
caffe train --solver <SOLVER_FILE> --gpu <GPU_NUMBER> 2>&1 | tee <LOG_FILE>
caffe train --solver solver.prototxt --gpu 0 2>&1 | tee train.log
아래와 같이 lmdb를 읽어오는 과정에서 에러가 발생했다.
train.prototxt 파일을 보니, data source가 ../lmdb로 되어있었다.
우리의 폴더명은 celeba.lmdb이므로, 폴더명을 lmdb로 수정한 후 다시 실행한다.
아래와 같이 GPU 메모리가 가득차는 에러가 발생했다.
모델의 batch size가 너무 커서 발생한 것일 수 있으므로, batch size를 줄이기 위해 train.prototxt 파일을 수정한다.
batch_size: 128 -> 64
batch size를 줄이고 나니 정상적으로 학습 가능했다. GPU 사용량을 확인하기 위해 아래 링크의 gmonitor를 사용했다.
https://github.com/mountassir/gmonitor#building-from-source
학습이 완료되면 아래와 같이 snapshot 폴더 안에 solverstate 파일과 caffemodel파일이 생성되어있다. 뒤의 번호는 Iteration 횟수이다.
zsk_face_detection/densebox_face-detection/test/visualTest 경로에 있는 detect.py 파일을 이용하여 방금 학습한 모델을 Test한다. Weights값으로는 가장 많이 학습한 파일을 사용한다. 명령어는 아래와 같다.
python detect.py --model ../../float/test.prototxt \
--weights ../../../../data_face_detection/lmdb/snapshot/conv_iter_180000.caffemodel \
--testImgList ./image_list_test.txt \
--inputImgPath ./ \
--outputPath ./output/ \
--gpu 0 --score 0 --bbox 0
명령어를 입력하면 위처럼 에러가 나는데, opencv 패키지의 rectangle 함수의 인자로 int값이 아닌 인자가 주어져서 발생한 에러이다. 이를 위해 detect.py 스크립트를 아래와 같이 수정한다.
수정하고 나면 아래와 같이 정상적으로 실행됨을 확인할 수 있다. (몇몇 Layer가 Ignore 됐는데 왜인지 모름.)
테스트 결과는 output 디렉토리에서 확인할 수 있다.
한장의 이미지(옆모습)을 제외하고는 모두 훌륭하게 얼굴의 위치를 잡아낸다.
위의 Test에서 사용되었던 test.prototxt 파일의 Input Layer를 튜토리얼과 같이 ImageData Layer로 수정한다.
test.prototxt 파일을 열어보면 calibration.txt 파일의 경로가 나타나있다. 이 경로는 Quantization 명령어를 입력하는 곳으로 부터의 상대 경로이다. 따라서 명령어를 입력할 곳에 calibration.txt 파일이 존재해야한다. 이를 위해 zsk_face_detection/densebox_face-detection/ 경로로 이동한다.
또, calibration.txt 파일을 열어보면 이미지 파일의 경로가 지정되어있다. 이는 현재 폴더의 img_celbab 폴더 안의 이미지 100장을 Input함을 의미한다.
vai_q_caffe quantize -model ./float/test.prototxt \
-weights ../../data_face_detection/lmdb/snapshot/conv_iter_180000.caffemodel \
-output_dir ./quantize \
-method 1
Quantization이 끝나면 아래와 같이 quantize 폴더 안에 파일들이 생성되어있다.
하나의 Input Layer를 갖도록 튜토리얼대로 수정한다.
왜인지 이미 하나의 Input Layer를 갖고있었다. 수정하지 않고 진행한다.
Quantization이된 deploy.prototxt파일과 deploy.caffemodel 파일을 이용한다. output 디렉토리와 net_name은 편한 곳을 지정해두어도 상관없지만, arch 파일은 튜토리얼에서 주어진 파일을 사용한다. (arm32 아키텍처로 크로스 컴파일하기 위해)
vai_c_caffe --prototxt quantize/deploy.prototxt \
--caffemodel quantize/deploy.caffemodel \
--output_dir ./compile/ --arch ./common/arch.json \
--net_name densebox
컴파일이 끝나면 아래와 같이 컴파일된 파일들을 확인할 수 있다.
이 과정부터는 Docker Container에서 나와서 Local에서 진행한다.
zsk_face_detection/densebox_face-detection/sdk 경로에 존재하는 sdk.sh 스크립트 파일을 실행시켜 Peatlinux SDK Installer를 실행한다. SDK 설치 경로는 zsk_face_detection/densebox_face-detection/sdk 경로 내에 설치한다.
설치가 완료되면 아래와 같이 파일들이 생성된다.
환경변수를 설정하기위해 아래 명령어를 입력한다. (아래 명령어는 linux를 다시 부팅할때마다 입력해주어야함.)
unset LD_LIBRARY_PATH
source environment-setup-cortexa9t2hf-neon-xilinx-linux-gnueabi
zsk_face_detection/densebox_face-detection/compile 경로에 우리가 compile하여 만들어 놓았던 dpu_densebox_0.elf 파일을 zsk_face_detection/densebox_face-detection/project 폴더로 복사한다. 그 후 zsk_face_detection/densebox_face-detection/project 경로에서 아래 명령어를 입력한다.
make
Make가 끝나면 아래와 같이 폴더에 fmc_face_detection_densebox 파일이 생성된다.
hello, how can i get train_list.txt? i want to do the all process. thx :)