Caffe Tutorial : 6.Interface (Kor) - ys7yoo/BrainCaffe GitHub Wiki
Interface)
์ธํฐํ์ด์ค (Caffe๋ ๋ ๋ง๋ค ๋ณํ๋ ์ฌ์ฉ๋ฒ, ์ฐ๊ตฌ ์ฝ๋๋ฅผ ๊ฐ์ง ์ธํฐํ์ด์ฑ๊ณผ ์ ์ ์์ ํํ์ ์ํด ์ปค๋งจ๋ ๋ผ์ธ, Python, ๊ทธ๋ฆฌ๊ณ Matlab ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๊ณ ์๋ค. Caffe๋ ์ค์ฌ์ผ๋ก C++ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ฉฐ ๊ฐ๋ฐ์ ์ํ ๋ชจ๋์์ ์ธํฐํ์ด์ค๋ฅผ ๋ ธ์ถ์ํค๋ ๋ฐ๋ณ์, ๋ชจ๋ ๋๋ง๋ค ๊ด์ต์ ๋ชจ์์ง(custom compilation)์ ์์ฒญํ์ง๋ ์๋๋ค. cmdcaffe, pycaffe, matcaffe ์ธํฐํ์ด์ค๊ฐ ๋น์ ์ ์ํด ์ค๋น๋ฌ๋ค.
1. ์ปค๋งจ๋๋ผ์ธ (Command Line)
์ปค๋งจ๋ ๋ผ์ธ ์ธํฐํ์ด์ค - cmdcaffe - ๋ ๋ชจ๋ธ ํธ๋ ์ด๋, ์ค์ฝ์ด๋ง, ์ง๋จ๋ค์ ์ํ Caffe ๋๊ตฌ์ด๋ค. ํ๋ฒ caffe๋ฅผ ์ด๋ ํ ๋์๋ง ์์ด ์คํ์์ผ๋ณด๋ผ. ์ด ๋๊ตฌ์ ๋ค๋ฅธ ๊ฒ๋ค์ caffe/build/tools์์์ ์ฐพ์์ ์๋ค. (The following example calls require completing the LeNet / MNIST example first.)
- Training : "caffe train"์ ์ ์ฅ๋ ์ค๋ ์ท์ผ๋ก๋ถํฐ ํ์ต์ ์ฌ๊ฐํ๋ฉด์ ์คํฌ๋์น๋ก๋ถํฐ ๋ชจ๋ธ๊ณผ ์๋ก์ด ๋ฐ์ดํฐ์ ์ ๋ฌด์ ์ ์กฐ์จ๋ ๋ชจ๋ธ์ ํ์ตํ๋ค.
- ๋ชจ๋ ํธ๋ ์ด๋์ -solver solver.prototxt ์ธ์๋ฅผ ํตํด solver ๊ตฌ์ฑ์ด ์๊ตฌ๋๋ค.
- ์ฌ๊ฐํ๋ ๊ฒ์ ํด๊ฒฐ์ฌ ์ค๋ ์ท์ ์ฝ์ด์ฌ๋ ค๋ฉด -snapshot model_iter_1000.solverstate ์ธ์๊ฐ ์๊ตฌ๋๋ค.
- ์ ์กฐ์จ์ํค๊ธฐ ์ํด์๋ ๋ชจ๋ธ ์ด๊ธฐํ๋ฅผ ์ํด -weights model.caffemodel๊ฐ ์๊ตฌ๋๋ค. ์์๋ก ๋ค์์ ์คํ์์ผ๋ณผ ์ ์๋ค.
# LeNet ํธ๋ ์ด๋
caffe train -solver examples/mnist/lenet_solver.prototxt
# GPU 2 ์์์ ํธ๋ ์ด๋
caffe train -solver examples/mnist/lenet_solver.prototxt -gpu 2
# ์ค๊ฐ์ง์ ์ค๋
์ท์ผ๋ก๋ถํฐ ํธ๋ ์ด๋ ์ฌ๊ฐ
caffe train -solver examples/mnist/lenet_solver.prototxt -snapshot examples/mnist/lenet_iter_5000.solverstate
์ ์กฐ์จ์ํค๋ ๊ฒ์ ๋ํ ์์๋ "examples/finetuning_on_flickr_style"์ ๋ณด๋ผ, ํ์ง๋ง ํธ๋ ์ด๋์ ๋ค์ ํ์ค๋ก ํธ์ถํ๋ค.
# ์คํ์ผ์ ์์๋ณด๊ธฐ์ํ ์ ์กฐ์จ๋ CaffeNet ๋ชจ๋ธ ๊ฐ์ค์น
caffe train -solver examples/finetuning_on_flickr_style/solver.prototxt -weights models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel
- Testing : "caffe test"๋ ํ ์คํธ ๋จ๊ผ์์ ๊ทธ๋ค์ ๊ฐ๋์ํด์ ์ํด ๋ชจ๋ธ์ ์ ์๋งค๊ธด๋ค. ๊ทธ์ ์ค์ฝ์ด๋ก ๋ง ์ถ๋ ฅ์ ๋ณด๊ณ ํ๋ค. ๋ง ์ค๊ณ๋ ์ ํ๋ ์ธก์ ์ด๋ ์ถ๋ ฅ์ผ๋ก์จ ์์ค์ ์ ์ํด์ผ๋ง ํ๋ค. ๋จ์ ์ฒ๋ฆฌ๋ ์ ์๋ ๋ณด๊ณ ๋ ๋ค์ ๊ณต์ ์ ์ ์ฒดํ๊ท ์ด ๊ธฐ๋ก๋๋ค.
# ๋ชจ๋ธ ๊ตฌ์กฐ "lenet_train_test.prototxt"์์ ์ ์๋ ๊ฒ์ฒ๋ผ ์ ํจ์ฑ ์ธํธ์์ ํ๋ จ๋ LeNet model๊ฐ ์ ์ ๋งค๊ฒจ์ง๋ค.
caffe test -model examples/mnist/lenet_train_test.prototxt -weights examples/mnist/lenet_iter_10000.caffemodel -gpu 0 -iterations 100
- Benchmarking: "caffe time"์ ํ์ด๋ฐ๊ณผ ๋์ผํ๋ฅผ ํตํด ๊ณ์ธต๊ฐ ๊ณ์ธต์ ๋ชจ๋ธ ์คํ์ ๋ฐด์น๋งํนํ๋ค. ์ด๊ฒ์ ์์คํ ์ํ์ ์ฒดํฌํ๊ณ ๋ชจ๋ธ์ ๋ํ ์๋์ ์คํ ์๊ฐ์ ์ธก์ ํ๋๋ฐ ์ ์ฉํ๋ค.
# (These example calls require you complete the LeNet / MNIST example first.)
# 10๋ฒ ๋ฐ๋ณต์ ์ํ CPU ์์ LeNet ํธ๋ ์ด๋ ์๊ฐ์ ์ธก์
caffe time -model examples/mnist/lenet_train_test.prototxt -iterations 10
# ๋ํดํธ 50 ๋ฐ๋ณต์ ์ํ GPU์์ LeNet ํธ๋ ์ด๋ ์๊ฐ์ ์ธก์
caffe time -model examples/mnist/lenet_train_test.prototxt -gpu 0
# 10๋ฒ ๋ฐ๋ณต์ ๋ํ ์ฒซ GPU ์์์ ์ฃผ์ด์ง๋ ๊ฐ์ค์น๋ก ๊ตฌ์ฑ๋ ๋ชจ๋ธ ์ค๊ณ ์๊ฐ์ ์ธก์
time a model architecture with the given weights on the first GPU for 10 iterations
caffe time -model examples/mnist/lenet_train_test.prototxt -weights examples/mnist/lenet_iter_10000.caffemodel -gpu 0 -iterations 10
- Diagnostics: "caffe device_query"์ ์ธ๊ธ์ ๋ํ GPU ๋ํ ์ผ๊ณผ ๋ค์ค GPU ๊ธฐ๊ณ์์ ์ฃผ์ด์ง ์ฅ์น์์์ ์คํํ๊ธฐ ์ํ ์ฅ์น ์์๋ฅผ ์ฒดํฌํ๋ ๊ฒ์ ๋ณด๊ณ ํ๋ค.
# ์ฒซ๋ฒ์งธ ์ฅ์น์ ๋ํ์ฌ ๋ฌผ์ด๋ณธ๋ค.
caffe device_query -gpu 0
- Parallelism: "-gpu"๋ ๋ค์ค GPU ์์์ ๋์๊ฐ๋ ID๋ค์ ๋ฆฌ์คํธ๋ฅผ ์ปด๋ง๋ก ๋๋์ ์๋ Caffe ๋๊ตฌ์ด๋ค. ํด๊ฒฐ์ฌ์ ๋ง์ ๊ฐ๊ฐ์ GPU์ ๋ํ์ฌ ์ธ์คํด์คํ๋์ด์ง๊ณ , ์ผํ ์ฒ๋ฆฌ๋์ ํฌ๊ธฐ๋ ํจ์จ์ ์ผ๋ก GPU์ ์์ ์ํ์ฌ ๊ณฑํด์ง๋ค.๋จ์ผ GPU ํธ๋ ์ด๋์ ์ฌ์์ฐํ๊ธฐ ์ํด์๋ ๋คํธ์ํฌ ์ ์์ ๋ง์ถ์ด ์ผํ ์ฒ๋ฆฌ๋ ์ฌ์ด์ฆ๋ฅผ ์ค์ฌ์ผ ํ๋ค.
# train on GPUs 0 & 1 (doubling the batch size)
caffe train -solver examples/mnist/lenet_solver.prototxt -gpu 0,1
# train on all GPUs (multiplying batch size by number of devices)
caffe train -solver examples/mnist/lenet_solver.prototxt -gpu all
2. Python
ํ์ด์ฌ ์ธํฐํ์ด์ค(pycaffe)๋ caffe ๋ชจ๋์ด๋ฉฐ ์ด ์คํฌ๋ฆฝํธ๋ caffe/python ์์ ์๋ค. ์ด๋ ๋ชจ๋ธ์ ํธ์ถํ๊ธฐ์ํด ์นดํ๋ฅผ ๋ถ๋ฌ์ค๊ณ , ์ ๋ฐฉํฅ๊ณผ ์ญ๋ฐฉํฅ ๊ณผ์ ์ ์ํํ๊ณ , IO๋ฅผ ๋ค๋ฃจ๊ณ , ๋คํธ์ํฌ๋ฅผ ์๊ฐํ ํ๋ฉฐ, ์ฌ์ง์ด ๋ชจ๋ธ์ ํด๊ฒฐํด์ฃผ๋ ๋๊ตฌ์ด๋ค. ๋ชจ๋ ๋ชจ๋ธ ๋ฐ์ดํฐ, ์ ๋์ฒด๋ค, ํ๋ผ๋ฏธํฐ๋ ์ฝ๊ณ ์ฐ๊ธฐ๋ฅผ ์ํด ์ ๊ณต๋๋ค.
- caffe.Net์ ํธ์ถํ๊ธฐ, ๊ตฌ์ฑํ๊ธฐ ๊ทธ๋ฆฌ๊ณ ๋ชจ๋ธ ์๋์ ์์ด ์์ฃผ ์ค์ํ ์ธํฐํ์ด์ค์ด๋ค. caffe.Classifier์ caffe.Detector๊ฐ ์ผ๋ฐ์ ์ ๋ฌด๋ฅผ ์ํ ํธ๋ฆฌํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค.
- caffe.SGDSolver๋ ํด๊ฒฐํด์ฃผ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค.
- caffe.io๋ ์กฐ๊ธฐ์ฒ๋ฆฌ์ ํ๋กํ ์ฝ ๋ฒํผ๋ก ์ ๋ ฅ / ์ถ๋ ฅ์ ๋ค๋ฃฌ๋ค.
- caffe.draw๋ ๋คํธ์ํฌ ๊ตฌ์กฐ๋ฅผ ์๊ฐํํ๋ค.
- Caffe blobs๋ค์ ์ฌ์ฉ์ ํธ๋ฆฌํ๊ณผ ํจ์จ์ฑ์ ์ํด numpy ndarrays๋ก์จ ์ ๊ณต๋์ด์ง๋ค.
ํํ ๋ฆฌ์ผ IPython ๋ ธํธ๋ถ์ caffe/example์์ ์ฐพ์์ ์๋ค : caffe/examples์ iPython notebook์ ์คํํ๋ผ. ๊ฐ๋ฐ์์๊ฒ๋, docstrings์ฐธ์กฐ๋ ์ ์ฒด ์ฝ๋์์ ์ฐพ์๋ณผ ์ ์๋ค.
make pycaffe๋ก pycaffe๋ฅผ ์ปดํ์ผํ๋ผ. PYTHONPATH=/path/to/caffe/python:$PYTHONPATH๋ฅผ ํธ์ถํ๊ฑฐ๋ caffe์ ์ถ๊ฐํจ์ผ๋ก์จ ๋น์ ์ ํ์ด์ฌ ์์น์ ๋ชจ๋ ๋๋ ํ ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ผ.
3. MATLAB
MATLAB ์ธํฐํ์ด์ค (matcaffe)๋ ๋น์ ์ matlab ์ฝ๋์ caffe๋ฅผ ํฉ์น ์ ์๋ caffe/matlab์ ์๋ caffe์ ํจํค์ง์ด๋ค. MatCaffe์์ ๋น์ ์ ๋ค์๊ณผ ๊ฐ์๊ฒ์ ํ ์ ์๋ค.
- Matlab์ ๋ค์ค ๋ง์ ๋ง๋ค ์ ์๋ค.
- ์ ๋ฐฉํฅ๊ณผ ์ญ๋ฐฉํฅ ์ฐ์ฐ์ ํ ์ ์๋ค.
- ๋คํธ์ํฌ ์์ ์๋ ์ด๋ค ๊ณ์ธต์ด๋ ํน์ ๊ณ์ธต์์ ์ด๋ ํ ํ๋ผ๋ฏธํฐ blob์ ์ ์ ํ ์ ์๋ค.
- ๋คํธ์ํฌ ์์ ์ด๋ ํ blob๋ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ์๋, ์ค์ ํ ์ ์์ผ๋ฉฐ, ์ ๋ ฅ blob๋ ์ถ๋ ฅ blob๋ค์ ์ ํญ์ ์ด์ง๋ ์๋ค.
- ํ์ผ์ ๋คํธ์ํฌ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ์ฅํ๊ณ ํ์ผ๋ก๋ถํฐ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ถ๋ฌ์ฌ์๋ ์๋ค.
- network์ blob๋ฅผ ์ฌ๊ตฌ์ฑํ ์ ์๋ค.
- ๋คํธ์ํฌ ํ๋ผ๋ฏธํฐ๋ฅผ ์์ ํ ์ ์์ผ๋ฉฐ, ๋คํธ์ํฌ ์์ ์ด ๊ฐ๋ฅํ๋ค.
- ํ์ต์ ์ํด Matlab์์ ๋ค์ค ํด๊ฒฐ์ฌ๋ฅผ ๋ง๋ค ์ ์๋ค.
- ํด๊ฒฐ์ฌ์ ์ค๋ ์ท์ผ๋ก๋ถํฐ์ ํ์ต์ ์ฌ๊ฐํ ์ ์๋ค.
- ํด๊ฒฐ์ฌ ๋ด์์ ํ์ต ๋ง๊ณผ ์คํ ๋ง์ ์ ์ดํ ์ ์๋ค.
- ๋ฐ๋ณต์ ํน์ ํ ์์น์์ ์์ํ ์ ์๊ณ Matlab์์ ์ญ์ผ๋ก ๊ฐ๊ฒ ์กฐ์ข ํ ์ ์๋ค.
- ๊ทธ๋๋์ธํธ ๋จ๊ณ์์ Matlab ์ฝ๋๋ฅผ ์์์ ์ผ๋ก ์์ ์ ์๋ค. ILSVRC ์ด๋ฏธ์ง ๋ถ๋ฅํ ๋ฐ๋ชจ๋ฒ์ ์ caffe/matlab/demo/classification_demo.m์ ์๋ค.(BVLC CaffeNet ์คํํ๊ธฐ ์ํด Model Zoo์์ ์ด๋ฅผ ๋ค์ด๋ก๋ ๋ฐ์ ํ์๊ฐ ์๋ค.)
MatCaffe ๊ตฌ์ถํ๊ธฐ
make all matcaffe๋ช ๋ น์ด๋ก MatCaffe๋ฅผ ๊ตฌ์ถํ๊ณ , ๊ทธ ํ๋ ๋ make mattest๋ฅผ ์ฌ์ฉํด์ ํ ์คํธํ ์ ์๋ค.
์ผ๋ฐ์ ๋ฌธ์ : ๋ง์ฝ make mattest ์คํ์ค์ libstdc++.so.6:version 'GLIBCXX_3.4.15' not found์ ๊ฐ์ ์๋ฌ ๋ฉ์ธ์ง๊ฐ ์คํ๋๋ฉด, ๋ณดํต ๋น์ ์ Matlab์ runtime ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ๋น์ ์ compile-time ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ง์ง ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. Matlab์ ์์ํ๊ธฐ ์ ์, ๋ค์๊ณผ ๊ฐ์ ์ฌํญ์ ํด์ค ํ์๊ฐ ์๋ค.
export LD_LIBRARY_PATH=/opt/intel/mkl/lib/intel64:/usr/local/cuda/lib64
export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6
ํน์ ์ด๋ฏธ ๋์ผํ ๊ฒ๋ค์ด ๋น์ ์ ์์คํ ์์ ์ค์น๋์ด ์๋ค๋ฉด, ๋ค์ ๋ฌธ์ ๊ฐ ๊ณ ์ณ์ก๋์ง ๋ณด๊ธฐ์ํด make mattest์ ์คํํด๋ณด๋ผ. ์ด ๋ฌธ์ ๋ ๋๋๋ก ์์ํ๋ ๋์์ Matlab์ด ๋น์ ์ LD_LIBRARY_PATH ํ๊ฒฝ๋ณ์์ ๋ฎ์ด์ธ ์๋ ์๊ธฐ ๋๋ฌธ์ ์ข ๋ ๋ณต์กํ๋ค. ๋น์ ์ ์ด ๋ฐํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ณด๊ธฐ์ํด !ldd ./matlab/+caffe/private/caffe_.mexa64์ ์คํํ ์ ์๋ค. (mex extension์ ์ฌ์ฉ์ ์์คํ ์ ๋ฐ๋ผ ์ฐจ์ด๊ฐ ๋ ์ ์๋ค.) ๊ทธ๋ฆฌ๊ณ compile_time ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ LD_PRELOAD ํ๊ฒฝ๋ณ์๋ฅผ ํธ์ถํจ์ผ๋ก์จ compile_time ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ๋ถ๋ฌ์ฌ ์ ์๋ค.
๊ตฌ์ถ๊ณผ ํ ์คํธ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ๋ง์นํ์, caffe root forder์์ matlab๋ฅผ ์คํํ๊ณ ๋ค์๊ณผ ๊ฐ์ ๋ช ๋ น์ด๋ฅผ Matlab ๋ช ๋ น์ฐฝ์ ์คํํจ์ ์ํด ์์น๋ฅผ ํ์ํ๋ ํจํค์ง๋ฅผ matlab์ ์ถ๊ฐํ๋ผ.
addpath ./matlab
savepath๋ฅผ ์คํํจ์ผ๋ก์จ ๋น์ ์ Matlab ํ์ ์์น๋ฅผ ์ ์ฅํ ์ ์์ด์ MatCaffe๋ฅผ ๋งค๋ฒ ์ฌ์ฉํ ๋ ๋ง๋ค ๋ค์ ์์ ๊ฐ์ ๋ช ๋ น์ด๋ฅผ ์คํํ ํ์๊ฐ ์๋ค.
MatCaffe ์ฌ์ฉํ๊ธฐ
MatCaffe๋ PyCaffe์ ์ฌ์ฉ๋ฒ๊ณผ ๋งค์ฐ ์ ์ฌํ๋ค.
์๋์ ๊ฐ์ ์์๋ ์์ธํ ์ฌ์ฉ๋ฒ์ ์๋ ค์ฃผ๋ฉฐ ๋น์ ์ด caffe root folder์์ Matlab์ ์คํํ๊ณ Model Zoo์์ BVLC CaffeNet๋ฅผ ์ค์นํ๋ค๊ณ ๊ฐ์ ํ๋ค.
model = './models/bvlc_reference_caffenet/deploy.prototxt';
weights = './models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel';
๋ชจ๋์ ์ฅ์น ์ค์
๋ชจ๋์ ์ฅ์น๋ ํญ์ ๋น์ ์ด ๋ง์ด๋ ํด๊ฒฐ์ฌ๋ฅผ ๋ง๋ค๊ธฐ ์ ์ ์ค์ ๋์ด์์ด์ผ๋ง ํ๋ค.
CPU ์ฌ์ฉ์:
caffe.set_mode_cpu();
GPU ์ฌ์ฉ์๋ ํด๋น GPU์ gpu_id ๋ช ์์:
caffe.set_mode_gpu();
caffe.set_device(gpu_id);
๋คํธ์ํฌ๋ฅผ ๋ง๋ค๊ณ ๊ทธ์ ๊ณ์ธต๊ณผ blob์ ์ ๊ทผํ๊ธฐ
๋คํธ์ํฌ ์์ฑ:
net = caffe.Net(model, weights, 'test'); % create net and load weights
ํน์
net = caffe.Net(model, 'test'); % create net but not load weights
net.copy_from(weights); % load weights
๊ทธ๋ฆฌ๊ณ ์ด๋ ๋ค์๊ณผ ๊ฐ์ด Net ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ๊ณ ,
Net with properties:
layer_vec: [1x23 caffe.Layer]
blob_vec: [1x15 caffe.Blob]
inputs: {'data'}
outputs: {'prob'}
name2layer_index: [23x1 containers.Map]
name2blob_index: [15x1 containers.Map]
layer_names: {23x1 cell}
blob_names: {15x1 cell}
๋๊ฐ์ containers.Map ์ค๋ธ์ ํธ๋ ๊ณ์ธต์ด๋ blob์ ์ธ๋ฑ์ค๋ฅผ ๊ทธ ์ด๋ฆ์ผ๋ก ์ฐพ๊ธฐ์ ์ ์ฉํ๋ค.
๋น์ ์ ์ด์ ์ด ๋คํธ์ํฌ์ ๋ชจ๋ blob๋ฅผ ์ ๊ทผํ๋ค. ๋ชจ๋ ๊ฒ์ blob '๋ฐ์ดํฐ'๋ฅผ ์ฑ์ฐ๊ธฐ ์ํด์๋:
net.blobs('data').set_data(ones(net.blobs('data').shape));
10์ผ๋ก blob๋ด์ ๋ชจ๋ ๊ฐ๋ค์ ๊ณฑํ๊ธฐ ์ํด์๋:
net.blobs('data').set_data(net.blobs('data').get_data() * 10);
Matlab์ 1๊ฐ์ ์ธ๋ฑ์ค๋ง ๋ฌ๋ ค์ ธ์๊ณ ์ด์ฐ์ ์ ์ด๊ธฐ ๋๋ฌธ์ ์ฃผ์ํด์ผํ๊ณ , Matlab ๋ด์์ ์ผ๋ฐ์ 4 blob ์ฐจ์์ [width, height, channels, num]์ด๋ฉฐ, width๊ฐ ์ ์ผ ๋จผ์ ์ค๋ ์ฐจ์์ด๋ค. ๋ฐ๋ผ์ ์ด๋ฏธ์ง๊ฐ BGR ์ฑ๋์ ์๋ค๋ ๊ฒ์ ์ ์ํด์ผํ๋ค.
๋ํ, Caffe๋ ๋จ์ ๋ float data๋ฅผ ์ฌ์ฉํ๋ค. ๋ง์ฝ ๋ฐ์ดํฐ๊ฐ ๋จ์ผ์ด ์๋๋ผ๋ฉด, set_data๊ฐ ์๋์ ์ผ๋ก ๋จ์ผ๋ก ๋ฐ์ดํฐ๋ค์ ๋ณํ์์ผ์ค ๊ฒ์ด๋ค. ๋น์ ์ ๋ํ ๋ชจ๋ ๊ณ์ธต์ ์ ๊ทผํด์๋ค, ๋ฐ๋ผ์ ๋น์ ์ ๋คํธ์ํฌ ์์ (network surgery)์ ์งํํ ์ ์๋ค. conv1 ํ๋ผ๋ฏธํฐ์ 10์ ๊ณฑํ๊ธฐ ์ํด์๋:
net.params('conv1', 1).set_data(net.params('conv1', 1).get_data() * 10); % set weights
net.params('conv1', 2).set_data(net.params('conv1', 2).get_data() * 10); % set bias
๋์ฒด์ ์ผ๋ก๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ๋ ์ฌ์ฉํ ์ ์๋ค.
net.layers('conv1').params(1).set_data(net.layers('conv1').params(1).get_data() * 10);
net.layers('conv1').params(2).set_data(net.layers('conv1').params(2).get_data() * 10);
๋น์ ์ด ๋ฐฉ๊ธ ์์ ํ ๋คํธ์ํฌ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด์๋:
net.save('my_net.caffemodel');
(String ํ์ ์ผ๋ก) ๊ณ์ธต์ ํ์ ์ ์ป๊ธฐ์ํด์๋:
layer_type = net.layers('conv1').type;
์ ๋ฐฉํฅ๊ณผ ์ญ๋ฐฉํฅ
์ ๋ฐฉํฅ ๊ณผ์ ์ net.forward ํน์ net.forward_prefilled์ผ๋ก ์ฒ๋ฆฌ๋์ด์ง ์ ์๋ค. net.forward ํจ์๋ ์ ๋ ฅ blob(๋ค)์ ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋ N-D๋ฐฐ์ด์ ์ ํ์์ ๋ฐฐ์ด์ ๊ฐ์ ธ์์ ์ถ๋ ฅ blob(๋ค)๋ก๋ถํฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋ ์ ํ์์ ๋ฐฐ์ด๋ก ๋ด๋ณด๋ธ๋ค. net.forward_prefilled ํจ์๋ ์ ๋ฐฉํฅ ๊ณผ์ ์ค๋์์ ์ ๋ ฅ blob๋ค์ ์กด์ฌํ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋๋ฐ ์ด๋ ํ ์ ๋ ฅ๋ ์ทจํ์ง์์ผ๋ฉฐ ์ถ๋ ฅ๋ ์์ฐํ์ง ์๋๋ค. data = rand(net.blobs('data').shape);์ ๊ฐ์ด ์ ๋ ฅ blob์ ๋ํด ๋ช๋ช ๋ฐ์ดํฐ๋ฅผ ์์ฑํ ํ์, ๋ค์์ ์คํํ ์ ์๋ค.
res = net.forward({data});
prob = res{1};
ํน์
net.blobs('data').set_data(data);
net.forward_prefilled();
prob = net.blobs('prob').get_data();
์ญ๋ฐฉํฅ ๊ณผ์ ๋ ๋น์ทํ๊ฒ net.backward ์ด๋ net.backward_prefilled๋ฅผ ์ฌ์ฉํ๋ฉฐ get_diff์ set_diff๋ก get_data์ set_data๋ฅผ ๋์ฒดํ๋ค. prob_diff = rand(net.blobs('prob').shape);์ ๊ฐ์ด ์ถ๋ ฅ blob์ ๋ํ ๋ช๋ช ๊ทธ๋๋์ธํธ๋ฅผ ์์ฑํํ์, ๋ค์์ ์คํํ ์ ์๋ค.
res = net.backward({prob_diff});
data_diff = res{1};
ํน์
net.blobs('prob').set_diff(prob_diff);
net.backward_prefilled();
data_diff = net.blobs('data').get_diff();
ํ์ง๋ง ์์๊ฐ์ ์ญ๋ฐฉํฅ ์ฐ์ฐ์ ์ฌ๋ฐ๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง์ง ๋ชปํ๋๋ฐ, ์ด๋ Caffe๊ฐ ๋คํธ์ํฌ๋ ์ญ๋ฐฉํฅ ์ฐ์ฐ์ ํ์๋ก ํ์ง ์๋ค๊ณ ๊ฒฐ์ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ฌ๋ฐ๋ฅธ ์ญ๋ฐฉํฅ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ์ํด์๋, ๋น์ ์ ๋คํธ์ํฌ prototxt์์ 'force_backward: true'๋ฅผ ์ค์ ํด์ค ํ์๊ฐ ์๋ค.
์ ๋ฐฉํฅ ํน์ ์ญ๋ฐฉํฅ ๊ณผ์ ์ ๋ชจ๋ ์ํํ ํ์, ๋ํ ๋ด๋ถ blob๋ค์์ data๋ diff๋ฅผ ์ทจํ ์ ์๋ค. ์๋ฅผ๋ค๋ฉด, ์ ๋ฐฉํฅ ๊ณผ์ ํ์ pool5์ feature๋ฅผ ์ถ์ถํ๊ธฐ ์ํด์๋:
pool5_feat = net.blobs('pool5').get_data();
์ฌ๊ตฌ์ฑ
10 ๋์ ์ 1๊ฐ ์ด๋ฏธ์ง๋ฅผ ํ๋์ฉ ์ฒ๋ฆฌํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํ์:
net.blobs('data').reshape([227 227 3 1]); % reshape blob 'data'
net.reshape();
์ด๋ฌ๋ฉด ์ ์ฒด ๋คํธ์ํฌ๊ฐ ์ฌ๊ตฌ์ฑ๋๋ฉฐ, net.blobs('prob').shape๋ [1000 1]; ๋ ๊ฒ์ด๋ค.
ํ์ต
๋น์ ์ด ์ฐ๋ฆฌ์ ImageNET Tutorial์ ๋ฐ๋ผ ํ์ตlmdbs์ ์ ํจ lmdbs๋ฅผ ์์ฑํด๋ดค๋ค๊ณ ๊ฐ์ ํ์. ํด๊ฒฐ์ฌ๋ฅผ ์์ฑํ๊ณ ILSVRC 2012 ๋ถ๋ฅํ ๋ฐ์ดํฐ์ธํธ์ ๋ํด ํ๋ จ์ํค๊ธฐ ์ํด์๋:
solver = caffe.Solver('./models/bvlc_reference_caffenet/solver.prototxt');
์ด๋ ํด๊ฒฐ์ฌ ์ค๋ธ์ ํธ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ค.
Solver with properties:
net: [1x1 caffe.Net]
test_nets: [1x1 caffe.Net]
ํ์ตํ๊ธฐ ์ํด์๋ :
solver.solve();
ํน์ ๋จ 1000๋ฒ ๋ฐ๋ณต์ผ๋ก๋ง ํ์ตํ๊ธฐ์ํด์๋ (๊ทธ๋์ ๋น์ ์ ๋ ๋ง์ ๋ฐ๋ณต์ผ๋ก ํ๋ ฅ์ํค๊ธฐ์ ์ ๋ง์ ๋ฌด์ธ๊ฐ๋ฅผ ํ ์ ์๋ค.)
solver.step(1000);
๋ฐ๋ณต์๋ฅผ ์ป๊ธฐ์ํด์๋:
iter = solver.iter();
ํด๋น ๋คํธ์ํฌ๋ฅผ ์ป๊ธฐ์ํด์๋:
train_net = solver.net;
test_net = solver.test_nets(1);
โyour_snapshot.solverstateโ ์ค๋ ์ท๋ถํฐ ์ฌ๊ฐํ๊ธฐ ์ํด์๋:
solver.restore('your_snapshot.solverstate');
์ ๋ ฅ๊ณผ ์ถ๋ ฅ
caffe.io ํด๋์ค๋ ๊ธฐ๋ณธ ์ ๋ ฅ ํจ์์ธ load_image์ read_mean๋ฅผ ์ ๊ณตํ๋ค. ์๋ฅผ๋ค๋ฉด, ILSVRC 2012 mean file๋ฅผ ์ฝ๊ธฐ ์ํด์๋(./data/ilsvrc12/get_ilsvrc_aux.sh๋ก ์คํํด์ ๋น์ ์ด ์ด๋ฏธ์ง๋ง ์์ ์๋นํ์ผ์ ๋ค์ด๋ก๋๋ฅผ ๋ฐ์๋จ๋ค๊ณ ๊ฐ์ ํ๋ค.):
mean_data = caffe.io.read_mean('./data/ilsvrc12/imagenet_mean.binaryproto');
Caffe์ ์์ ์ด๋ฏธ์ง๋ฅผ ์ฝ๊ณ width = 256; height = 256;๋ฅผ ์ํ๋ค๊ณ ๊ฐ์ ํ์ฌ [width, height]๋ฅผ ์ฌ์ค์ ํ๊ธฐ ์ํด์๋:
im_data = caffe.io.load_image('./examples/images/cat.jpg');
im_data = imresize(im_data, [width, height]); % resize using Matlab's imresize
width๊ฐ ๊ฐ์ฅ๋จผ์ ์ค๋ ์ฐจ์์ด๋ฉฐ BGR ์ฑ๋์ธ๊ฒ์ ์ ์๊ฐํด์ผํ๋ฉฐ, ์ด๋ Matlab์ ์ด๋ฏธ์ง๋ก ์ ์ฅ๋๋ ์ผ๋ฐ์ ๋ฐฉ๋ฒ๊ณผ๋ ๋ค๋ฅด๋ค.
๋ง์ฝ caffe.io.load_image์ ์ฌ์ฉํ๊ธฐ๋ฅผ ์์น์๊ณ , ๋น์ ์ด ์ง์ ์ด๋ฏธ์ง๋ฅผ ๋ถ๋ฌ์ค๊ธฐ๋ฅผ ์ํ๋ค๋ฉด, ๋ค์์ ํ ์ ์๋ค:
im_data = imread('./examples/images/cat.jpg'); % read image
im_data = im_data(:, :, [3, 2, 1]); % convert from RGB to BGR
im_data = permute(im_data, [2, 1, 3]); % permute width and height
im_data = single(im_data); % convert to single precision
๋ํ, ๋น์ ์ ์๋ง ์ด๋ฏธ์ง๋ก๋ถํฐ ํฌ๋กญ์ ์ทจํจ์ ์ํด ์ ๋ ฅ์ ์ด๋ป๊ฒ ๋ง๋ จํ๋์ง ๋ณด๊ธฐ์ํด์ caffe/matlab/demo/classification_demo.m๋ฅผ ํ๋ฒ ๋ณผ ์ ์๋ค.
์ฐ๋ฆฌ๋ ์ด๋ป๊ฒ Matlab์ผ๋ก HDF5 ๋ฐ์ดํฐ๊ฐ ์ฝ๊ณ ์ฐ์ด๋์ง caffe/matlab/hdf5creation์ ๋ณด์ฌ์ค๋ค. ์ฐ๋ฆฌ๋ ๋ฐ์ดํฐ ์ถ๋ ฅ์ ๋ํ ์ฌ๋ถ์ ํจ์๋ฅผ ์ ๊ณตํ์ง์์ผ๋ฉฐ ์ด๋ Matlab ๊ทธ์์ฒด๋ง์ผ๋ก ์ด๋ฏธ ๊ฝค ๊ฐ๋ ฅํ ์ถ๋ ฅ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๋ง๊ณผ ํด๊ฒฐ์ฌ ์ด๊ธฐํ
๋ชจ๋ ํด๊ฒฐ์ฌ์ ๋น์ ์ด ๋ง๋ ํญ์ ์๋ํ๋ ๋ง๋ค์ ์ด๊ธฐํํ๊ธฐ ์ํด์๋ caffe.reset_all()์ ํธ์ถํ ์ ์๋ค.