์ฝ์ ์๋ฃ: https://tensorflowkorea.gitbooks.io/tensorflow-kr/content/g3doc/how_tos/variable_scope/
์ฃผ์ ํจ์
- tf.get_variable(<name>, <shape>, <initializer>): ์ ๋ ฅ๋ ์ด๋ฆ์ ๋ณ์๋ฅผ ์์ฑํ๊ฑฐ๋ ๋ฐํ
- tf.variable_scope(<scope_name>): tf.get_variable()์ ์ ๋ฌ๋ ์ด๋ฆ์ ๋ค์์คํ์ด์ค๋ฅผ ๊ด๋ฆฌ (with์ ํจ๊ป ์ฐ์)
- tf.get_variable_scope(): ํ์ฌ variable scope๋ฅผ ๋ฐํ
tf.get_variable()
- tf.Variable()์ฒ๋ผ ์ง์ ๊ฐ์ ์ ๋ฌํ์ง ์๊ณ Initializer๋ฅผ ์ฌ์ฉ
tf.constant_initializer(value): ์ ๊ณต๋ ๊ฐ์ผ๋ก ๋ชจ๋ ๊ฒ์ ์ด๊ธฐํ
tf.random_uniform_initializer(a, b): [a, b]๋ฅผ ๊ท ์ผํ๊ฒ ์ด๊ธฐํ
tf.random_normal_initializer(mean, stddev): ์ฃผ์ด์ง mean๊ณผ stddev๋ก ์ ๊ท๋ถํฌ์์ ์ด๊ธฐํ
- variable scope์ reuse์ฌ๋ถ์ ๋ฐ๋ผ 1) ๋ณ์๋ฅผ ์์ฑํ๊ฑฐ๋ 2) ๋ณ์๋ฅผ ๋ฐํํจ
1) tf.get_variable_scope().reuse == False ์ผ ๋
- ๋ณ์์ ์ด๋ฆ์ 'ํ์ฌ variable scope ์ด๋ฆ + ์ ๊ณต๋ name' ์ผ๋ก ์ ํด์ง๋ฉฐ, ์ด๋ฐ ์ด๋ฆ์ ๊ฐ์ง ๋ณ์๊ฐ ์๋์ง ํ์ธํจ
- ๊ทธ๋ฐ ๋ณ์๊ฐ ์กด์ฌํ๋ค๋ฉด Raise ValueError
- ๊ทธ๋ฐ ๋ณ์๊ฐ ์๋ค๋ฉด ๋ณ์๋ฅผ ์์ฑ
2) tf.get_variable_scope().reuse == True ์ผ ๋
- ๋ณ์์ ์ด๋ฆ์ 'ํ์ฌ variable scope ์ด๋ฆ + ์ ๊ณต๋ name' ์ผ๋ก ์ ํด์ง๋ฉฐ, ์ด๋ฐ ์ด๋ฆ์ ๊ฐ์ง ๋ณ์๊ฐ ์๋์ง ํ์ธํจ
- ๊ทธ๋ฐ ๋ณ์๊ฐ ์กด์ฌํ๋ค๋ฉด ํด๋น ๋ณ์๋ฅผ ใน๋ฐํ
- ๊ทธ๋ฐ ๋ณ์๊ฐ ์๋ค๋ฉด Raise ValueError
tf.variable_scope()
- tf.get_variable_scope().reuse_variables()๋ฅผ ํธ์ถํด ํ์ฌ variable scope์ reuse ํ๋๊ทธ๋ฅผ True๋ก ์ค์ ํ ์ ์์ (reuse ํ๋๊ทธ๋ ํด๋น variable scope์ ๋ณ์๋ค์ ์ฌ์ฌ์ฉ(๊ณต์ ) ์ฌ๋ถ๋ฅผ ๋ํ๋)
- ๊ทธ๋ฌ๋ reuse ํ๋๊ทธ๋ฅผ False๋ก ์ค์ ํ ์๋ ์์
์ด์ :
์ด์ ๋ ๋ชจ๋ธ์ ์์ฑํ๋ ํจ์๋ฅผ ๊ตฌ์ฑํ๋ ๊ฒ์ ํ์ฉํ๊ธฐ ์ํด์์ ๋๋ค. ์ด์ ์ฒ๋ผmy_image_filter(inputs) ํจ์๋ฅผ ์์ฑํ๋ค๊ณ ์์ํด๋ณด์ญ์์ค. ๋ณ์ ๋ฒ์์์ reuse=True์ ํจ๊ป ํจ์๋ฅผ ํธ์ถํ๋ ๋๊ตฐ๊ฐ๋ ๋ชจ๋ ๋ด๋ถ ๋ณ์๊ฐ ์ฌ์ฌ์ฉ ๋ ๊ฒ์ผ๋ก ์์ํฉ๋๋ค. ํจ์ ๋ด๋ถ์์ reuse=False๋ฅผ ๊ฐ์ ๋ก ํ์ฉํ๋ฉด ์ด ๊ณ์ฝ์ด ๊นจ์ง๊ฒ ๋๊ณ , ์ด๋ฐ ๋ฐฉ๋ฒ์ผ๋ก ํ๋ผ๋ฏธํฐ๋ฅผ ๊ณต์ ํ๋ ๊ฒ์ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.
- ์์ variable scope์ reuse ํ๋๊ทธ๊ฐ True์ด๋ฉด ํ์ variable scope์ reuse ํ๋๊ทธ๋ True๊ฐ ๋จ (sub-scope๋ก reuse๊ฐ ์์๋๋ค๊ณ ์๊ฐํ ์ ์์)
- reuse ํ๋๊ทธ๊ฐ True์ธ variable scope๋ฅผ ์ข ๋ฃํ์ฌ reuse ํ๋๊ทธ๊ฐ False์ธ variable scope๋ก ๋๊ฐ ์ ์์
with tf.variable_Scope("root"):
assert tf.get_variable_scope().reuse == False
with tf.variable_scope("foo"):
assert tf.get_variable_scope().reuse == False
with tf.variable_scope("foo", reuse=True):
assert tf.get_variable_scope().reuse == True
with tf.variable_scope("bar"):
assert tf.get_variable_scope().reuse == True
assert tf.get_variable_scope().reuse == False
- with ... as ... ๋ฅผ ์ด์ฉํด variable scope๋ฅผ ์บก์ฒํด๋๊ณ ์ดํ์ ์ฌ์ฉํ ์ ์์
with tf.variable_scope("foo") as foo_scope:
assert foo_scope.name == "foo"
with tf.variable_scope("bar"):
with tf.variable_scope("baz") as other_scope:
assert other_scope.name == "bar/baz"
# Attend here #
with tf.variable_scope(foo_scope) as foo_scope2:
assert foo_scope2.name == "foo"
- variable scope ์์ฒด์ initializer๋ฅผ ์ค์ ํด ๊ทธ ์๋์ ์์ฑํ ๋ณ์๋ค์ initializer๋ฅผ ํ ๋ฒ์ ์ค์ ํด์ค ์ ์์ (๊ทธ๋ฌ๋ tf.get_variable()์ initializer๋ฅผ ๋ช ์ํ๋ฉด ์ค๋ฒ๋ผ์ด๋๋จ)
with tf.variable_Scope("foo", initializer=tf.constant_initializer(0.4)):
v = tf.get_variable("v", [1])
assert v.eval() == 0.4 # Default initializer
w = tf.get_variable("w", [1], initializer=tf.constant_initializer(0.3)):
assert w.eval() == 0.3 # Specific initializer
with tf.variable_scope("bar"):
v = tf.get_variable("v", [1])
assert v.eval() == 0.4 # Inherited default initializer
with tf.variable_scope("baz", initializer=tf.constant_initializer(0.2)):
v = tf.get_variable("v", [1])
assert v.eval() == 0.2 # Changed default initializer
์์
Incorrect example
def my_image_filter(input_images):
# conv1
conv1_weights = tf.Variable(tf.random_normal([5, 5, 32, 32]),
name="conv1_weights")
conv1_biases = tf.Variable(tf.zeros([32]), name="conv1_biases")
conv1 = tf.nn.conv2d(input_images, conv1_weights,
strides=[1, 1, 1, 1], padding='SAME')
relu1 = tf.nn.relu(conv1 + conv1_biases)
# conv2
conv2_weights = tf.Variable(tf.random_normal([5, 5, 32, 32]),
name="conv2_weights")
conv2_biases = tf.Variable(tf.zeros([32]), name="conv2_biases")
conv2 = tf.nn.conv2d(relu1, conv2_weights,
strides=[1, 1, 1, 1], padding='SAME')
relu1 = tf.nn.relu(conv2 + conv2_biases)
# Apply 2 images to my_image_filter
result1 = my_image_filter(image1)
result2 = my_image_filter(image2)
โ ์๋ชป๋ ์ด์ : image1๊ณผ image2๋ฅผ my_image_filter์ ์ ์ฉํ ๋ ๊ฐ์ ๋ณ์ ์ธํธ๋ฅผ ๊ณต์ ํด์ผ ํ๋๋ฐ ๋ณ์ ์ธํธ๊ฐ ๊ฐ๊ฐ ์์ฑ๋จ (์๋ฌ๊ฐ ๋๋ ๊ฑด ์๋์ง๋ง ์๋์ ๋ง์ง ์์)
Correct example
def conv_relu(input, kernel_shape, bias_shape):
# Create variable named "weights"
weights = tf.get_variable("weights", kernel_shape,
initializer=tf.random_normal_initializer())
# Create variable named "biases"
biases = tf.get_variable("biases", bias_shape,
initializer=tf.constant_initializer(0.0))
conv = tf.nn.conv2d(input, wegiths, strides=[1, 1, 1, 1], padding='SAME')
return tf.nn.relu(conv + biases)
def my_image_filter(input_images):
with tf.variable_scope("conv1"):
# Variables created here will be named "conv1/weights", "conv1/biases"
relu1 = conv_relu(input_images, [5, 5, 32, 32], [32])
with tf.variable_scope("conv2"):
# Variables created here will be named "conv2/weights", "conv2/biases"
return conv_relu(relu1, [5, 5, 32, 32], [32])
# Raises ValueError
result1 = my_image_filter(image1)
result2 = my_image_filter(image2)
# Use this instead
with tf.variable_scope("image_filters") as scope:
result1 = my_image_filter(image1)
scope.reuse_variables()
result2 = my_image_filter(image2)
my_image_filter ๊ตฌ์กฐ๋ conv1 + relu1 + conv2 + relu2 ์ธ๋ฐ ์ฌ๊ธฐ์ (conv + relu) ์ธํธ๊ฐ ๋ ๊ฐ ์๋ค๊ณ ์๊ฐํ์ฌ conv_relu() ๋ชจ๋์ ๋ง๋ ๊ฒ์ด๋ค. conv_relu() ๋ด๋ถ์์ weights์ biases๋ผ๋ ์ด๋ฆ์ ๋ณ์๋ฅผ tf.get_variable()๋ก ๊ฐ์ ธ์๋ค. ๊ทธ๋ฌ๋ conv1๊ณผ conv2๋ ์๋ก ๋ค๋ฅธ ๊ฐ์ weights์ biases๋ฅผ ๊ฐ์ ธ์ผ ํ๊ธฐ ๋๋ฌธ์ tf.variable_scope()๋ฅผ ์ด์ฉํด ๊ฐ๊ฐ conv1/weights, conv1/biases, conv2/weights, conv2/biases๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ ์ด๋ฏธ์ง image1, image2์ ๋ํ์ฌ my_image_filter๋ฅผ ์ ์ฉํ ๋๋ conv1/weights, conv1/biases, conv2/weights, conv2/biases๊ฐ (๋ ์ด๋ฏธ์ง์ ๋ํ์ฌ) ๊ณต์ ๋๋ ๊ฐ์ด์ด์ผ ํ๋ค. ๊ทธ๋ฌ๋ ์ด๋ฐ ์๋๋ฅผ ๊ฐ์ง๊ณ ๊ทธ๋ฅ my_image_filter๋ฅผ ๋ ๋ฒ ๋๋ ค๋ฒ๋ฆฌ๋ฉด ValueError(... conv1/weights already exists ...)๊ฐ ๋๋ค. ์ฆ ๋ณ์๊ฐ ์ฐ์ฐํ ๊ณต์ ๋ ๊ฒ์ธ์ง๋ฅผ ํ์ธํ๋ ๊ฒ์ด๋ค. ๋ณ์๋ฅผ ๊ณต์ ํ๋ ค๋ฉด reuse_variables()๋ฅผ ์ด์ฉํด ๋ณ์๋ฅผ ์ฌ์ฌ์ฉํ ๊ฒ์์ ๋ช ์ํด์ผ ํ๋ค.
'๋จธ์ ๋ฌ๋, ๋ฅ๋ฌ๋ > OCR' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
TF Guide - Tensors ๊ณต๋ถ (0) | 2019.08.19 |
---|---|
Multi-GPU Model์์ h5(hdf5)๋ฅผ ๋ก๋ํ์ง ๋ชปํ๋ ๋ฌธ์ (0) | 2019.08.13 |
Attention ๊ณต๋ถ (0) | 2019.08.12 |
Attention Is All You Need ๊ณต๋ถ (0) | 2019.08.09 |
ResNet ๊ณต๋ถ (0) | 2019.07.31 |
๋๊ธ