AutoGraph - lshhhhh/deep-learning-study GitHub Wiki

Why do we need graphs in TensorFlow?

  • ์„ฑ๋Šฅ: (๊ณตํ†ต์˜ sub-expressions์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜, pruning, kernel fusing์„ ํ•˜๋Š” ๋“ฑ์˜) ๋ชจ๋“  ์ข…๋ฅ˜์˜ ์ตœ์ ํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.
  • ์ด์‹์„ฑ(portability): ๊ณ„์‚ฐ์— ๋Œ€ํ•œ platform-independent ๋ชจ๋ธ์„ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์—, distributed training๊ณผ ๋ชจ๋“  ์ข…๋ฅ˜์˜ ํ™˜๊ฒฝ์—์„œ์˜ deployment๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•œ๋‹ค.

    multiple GPU๋‚˜ TPU์—์„œ์˜ distributed training
    TensorFlow Lite๋ฅผ ์ด์šฉํ•˜์—ฌ mobile์ด๋‚˜ IoT๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ platform์—์„œ ๋ชจ๋ธ์„ deploy

TensorFlow Functions and Graphs

TF 1.x์—์„œ๋Š” session.run์„ ํ†ตํ•ด ์ž…๋ ฅ๊ณผ ํ•จ์ˆ˜๋ฅผ ์ง€์ •ํ•˜์—ฌ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์˜€๋‹ค. TF 2.0์—์„œ๋Š” ์„ธ์…˜ ๋Œ€์‹  tf.function()๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด TF๊ฐ€ ์ด ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜์˜ ๊ทธ๋ž˜ํ”„๋กœ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด JIT ์ปดํŒŒ์ผ์„ ํ•œ๋‹ค. ์ด ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•๋ถ„์— TF 2.0์—์„œ default ๋ชจ๋“œ๊ฐ€ ๊ทธ๋ž˜ํ”„ ๋ชจ๋“œ๊ฐ€ ์•„๋‹Œ eager ๋ชจ๋“œ์ด์ง€๋งŒ, ๊ทธ๋ž˜ํ”„์˜ ์žฅ์ ์„ ๋ชจ๋‘ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์—ˆ๋‹ค. (Eager Execution for Faster Prototyping, Graph for Execution)

# TF 1.x
outputs = session.run(f(placeholder), feed_dict={placeholder: input})
# TF 2.0
outputs = f(input)

๋จผ์ € Python function -> TensorFlow function ๋ณ€ํ™˜์„ ํ•ด๋ณด์ž.

def cube(x):
    return x ** 3
>>> cube(2)
8
>>> cube(tf.constant(2.0))
<tf.Tensor: id=18634148, shape=(), dtype=float32, numpy=8.0>

>>> tf_cube = tf.function(cube)
>>> tf_cube
<tensorflow.python.eager.def_function.Function at 0x1546fc080>
>>> tf_cube(2)
<tf.Tensor: id=18634201, shape=(), dtype=int32, numpy=8>
>>> tf_cube(tf.constant(2.0))
<tf.Tensor: id=18634211, shape=(), dtype=float32, numpy=8.0>

๋” ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” tf.function decorator๋ฅผ ์จ์„œ ๋งŒ๋“ ๋‹ค.

@tf.function
def tf_cube(x):
    return x ** 3

TF function์—์„œ ๋ณธ๋ž˜์˜ python function๋„ ์‰ฝ๊ฒŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

>>> tf_cube.python_function(2)
8
  1. Python ํ•จ์ˆ˜์— ๋Œ€ํ•˜์—ฌ computation graph, ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” node๋“ค pruning, expressions์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ(e.g., 1 + 2 -> 3).. ๋“ฑ๋“ฑ์„ ์ตœ์ ํ™”ํ•œ๋‹ค.
  2. ์ตœ์ ํ™”๋œ graph๊ฐ€ ์ค€๋น„๋˜๋ฉด, TF ํ•จ์ˆ˜๋Š” graph์—์„œ ์ ์ ˆํ•œ ์ˆœ์„œ๋กœ, ๋ณ‘๋ ฌ ์ˆ˜ํ–‰์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋ณ‘๋ ฌ๋กœ๋„, ํšจ์œจ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ ๊ธฐ์กด์˜ Python ํ•จ์ˆ˜์— ๋น„ํ•ด ๋งŽ์ด ๋นจ๋ผ์ง€๊ณ , ํŠนํžˆ ๋ณต์žกํ•œ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ๋” ์œ ์šฉํ•˜๋‹ค. Python ํ•จ์ˆ˜๋ฅผ boostํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด TF function์œผ๋กœ ๋ฐ”๊ฟ”๋ณด์ž.

AutoGraph and Tracing

Module: tf.autograph

ํ…์„œํ”Œ๋กœ๋Š” Python ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ ์—†๋Š” ๋ชจ๋ฐ”์ผ, C++, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ™์€ ํ™˜๊ฒฝ์—์„œ๋„ ์‹คํ–‰๋˜๋Š”๋ฐ, ์‚ฌ์šฉ์ž๊ฐ€ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์ฝ”๋“œ๋ฅผ ์žฌ์ž‘์„ฑํ•˜์ง€ ์•Š๋„๋ก @tf.function๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด AutoGraph๊ฐ€ ํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ ๋™์ผํ•œ ํ…์„œํ”Œ๋กœ ๊ทธ๋ž˜ํ”„ ์ฝ”๋“œ๋กœ ๋ณ€๊ฒฝํ•จ์œผ๋กœ์จ ๊ฐ€๋Šฅํ•œ ์ผ์ด๋‹ค.

TF 2.0์—์„œ AutoGraph๋Š” tf.function์ด ์‚ฌ์šฉ๋˜๋ฉด ์ž๋™์œผ๋กœ ์ ์šฉ๋œ๋‹ค.

AutoGraph process

  1. ๋จผ์ €, ๋ชจ๋“  control flow statement (for, if, while, break, continue, return)๋ฅผ ์•Œ๊ธฐ ์œ„ํ•ด Python ํ•จ์ˆ˜๋ฅผ ๋ถ„์„ํ•œ๋‹ค. ํ•จ์ˆ˜ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•œ ํ›„์—, autoGraph๋Š” control flow๋ฅผ ์ ์ ˆํ•œ TF operation์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ๋œ ํ•จ์ˆ˜๋ฅผ output์œผ๋กœ ๋‚ด๋ณด๋‚ธ๋‹ค.
    • for/while -> tf.while_loop (break๊ณผ continue ๋ฌธ ์ง€์›)
    • if -> tf.cond
    • for _ in dataset -> dataset.reduce
  2. ๋‹ค์Œ์œผ๋กœ๋Š” TF๋Š” ์ด ์—…๊ทธ๋ ˆ์ด๋“œ๋œ ํ•จ์ˆ˜๋ฅผ callํ•˜๋Š”๋ฐ, argument๋ฅผ passํ•˜๋Š” ๋Œ€์‹ , symbolic tensor(์‹ค์ œ ๊ฐ’์€ ์—†๊ณ , ์ด๋ฆ„๊ณผ data type, shape๋งŒ ๋“ค์–ด์žˆ๋Š” tensor)๋ฅผ passํ•œ๋‹ค.
  3. ์ด TF ํ•จ์ˆ˜๋ฅผ tracingํ•˜์—ฌ ๊ทธ๋ž˜ํ”„๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค.

์ด์ œ ์ด ํ•จ์ˆ˜๋Š” ๊ทธ๋ž˜ํ”„ ๋ชจ๋“œ๋กœ ์‹คํ–‰๋œ๋‹ค.

AutoGraph๋Š” ์ž„์˜์˜ ์ค‘์ฒฉ๋œ control flow๋„ ์ง€์›ํ•œ๋‹ค. ์‹œํ€€์Šค(sequence) ๋ชจ๋ธ, ๊ฐ•ํ™” ํ•™์Šต, ๋…์ž์ ์ธ ํ›ˆ๋ จ ๋ฃจํ”„ ๋“ฑ ๋ณต์žกํ•œ ๋จธ์‹ ๋Ÿฌ๋‹ ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐ„๊ฒฐํ•˜๋ฉด์„œ ๋†’์€ ์„ฑ๋Šฅ์„ ๋‚ด๋„๋ก ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.