-
Notifications
You must be signed in to change notification settings - Fork 1
Tutiroal_04
์ด ํํ ๋ฆฌ์ผ์์๋ Caffe2์ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ์์์ ๋ํด ์๊ฐํ๋๋ก ํ๊ฒ ์ต๋๋ค.
- Workspaces(์์ ๊ณต๊ฐ)
- Operators(์ฐ์ฐ์)
- Nets
์ด ์ฑํฐ๋ฅผ ์์ํ๊ธฐ์ ์์ Intro Tutorial์ ๋ณต์ตํ์ ๋ ์ข์ต๋๋ค.
์ด ํํ ๋ฆฌ์ผ์์๋ Caffe2์ ๊ธฐ๋ณธ์ด๋ผ๊ณ ํ ์ ์๋ ์ฐ์ฐ์์ net์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋น๋กฏํ ๊ธฐ๋ณธ ๊ฐ๋ ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ , caffe2๋ฅผ importํฉ๋๋ค. core
์ workspace
๋ ๊ฐ์ฅ ๋ง์ด ์ฐ๊ฒ ๋ 2๊ฐ์ง๊ฐ ๋ ๊ฒ์
๋๋ค. caffe2์ ์ํด ๋ง๋ค์ด์ง ํ๋กํ ์ฝ ๋ฒํผ๋ฅผ ์กฐ์ข
ํ๊ณ ์ถ๋ค๋ฉด, caffe2.proto
์์ caffe2_pb2
๋ ํจ๊ป importํฉ๋๋ค.
# ๊ธฐ๋ณธ์ ์ธ ํ์ด์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ช ๊ฐ importํด์ค๋๋ค.
from matplotlib import pyplot
import numpy as np
import time
# ์๋์ droid๋ค์ด ์ง๊ธ ์ฐพ๋ ๊ฒ๋ค์
๋๋ค.
from caffe2.python import core, workspace
from caffe2.proto import caffe2_pb2
# Let's show all plots inline.
%matplotlib inline
caffe2๊ฐ GPU๋ฅผ ์ง์ํ์ง ์๋๋ค๋ ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ๋ฐ์ ์๋ ์์ต๋๋ค. CPU ์ ์ฉ ๋น๋๋ฅผ ์คํ์ํค๊ณ ์๋ค๋ ์๋ฏธ์ ๋๋ค. CPU๋ง์ผ๋ก๋ ์๋ฌด ๋ฌธ์ ์์ด ์คํํ ์ ์๊ณ , ๋ฌธ์ ๋ฅผ ์ผ์ผํค์ง ์์ผ๋ ๊ฑฑ์ ํ์ง ๋ง์ธ์!
๋จผ์ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ๋ชจ์ด๋ workspace๋ถํฐ ์ดํด๋ด ์๋ค.
๋ง์ฝ Matlab์ ์ต์ํ๋ค๋ฉด, workspace๋ ๋ง๋ค๊ณ ์ ์ฅํ๋ blob๋ค๋ก ๊ตฌ์ฑ๋์ด์์ต๋๋ค. ์ง๊ธ์ blob์ numpy์ ndarray์ ์ ์ฌํ์ง๋ง ์ฐ์์ ์ธ n์ฐจ์์ Tensor๋ก ๊ฐ์ฃผ ํ ๊ฒ์ ๋๋ค. ์๋์ blob์ ๋ชจ๋ ์ ํ์ C++ ๊ฐ์ฒด๋ฅผ ์ ์ฅ ํ ์ ์๋ ์ ํํ๋ ํฌ์ธํฐ์ง๋ง, Tensor๋ blob์ ์ ์ฅ๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ์ ํ์ด๋ผ๋ ๊ฒ์ ๋ณด์ฌ์ค ๊ฒ์ ๋๋ค. ๋จผ์ ์ธํฐํ์ด์ค๋ถํฐ ๋ณด์ฌ๋๋ฆฌ๊ฒ ์ต๋๋ค.
Blobs()
๋ workspace์ ์กด์ฌํ๋ ๋ชจ๋ blob๋ค์ ์ถ๋ ฅํฉ๋๋ค. HasBlob()
์ฟผ๋ฆฌ๋ workspace์ blob์ด ์กด์ฌํ๋์ง ์ฌ๋ถ๋ฅผ ์๋ ค์ค๋๋ค. ์ง๊ธ์ ์๋ฌด๊ฒ๋ ๊ฐ๊ณ ์์ง ์์ต๋๋ค.
print("Current blobs in the workspace: {}".format(workspace.Blobs()))
print("Workspace has blob 'X'? {}".format(workspace.HasBlob("X")))
FeedBlob()
์ ์ฌ์ฉํด blob์ workspace๋ก ๋ณด๋ผ ์ ์์ต๋๋ค.
X = np.random.randn(2, 3).astype(np.float32)
print("Generated X from numpy:\n{}".format(X))
workspace.FeedBlob("X", X)
Generated X from numpy:
[[-0.56927377 -1.28052795 -0.95808828]
[-0.44225693 -0.0620895 -0.50509363]]
์ด์ workspace์ ์ด๋ค blob์ด ์๋์ง ํ์ธ ํด ๋ด ์๋ค.
print("Current blobs in the workspace: {}".format(workspace.Blobs()))
print("Workspace has blob 'X'? {}".format(workspace.HasBlob("X")))
print("Fetched X:\n{}".format(workspace.FetchBlob("X")))
Current blobs in the workspace: [u'X']
Workspace has blob 'X'? True
Fetched X:
[[-0.56927377 -1.28052795 -0.95808828]
[-0.44225693 -0.0620895 -0.50509363]]
์ ๋ฐฐ์ด๋ค์ด ๋์ผํ ๊ฒ์ธ์ง ํ์ธ ํด ๋ด ์๋ค.
np.testing.assert_array_equal(X, workspace.FetchBlob("X"))
๋ง์ฝ, ์กด์ฌํ์ง ์๋ blob์ ์ ๊ทผ์ ์๋ํ๋ค๋ฉด ์๋ฌ๊ฐ ๋ํ๋ ๊ฒ์ ๋๋ค.
try:
workspace.FetchBlob("invincible_pink_unicorn")
except RuntimeError as err:
print(err)
[enforce fail at pybind_state.cc:441] gWorkspace->HasBlob(name).
์ฆ์ ์ฌ์ฉํ์ง ๋ชปํ ์๋ ์๋ ๊ฒ์ด ์์ต๋๋ค: ํ์ด์ฌ์์, ๊ฐ๊ฐ ๋ค๋ฅธ ์ด๋ฆ์ ๊ฐ๊ณ ์๋ ์ฌ๋ฌ ๊ฐ์ workspace๋ฅผ ๊ฐ๊ณ ์์
์ ์ ํํ ์ ์์ต๋๋ค. ๋ค๋ฅธ workspace์ ์กด์ฌํ๋ blob๋ค์ ์๋ก์๊ฒ ๋
๋ฆฝ์ ์
๋๋ค. CurrentWorkspace
๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์ฌ ํ์ฌ workspace๋ฅผ ์กฐํํ ์ ์์ต๋๋ค. ์ด๋ฆ(gutentag)์ ์ด์ฉํด ์์
๊ณต๊ฐ์ ์ ํํ๊ณ , ๋ง์ฝ ์กด์ฌํ์ง ์๋๋ค๋ฉด ์์ฑํด๋ด
์๋ค.
print("Current workspace: {}".format(workspace.CurrentWorkspace()))
print("Current blobs in the workspace: {}".format(workspace.Blobs()))
# workspace๋ฅผ ์ ํํฉ๋๋ค. ๋ ๋ฒ์งธ ์ธ์ "True"๋ workspace๊ฐ ์์ ๋ ์์ฑํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
workspace.SwitchWorkspace("gutentag", True)
# ํ์ฌ workspace๋ฅผ ์ถ๋ ฅ ํด๋ด
์๋ค. ์์ง workspace์ ์๋ฌด๊ฒ๋ ์๋ ๊ฒ์ ์์ง ๋ง์ธ์.
print("Current workspace: {}".format(workspace.CurrentWorkspace()))
print("Current blobs in the workspace: {}".format(workspace.Blobs()))
Current workspace: default
Current blobs in the workspace: ['X']
Current workspace: gutentag
Current blobs in the workspace: []
๊ธฐ๋ณธ workspace๋ก ๋ค์ ๋์๊ฐ ๋ด ์๋ค.
workspace.SwitchWorkspace("default")
print("Current workspace: {}".format(workspace.CurrentWorkspace()))
print("Current blobs in the workspace: {}".format(workspace.Blobs()))
Current workspace: default
Current blobs in the workspace: ['X']
๋ง์ง๋ง์ผ๋ก, ResetWorkspace()
๋ ํ์ฌ workspace์ ๋ชจ๋ ๋ด์ฉ์ ์ญ์ ํฉ๋๋ค.
workspace.ResetWorkspace()
Caffe2์ ์ฐ์ฐ์๋ ์ผ์ข
์ ํจ์๋ผ๊ณ ํ ์ ์์ต๋๋ค. C++์ชฝ์์๋ ๋ชจ๋ ๊ณตํต ์ธํฐํ์ด์ค์์ ํ์๋์ด ์ ํ๋ณ๋ก ๋ฑ๋ก๋๋ฏ๋ก runtime ์ค์ ๋ค๋ฅธ ์ฐ์ฐ์๋ฅผ ํธ์ถ ํ ์ ์์ต๋๋ค. ์ฐ์ฐ์์ ์ธํฐํ์ด์ค๋ caffe2/proto/caffe2.proto
์ ์ ์๋์ด์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก, ๊ทธ๊ฒ์ ์ฌ๋ฌ ๊ฐ์ ์
๋ ฅ์ ๋ฐ์ ์ฌ๋ฌ ๊ฐ์ ์ถ๋ ฅ์ ๋ง๋ค์ด๋
๋๋ค.
Caffe2 Python์์ "์ฐ์ฐ์ ๋ง๋ค๊ธฐ"๋ผ๊ณ ๋งํ๋ฉด ์๋ฌด๊ฒ๋ ์คํ๋์ง ์์ต๋๋ค. ์ฐ์ฐ์์ ํน์ง์ ์ง์ ํ๋ ํ๋กํ ์ฝ ๋ฒํผ๋ฅผ ์์ฑ ํ ๋ฟ์ด์ฃ . ๋์ค์ ์คํ์ ์ํด C ++ ๋ฐฑ์๋๋ก ์ ์ก๋ฉ๋๋ค. protobuf์ ์ต์ํ์ง ์๋ค๋ฉด ๊ตฌ์กฐํ ๋ ๋ฐ์ดํฐ๋ฅผ ์ํ json๊ฐ์ ์ง๋ ฌํ ๋๊ตฌ๋ผ๊ณ ์๊ฐํ๋ฉด ์ข์ต๋๋ค. ํ๋กํ ์ฝ ๋ฒํผ์ ๋ํ ์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
์ค์ ์์ ๋ฅผ ์ดํด๋ด ์๋ค.
# ์ฐ์ฐ์ ์์ฑ
op = core.CreateOperator(
"Relu", # ์คํ์ํค๊ณ ์ํ๋ ์ฐ์ฐ์์ ํ์
["X"], # ์ด๋ฆ์ ์ด์ฉํด input blob์ listing
["Y"], # ์ด๋ฆ์ ์ด์ฉํด output blob์ listing
)
# ๋!
์์ ์ธ๊ธํ๋ฏ, ์์ฑ๋ ์ฐ์ฐ์๋ผ๋ ๊ฒ์ ์ค์ง์ ์ผ๋ก protobuf ๊ฐ์ฒด์ ๋๋ค. ๋ด์ฉ์ ์ดํด๋ด ์๋ค.
print("Type of the created op is: {}".format(type(op)))
print("Content:\n")
print(str(op))
Type of the created op is: <class 'caffe2.proto.caffe2_pb2.OperatorDef'>
Content:
input: "X"
output: "Y"
name: ""
type: "Relu"
๋์ต๋๋ค, ์ฐ์ฐ์๋ฅผ ์คํ์์ผ๋ด
์๋ค. ๋จผ์ , input X๋ฅผ workspace๋ก ๊ฐ์ ธ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋์, ์ฐ์ฐ์๋ฅผ ์คํ์ํค๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ workspace.RunOperatorOnce(operator)
๋ช
๋ น์ด ์
๋๋ค.
workspace.FeedBlob("X", np.random.randn(2, 3).astype(np.float32))
workspace.RunOperatorOnce(op)
์คํ ์ดํ์, ์ฐ์ฐ์๊ฐ ์ ๋๋ก ์ผ์ ์ํํ๋์ง ์ดํด๋ด ์๋ค. ์ฌ๊ธฐ์๋ ์ฐ์ฐ์๊ฐ ์ ๊ฒฝ๋ง([Relu])์ ํ์ฑํํ๋ ์ญํ ์ ํ๋ ํจ์์ ๋๋ค.
print("Current blobs in the workspace: {}\n".format(workspace.Blobs()))
print("X:\n{}\n".format(workspace.FetchBlob("X")))
print("Y:\n{}\n".format(workspace.FetchBlob("Y")))
print("Expected:\n{}\n".format(np.maximum(workspace.FetchBlob("X"), 0)))
Current blobs in the workspace: ['X', 'Y']
X:
[[ 1.03125858 1.0038228 0.0066975 ]
[ 1.33142471 1.80271244 -0.54222912]]
Y:
[[ 1.03125858 1.0038228 0.0066975 ]
[ 1.33142471 1.80271244 0. ]]
Expected:
[[ 1.03125858 1.0038228 0.0066975 ]
[ 1.33142471 1.80271244 0. ]]
์ด ์์์ Y์ ์ถ๋ ฅ์ด ์ผ์นํ๋ ๊ฒ์ ๊ธฐ๋ ํ ๊ฒ์ด๋ผ๋ฉด, ์ด ์ฐ์ฐ์๋ ์ ๋๋ก ์๋ํ๊ณ ์๋ ๊ฒ์ ๋๋ค.
์ฐ์ฐ์๋ ํ์ํ๋ค๋ฉด ์ ํ์ ์ธ์(arguments) ๋ํ ์ฌ์ฉํฉ๋๋ค. ์ฐ์ฐ์์ ์ธ์๋ ํค-๊ฐ ์์ผ๋ก ์ง์ ๋ฉ๋๋ค. ํ ์๋ฅผ ๋ง๋ค์ด Gaussian ํ๋ฅ ๋ณ์๋ก ์ฑ์ฐ๋ ๊ฐ๋จํ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
op = core.CreateOperator(
"GaussianFill",
[], # GaussianFill์ ๋ค๋ฅธ ์ธ์(ํ๋ผ๋ฏธํฐ)๋ฅผ ํ์๋กํ์ง ์์ต๋๋ค.
["Z"],
shape=[100, 100], # int๋ค์ ๋ฆฌ์คํ
ํด์ ์ธ์๋ฅผ ์ค์ ํฉ๋๋ค.
mean=1.0, # floatํ์์ผ๋ก ์์์ ์๋ ํ์๋ฆฌ๋ฅผ ๊ฐ๋ mean
std=1.0, # floatํ์์ผ๋ก ์์์ ์๋ ํ์๋ฆฌ๋ฅผ ๊ฐ๋ std
)
print("Content of op:\n")
print(str(op))
Content of op:
output: "Z"
name: ""
type: "GaussianFill"
arg {
name: "std"
f: 1.0
}
arg {
name: "shape"
ints: 100
ints: 100
}
arg {
name: "mean"
f: 1.0
}
๊ทธ๊ฒ์ ์คํํ๊ณ ์๋ํ ๋๋ก ๊ฐ์ด ๋์ค๋์ง ๋ด ์๋ค.
workspace.RunOperatorOnce(op)
temp = workspace.FetchBlob("Z")
pyplot.hist(temp.flatten(), bins=50)
pyplot.title("Distribution of Z")
<matplotlib.text.Text at 0x7f2bd2d51710>
์ข ๋ชจ์์ ๊ณก์ ์ด ๋ณด์ฌ์ง๋ฉด ์ ๋๋ก ์๋ ๋ ๊ฒ์ ๋๋ค!
net์ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ณ์ฐ ๊ทธ๋ํ์ ๋๋ค. Net์ ์ผ๋ จ์ ๋ช ๋ น์ผ๋ก ์์ฑ๋ ํ๋ก๊ทธ๋จ์ฒ๋ผ, ์ฌ๋ฌ ๊ฐ์ ์ฐ์ฐ์๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ํ ๋ฒ ์ดํด๋ด ์๋ค.
์ฐ๋ฆฌ๊ฐ net์ ๋ํด ๋งํ ๋, BlobReference์ ๋ํด์๋ ํจ๊ป ๋งํ๊ณ ์๋ ์ ์ ๋๋ค. BlobReference๋ ๋ฌธ์์ด ์ฃผ์๋ฅผ ๊ฐ์ธ์ ์ฐ์ฐ์๋ฅผ ์ฝ๊ฒ ์ฐ๊ฒฐ์ํฌ ์ ์๋๋ก ํ๋ ๊ฐ์ฒด์ ๋๋ค.
๋ค์์ ํ์ด์ฌ math์ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ์ ์ญํ ์ ํ๋ network๋ฅผ ๋ง๋ค์ด๋ด ์๋ค.
X = np.random.randn(2, 3)
W = np.random.randn(5, 3)
b = np.ones(5)
Y = X * W^T + b
์ฐจ๊ทผ์ฐจ๊ทผ ๊ณผ์ ์ ๋ณด์ฌ๋๋ฆฌ๊ฒ ์ต๋๋ค. Caffe2์ core.Net
์ NetDef ํ๋กํ ์ฝ ๋ฒํผ์ ์ฃผ๋ณ์ ๊ฐ์ธ๋ class์
๋๋ค.
network๋ฅผ ์์ฑํ๋ฉด, ๊ทธ ๊ธฐ์ ์ ํ๋กํ ์ฝ ๋ฒํผ๋ ๋คํธ์ํฌ ์ด๋ฆ์ ์ ์ธํ๊ณ ๊ธฐ๋ณธ์ ์ผ๋ก ๋น์ด์์ต๋๋ค. net์ ๋ง๋ค๊ณ proto ๋ด์ฉ์ ๋ณด์ฌ์ฃผ๊ฒ ๋ง๋ค์ด ๋ด ์๋ค.
net = core.Net("my_first_net")
print("Current network proto:\n\n{}".format(net.Proto()))
Current network proto:
name: "my_first_net"
X๋ผ๊ณ ๋ถ๋ฆฌ๋ blob์ ๋ง๋ค๊ณ , GaussianFill์ ์ด์ฉํด์ ๋๋ค ๋ฐ์ดํฐ๋ก ์ฑ์๋๋ค.
X = net.GaussianFill([], ["X"], mean=0.0, std=1.0, shape=[2, 3], run_once=0)
print("New network proto:\n\n{}".format(net.Proto()))
New network proto:
name: "my_first_net"
op {
output: "X"
name: ""
type: "GaussianFill"
arg {
name: "std"
f: 1.0
}
arg {
name: "run_once"
i: 0
}
arg {
name: "shape"
ints: 2
ints: 3
}
arg {
name: "mean"
f: 0.0
}
}
์์ core.CreateOperator
ํธ์ถ๊ณผ ์ฝ๊ฐ์ ์ฐจ์ด์ ์ ๊ด์ฐฐ ํ ์ ์์ ๊ฒ์
๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก, net์ด ์๋ค๋ฉด, ์ฐ์ฐ์๋ฅผ ๋ฐ๋ก ์์ฑํ๊ณ ๋์์ ํ์ด์ฌ ํธ๋ฆญ์ ์ฌ์ฉํ์ฌ net์ ์ถ๊ฐ์ํฌ ์ ์์ต๋๋ค : SomeOp๊ฐ ์ฐ์ฐ์์ ๋ฌธ์์ด ํ์
์ผ๋ก ๋ฑ๋ก๋ ์ํ์์ net.SomeOp
์ ํธ์ถํ๋ฉด ์ด๊ฒ์ ๊ณง๋ฐ๋ก ๋ค์์ผ๋ก ๋ฒ์ญ์ํต๋๋ค.
op = core.CreateOperator("SomeOp", ...)
net.Proto().op.append(op)
๋ํ, X๊ฐ ๋ฌด์์ธ์ง ๊ถ๊ธํ ์ ์์ต๋๋ค. X๋ ๊ธฐ๋ณธ์ ์ผ๋ก 2๊ฐ์ง๋ฅผ ๊ธฐ๋กํ๋ BlobReference
์
๋๋ค.
- ์ด๋ฆ์ด ๋ฌด์์ธ์ง. str(X)๋ฅผ ์ด์ฉํด์ ์ด๋ฆ์ ์ ๊ทผ ํ ์ ์์ต๋๋ค.
- ๊ทธ๊ฒ์ผ๋ก๋ถํฐ ์ด๋ค net์ด ์์ฑ๋๋์ง. ๋ด๋ถ ๋ณ์
_from_net
์ ์ํด์ ๊ธฐ๋ก๋๋๋ฐ ๋ณ๋ก ํ์ํ์ง๋ ์์ ๊ฒ์ ๋๋ค.
์ ํจ์ฑ์ ๊ฒ์ฌํด๋ด ์๋ค. ๋ ํ ๊ฐ์ง ๊ธฐ์ตํด์ผ ํ ๊ฒ์ ์ฐ๋ฆฌ๋ ์์ง ์๋ฌด๊ฒ๋ ์คํํ์ง ์์๋ค๋ ๊ฒ์ ๋๋ค. ๋ฐ๋ผ์ X๋ symbol์ผ ๋ฟ ์๋ฌด๊ฒ๋ ๊ฐ๊ณ ์์ง ์์ต๋๋ค. ์ง๊ธ ๋น์ฅ ์ซ์ ๊ฐ์ ์ป๋ ๊ฒ์ ๊ธฐ๋ํ์ง๋ ๋ง์ธ์ :)
print("Type of X is: {}".format(type(X)))
print("The blob name is: {}".format(str(X)))
Type of X is: <class 'caffe2.python.core.BlobReference'>
The blob name is: X
๊ณ์ํด์ W์ b๋ฅผ ์์ฑํฉ๋๋ค.
W = net.GaussianFill([], ["W"], mean=0.0, std=1.0, shape=[5, 3], run_once=0)
b = net.ConstantFill([], ["b"], shape=[5,], value=1.0, run_once=0)
์ด์ , ๊ฐ๋จํ ์ฝ๋๊ฐ ํ๋ ์๊ฒผ์ต๋๋ค. BlobReference ๊ฐ์ฒด๋ ์์ฑ๋ net์ด ๋ฌด์์ธ์ง ์๊ณ ์๊ธฐ ๋๋ฌธ์, net์์ ์ฐ์ฐ์๋ฅผ ๋ง๋ค ์ ์์ ๋ฟ๋ง ์๋๋ผ BlobReference์ผ๋ก๋ถํฐ ์ฐ์ฐ์๋ฅผ ๋ง๋ค ์๋ ์์ต๋๋ค. ์ด๋ฐ ์์ผ๋ก FC์ฐ์ฐ์๋ฅผ ๋ง๋ค์ด๋ด ์๋ค.
Y = X.FC([W, b], ["Y"])
X.FC(...)
๋ X
๋ฅผ ํด๋น ์ฐ์ฐ์์ ์ฒซ ๋ฒ์งธ input์ผ๋ก ์ฝ์
ํด net.FC
์ ๊ฐ๋จํ ๋๋ฆฌ์ ์ญํ ์ ํฉ๋๋ค. ๋ฐ๋ผ์ ์์์ ํ ์์
์ ๋ค์์ ๊ฒ๊ณผ ๋์ผํฉ๋๋ค.
Y = net.FC([X, W, b], ["Y"])
ํ์ฌ network๋ฅผ ์ดํด๋ด ์๋ค.
print("Current network proto:\n\n{}".format(net.Proto()))
Current network proto:
name: "my_first_net"
op {
output: "X"
name: ""
type: "GaussianFill"
arg {
name: "std"
f: 1.0
}
arg {
name: "run_once"
i: 0
}
arg {
name: "shape"
ints: 2
ints: 3
}
arg {
name: "mean"
f: 0.0
}
}
op {
output: "W"
name: ""
type: "GaussianFill"
arg {
name: "std"
f: 1.0
}
arg {
name: "run_once"
i: 0
}
arg {
name: "shape"
ints: 5
ints: 3
}
arg {
name: "mean"
f: 0.0
}
}
op {
output: "b"
name: ""
type: "ConstantFill"
arg {
name: "run_once"
i: 0
}
arg {
name: "shape"
ints: 5
}
arg {
name: "value"
f: 1.0
}
}
op {
input: "X"
input: "W"
input: "b"
output: "Y"
name: ""
type: "FC"
}
๋๋ฌด ์ฅํฉํ์ฃ ? ๊ทธ๋ํ๋ก ์๊ฐํ ํด๋ด ์๋ค. Caffe2๋ ์์ฃผ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์๊ฐํ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. ipython์ผ๋ก ๊ทธ๊ฒ์ ๋ณด์ฌ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
from caffe2.python import net_drawer
from IPython import display
graph = net_drawer.GetPydotGraph(net, rankdir="LR")
display.Image(graph.create_png(), width=800)
์ฐ๋ฆฌ๋ Net
์ ์ ์ํ์ง๋ง ์์ง ์๋ฌด๊ฒ๋ ์คํ๋์ง๋ ์์์ต๋๋ค. ์์ net์ ๋คํธ์ํฌ์ ์ ์๋ฅผ ๊ฐ๊ณ ์๋ protobuf๋ผ๋ ๊ฒ์ ๊ธฐ์ตํ์ธ์. ์ค์ ๋ก ๋คํธ์ํฌ๋ฅผ ์คํํ๊ธฐ ์ํ ๋, ๋ค์์ ์ผ๋ค์ด ์ผ์ด๋ฉ๋๋ค.
- protobuf์์ C++ net ๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํํฉ๋๋ค.
- ์ธ์คํด์คํ ๋ net์ Run () ํจ์๋ฅผ ํธ์ถํฉ๋๋ค.
์ฐ๋ฆฌ๊ฐ ๋ฌด์ธ๊ฐ๋ฅผ ํ๊ธฐ ์ ์ ResetWorkspace()
๋ช
๋ น์ด๋ฅผ ์ด์ฉํด ๋ชจ๋ workspace์ ์์ ๋ณ์๋ค์ clearํด์ผ ํฉ๋๋ค.
ํ์ด์ฌ์ ์ด์ฉํด์ net์ ์คํ์ํค๋ ๋ฐฉ๋ฒ์ ๋ ๊ฐ์ง๊ฐ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์๋ ์์ ์ค์ ์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ํ ํ ๊ฒ์ ๋๋ค.
-
์ธ์คํด์คํ์์ผ ์คํ์ํจ ํ์ ๋ฐ๋ก ํ๊ดดํ๋
workspace.RunNetOnce()
์ ์ฌ์ฉํฉ๋๋ค. -
์กฐ๊ธ ๋ ๋ณต์กํ๊ณ 2๊ฐ์ง ๋จ๊ณ๊ฐ ํ์ํฉ๋๋ค:
(a) workspace๊ฐ ์์ ํ C++ net ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํด
workspace.CreateNet()
๋ฅผ ํธ์ถํฉ๋๋ค.(b) network ์ด๋ฆ์ ์ ๋ฌํด์
workspace.RunNet()
์ ์ฌ์ฉํฉ๋๋ค.
workspace.ResetWorkspace()
print("Current blobs in the workspace: {}".format(workspace.Blobs()))
workspace.RunNetOnce(net)
print("Blobs in the workspace after execution: {}".format(workspace.Blobs()))
# blobs์ ๋ด์ฉ์ dumpํฉ์๋ค.
for name in workspace.Blobs():
print("{}:\n{}".format(name, workspace.FetchBlob(name)))
Current blobs in the workspace: []
Blobs in the workspace after execution: ['W', 'X', 'Y', 'b']
W:
[[-0.96537346 0.42591459 0.66788739]
[-0.47695673 2.25724339 -0.10370601]
[-0.20327474 -3.07469416 0.47715324]
[-1.62159526 0.73711687 -1.42365313]
[ 0.60718107 -0.50448036 -1.17132831]]
X:
[[-0.99601173 -0.61438894 0.10042733]
[ 0.23359862 0.15135486 0.77555442]]
Y:
[[ 1.76692021 0.07781416 3.13944149 2.01927781 0.58755434]
[ 1.35693741 1.14979863 0.85720366 -0.37135673 0.15705228]]
b:
[ 1. 1. 1. 1. 1.]
์, ์ด๋ฒ์๋ ๋ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ด์ฉํด net์ ์์ฑํ๊ณ ์คํ์์ผ๋ด
์๋ค. ResetWorkspace()
๋ฅผ ์ฌ์ฉํ์ฌ ๋ณ์๋ฅผ ์ง์ฐ๊ณ , ์ ์ ์์ฑ ํด ๋ workspace์ net ๊ฐ์ฒด์ธ CreateNet(net_object)
๋ฅผ ์ด์ฉํด net์ ๋ง๋ญ๋๋ค. ์ดํ RunNet(net_name)
์ ์ด๋ฆ์ ์ ๋ฌํ์ฌ net์ ์คํํฉ๋๋ค.
workspace.ResetWorkspace()
print("Current blobs in the workspace: {}".format(workspace.Blobs()))
workspace.CreateNet(net)
workspace.RunNet(net.Proto().name)
print("Blobs in the workspace after execution: {}".format(workspace.Blobs()))
for name in workspace.Blobs():
print("{}:\n{}".format(name, workspace.FetchBlob(name)))
Current blobs in the workspace: []
Blobs in the workspace after execution: ['W', 'X', 'Y', 'b']
W:
[[-0.29295802 0.02897477 -1.25667715]
[-1.82299471 0.92877913 0.33613944]
[-0.64382178 -0.68545657 -0.44015241]
[ 1.10232282 1.38060772 -2.29121733]
[-0.55766547 1.97437167 0.39324901]]
X:
[[-0.47522315 -0.40166432 0.7179445 ]
[-0.8363331 -0.82451206 1.54286408]]
Y:
[[ 0.22535783 1.73460138 1.2652775 -1.72335696 0.7543118 ]
[-0.71776152 2.27745867 1.42452145 -4.59527397 0.4452306 ]]
b:
[ 1. 1. 1. 1. 1.]
RunNetOnce
์ RunNet
์ ๋ช ๊ฐ์ง ์ฐจ์ด์ ์ด ์๋๋ฐ, ์๋ง ์ฃผ์ ์ฐจ์ด์ ์ ์ฐ์ฐ์๋์ผ ๊ฒ์
๋๋ค. RunNetOnce
๋ protobuf๋ฅผ ์ง๋ ฌํํ์ฌ Python๊ณผ C ์ฌ์ด๋ฅผ ํต๊ณผํ๊ณ ๋คํธ์ํฌ๋ฅผ ์ธ์คํด์คํํ๋ ๊ฒ๊น์ง ํฌํจํ๊ธฐ ๋๋ฌธ์ ์คํํ๋ ๋ฐ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆด ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ๋ฅผ ์ ๋ฐ์ ์ผ๋ก ์ดํด๋ณด๊ฒ ์ต๋๋ค.
# `%timeit`์ ๋ง๋ฒ์ด C++์์ ์ ๋๋ก ์๋ํ์ง ์๋ ๊ฒ ๊ฐ์์ loop๋ฅผ ์ด์ฉํ๊ฒ ์ต๋๋ค.
start = time.time()
for i in range(1000):
workspace.RunNetOnce(net)
end = time.time()
print('Run time per RunNetOnce: {}'.format((end - start) / 1000))
start = time.time()
workspace.CreateNet(net)
for i in range(1000):
workspace.RunNet(net.Proto().name)
end = time.time()
print('Run time per RunNet: {}'.format((end - start) / 1000))
Run time per RunNetOnce: 0.000364284992218
Run time per RunNet: 4.42600250244e-06
ํ์ด์ฌ์์ Caffe2๋ฅผ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด ์์ ๋ช ๊ฐ์ง ์ฃผ์ ๊ตฌ์ฑ ์์๋ฅผ ํ์ฉํ๋ ๊ฒ๋ง์ผ๋ก๋ ์ข์ ๊ฒ์ ๋๋ค. ๋ ๋ง์ ๊ฒ์ด ํ์ํ๋ค๊ณ ๋๊ปด์ง๋ฉด, ํํ ๋ฆฌ์ผ์ ์ถ๊ฐ ํ ๊ณํ์ ๋๋ค. ์ด์ ๋ถํฐ, ํํ ๋ฆฌ์ผ์ ๋๋จธ์ง ๋ถ๋ถ์ ํ์ธ ํด๋ณด์ธ์!