tensorflow2x

tensorflow (version 2.x)

ํ…์„œํ”Œ๋กœ 2.x์˜ ์ดํ•ด

: ํ…์„œํ”Œ๋กœ 2.x๋Š” ์ผ€๋ผ์Šค(keras)์™€ ๊ฐ™์€ ํ•˜์ด ๋ ˆ๋ฒจ API๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•˜๋ฉฐ, ๋‚ด๋ถ€์˜ ์„ธ๋ถ€์ •๋ณด๋ฅผ ๋” ๋งŽ์ด ์ œ์–ดํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ํ…์„œํ”„๋กค 1.x์ธ ๋กœ์šฐ๋ ˆ๋ฒจ API๋ฅผ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•œ๋‹ค

์ฆ‰์‹œ ์‹คํ–‰ (eager execution)

: ํ…์„œ ํ”Œ๋กœ 2.x์€ ํ…์„œํ”Œ๋กœ 1.x์˜ ์ •์  ๊ณ„์‚ฐ ๊ทธ๋ž˜ํ”„๋ฅผ ์ •์˜ํ•œ๊ฒƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ, ํŠน๋ณ„ํ•œ ์„ธ์…˜ ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ํ”Œ๋ ˆ์ด์Šค ํ™€๋” ์—…์ด๋„ ๋…ธ๋“œ๋ฅผ ์ฆ‰์‹œ ์ •์˜, ๋ณ€๊ฒฝ, ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๊ฒƒ์ด ๋ฐ”๋กœ ์ฆ‰์‹œ ์‹คํ–‰์ด๋‹ค . ์ฆ‰, ๋ชจ๋ธ ์ •์˜๊ฐ€ ๋™์ ์ด๊ณ  ์‹คํ–‰์ด ์ฆ‰์‹œ ์ด๋ค„์ง„๋‹ค, ๊ทธ๋ž˜ํ”„์™€ ์„ธ์…˜์€ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์œผ๋กœ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค

์˜คํ† ๊ทธ๋ž˜ํ”„(AutoGraph)

: ํ…์„œ ํ”Œ๋กœ 2.x์€ ๊ธฐ๋ณธ์ ์œผ๋กœ if-while, print()๊ณผ ๊ฐ™์ด ๊ธฐ๋ณธ ํŠน์ง•๊ณผ ๊ฐ™์€ ์ œ์–ดํ๋ฆ„์„ ํฌํ•จํ•ด ๋ช…๋ นํ˜• ํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ ์ง€์›ํ•˜์—ฌ, ํˆฌ๋ช…ํ•˜๊ณ  ์—ญ๋™์ ์ด๋ฉฐ ์ฆ‰์‹œ ์‹คํ–‰ ํŒŒ์ด์ฌ ํ˜•์‹ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ํšจ์œจ์ ์ธ ๊ทธ๋ž˜ํ”„ ๊ณ„์‚ฐ์„ ํ†ตํ•ด ๋‘์„ธ๊ณ„๋ฅผ ๋ชจ๋‘ ํ™œ์šฉํ•˜๋Š” ์—ฐ๊ฒฐ๊ณ ๋ฆฌ๋ฅผ ๋งŒ๋“ ๋‹ค

  • ์˜คํ†  ๊ทธ๋ž˜ํ”„ ์‚ฌ์šฉ๋ฐฉ๋ฒ•

    : ํŒŒ์ด์ฌ ์ฝ”๋“œ์— ํŠน์ • ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(decorator) tf.function์„ ์–ด๋…ธ๋ฐ์ด์…˜(annotation)์ฒ˜๋Ÿผ ์จ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด๋œ๋‹ค.

import tensorflow as tf

def linear_layer(x):
  return 3 * x + 2

@tf.function
def simple_nn(x):
  return tf.nn.relu(linear_layer(x))

def simple_function(x):
    return 3*x
  • simple_nn์„ ์‚ดํŽด๋ณด๋ฉด ํ…์„œํ”Œ๋กœ ๋‚ด๋ถ€์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ํŠน์ˆ˜ ํ•ธ๋“ค๋ผ๋Š” ๊ฒƒ์„ ์•Œ์ˆ˜ ์žˆ์œผ๋ฉฐ, simple_function์€ ์ผ๋ฐ˜ ํŒŒ์ด์ฌ ํ•ธ๋“ค๋Ÿฌ๋‹ค.

  • tf.function์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ํ•˜๋‚˜์˜ ์ฃผ ํ•จ์ˆ˜์—๋งŒ ์–ด๋…ธํ…Œ์ด์…˜์„ ๋‹ฌ๋ฉด ๊ฑฐ๊ธฐ์—์„œ ํ˜ธ์ถœ๋œ ๋‹ค๋ฅธ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” ์ž๋™์œผ๋กœ ํˆฌ๋ช…ํ•˜๊ฒŒ ์ตœ์ ํ™”๋œ ๊ณ„์‚ฐ ๊ทธ๋ž˜ํ”„๋กœ ๋ณ€ํ™˜๋œ๋‹ค

import  tensorflow as tf
import timeit

cell = tf.keras.layers.LSTMCell(100)

@tf.function
def fn(input, state):
    return cell(input, state)

input = tf.zeros([100, 100])
state = [tf.zeros([100, 100])] * 2
# warmup
cell(input, state)
fn(input, state)

graph_time = timeit.timeit(lambda: cell(input, state), number=100)
auto_graph_time = timeit.timeit(lambda: fn(input, state), number=100)
print('graph_time:', graph_time)
print('auto_graph_time:', auto_graph_time)
graph_time: 0.09712530000000008
auto_graph_time: 0.0456865999999998

์ผ€๋ผ์Šค API : 3๊ฐ€์ง€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ

  • ์ผ€๋ผ์Šค๋Š” ์ˆœ์ฐจ์  API, ํ•จ์ˆ˜์  API, ๋ชจ๋ธ ์„œ๋ธŒํด๋ž˜์‹ฑ์˜ ์„ธ๊ฐ€์ง€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ๊ณผ ํ•จ๊ป˜ ๋” ํ•˜์ด๋ ˆ๋ฒจ API๋ฅผ ์ œ๊ณตํ•œ๋‹ค

์ˆœ์ฐจ์ (Sequentail) API

  • ์ˆœ์ฐจ์  API๋Š” 90%์˜ ์‚ฌ๋ก€์— ์ ํ•ฉํ•œ ๋งค์šฐ ์šฐ์•„ํ•˜๊ณ  ์ง๊ด€์ ์ด๋ฉฐ ๊ฐ„๊ฒฐํ•œ ๋ชจ๋ธ์ด๋‹ค.

tf.keras.utils.plot_model(model, to_file="model.png")
sequentialAPI

ํ•จ์ˆ˜์ (function) API

  • ํ•จ์ˆ˜์  API๋Š” ๋‹ค์ค‘ ์ž…๋ ฅ, ๋‹ค์ค‘ ์ถœ๋ ฅ, ๋น„์ˆœ์ฐจ ํ๋ฆ„๊ณผ์˜ ์ž”์กด ์—ฐ๊ฒฐ, ๊ณต์œ , ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๊ณ„์ธต์„ ํฌํ•จํ•ด ์ข€๋” ๋ณต์žกํ•œ(๋น„์„ ํ˜•) ์œ„์ƒ(topology)์œผ๋กœ ๋ชจ๋ธ์„ ๊ตฌ์ถ•ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•˜๋‹ค

  • ๊ฐ ๊ณ„์ธต์€ ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•˜๊ณ (์ž…๋ ฅ์€ ํ…์„œ) ๊ฐ ๊ณ„์ธต์€ ํ…์„œ๋ฅผ ์ถœ๋ ฅ์œผ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

  • ๋‘๊ฐœ์˜ ๊ฐœ๋ณ„ ์ž…๋ ฅ, ๋‘ ๊ฐœ์˜ ๊ฐœ๋ณ„ ๋กœ์ง€์Šคํ‹ฑ ํšŒ๊ท€๋ฅผ ์ถœ๋ ฅ์œผ๋กœ, ํ•˜๋‚˜์˜ ๊ณต์œ  ๋ชจ๋“ˆ์„ ์ค‘๊ฐ„์— ๊ฐ–๋Š” ์˜ˆ์ œ

import tensorflow as tf

def build_model():
    # ๊ฐ€๋ณ€ ๊ธธ์ด ์ •์ˆ˜์˜ ์‹œํ€€์Šค
    text_input_a = tf.keras.Input(shape=(None,), dtype='int32')

    # ๊ฐ€๋ณ€ ๊ธธ์ด ์ •์ˆ˜์˜ ์‹œํ€€์Šค
    text_input_b = tf.keras.Input(shape=(None,), dtype='int32')

    # 1000๊ฐœ์˜ ๊ณ ์œ  ๋‹จ์–ด๋ฅผ 128์ฐจ์› ๋ฒกํ„ฐ์— ๋งคํ•‘ํ•ด์„œ ์ž„๋ฒ ๋”ฉ
    shared_embedding = tf.keras.layers.Embedding(1000, 128)

    # ์–‘์ชฝ ์ž…๋ ฅ์„ ์ธ์ฝ”๋”ฉํ•˜๊ณ ์ž ๋™์ผํ•œ ๊ณ„์ธต ์žฌ์‚ฌ์šฉ
    encoded_input_a = shared_embedding(text_input_a)
    encoded_input_b = shared_embedding(text_input_b)

    # ์ตœ์ข…์ ์œผ๋กœ 2๊ฐœ์˜ ๋กœ์ง€์Šคํ‹ฑ ์˜ˆ์ธก
    prediction_a = tf.keras.layers.Dense(1, activation='sigmoid', name='prediction_a')(encoded_input_a)
    prediction_b = tf.keras.layers.Dense(1, activation='sigmoid', name='prediction_b')(encoded_input_b)

    # 2๊ฐœ์˜ ์ž…๋ ฅ๊ณผ 2๊ฐœ์˜ ์ถœ๋ ฅ
    # ๊ฐ€์šด๋ฐ๋Š” ๋ชจ๋ธ์ด ์žˆ๋‹ค.
    model = tf.keras.Model(inputs=[text_input_a, text_input_b], 
    outputs=[prediction_a, prediction_b])

    tf.keras.utils.plot_model(model, to_file="shared_model.png")

build_model()
  • ๋น„์„ ํ˜• ์œ„์ƒ์˜ ์˜ˆ

functionAPI

๋ชจ๋ธ ์„œ๋ธŒํด๋ž˜์‹ฑ

  • ๋ชจ๋ธ ์„œ๋ธŒํด๋ž˜์‹ฑ์€ ์ตœ๊ณ ์˜ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•˜๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ์ž์‹ ์˜ ๊ณ„์ธต์„ ์ •์˜ํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ. ๋น„์œ ํ•˜์ž๋ฉด ํ‘œ์ค€์ ์ด๊ณ  ์ž˜ ์•Œ๋ ค์ง„ ๋ ˆ๊ณ  ๋ธ”๋ก์„ ๊ตฌ์„ฑํ•˜๋Š” ๋Œ€์‹  ์ž์‹ ๋งŒ์˜ ๋ ˆ๊ณ  ๋ธ”๋ก์„ ๋งŒ๋“ค๊ณ ์ž ํ• ๋•Œ ์œ ์šฉ

  • init : ์„ ํƒ์ ์œผ๋กœ ์ด ๊ณ„์ธต์—์„œ ์‚ฌ์šฉํ•  ๋ชจ๋“  ํ•˜์œ„ ๊ณ„์ธต์„ ์ •์˜ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ, ๋ชจ๋ธ ์„ ์–ธ์„ ํ• ๋•Œ๋Š” ์ƒ์„ฑ์ž๋‹ค

  • build : ๊ฒŒ์ธต์˜ ๊ฐ€์ค‘์น˜๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ, dd_weight()๋กœ ๊ฐ€์ค‘์น˜๋ฅผ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋‹ค

  • call : ์ˆœ๋ฐ˜ํ–ฅ ์ „๋‹ฌ ์ •์˜, ๊ณ„์ธต์ด ํ˜ธ์ถœ๋˜๊ณ  ํ•จ์ˆ˜ ํ˜•์‹์œผ๋กœ ์ฒด์ธ๋˜๋Š” ๊ณณ์ด๋‹ค

  • ์„ ํƒ์ ์œผ๋กœ get_config()๋ฅผ ์‚ฌ์šฉํ•ด ๊ฒŒ์ธต์„ ์ง๋ ฌํ™”(serialize)ํ•  ์ˆ˜ ์žˆ๊ณ , from_config()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ญ์งˆ๋ ฌํ™”(deserialize)ํ•  ์ˆ˜ ์žˆ๋‹ค

์ฝœ๋ฐฑ (callback)

: ์ฝœ๋ฐฑ์€ ํ›ˆ๋ จ ์ค‘์— ๋…์ž‘์„ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜๊ณ ์ž ๋ชจ๋ธ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฐ์ฒด

  • ModelCheckPoint : ์ •๊ธฐ์ ์œผ๋กœ ๋ชจ๋ธ์˜ ์ฒดํฌ ํฌ์ธํŠธ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ๋ณต๊ตฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉ

  • LearningRateScheduler : ์ตœ์ ํ™”ํ•˜๋Š” ๋™์•ˆ ํ•™์Šต๋ฅ ์„ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ๋•Œ ์‚ฌ์šฉ

  • EarlyStopping : ๊ฒ€์ฆ ์„ฑ๋Šฅ์ด ํ•œ๋™์•ˆ ๊ฐœ์„ ๋˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ํ›ˆ๋ จ์„ ์ค‘๋‹จํ•  ๋•Œ ์‚ฌ์šฉ

  • TensorBoard : ํ…์„œ๋ณด๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๋ชจ๋ธ์˜ ํ–‰๋™์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•  ๋•Œ ์‚ฌ์šฉ

๋ชจ๋ธ๊ณผ ๊ฐ€์ค‘์น˜ ์ €์žฅ

  • ๊ฐ€์ค‘์น˜๋ฅผ ํ…์„œํ”Œ๋กœ ์ฒดํฌํฌ์ธํŠธ ํŒŒ์ผ๋กœ ์ €์žฅ

model.save_weight('./weigth/model') # ์ €์žฅ
model.load_weight(file_path) # ๋ณต์›
  • ๊ฐ€์ค‘์น˜ ์ด์™ธ์˜ ๋ชจ๋ธ์€ JSON ํ˜•์‹์œผ๋กœ ์ง๋ ฌํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค

json_string = model.to_json() # ์ €์žฅ
model = tf.keras.model_from_json(json_string) # ๋ณต์›
  • YAML์œผ๋กœ ์ง๋ ฌํ™”

yaml_string = model.to_yaml() # ์ €์žฅ
model = tf.keras.model_from_yaml(yaml_string) # ๋ณต์›
  • ๋ชจ๋ธ์„ ๊ฐ€์ค‘์น˜์™€ ์ตœ์ ํ™” ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ํ•จ๊ป˜ ์ €์žฅ

model.save('model.hs') # ์ €์žฅ
model = tf.keras.models.load_model('model.hs') # ๋ณต์›

๋ฐ์ดํ„ฐ์…‹ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • ์ƒ์„ฑ

    • from_tensor_slices() : ๊ฐœ๋ณ„(๋˜๋Š” ๋‹ค์ค‘) ๋„˜ํŒŒ์ด(๋˜๋Š” ํ…์„œ)๋ฅผ ๋ฐ›๊ณ  ๋ฐฐ์น˜๋ฅผ ์ง€์›

    • from_tensor() : 1๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ๋ฐฐ์น˜๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค

    • from_generator() : ์ƒ์„ฑ์ž ํ•จ์ˆ˜์—์„œ ์ž…๋ ฅ์„ ์ทจํ•œ๋‹ค

  • ๋ณ€ํ™˜

    • batch() : ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ์…‹์„ ์ง€์ •ํ•œ ํฌ๊ธฐ๋กœ ๋ถ„ํ• 

    • repeat() : ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์ œ

    • shuffle() : ๋ฐ์ดํ„ฐ๋ฅผ ๋ฌด์ž‘์œ„๋กœ ์„ž๋Š”๋‹ค

    • map() : ๋ฐ์ดํ„ฐ์— ํ•จ์ˆ˜๋ฅผ ์ ์šฉ

    • filter() : ๋ฐ์ดํ„ฐ๋ฅผ ๊ฑฐ๋ฅด๊ณ ์ž ํ•จ์ˆ˜๋ฅผ ์ ์š”

  • ๋ฐ˜๋ณต

    • next_batch = iterator.get_next()

Last updated

Was this helpful?