์๋ ํ์ธ์ ์ฌ๋ฌ๋ถ,
Keras๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ๋ฅ๋ฅผ ์ํด CNN ๋ชจ๋ธ์ ํ๋ จํ๊ณ ์ถ์ต๋๋ค. ๋ด๊ฐ ์๋ ๋ฐ์ ๊ฐ์ด VGG, ImageNet ๋ฑ๊ณผ ๊ฐ์ ์ฌ์ ํ๋ จ๋ ๊ณต๊ฐ CNN ๋ชจ๋ธ์ด ๋ง์ด ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ถํํ๋ ์ด๋ฌํ ์ฌ์ ํ๋ จ๋ ๋ชจ๋ธ์ caffe ๋๋ cuda-convnet๊ณผ ๊ฐ์ ๋ค๋ฅธ CNN ํ๋ ์์ํฌ๋ก ์์ฑ๋ฉ๋๋ค. ์ด๋ฌํ ์ข ๋ฅ์ ์ฌ์ ํ๋ จ๋ ๋ชจ๋ธ ๋๋ ๊ฐ์ค์น๋ฅผ ์ฌ์ฉํ์ฌ Keras ์์ฐจ ๋ชจ๋ธ์ ์ด๊ธฐํํ ๋ค์ ๋ฏธ์ธ ์กฐ์ ํ๋ จ์ ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ ๋๊น?
๊ฐ์ฌ ํด์
์ฐ ๋ฐ์ฌ
๋๋ ๋ํ ์ด๊ฒ์ ์ค๋ช ํ๊ธฐ ์ํ ํํ ๋ฆฌ์ผ์ ๋ณด๊ธฐ๋ฅผ ํฌ๋งํ๋ค.
์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ํด ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค. ์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ๊ณง ์ถ๊ฐํ๊ณ ์ถ์ ๊ธฐ๋ฅ ์ค ํ๋์ ๋๋ค. https://github.com/fchollet/keras/issues/100
์ฌ์ ํ ๊ด์ฌ์ด ์๋ ์ฌ๋์ด ์๋ค๋ฉด ๋ณํ ๋ชจ๋์ด ์๋ ์ด Keras ํฌํฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
https://github.com/MarcBS/keras
์ต์์,
๋งํฌ
์๋
,
๋๋ ๋น์ ์ด ์ธ๊ธ ํ caffe์์ keras ๋ณํ ๋ชจ๋์ ์๋ํ์ง๋ง caffe2keras.py๋ฅผ ์คํํ ๋์ด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ ์ญ ์ด๋ฆ 'network_input'์ด(๊ฐ) ์ ์๋์ง ์์์ต๋๋ค.
๋์์ด ๋์ จ๋์?
@dhruvjain ์ด ํฌํฌ ๋ฅผ ์ธ๊ธํ๋ ๊ฒฝ์ฐ ์ฌ๊ธฐ ์์ ์ ๋ฌธ์ ๋ฅผ ์ฌ์ญ์์ค.
๋ํ ๋ณํํ๋ ค๋ ๋ชจ๋ธ ํ์ผ์ด๋ ์ต์ํ .prototxt๋ฅผ ํฌํจํ ์ ์๋ค๋ฉด ๋งค์ฐ ์ ์ฉํ ๊ฒ์ ๋๋ค.
caffenet ๋ชจ๋ธ์ ๋ณํํ๋ ๋ฐ ์ฌ์ฉํ๋๋ฐ prototxt๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ด๋ฆ: "์นดํ๋ท"
force_backward: ์ฐธ
์
๋ ฅ ๋ฐ์ดํฐ"
input_dim: 1
input_dim: 3
input_dim: 227
input_dim: 227
์
๋ ฅ: "๋ ์ด๋ธ"
input_dim: 1
input_dim: 1
input_dim: 1
input_dim: 1
์ธต {
์ด๋ฆ: "conv1"
์ ํ: "์ปจ๋ณผ๋ฃจ์
"
ํ๋จ: "๋ฐ์ดํฐ"
์๋จ: "conv1"
convolution_param {
num_์ถ๋ ฅ: 96
์ปค๋ ํฌ๊ธฐ: 11
๋ณดํญ: 4
}
}
์ธต {
์ด๋ฆ: "relu1"
์ ํ: "ReLU"
ํ๋จ: "conv1"
์๋จ: "conv1"
}
์ธต {
์ด๋ฆ: "pool1"
์ ํ: "ํ๋ง"
ํ๋จ: "conv1"
์๋จ: "pool1"
pooling_param {
ํ: ์ต๋
์ปค๋ ํฌ๊ธฐ: 3
๋ณดํญ: 2
}
}
์ธต {
์ด๋ฆ: "norm1"
์ ํ: "LRN"
ํ๋จ: "pool1"
์๋จ: "norm1"
lrn_param {
๋ก์ปฌ ํฌ๊ธฐ: 5
์ํ: 0.0001
๋ฒ ํ: 0.75
}
}
์ธต {
์ด๋ฆ: "conv2"
์ ํ: "์ปจ๋ณผ๋ฃจ์
"
ํ๋จ: "norm1"
์๋จ: "conv2"
convolution_param {
num_์ถ๋ ฅ: 256
ํจ๋: 2
์ปค๋ ํฌ๊ธฐ: 5
๊ทธ๋ฃน: 2
}
}
์ธต {
์ด๋ฆ: "relu2"
์ ํ: "ReLU"
ํ๋จ: "conv2"
์๋จ: "conv2"
}
์ธต {
์ด๋ฆ: "pool2"
์ ํ: "ํ๋ง"
ํ๋จ: "conv2"
์๋จ: "pool2"
pooling_param {
ํ: ์ต๋
์ปค๋ ํฌ๊ธฐ: 3
๋ณดํญ: 2
}
}
์ธต {
์ด๋ฆ: "norm2"
์ ํ: "LRN"
ํ๋จ: "pool2"
์๋จ: "norm2"
lrn_param {
๋ก์ปฌ ํฌ๊ธฐ: 5
์ํ: 0.0001
๋ฒ ํ: 0.75
}
}
์ธต {
์ด๋ฆ: "conv3"
์ ํ: "์ปจ๋ณผ๋ฃจ์
"
ํ๋จ: "norm2"
์๋จ: "conv3"
convolution_param {
num_์ถ๋ ฅ: 384
ํจ๋: 1
์ปค๋ ํฌ๊ธฐ: 3
}
}
์ธต {
์ด๋ฆ: "relu3"
์ ํ: "ReLU"
ํ๋จ: "conv3"
์๋จ: "conv3"
}
์ธต {
์ด๋ฆ: "conv4"
์ ํ: "์ปจ๋ณผ๋ฃจ์
"
ํ๋จ: "conv3"
์๋จ: "conv4"
convolution_param {
num_์ถ๋ ฅ: 384
ํจ๋: 1
์ปค๋ ํฌ๊ธฐ: 3
๊ทธ๋ฃน: 2
}
}
์ธต {
์ด๋ฆ: "relu4"
์ ํ: "ReLU"
ํ๋จ: "conv4"
์๋จ: "conv4"
}
์ธต {
์ด๋ฆ: "conv5"
์ ํ: "์ปจ๋ณผ๋ฃจ์
"
ํ๋จ: "conv4"
์๋จ: "conv5"
convolution_param {
num_์ถ๋ ฅ: 256
ํจ๋: 1
์ปค๋ ํฌ๊ธฐ: 3
๊ทธ๋ฃน: 2
}
}
์ธต {
์ด๋ฆ: "relu5"
์ ํ: "ReLU"
ํ๋จ: "conv5"
์๋จ: "conv5"
}
์ธต {
์ด๋ฆ: "pool5"
์ ํ: "ํ๋ง"
ํ๋จ: "conv5"
์๋จ: "pool5"
pooling_param {
ํ: ์ต๋
์ปค๋ ํฌ๊ธฐ: 3
๋ณดํญ: 2
}
}
์ธต {
์ด๋ฆ: "fc6"
์ ํ: "๋ด๋ถ ์ ํ"
ํ๋จ: "pool5"
์๋จ: "fc6"
inner_product_param {
num_์ถ๋ ฅ: 4096
}
}
์ธต {
์ด๋ฆ: "relu6"
์ ํ: "ReLU"
ํ๋จ: "fc6"
์๋จ: "fc6"
}
์ธต {
์ด๋ฆ: "drop6"
์ ํ: "์ค๋จ"
ํ๋จ: "fc6"
์๋จ: "fc6"
dropout_param {
dropout_ratio: 0.5
}
}
์ธต {
์ด๋ฆ: "fc7"
์ ํ: "๋ด๋ถ ์ ํ"
ํ๋จ: "fc6"
์๋จ: "fc7"
inner_product_param {
num_์ถ๋ ฅ: 4096
}
}
์ธต {
์ด๋ฆ: "relu7"
์ ํ: "ReLU"
ํ๋จ: "fc7"
์๋จ: "fc7"
}
์ธต {
์ด๋ฆ: "drop7"
์ ํ: "์ค๋จ"
ํ๋จ: "fc7"
์๋จ: "fc7"
dropout_param {
dropout_ratio: 0.5
}
}
์ธต {
์ด๋ฆ: "fc8"
์ ํ: "๋ด๋ถ ์ ํ"
ํ๋จ: "fc7"
์๋จ: "fc8"
inner_product_param {
num_์ถ๋ ฅ: 1000
}
}
์ ๋ง ์ค์ํ ๊ธฐ๋ฅ...
์ด Caffe-to-Keras ๊ฐ์ค์น ๋ณํ๊ธฐ๋ ๋น์ ์ด ์ฐพ๊ณ ์๋ ๊ฒ์ ๋๋ค:
https://github.com/pierluigiferrari/caffe_weight_converter
.caffemodel
ํ์ผ์ .h5
๊ฐ์ค์น ํ์ผ๋ก ๋ณํํฉ๋๋ค. ๋ชจ๋ธ ์ ์๊ฐ ์๋ ๊ฐ์ค์น๋ง ๋ณํํ์ง๋ง ์ด์จ๋ ๊ฐ์ค์น๋ ์ค์ ๋ก ํ์ํ ์ ๋ถ์
๋๋ค.
์ฃผ์ด์ง ๋ชจ๋ธ์ ๋ํด ๋ชจ๋ธ ์ ์๋ Keras ํต์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ ์ด์ด๋ง ํ์ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ ์๋์ผ๋ก Keras๋ฅผ ์์ฑํ๋ ๊ฒ์ด ๋งค์ฐ ์ฝ๊ฑฐ๋ ๋ชจ๋ธ ์ ์๊ฐ ๋ณต์กํ๊ณ ์ฌ์ฉ์ ์ง์ ๋ ์ด์ด ์ ํ์ด ์๋ ๊ฒฝ์ฐ ๋ชจ๋ธ ์ ์ ๋ณํ๊ธฐ๊ฐ ์คํจํ ์ ์์ต๋๋ค. ๊ทธ๋๋.
๋ณํ๋ ์ keras ๋ชจ๋ธ์์ ์์๋๋ ๋ชจ์ ์ ๋ ฅ์ ๋ฌด์์ ๋๊น? (3,224,224) ๋๋ (224,224,3)? caffe๋ (3,224,224)์ keras๋ (224,224,3)๊ณผ ํจ๊ป ์๋ํ๊ธฐ ๋๋ฌธ์...
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ํด ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค. ์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ๊ณง ์ถ๊ฐํ๊ณ ์ถ์ ๊ธฐ๋ฅ ์ค ํ๋์ ๋๋ค. https://github.com/fchollet/keras/issues/100