Caffe Tutorial : 1.Blobs, Layers, and Nets (Kor) - ys7yoo/BrainCaffe GitHub Wiki

Blobs, ๊ณ„์ธต๋“ค, ๊ทธ๋ฆฌ๊ณ  ๋ง๋“ค : Caffe ๋ชจ๋ธ ๋ถ„์„ (blobs, Layers, and Nets : Anatomy of a Caffe Model)

์‹ฌ์ธต ๋„คํŠธ์›Œํฌ(deep networks)๋Š” ์ˆ˜๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜๋Š” ๋‚ด๋ถ€ ์—ฐ๊ฒฐ ๊ณ„์ธต์˜ ์ง‘๋‹จ์œผ๋กœ์จ ํ‘œํ˜„๋˜๋Š” ๊ตฌ์กฐ์  ๋ชจ๋ธ์ด๋‹ค. Caffe๋Š” ๊ทธ ์ž์ฒด ๋ชจ๋ธ ๊ฐœ์š”์—์„œ ๊ณ„์ธต๊ณผ ๊ณ„์ธต์˜ ๋ง์œผ๋กœ ์„ ์–ธํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ๋ง์€ ์ž…๋ ฅ๋ฐ์ดํ„ฐ์—์„œ๋ถ€ํ„ฐ ์†์‹ค๊นŒ์ง€ ์ „์ฒด๊ฐ€ ์ƒํ–ฅ์‹(bottom to top)์œผ๋กœ ์ •์˜๋œ๋‹ค. Caffe๋Š” ์ •๋ฐฉํ–ฅ๊ณผ ์—ญ๋ฐฉํ–ฅ์˜ ์ฒ˜๋ฆฌ๋ฐฉ์‹์˜ ๋ง์„ ํ†ตํ•ด ์œ ๋„๋œ ํ๋ฆ„๊ณผ ๋ฐ์ดํ„ฐ๋กœ์จ ์ €์žฅํ•˜๋ฉฐ ์†Œํ†ตํ•˜๊ณ , ๊ทธ๋ฆฌ๊ณ  blobs๋กœ์จ ์ •๋ณด ๋ฉ์–ด๋ฆฌ๋ฅผ ๋‹ค๋ฃฌ๋‹ค.
Blob๋ž€ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋Œ€ํ•œ ํ‘œ์ค€๋ฐฐ์—ด๊ณผ ํ†ตํ•ฉ๋œ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ์ด ๊ณ„์ธต์€ ๋ชจ๋ธ๊ณผ ๊ณ„์‚ฐ ์–‘์ชฝ ๋ชจ๋‘์˜ ๊ธฐ๋ฐ˜์œผ๋กœ์จ ๋‹ค์Œ์—ญํ• ์„ ํ•ด์ค€๋‹ค. ๋ง์€ ์ˆ˜์ง‘๊ณผ ๊ณ„์ธต๊ฐ„ ์—ฐ๊ฒฐ๋กœ ์ •์˜๋œ๋‹ค. Blob์˜ ์„ธ๋ถ€์‚ฌํ•ญ์€ ๊ณ„์ธต๊ณผ ๋ง ์•ˆ์ด๋‚˜ ํ˜น์€ ์„œ๋กœ๋ฅผ ๊ฐ€๋กœ์ง€๋ฅด๋ฉฐ ์–ด๋–ป๊ฒŒ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ณ  ์†Œํ†ตํ•˜๋Š”์ง€๋ฅผ ๋ฌ˜์‚ฌํ•œ๋‹ค. ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ(Solving)์ด ์ตœ์ ํ™”์™€ ๋ชจ๋ธ๋ง์„ ๋‚˜๋ˆ„์–ด ๋ถ„๋ฆฌํ•ด ๋”ฐ๋กœ๋”ฐ๋กœ ๊ตฌ์„ฑํ•œ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ข€ ๋” ์ž์„ธํ•˜๊ฒŒ ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ๋“ค์„ ์‚ดํŽด๋ณผ ๊ฒƒ์ด๋‹ค.

1.Blob ์ €์žฅ๊ณผ ์†Œํ†ต (Blob Storage and Communication)

Blob๋Š” Caffe๋กœ ๋‚˜์•„๊ฐ€๊ณ  ์ฒ˜๋ฆฌ๋˜๋Š” ์‹ค์ œ ๋ฐ์ดํ„ฐ๋กœ ๋น ๋ฅด๊ฒŒ ์ด๋™ํ•˜๋ฉฐ, ๊ทธ๋ฆฌ๊ณ  ๋˜ํ•œ hood๊ฐ€ CPU์™€ GPU ์‚ฌ์ด์˜ ๋™์ผํ™” ๋Šฅ๋ ฅ์„ ์ œ๊ณตํ•œ๋‹ค. ์ˆ˜ํ•™์ ์œผ๋กœ, blob๋Š” C์™€ ์œ ์‚ฌํ•œ ๋ฐฉ์‹์œผ๋กœ ์ €์žฅ๋œ N์ฐจ์›์˜ ๋ฐฐ์—ด์ด๋‹ค. Caffe๋Š” blobs๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์†Œํ†ตํ•œ๋‹ค. Blobs๋Š” ์ด๋ฏธ์ง€ ์ผํšŒ ์ฒ˜๋ฆฌ๋Ÿ‰, ๋ชจ๋ธ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ทธ๋ฆฌ๊ณ  ์ตœ์ ํ™”์— ๋Œ€ํ•œ ์œ ๋„์ฒด๋“ค ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์žก์•„๋‘๋Š” ํ†ตํ•ฉ๋œ ๋ฉ”๋ชจ๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค. Blob๋Š” ํ•„์š”ํ•œ๋งŒํผ CPU ํ˜ธ์ŠคํŠธ๋ถ€ํ„ฐ GPU ์žฅ์น˜๊นŒ์ง€ ๋™์ผํ™”ํ•จ์— ์˜ํ•ด ๊ณ„์‚ฐ์ ์ด๊ณ  ์ง€๋Šฅ์ ์œผ๋กœ ๋„˜์–ด์„œ ์ด๋Ÿฌ๊ณผ์ •์„ ํ•˜๋Š” ํ˜ผํ•ฉ๋œ CPU/GPU ์ž‘์—…์„ ๋ณด์ด์ง€ ์•Š๊ฒŒํ•œ๋‹ค. ํ˜ธ์ŠคํŠธ์™€ ์žฅ์น˜์˜ ๋ฉ”๋ชจ๋ฆฌ๋Š” ํšจ์œจ์  ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ์œ„ํ•ด ์š”๊ตฌ๋˜๋Š” ๋งŒํผ ํ• ๋‹น๋œ๋‹ค. ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ์ผํšŒ ์ฒ˜๋ฆฌ๋Ÿ‰์— ๋Œ€ํ•œ ํ‹€์— ์ ์šฉ๋œ blob ์ฐจ์›์€ N x K(์ฑ„๋„) x H(๋†’์ด) x W(๋ฐ‘๋ณ€)๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค. Blob ๋ฉ”๋ชจ๋ฆฌ๋Š” ๊ตฌ์„ฑ์—์„œ ํ–‰ ์šฐ์„ ์ด๋ผ ๋ ์ชฝ/ ๊ฐ€์žฅ ์˜ค๋ฅธ์ชฝ ์ฐจ์›๋ถ€ํ„ฐ ์ œ์ผ ๋น ๋ฅด๊ฒŒ ์ „ํ™˜๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 4์ฐจ์› blob์—์„œ, ์ง€ํ‘œ (n,k,h,w)์ธ๋ฑ์Šค์— ๊ฐ’์€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ((n*K+k)*H+h)*W+w๋กœ ๋ฐฐ์น˜๋œ๋‹ค.

  • ์ˆซ์ž N์€ ๋ฐ์ดํ„ฐ์˜ ์ผํšŒ ์ฒ˜๋ฆฌ๋Ÿ‰ ์‚ฌ์ด์ฆˆ์ด๋‹ค. ์ผ๊ด„์ฒ˜๋ฆฌ๋Š” ์†Œํ†ต๊ณผ ์žฅ์น˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ์žˆ์–ด ์ข€ ๋” ๋‚˜์€ ์ฒ˜๋ฆฌ์œจ์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. 256 ์ด๋ฏธ์ง€ ์ผํšŒ ์ฒ˜๋ฆฌ๋Ÿ‰ ํ›ˆ๋ จํ•˜๋Š” ์ด๋ฏธ์ง€๋ง์— ๋Œ€ํ•˜์—ฌ N์€ 256์ด๋‹ค

  • ์ฑ„๋„ K๋Š” ํ–ฅํ›„์˜ RGB์ด๋ฏธ์ง€ K = 3์— ๋Œ€ํ•œ ์ˆ˜์ด๋‹ค.

๋น„๋ก Caffe example์† ๋งŽ์€ blob๋“ค์ด ์ด๋ฏธ์ง€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ ์ถ•๋“ค์„ ๊ฐ€์ง„ 4์ฐจ์›์œผ๋กœ ์ œ๊ณตํ• ์ง€๋ผ๋„, ์ด๋ฏธ์ง€๊ฐ€ ์•„๋‹Œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•˜์—ฌ blob๋“ค์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ์œ ํšจํ•œ ๋ฐฉ๋ฒ•์ž„์„ ์•Œ์•„์•ผํ•œ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ๋งŒ์•ฝ ๊ฐ„๋‹จํžˆ ํ‹€์— ์ ์šฉ๋œ ๋‹ค์ค‘๊ณ„์ธต ํผ์…‰ํŠธ๋ก  (ํ•™์Šต๋Šฅ๋ ฅ์„ ๊ฐ–๋Š” ํŒจํ„ด๋ถ„๋ฅ˜์žฅ์น˜)์™€ ๊ฐ™์€ ์™„์ „ ์ ‘์†๋ง์ด ํ•„์š”ํ•˜๋‹ค๋ฉด, 2์ฐจ์› blobs (shape(N, D))์„ ์‚ฌ์šฉํ•˜๊ณ  ์šฐ๋ฆฌ๊ฐ€ ํ›„์— ๋‹ค๋ฃฐ ๋‚ด๋ถ€์ƒ์‚ฐ๊ณ„์ธต์„ ํ•„์š”๋กœ ํ•œ๋‹ค. ํŒŒ๋ผ๋ฏธํ„ฐ blob ์ฐจ์›๋“ค์€ ๊ณ„์ธต์˜ ๊ตฌ์„ฑ๊ณผ ํƒ€์ž…์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•˜๋‹ค. 11 x 11 ๊ณต๊ฐ„ ์ฐจ์›์— ๋Œ€ํ•œ 96๊ฐœ์˜ ํ•„ํ„ฐ๋“ค๋กœ ๊ตฌ์„ฑ๋œ ์ปจ๋ณผ๋ฃจ์…˜ ๊ณ„์ธต์—๋Œ€ํ•˜์—ฌ 3๊ฐœ ์ธํ’‹ blob๋Š” 96 x 3 x 11 x 11์ด ๋œ๋‹ค. 100๊ฐœ ์ถœ๋ ฅ ์ฑ„๋„๊ณผ 1024 ์ž…๋ ฅ์ฑ„๋„๋กœ ๊ตฌ์„ฑ๋œ ๋‚ด๋ถ€์ƒ์„ฑ / ์™„์ „ ์ ‘์† ๊ณ„์ธต์— ํ•ดํ•˜์—ฌ ํŒŒ๋ผ๋ฏธํ„ฐ blob๋Š” 1000 x 1024์ด๋‹ค.

์‚ฌ์šฉ์ž ์ง€์ • ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ž์‹ ๋งŒ์˜ ๋ฐ์ดํ„ฐ ๊ณ„์ธต์ด๋‚˜ ์ž…๋ ฅ ์ค€๋น„ ํˆด์„ ์ฒ˜๋ฆฌํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‹น์‹ ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๊ธฐ๋งŒํ•œ๋‹ค๋ฉด, ๋‹น์‹ ์ด ํ•  ์ผ์€ ๋๋‚œ๋‹ค. ๊ณ„์ธต์˜ ๋ชจ๋“ˆ์„ฑ ๊ฐœ์„ ์ด ๋‹น์‹ ์ด ์ˆ˜ํ–‰ํ•ด์•ผํ•  ๋‚˜๋จธ์ง€ ์ž‘์—…์ด๋‹ค.

๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ (Implementation Details)

์šฐ๋ฆฌ๋Š” ์ข…์ข… blob์˜ ๊ธฐ์šธ๊ธฐ ๋งŒํผ์ด๋‚˜ ๊ฐ’์— ๋Œ€ํ•ด ํฅ๋ฏธ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— blob๋Š” โ€œdataโ€์™€ โ€œdiffโ€๋ผ๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ๋‘ ๋ฉ์–ด๋ฆฌ๋ฅผ ์ €์žฅํ•œ๋‹ค. "data"๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋Š” ํ‰๋ฒ”ํ•œ ๋ฐ์ดํ„ฐ์ด๊ณ  ํ›„์ž๋Š” ๋„คํŠธ์›Œํฌ์— ์˜ํ•ด ๊ทธ๋ž˜๋””์–ธํŠธ๋กœ ๊ณ„์‚ฐ๋œ ๊ฒƒ์ด๋‹ค. ์ข€๋” ๋‚˜์•„๊ฐ€ ์‹ค์ œ ๊ฐ’์ด CPU์™€ GPU ๋ชจ๋‘์— ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์—. ์ด๋“ค์—๊ฒŒ ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์€ 2๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. ๊ฐ’์„ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š๋Š” โ€œconstโ€ ๋ฐฉ๋ฒ•, ๊ทธ๋ฆฌ๊ณ  ๊ฐ’์„ ๋ณ€ํ™˜ํ•˜๋Š” โ€œmutableโ€ ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•œ๋‹ค.

Const Dtype * cpu_data() const;
Dtype* mutable_cpu_data;

์ด๋ ‡๊ฒŒ ์ฝ”๋”ฉ์„ ํ•˜๋Š” ์ด์œ ๋Š” blob๋Š” ๋ฐ์ดํ„ฐ ์ „์†ก์„ ์ตœ์†Œํ™”ํ•˜๊ณ  ๋””ํ…Œ์ผ์„ ๋™์ผํ™”ํ•˜๋Š” ๊ณผ์ •์„ ๋ณด์ด์ง€ ์•Š๊ฒŒ ํ•˜๊ธฐ์œ„ํ•ด CPU์™€ GPU์‚ฌ์—์ด ๊ฐ’์„ ๋™์ผํ™”ํ•˜๋Š” โ€œSyncedMemโ€ class๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋‹น์‹ ์ด ๊ฐ’์„ ๋ฐ”๋€Œ์ง€ ์•Š๊ธธ ์›ํ•œ๋‹ค๋ฉด ํ•ญ์ƒ const๋ฅผ ์‚ฌ์šฉํ•˜๋˜, ์ ˆ๋Œ€ ์ž์‹ ์˜ ๊ฐ์ฒด์˜ ํฌ์ธํ„ฐ๋ฅผ ์ €์žฅํ•˜์ง€ ๋งˆ๋ผ. ๋งค๋ฒˆ ๋‹น์‹ ์ด blob๋ฅผ ๋งŒ๋“ค ๋•Œ๋งˆ๋‹ค, โ€œSyncedMemโ€์ด ์–ธ์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌํ• ์ง€ ์ฐพ์•„๋‚ผ ํ•„์š”๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๋Š” ํ•จ์ˆ˜๋ฅผ ํ•„์š”๋กœํ•œ๋‹ค. ์‹ค์ œ๋กœ GPU๊ฐ€ ์กด์žฌํ•  ๋•Œ, ๋””์Šคํฌ๋ถ€ํ„ฐ CPU์ฝ”๋“œ์˜ ์ฝ”๋“œ๊นŒ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋ฉด์„œ GPU ๊ณ„์‚ฐ์„ ํ•˜๋Š” ์žฅ์น˜ ์ปค๋„์„ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ๊ทธ๋ฆฌ๊ณ  ๊ณ ๋‹จ๊ณ„์˜ ์ˆ˜ํ–‰์„ ํ•˜๋Š”๋™์•ˆ ์ €๋‹จ๊ณ„์˜ ์‚ฌํ•ญ์„ ๋ฌด์‹œํ•˜๋ฉด์„œ ๋‹ค์Œ ๊ณ„์ธต์œผ๋กœ blob๋ฅผ ์ „์†กํ•œ๋‹ค. ๋ชจ๋“ ๊ณ„์ธต์ด GPU์ˆ˜ํ–‰๋Šฅ๋ ฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ•œ, ๋ชจ๋“  ์ค‘์†๋„ ๋ฐ์ดํ„ฐ(intermediate Data)์™€ ๊ทธ๋ž˜๋””์–ธํŠธ๋Š” GPU์— ๋‚จ์„ ๊ฒƒ์ด๋‹ค. ๋งŒ์•ฝ blob๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌํ•ด์˜ฌ ๋•Œ, ํ™•์ธํ•˜๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋ฉด ์„ค๋ช…๋˜์–ด์žˆ๋Š” ์˜ˆ์ œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ œ์‹œํ•œ๋‹ค.

// ๋ฐ์ดํ„ฐ๊ฐ€ CPU์ƒ์—์„œ ์ดˆ๊ธฐํ™” ๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ , blob๋ฅผ ์ €์žฅํ•œ๋‹ค.
const Dtype* foo;
Dtype* bar;
foo = blob.gpu_data(); // data copied cpu->gpu.
foo = blob.cpu_data(); // no data copied since both have up-to-date contents.
bar = blob.mutable_gpu_data(); // no data copied.
// ... ๊ณผ์ • ์ƒ๋žต ...
bar = blob.mutable_gpu_data(); // no data copied when we are still on GPU.
foo = blob.cpu_data(); // data copied gpu->cpu, since the gpu side has modified the data
foo = blob.gpu_data(); // no data copied since both have up-to-date contents
bar = blob.mutable_cpu_data(); // still no data copied.
bar = blob.mutable_gpu_data(); // data copied cpu->gpu.
bar = blob.mutable_cpu_data(); // data copied gpu->cpu.

2.๊ณ„์ธต ์—ฐ์‚ฐ๊ณผ ์—ฐ๊ฒฐ (Layer computation and connections)

๊ณ„์ธต์€ ๊ณ„์‚ฐ์˜ ํ•ต์‹ฌ์ ์ธ ๋‹จ์œ„์™€ ๋ชจ๋ธ์ด ํ•„์ˆ˜์ ์ธ๋ฐ ๊ณ„์ธต์€ ํ•„ํ„ฐ๋“ค๊ณผ pool๋กœ ๋‘˜๋‘˜๋ง๋ ค์žˆ์œผ๋ฉฐ, ๋‚ด๋ถ€ ์ƒ์‚ฐ์„ ์ทจํ•˜๊ณ , Rectified linear์™€ ์‹œ๊ทธ๋ชจ์ด๋“œ, ๊ทธ๋ฆฌ๊ณ  ๋‹ค๋ฅธ elementwise tramformation๊ฐ™์€ ๋น„์„ ํ˜•์„ฑ์„ ์ ์šฉํ•˜๊ณ , ์ผ๋ฐ˜ํ™”ํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ๊ทธ๋ฆฌ๊ณ  softmax๋‚˜ hinge๊ฐ™์€ ์†์‹ค์„ ๊ณ„์‚ฐํ•œ๋‹ค. ๋ชจ๋“  ์‹คํ–‰๋“ค์€ ๊ณ„์ธต ์นดํƒˆ๋กœ๊ทธ๋ฅผ ๋ณด์•„๋ผ. ๋Œ€๋ถ€๋ถ„์˜ ํƒ€์ž…๋“ค์ด ์š”๊ตฌํ•˜๋Š” ์ตœ์‹  ๋”ฅ๋Ÿฌ๋‹ ๊ณ„์ธต ์—ญํ• ๋“ค์ด ์—ฌ๊ธฐ์— ์žˆ๋‹ค.

์œ„์™€ ๊ฐ™์€ ๊ณ„์ธต์€ bottom์—ฐ๊ฒฐ์„ ํ†ตํ•˜์—ฌ ์ž…๋ ฅ์„ ๋ฐ›๊ณ , top์—ฐ๊ฒฐ์„ ํ†ตํ•œ ์ถœ๋ ฅ์„ ๋งŒ๋“ค์–ด ๋‚ธ๋‹ค ๊ฐ๊ฐ์˜ ๊ณ„์ธตํƒ€์ž…์€ 3๊ฐ€์ง€์˜ ์ค‘์š”ํ•œ ์—ฐ์‚ฐ์ธ setup, forward, backward์œผ๋กœ ์ •์˜๋œ๋‹ค.

  1. Setup : ๋ชจ๋ธ ์ดˆ๊ธฐํ™”์™€ ๋™์‹œ์— ๊ณ„์ธต๊ณผ ๊ณ„์ธต๊ฐ„ ์—ฐ๊ฒฐ์„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
  2. Forward : bottom์œผ๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์ž…๋ ฅ์„ ๊ณ„์‚ฐํ•˜์—ฌ top์œผ๋กœ ์ถœ๋ ฅ์„ ๋ณด๋‚ธ๋‹ค.
  3. Backward : top ๊ทธ๋ž˜๋””์–ธํŠธ w.r.t.๋ฅผ ์ถœ๋ ฅ ๊ทธ๋ž˜๋””์–ธํŠธ w.r.t๋ฅผ ์ธํ’‹์œผ๋กœ ๊ณ„์‚ฐํ•˜์—ฌ bottom์œผ๋กœ ์ „์†กํ•œ๋‹ค. ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ตฌ์„ฑ๋œ ๊ณ„์ธต์€ ๊ทธ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ w.r.t.๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ์ด๋ฅผ ๋‚ด๋ถ€์— ์ €์žฅํ•œ๋‹ค.

์ข€ ๋” ์ž์„ธํ•˜๊ฒŒ Forward์™€ Backward ๊ธฐ๋Šฅ์€ ํ•˜๋‚˜๋Š” CPU์—์„œ, ํ•˜๋‚˜๋Š” GPU์—์„œ ๊ณ„์‚ฐ์„ ํ•  ๊ฒƒ์ด๋‹ค. ๋งŒ์•ฝ GPU ๋ฒ„์ „์—์„œ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†๋‹ค๋ฉด, ๊ณ„์ธต์ด ๋ฐฑ์—… ์˜ต์…˜์œผ๋กœ CPU๊ธฐ๋Šฅ์œผ๋กœ ํ›„ํ‡ดํ•œ๋‹ค. ๋น„๋ก ์ถ”๊ฐ€์ ์ธ ๋ฐ์ดํ„ฐ ์ „์†ก ๋น„์šฉ์ด ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ๋น ๋ฅธ ํ…Œ์ŠคํŠธ๋ฅผ ์›ํ•œ๋‹ค๋ฉด ์ด ๋ฐฉ๋ฒ•์ด ์œ ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.(์ž…๋ ฅ์ด GPU๋ถ€ํ„ฐ CPU๊นŒ์ง€ ๋ณต์‚ฌํ•  ๊ฒƒ์ด๊ณ , ์•„์›ƒํ’‹์ด ์—ญ์œผ๋กœ CPU์—์„œ GPU๊นŒ์ง€ ๋ณต์‚ฌํ•  ๊ฒƒ์ด๋‹ค.) ๊ณ„์ธต๋“ค์€ ์ „์ฒด ๋„คํŠธ์›Œํฌ์˜ ์‹คํ–‰์— ์žˆ์–ด ๋‘๊ฐ€์ง€ ์ค‘๋Œ€ํ•œ ์ž„๋ฌด์ด ์žˆ๋Š”๋ฐ, ์ž…๋ ฅ์„ ๋ฐ›์•„ ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•˜๋Š” ์ •๋ฐฉํ–ฅ ๊ณผ์ •๊ณผ, ์ถœ๋ ฅ์— ๋Œ€ํ•œ ๊ทธ๋ž˜๋””์–ธํŠธ๋ฅผ ์ž…๋ ฅ๊ณผ ํŒŒ๋ฆฌ๋ฏธํ„ฐ์— ๋Œ€ํ•˜์—ฌ ๊ทธ๋ž˜๋””์–ธํŠธ๋ฅผ ์—ฐ์‚ฐํ•˜์—ฌ ์ทจํ•˜๋Š” ์—ญ๋ฐฉํ–ฅ ๊ณผ์ •์ด ์žˆ๋Š”๋ฐ ์ด๋Š” ์ดˆ๊ธฐ ๊ณ„์ธต์œผ๋กœ back-propagated ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฌํ•œ ๊ณผ์ •๋“ค์ด ๊ฐ๊ฐ ๊ณ„์ธต์˜ forward์™€ backward์˜ ๊ตฌ์กฐ์ด๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ ๊ณ„์ธต๋“ค์„ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์€ ์ฝ”๋“œ์˜ ๋ชจ๋“ˆ์„ฑ๊ณผ ๋„คํŠธ์›Œํฌ์˜ ๊ตฌ์กฐ์  ํŠน์„ฑ์— ์˜ํ•ด ์ตœ์†Œ์˜ ๋…ธ๋ ฅ์„ ํ•„์š”๋กœ ํ•œ๋‹ค. ๊ณ„์ธต์— ๋Œ€ํ•œ ์„ค์ •, ์ •๋ฐฉํ–ฅ๊ณผ ์—ญ๋ฐฉํ–ฅ์„ ์ •์˜ํ•˜๋ผ. ๊ทธ ๋‹ค์Œ์€ ๋ง(net)์˜ ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ ์–ธ๊ธ‰ํ•  ๊ฒƒ์ด๋‹ค.

3.๋ง ์ •์˜์™€ ์ž‘๋™ (Net Definition And Operation)

๋ง์€ ๋ถ€๋ถ„์ ์œผ๋กœ ํ•จ์ˆ˜์™€ ํ•จ์ˆ˜๊ทธ๋ž˜๋””์–ธํŠธ๋ฅผ ๊ตฌ์„ฑ๊ณผ ์ž๋™ ์ฐจ๋ณ„ํ™”๋ฅผ ํ†ตํ•ด ์ •์˜ํ•œ๋‹ค. ๋ชจ๋“  ๊ณ„์ธต์—์„œ ์ถœ๋ ฅ์˜ ๊ตฌ์„ฑ์€ ์ฃผ์–ด์ง„ ์—ญํ• ์„ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ , ๋ชจ๋“  ๊ณ„์ธต์—์„œ ์—ญ๋ฐฉํ–ฅ ๊ตฌ์„ฑ์€ ์†์‹ค์—์„œ ์—ญํ• ๋ฅผ ํ•™์Šตํ•˜๋Š” ๊ฒƒ๊นŒ์ง€์˜ ๊ทธ๋ž˜๋””์–ธํŠธ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค. Caffe ๋ชจ๋ธ๋“ค์€ ์ข…๋‹จ ๊ธฐ๊ณ„ํ•™์Šต ์—”์ง„์ด๋‹ค. ๋ง์€ Computation graph(Direct Acyclic graph (DAG)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.)๋กœ ์—ฐ๊ฒฐ๋œ ๊ณ„์ธต๋“ค์˜ ์ง‘ํ•ฉ์ด๋‹ค. Caffe๋Š” ์ •๋ฐฉํ–ฅ๊ณผ ์—ญ๋ฐฉํ–ฅ ๊ณผ์ •์˜ ์ •ํ™•๋„๋ฅผ ํ™•์‹คํžˆ ํ•˜๊ธฐ์œ„ํ•ด ๋ชจ๋“  ๊ณผ์ •์„ ๊ธฐ๋กํ•œ๋‹ค. ์ „ํ˜•์ ์ธ ๋ง์€ ๋””์Šคํฌ์—์„œ ํ˜ธ์ถœํ•˜๋Š” ๋ฐ์ดํ„ฐ ๊ณ„์ธต์œผ๋กœ ์‹œ์ž‘ํ•ด์„œ ๋ถ„๋ฅ˜ํ™”๋‚˜ ๋ณต๊ตฌ ๊ฐ™์€ ์—ญํ• ์— ๋Œ€ํ•œ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ์†์‹ค ๊ณ„์ธต์œผ๋กœ ๋์„ ๋งบ๋Š”๋‹ค. ๋ง์€ ๊ณ„์ธต์˜ ์ง‘๋‹จ์œผ๋กœ ์„ ์–ธ๋˜๊ณ  ํ‰์„œ๋ฌธ ๋ชจ๋ธ๋ง ์–ธ์–ด๋กœ ๊ทธ๋“ค์˜ ์—ฐ๊ฒฐ์ด ์ •์˜๋œ๋‹ค. ๊ฐ„๋‹จํžˆ logistic regression classifier๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ ๋œ๋‹ค. http://caffe.berkeleyvision.org/tutorial/fig/logreg.jpg

name: "LogReg"
layer {
  name: "mnist"
  type: "Data"
  top: "data"
  top: "label"
  data_param {
    source: "input_leveldb"
    batch_size: 64
  }
}

layer {
  name: "ip"
  type: "InnerProduct"
  bottom: "data"
  top: "ip"
  inner_product_param {
    num_output: 2
  }
}
 
layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "ip"
  bottom: "label"
  top: "loss"
}

๋ชจ๋ธ ์ดˆ๊ธฐํ™”๋Š” โ€œNet :: Init()โ€๋กœ ๋‹ค๋ฃจ์–ด ์ง„๋‹ค. ์ดˆ๊ธฐํ™”๋Š” ์ฃผ๋กœ ๋‘๊ฐ€์ง€ ์—ญํ• ์„ ํ•œ๋‹ค. ๊ณ„์ธต๋“ค์˜ โ€œSetUp()โ€ ๊ธฐ๋Šฅ์„ ํ˜ธ์ถœํ•˜๋ฉฐ, ๊ณ„์ธต๋“ค๊ณผ blobs๋ฅผ ์ƒ์„ฑํ•จ์— ์˜ํ•ด ์ „์ฒด DAG ๋ฐœํŒ์„ ๋งˆ๋ จํ•œ๋‹ค. (C++ Geeks์—์„œ๋Š” ๋ง์€ ์ƒ์กด์‹œ๊ฐ„๋™์•ˆ ๊ณ„์ธต๊ณผ bolb์˜ ์†Œ์œ ๊ถŒ์„ ์œ ์ง€ํ•œ๋‹ค.) ๋˜ํ•œ ๋‹ค๋ฅธ ๊ฒƒ๋“ค์˜ ์ง‘๋‹จ์— ๋Œ€ํ•˜์—ฌ ๊ณผ์ •์„ ์ ๋Š”๋ฐ ์ด๋ฅผ ํ…Œ๋ฉด ์ „์ฒด ๋„คํŠธ์›Œํฌ์˜ ์„ค๊ณ„๊ตฌ์กฐ์˜ ์ •ํ™•๋„๋ฅผ ์œ ํšจํ•˜๊ฒŒ ํ•˜๋Š”๊ฒƒ๊ณผ ๊ฐ™์€ ๊ฒƒ๋“ค์„ ๊ธฐ๋กํ•ด๋‘”๋‹ค. ๋˜, ์ดˆ๊ธฐํ™”ํ•˜๋Š”๋™์•ˆ, ๋ง์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ INFO์— ๋กœ๊น…ํ•จ์œผ๋กœ์จ ์ดˆ๊ธฐํ™”๋ฅผ ์„ค๋ช…ํ•œ๋‹ค.

I0902 22:52:17.931977 2079114000 net.cpp:39] Initializing net from parameters:
name: "LogReg"
[...model prototxt printout...]
# ๊ณ„์ธต๊ฐ„์˜ ๋„คํŠธ์›Œํฌ๋ฅผ ๊ตฌ์„ฑํ•œ๋‹ค.
I0902 22:52:17.932152 2079114000 net.cpp:67] Creating Layer mnist
I0902 22:52:17.932165 2079114000 net.cpp:356] mnist -> data
I0902 22:52:17.932188 2079114000 net.cpp:356] mnist -> label
I0902 22:52:17.932200 2079114000 net.cpp:96] Setting up mnist
I0902 22:52:17.935807 2079114000 data_layer.cpp:135] Opening leveldb input_leveldb
I0902 22:52:17.937155 2079114000 data_layer.cpp:195] output data size: 64,1,28,28
I0902 22:52:17.938570 2079114000 net.cpp:103] Top shape: 64 1 28 28 (50176)
I0902 22:52:17.938593 2079114000 net.cpp:103] Top shape: 64 (64)
I0902 22:52:17.938611 2079114000 net.cpp:67] Creating Layer ip
I0902 22:52:17.938617 2079114000 net.cpp:394] ip <- data
I0902 22:52:17.939177 2079114000 net.cpp:356] ip -> ip
I0902 22:52:17.939196 2079114000 net.cpp:96] Setting up ip
I0902 22:52:17.940289 2079114000 net.cpp:103] Top shape: 64 2 (128)
I0902 22:52:17.941270 2079114000 net.cpp:67] Creating Layer loss
I0902 22:52:17.941305 2079114000 net.cpp:394] loss <- ip
I0902 22:52:17.941314 2079114000 net.cpp:394] loss <- label
I0902 22:52:17.941323 2079114000 net.cpp:356] loss -> loss
# ์†์‹ค์„ ์„ค์ •ํ•˜๊ณ  ์—ญ๋ฐฉํ–ฅ ๊ณผ์ •์„ ๊ตฌ์„ฑํ•œ๋‹ค.
I0902 22:52:17.941328 2079114000 net.cpp:96] Setting up loss
I0902 22:52:17.941328 2079114000 net.cpp:103] Top shape: (1)
I0902 22:52:17.941329 2079114000 net.cpp:109]     with loss weight 1
I0902 22:52:17.941779 2079114000 net.cpp:170] loss needs backward computation.
I0902 22:52:17.941787 2079114000 net.cpp:170] ip needs backward computation.
I0902 22:52:17.941794 2079114000 net.cpp:172] mnist does not need backward computation.
# ์ถœ๋ ฅ์„ ๊ฒฐ์ •ํ•œ๋‹ค.
I0902 22:52:17.941800 2079114000 net.cpp:208] This network produces output loss
# ์ดˆ๊ธฐํ™”๋ฅผ ๋งˆ์น˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์น˜๋ฅผ ๋ณด๊ณ ํ•œ๋‹ค.
I0902 22:52:17.941810 2079114000 net.cpp:467] Collecting Learning Rate and Weight Decay.
I0902 22:52:17.941818 2079114000 net.cpp:219] Network initialization done.
I0902 22:52:17.941824 2079114000 net.cpp:220] Memory required for data: 201476

๋„คํŠธ์›Œํฌ์˜ ๊ตฌ์กฐ๋Š” ๋‹จ๋ง๊ธฐ์— ์ƒ๊ด€์—†์ด ์†Œํ”„ํŠธ์›จ์–ด ํ”„๋กœ๊ทธ๋žจ์ด๋‚˜ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. ์•ž์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์„ค๋ช…ํ–ˆ๋˜ ๊ฒƒ์„ ๋Œ์ด์ผœ ๋ณด๋ฉด, bolb์™€ ๊ณ„์ธต์€ ๋ชจ๋ธ ์„ ์–ธ์œผ๋กœ๋ถ€ํ„ฐ ๋ณด์ด์ง€์•Š๋Š” ๊ณณ์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ์‚ฌํ•ญ๋“ค์ด๋ผ๊ณ  ํ•˜์˜€๋‹ค. ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“  ํ›„์—, ๋„คํŠธ์›Œํฌ๋Š” โ€œCaffe::mode()โ€์—์„œ์™€ ์ •์˜๋˜๊ณ  โ€œCaffe::set_mode()โ€์—์„œ ์„ค์ •๋œ ๋‹จ์ผ ์Šค์œ„์น˜๋ฅผ ์„ค์ •ํ•จ์— ์˜ํ•ด์„œ CPU๋‚˜ GPU์ƒ์—์„œ ์ž‘๋™ํ•œ๋‹ค. ๊ณ„์ธต๋“ค์€ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” CPU์™€ GPUํ‹€์— ์ƒ์‘ํ•˜๋Š” ๊ฒƒ์— ๋”ธ๋ ค์žˆ๋‹ค. (์ˆ˜๋งŽ์€ ์—๋Ÿฌ๊ฐ€ ๋“ฑ์žฅํ•˜์ง€๋งŒ ์ด๋ฅผ ๋ง‰๋Š” ํ…Œ์ŠคํŠธ๋„ ํ•จ๊ป˜ํ•œ๋‹ค.) CPU/GPU ์Šค์œ„์น˜๋Š” ๋งค๋„๋Ÿฝ๊ณ  ๋ชจ๋ธ ์„ ์–ธ์— ๋Œ€ํ•ด ๋…๋ฆฝ์ ์ด๋‹ค. ์ด๊ฒƒ์€ ์—ฐ๊ตฌ๋‚˜ ๋ฐฐ์น˜ ๊ฐ™์€ ๋“ค์„ ์œ„ํ•˜์—ฌ ๋ชจ๋ธ๊ณผ ์ˆ˜ํ–‰์„ ๋‚˜๋ˆ„์–ด ์ •์˜ํ•˜๋Š” ์ตœ์ƒ์˜ ๋ฐฉ๋ฒ•์ด๋‹ค.

๋ชจ๋ธ ํ˜•ํƒœ(Model Format)

Binary protocol buffer (binaryproto) Caffemodel files๋กœ์จ ํ•™์Šต๋œ ๋ชจ๋ธ์„ ๊ธ‰์ˆ˜ํ™” ํ•˜๋Š” ๋™์•ˆ ๋ชจ๋ธ์€ Plaintext Protocol Buffer Schema (prototxt)๋กœ ์„ ์–ธ๋œ๋‹ค. Model ํ˜•ํƒœ๋Š” caffe.proto ์•ˆ์˜ protobuf schema์— ์˜ํ•ด ์ •์˜๋œ๋‹ค. ์†Œ์ŠคํŒŒ์ผ์˜ ๋Œ€๋ถ€๋ถ„ ๋ผ์ธ๋“ค์ด ์„ค๋ช…์ด ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. Caffe๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ•์ ์— ๋Œ€ํ•˜์—ฌ Google Protocol Buffer๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. Minimal-size binary strings (๊ธ‰์ˆ˜ํ™” ํ• ๋•Œ, - Serialized), Efficient Serialization, ์•„์ฃผ ํ™•์‹คํ•œ C++๊ณผ Python, ๋‹ค์–‘ํ•œ ์–ธ์–ด์—์„œ ํšจ์œจ์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค ์ˆ˜ํ–‰ ๊ทธ๋ฆฌ๊ณ  ์ด์ง„์ˆ˜ ๋ฒ„์ „๊ณผ ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๊ธ€ ํ˜•ํƒœ์ด๋‹ค. ์ด๋Ÿฌํ•œ ๋ชจ๋“  ๊ฒƒ๋“ค์€ Caffe์—์„œ ๋ชจ๋ธ๋ง์—๋Œ€ํ•œ ํ™•์žฅ์„ฑ๊ณผ ์œ ์—ฐ์„ฑ์— ๊ธฐ์—ฌํ•œ๋‹ค.

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