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()์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

ํŠœํ† ๋ฆฌ์–ผ ๋ฉ”๋‰ด๋กœ ๋Œ์•„๊ฐ€๊ธฐ