ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • โœฑ ํ•ธ์ฆˆ์˜จ ๋จธ์‹ ๋Ÿฌ๋‹ 17์žฅ ์˜คํ† ์ธ์ฝ”๋”, GAN ๊ทธ๋ฆฌ๊ณ  ํ™•์‚ฐ ๋ชจ๋ธ โœฑ
    ๐Ÿฎ ์ด๊ฒƒ์ €๊ฒƒ ๊ณต๋ถ€/โœฉ ํ•ธ์ฆˆ์˜จ ๋จธ์‹ ๋Ÿฌ๋‹ 2026. 2. 5. 21:38

    ์˜คํ† ์ธ์ฝ”๋” : ์ง€๋„ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„(๋ ˆ์ด๋ธ”๋˜์–ด ์žˆ์ง€ ์•Š์€ ํ›ˆ๋ จ ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ) ์ž ์žฌ ํ‘œํ˜„ ๋˜๋Š” ์ฝ”๋”ฉ์ด๋ผ ๋ถ€๋ฅด๋Š” ์ž…๋ ฅ ๋ฐ์ดํ„ฐ์˜ ๋ฐ€์ง‘ ํ‘œํ˜„์„ ํ•™์Šตํ•  ์ˆ˜ ์žˆ๋Š” ์ธ๊ณต์‹ ๊ฒฝ๋ง์ด๋‹ค. 

    ์ฝ”๋”ฉ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ž…๋ ฅ๋ณด๋‹ค ํ›จ์”ฌ ๋‚ฎ์€ ์ฐจ์›์„ ๊ฐ€์ง„๋‹ค.

    ๋”ฐ๋ผ์„œ ์˜คํ† ์ธ์ฝ”๋”๋Š” ์ฐจ์› ์ถ•์†Œ, ํŠนํžˆ ์‹œ๊ฐํ™”์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค.

    ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ๊ฐ•๋ ฅํ•œ ํŠน์„ฑ ์ถ”์ถœ๊ธฐ์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜๋ฏ€๋กœ ์‹ฌ์ธต ์‹ ๊ฒฝ๋ง์˜ ๋น„์ง€๋„ ์‚ฌ์ „ ํ›ˆ๋ จ์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

    ์ƒ์„ฑ ๋ชจ๋ธ : ์ผ๋ถ€ ์˜คํ† ์ธ์ฝ”๋”๋Š” ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ์™€ ๋งค์šฐ ๋น„์Šทํ•œ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์˜ˆ) ์–ผ๊ตด ์‚ฌ์ง„์œผ๋กœ ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ํ›ˆ๋ จํ•˜๋ฉด ์ด ๋ชจ๋ธ์€ ์ƒˆ๋กœ์šด ์–ผ๊ตด์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

     

    ์ƒ์„ฑ์  ์ ๋Œ€ ์‹ ๊ฒฝ๋ง(GAN)๋„ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    ์ง€๊ธˆ ์ƒ์„ฑ ํ•™์Šต ๋ถ„์•ผ์—์„œ ์ฃผ๋ชฉํ•  ๋งŒํ•œ ๊ฒƒ์€ ํ™•์‚ฐ ๋ชจ๋ธ์ด๋‹ค. 

    GAN๋ณด๋‹ค ๋‹ค์–‘ํ•˜๊ณ  ๊ณ ํ’ˆ์งˆ์˜ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๋ฉด์„œ๋„ ํ›จ์”จ ใ„ด๋” ์‰ฝ๊ฒŒ ํ›ˆ๋ จํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์ง€๋งŒ ์‹คํ–‰ ์†๋„๊ฐ€ ํ›จ์”ฌ ๋А๋ฆฌ๋‹ค.

     

    ์˜คํ† ์ธ์ฝ”๋”, GAN, ํ™•์‚ฐ ๋ชจ๋ธ์€ ๋ชจ๋‘ ๋น„์ง€๋„ ํ•™์Šต์ด๋ฉฐ, ๋ชจ๋‘ ์ž ์žฌ ํ‘œํ˜„์„ ํ•™์Šตํ•˜๊ณ  ์ƒ์„ฑ ๋ชจ๋ธ๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

     

    ์˜คํ† ์ธ์ฝ”๋”๋Š” ๋‹จ์ˆœํžˆ ์ž…๋ ฅ์„ ์ถœ๋ ฅ์œผ๋กœ ๋ณต์‚ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šด๋‹ค.

    ๋„คํŠธ์›Œํฌ์— ์ œ์•ฝ์„ ๊ฐ€ํ•ด(์ž ์žฌ ํ‘œํ˜„ ํฌ๊ธฐ ์ œํ•œ, ์ž…๋ ฅ์— ์žก์Œ ์ถ”๊ฐ€ ๋“ฑ) ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ๋‹จ์ˆœํžˆ ์ž…๋ ฅ์„ ์ถœ๋ ฅ์œผ๋กœ ๋ฐ”๋กœ ๋ณต์‚ฌํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๊ฒŒ ํ•œ๋‹ค. 

    ์ฝ”๋”ฉ์€ ์ด์ • ์ œ์•ฝ ์กฐ๊ฑดํ•˜์—์„œ ํ•ญ๋“ฑ ํ•จ์ˆ˜๋ฅผ ํ•™์Šตํ•˜๋ ค๋Š” ์˜คํ† ์ธ์ฝ”๋”์˜ ๋…ธ๋ ฅ์œผ๋กœ ์ƒ๊ฒจ๋‚œ ๋ถ€์‚ฐ๋ฌผ์ด๋‹ค.

     

    GAN์€ ์‹ ๊ฒฝ๋ง ๋‘ ๊ฐœ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

    ์ƒ์„ฑ์ž๋Š” ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ์™€ ๋น„์Šทํ•˜๊ฒŒ ๋ณด์ด๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํŒ๋ณ„์ž๋Š” ๊ฐ€์งœ ๋ฐ์ดํ„ฐ์™€ ์ง„์งœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌ๋ณ„ํ•œ๋‹ค.

    ์ ๋Œ€์  ํ›ˆ๋ จ : ์ด ๊ตฌ์กฐ๋Š” ์‹ ๊ฒฝ๋ง์ด ํ›ˆ๋ จํ•˜๋Š” ๋™์•ˆ ์ƒ์„ฑ์ž์™€ ํŒ๋ณ„์ž๊ฐ€ ์„œ๋กœ ๊ฒฝ์Ÿํ•œ๋‹ค.

     

    ์žก์Œ ์ œ๊ฑฐ ํ™•์‚ฐ ๋ชจ๋ธ(DDPM)์€ ์ด๋ฏธ์ง€์—์„œ ์•„์ฃผ ์ž‘์€ ์žก์Œ์„ ์ œ๊ฑฐํ•˜๋„๋ก ํ›ˆ๋ จ๋œ๋‹ค.

    ๊ทธ ๋‹ค์Œ ๊ฐ€์šฐ์Šค ์žก์Œ์œผ๋กœ ๊ฐ€๋“์ฐฌ ์ด๋ฏธ์ง€์—์„œ ํ™•์‚ฐ ๋ชจ๋ธ์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰ํ•˜๋ฉด ํ›ˆ๋ จ ์ด๋ฏธ์ง€์™€ ์œ ์‚ฌํ•œ (ํ•˜์ง€๋งŒ ๋™์ผํ•˜์ง€ ์•Š์€) ๊ณ ํ’ˆ์งˆ ์ด๋ฏธ์ง€๊ฐ€ ์„œ์„œํžˆ ๋“œ๋Ÿฌ๋‚œ๋‹ค.


    17.1 ํšจ์œจ์ ์ธ ๋ฐ์ดํ„ฐ ํ‘œํ˜„

    ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์ž…๋ ฅ์„ ๋ฐ›์•„ ํšจ์œจ์ ์ธ ๋‚ด๋ถ€ ํ‘œํ˜„์œผ๋กœ ๋ฐ”๊พธ๊ณ  ์ž…๋ ฅ๊ณผ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์–ด๋–ค ๊ฒƒ์„ ์ถœ๋ ฅํ•œ๋‹ค.

    ์˜คํ† ์ธ์ฝ”๋”๋Š” ํ•ญ์ƒ ์ž…๋ ฅ์„ ๋‚ด๋ถ€ ํ‘œํ˜„์œผ๋กœ ๋ฐ”๊พธ๋Š” ์ธ์ฝ”๋”(์ธ์ง€ ๋„คํŠธ์›Œํฌ)์™€ ๋‚ด๋ถ€ ํ‘œํ˜„์„ ์ถœ๋ ฅ์œผ๋กœ ๋ฐ”๊พธ๋Š” ๋””์ฝ”๋”(์ƒ์„ฑ ๋„คํŠธ์›Œํฌ)์˜ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. 

    ์ถœ๋ ฅ ์ธต์˜ ๋‰ด๋Ÿฐ ์ˆ˜๊ฐ€ ์ž…๋ ฅ ๊ฐœ์ˆ˜์™€ ๋™์ผํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์ œ์™ธํ•˜๋ฉด ์ผ๋ฐ˜์ ์œผ๋กœ ์˜คํ† ์ธ์ฝ”๋”๋Š” ๋‹ค์ธต ํผ์…‰ํŠธ๋ก (MLP)์™€ ๊ตฌ์กฐ๊ฐ€ ๋™์ผํ•˜๋‹ค.

    ์œ„ ์‚ฌ์ง„์—์„œ๋Š” ๋‰ด๋Ÿฐ ๋‘ ๊ฐœ๋กœ ๊ตฌ์„ฑ๋œ ํ•˜๋‚˜์˜ ์€๋‹‰ ์ธต์ด ์žˆ๊ณ (์ธ์ฝ”๋”) ๋‰ด๋Ÿฐ ์„ธ ๊ฐœ๋กœ ๊ตฌ์„ฑ๋œ ์ถœ๋ ฅ ์ธต์ด ์žˆ๋‹ค.(๋””์ฝ”๋”)

    ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์ž…๋ ฅ์„ ์žฌ๊ตฌ์„ฑํ•˜๊ธฐ ๋–„๋ฌธ์— ์ถœ๋ ฅ์„ ์ข…์ข… ์žฌ๊ตฌ์„ฑ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

    ๋น„์šฉ ํ•จ์ˆ˜๋Š” ์žฌ๊ตฌ์„ฑ์ด ์ž…๋ ฅ๊ณผ ๋‹ค๋ฅผ ๋•Œ ๋ชจ๋ธ์— ๋ฒŒ์ ์„ ๋ถ€๊ณผํ•˜๋Š” ์žฌ๊ตฌ์„ฑ ์†์‹ค์„ ํฌํ•จํ•œ๋‹ค. 

     

    ๋‚ด๋ถ€์˜ ํ‘œํ˜„์ด ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ณด๋‹ค ์ €์ฐจ์›์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ณผ์†Œ์™„์ „์ด๋ผ๊ณ  ํ•œ๋‹ค. 

    ์ž…๋ ฅ์„ ์ฝ”๋”ฉ์œผ๋กœ ๊ฐ„๋‹จํžˆ ๋ณต์‚ฌํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ์ž…๋ ฅ๊ณผ ๋˜‘๊ฐ™์€ ๊ฒƒ์„ ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ํŠน์„ฑ์„ ํ•™์Šตํ•˜๋„๋ก ๋งŒ๋“ ๋‹ค. (์ค‘์š”ํ•˜์ง€ ์•Š์€ ๊ฒƒ์€ ๋ฒ„๋ฆฐ๋‹ค.)


    17.2 ๊ณผ์†Œ์™„์ „ ์„ ํ˜• ์˜คํ† ์ธ์ฝ”๋”๋กœ PCA ์ˆ˜ํ–‰ํ•˜๊ธฐ

    ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์„ ํ˜• ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ๋น„์šฉ ํ•จ์ˆ˜๊ฐ€ ํ‰๊ท  ์ œ๊ณฑ ์˜ค์ฐจ(MSE)๋ผ๋ฉด, ์ด๋Š” ๊ฒฐ๊ตญ ์ฃผ์„ฑ๋ถ„ ๋ถ„์„(PCA)๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

     

    import tensorflow as tf
    
    encoder = tf.keras.Sequential([tf.keras.layers.Dense(2)])
    decoder = tf.keras.Sequential([tf.keras.layers.dense(3)])
    autoencoder = tf.keras.Sequential([encoder, decoder])
    
    optimizer = tf.keras.optimizers.SGD(learning_rate=0.5)
    autoencoder.compile(loss="mse", optimizer=optimizer)

    3D ๋ฐ์ดํ„ฐ์…‹์— PCA๋ฅผ ์ ์šฉํ•ด 2D์— ํˆฌ์˜ํ•˜๋Š” ์„ ํ˜• ์˜คํ† ์ธ์ฝ”๋”์ด๋‹ค.

     

    ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ์ธ์ฝ”๋”์™€ ๋””์ฝ”๋” ๋‘ ๊ฐœ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌ์„ฑํ•œ๋‹ค. ๋‘˜ ๋‹ค ํ•˜๋‚˜์”ฉ Dense ์ธต์„ ๊ฐ€์ง„ ์ผ๋ฐ˜์ ์ธ Sequential ๋ชจ๋ธ์ด๋‹ค. ์˜คํ† ์ธ์ฝ”๋”๋Š” ์ธ์ฝ”๋” ๋‹ค์Œ์— ๋””์ฝ”๋”๊ฐ€ ๋’ค๋”ฐ๋ฅด๋Š” Sequential ๋ชจ๋ธ์ด๋‹ค.

    ์˜คํ† ์ธ์ฝ”๋”์˜ ์ถœ๋ ฅ ๊ฐœ์ˆ˜๊ฐ€ ์ž…๋ ฅ์˜ ๊ฐœ์ˆ˜์™€ ๋™์ผํ•˜๋‹ค. 

    PCA๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉฐ(๋ชจ๋“  ๋‰ด๋Ÿฐ์ด ์„ ํ˜•์ด๋‹ค.) ๋น„์šฉํ•จ์ˆ˜๋Š” MSE์ด๋‹ค. ← PCA๊ฐ€ ์„ ํ˜• ๋ณ€ํ™˜์ธ ์ด์œ 

     

    X_train = [...] # 3D ๋ฐ์ดํ„ฐ์…‹์„ ์ƒ์„ฑํ•œ๋‹ค.
    history = autoencoder.fit(X_train, X_train, epochs=500, verbose=False)
    codings = encoder.predict(X_train)

    ์ด ๋ชจ๋ธ์„ ๊ฐ€์ƒ์˜ 3D ๋ฐ์ดํ„ฐ์…‹์— ํ›ˆ๋ จํ•œ๋‹ค.

    ์ด ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด ๋™์ผํ•œ ๋ฐ์ดํ„ฐ์…‹์„ ์ธ์ฝ”๋”ฉํ•œ๋‹ค. (2D๋กœ ํˆฌ์˜ํ•œ๋‹ค.)

     

    X_train์ด ์ž…๋ ฅ๊ณผ ํƒ€๊นƒ์—๋„ ์‚ฌ์šฉ๋œ๋‹ค. 

    ์™ผ์ชฝ์€ ์›๋ณธ 3D ๋ฐ์ดํ„ฐ์…‹์ด๊ณ  ์˜ค๋ฅธ์ชฝ์€ ์˜คํ† ์ธ์ฝ”๋”์˜ ์€๋‹‰ ์ธต ์ถœ๋ ฅ(์ฝ”๋”ฉ ์ธต)์ด๋‹ค.

    ์˜คํ† ์ธ์ฝ”๋”๋Š” PCA์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ์— ์žˆ๋Š” ๋ถ„์‚ฐ์ด ๊ฐ€๋Šฅํ•œ ํ•œ ๋งŽ์ด ๋ณด์กด๋˜๋„๋ก ๋ฐ์ดํ„ฐ๋ฅผ ํˆฌ์˜ํ•  ์ตœ์ƒ์˜ 2D ํ‰๋ฉด์„ ์ฐพ๋Š”๋‹ค.


    17.3 ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”

    ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”(์‹ฌ์ธต ์˜คํ† ์ธ์ฝ”๋”) : ๋‹ค๋ฅธ ์‹ ๊ฒฝ๋ง๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์˜คํ† ์ธ์ฝ”๋”๋„ ์€๋‹‰ ์ธต์„ ์—ฌ๋Ÿฌ ๊ฐœ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. 

    ์ธต์„ ๋” ์ถ”๊ฐ€ํ•˜๋ฉด ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ๋” ๋ณต์žกํ•œ ์ฝ”๋”ฉ์„ ํ•™์Šตํ•  ์ˆ˜ ์žˆ๋‹ค. 

    ๊ทธ๋Ÿฌ๋‚˜ ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ๋„ˆ๋ฌด ๊ฐ•๋ ฅํ•ด์ง€์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ์žฌ๊ตฌ์„ฑํ•˜๊ฒ ์ง€๋งŒ ์ด ๊ณผ์ •์—์„œ ์œ ์šฉํ•œ ๋ฐ์ดํ„ฐ ํ‘œํ˜„์„ ํ•™์Šตํ•˜์ง„ ๋ชปํ•œ๋‹ค.

     

    ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”์˜ ๊ตฌ์กฐ๋Š” ์ „ํ˜•์ ์œผ๋กœ ๊ฐ€์šด๋ฐ ์€๋‹‰ ์ธต(์ฝ”๋”ฉ ์ธต)์„ ๊ธฐ์ค€์œผ๋กœ ๋Œ€์นญ์ด๋‹ค. 

    17.3.1 ์ผ€๋ผ์Šค๋กœ ์ ์ธต ์˜คํ† ์ธ์ฝ”๋” ๊ตฌํ˜„ํ•˜๊ธฐ

    stacked_encoder = tf.keras.Sequential([
        tf.keras.layers.Flatten().
        tf.keras.layers.Dense(100, activation="relu"),
        tf.keras.layers.Dense(30, activation="relu"),
    ])
    stacked_decoder = tf.keras.Sequential([
        tf.keras.layers.Dense(100, activation="relu"),
        tf.keras.layers.Dense(28 * 28),
        tf.keras.layers.Reshape([28, 28])
    ])
    stacked_ae = tf.keras.Sequential([stacked_encoder, stacked_decoder])
    
    stacked_ae.compile(loss="mse", optimizer="nadam")
    history = stacked_ae.fit(X_train, X_train, epochs=20,
                             validation_data=(X_valid, X_valid))

    ์ธ์ฝ”๋”๋Š” 28x28 ํ”ฝ์…€์˜ ํ‘๋ฐฑ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ›๋Š”๋‹ค. ๊ทธ๋‹ค์Œ ๊ฐ ์ด๋ฏธ์ง€๋ฅผ 784 ํฌ๊ธฐ์˜ ๋ฒกํ„ฐ๋กœ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ํŽผ์นœ๋‹ค. ์ด ๋ฒกํ„ฐ๋ฅผ ํฌ๊ธฐ๊ฐ€ ์ ์  ์ค„์–ด๋“œ๋Š” Dense ์ธต ๋‘ ๊ฐœ์— ํ†ต๊ณผ์‹œํ‚จ๋‹ค. ๋‘ ์ธต์€ ๋ชจ๋‘ ReLU ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๊ฐ ์ž…๋ ฅ ์ด๋ฏธ์ง€์— ๋Œ€ํ•ด ์ธ์ฝ”๋”๋Š” ํฌ๊ธฐ๊ฐ€ 30์ธ ๋ฒกํ„ฐ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. 

    ๋””์ฝ”๋”๋Š” ์ธ์ฝ”๋”๊ฐ€ ์ถœ๋ ฅํ•œ ํฌ๊ธฐ๊ฐ€ 30์ธ ์ฝ”๋”ฉ์„ ๋ฐ›๋Š”๋‹ค. ๊ทธ๋‹ค์Œ ํฌ๊ธฐ๊ฐ€ ์ ์  ์ปค์ง€๋Š” Dense ์ธต ๋‘ ๊ฐœ์— ํ†ต๊ณผ์‹œํ‚จ๋‹ค. ์ตœ์ข… ๋ฒกํ„ฐ๋ฅผ 28x28 ๋ฐฐ์—ด๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ๋””์ฝ”๋”์˜ ์ถœ๋ ฅ์ด ์ธ์ฝ”๋”์˜ ์ž…๋ ฅ๊ณผ ๋™์ผํ•œ ํฌ๊ธฐ๊ฐ€ ๋˜๋„๋ก ๋งŒ๋“ ๋‹ค.

    ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ์ปดํŒŒ์ผํ•  ๋•Œ ํ‰๊ท  MSE ์†์‹ค๊ณผ Nadam ์˜ตํ‹ฐ๋งˆ์ด์ €๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

    ๋งˆ์ง€๋ง‰์œผ๋กœ X_train์„ ์ž…๋ ฅ๊ณผ ํƒ€๊นƒ์œผ๋กœ ์‚ฌ์šฉํ•ด ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•œ๋‹ค. ๋น„์Šทํ•˜๊ฒŒ X_valid๋ฅผ ๊ฒ€์ฆ ์ž…๋ ฅ๊ณผ ๊ฒ€์ฆ ํƒ€๊นƒ์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

    17.3.2 ์žฌ๊ตฌ์„ฑ ์‹œ๊ฐํ™”

    ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์ ์ ˆํžˆ ํ›ˆ๋ จ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์„ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์˜ ํฌ๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ํฌ์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค. 

    import numpy as np
    
    def plot_reconstructions(model, images=X_valid, n_images=5):
        reconstructions = np.clip(model.predict(images[:n_images]), 0, 1)
        fit = plt.figure(figsize=(n_images * 1.5, 3))
        
        for image_index in range(n_images):
            plt.subplot(2, n_images, 1 + image_index)
            plt.imshow(images[images_index], cmap="binary")
            plt.axis("off")
            plt.subplot(2, n_images, 1 + n_images + image_index)
            plt.imshow(reconstructions[image_index], cmap="binary")
            plt.axis("off")
            
    plot_reconstructions(stacked_ae)
    plt.show()

    17.3.3 ํŒจ์…˜ MNIST ๋ฐ์ดํ„ฐ์…‹ ์‹œ๊ฐํ™”

    ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ํ›ˆ๋ จํ–ˆ์œผ๋ฏ€๋กœ ์ด ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ์…‹์˜ ์ฐจ์›์„ ์ถ•์†Œํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์˜คํ† ์ธ์ฝ”๋”์˜ ์žฅ์ ์ด ์ƒ˜ํ”Œ๊ณผ ํŠน์„ฑ์ด ๋งŽ์€ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ์…‹์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ์‚ฌ์šฉํ•ด ์ ์ ˆํ•œ ์ˆ˜์ค€์œผ๋กœ ์ฐจ์›์„ ์ถ•์†Œํ•œ ํ›„ ๋‹ค๋ฅธ ์ฐจ์› ์ถ•์†Œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•ด ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

    from sklearn.manifold import TSNE
    X_valid_compressed = stacked_encoder.predict(X_valid)
    tsne = TSNE(init="pca", learning_rate="auto", random_state=42)
    X_valid_2D = tsne.fit_trainsform(X_valid_compressed)

    ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”์˜ ์ธ์ฝ”๋” ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด ์ฐจ์›์„ 30์œผ๋กœ ์ค„์ธ๋‹ค.

    ๊ทธ๋‹ค์Œ t-SNE ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•œ ์‚ฌ์ดํ‚ท๋Ÿฐ ํด๋ž˜์Šค๋กœ ์‹œ๊ฐํ™”๋ฅผ ์œ„ํ•ด ์ฐจ์›์„ 2๊นŒ์ง€ ์ค„์ธ๋‹ค.

    plt.scatter(X_valid_2D[:, 0], X_valid_2D[:, 1], c=y_valid, s=10, cmap="tab10"))
    plt.show()

    ์ด ๋ฐ์ดํ„ฐ์…‹์„ ๊ทธ๋ž˜ํ”„๋กœ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๋‹ค. 

    17.3.4 ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ์‚ฌ์šฉํ•œ ๋น„์ง€๋„ ์‚ฌ์ „ ํ›ˆ๋ จ

    ๋ ˆ์ด๋ธ”๋œ ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์ง€ ์•Š์€ ๋ณต์žกํ•œ ์ง€๋„ ํ•™์Šต ๋ฌธ์ œ๋ฅผ ๋‹ค๋ฃจ์–ด์•ผ ํ•œ๋‹ค๋ฉด ๋น„์Šทํ•œ ๋ฌธ์ œ๋ฅผ ํ•™์Šตํ•œ ์‹ ๊ฒฝ๋ง์„ ์ฐพ์•„ ํ•˜์œ„ ์ธต์„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

    ์ €์ˆ˜์ค€์˜ ํŠน์„ฑ์„ ํ•™์Šตํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋‹ˆ ์ ์€ ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ๊ณ ์„ฑ๋Šฅ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•  ์ˆ˜ ์žˆ๋‹ค.

    ๊ธฐ์กด์˜ ๋„คํŠธ์›Œํฌ์—์„œ ํ•™์Šตํ•œ ํŠน์„ฑ ๊ฐ์ง€ ๊ธฐ๋Šฅ์„ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.

     

    ๋น„์Šทํ•˜๊ฒŒ ๋Œ€๋ถ€๋ถ„์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ ˆ์ด๋ธ”๋˜์ง€ ์•Š์€ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ์…‹์ด ์žˆ๋‹ค๋ฉด ๋จผ์ € ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ํ›ˆ๋ จํ•œ๋‹ค.

    ๊ทธ๋Ÿฐ ๋‹ค์Œ ์˜คํ† ์ธ์ฝ”๋”์˜ ํ•˜์œ„ ์ธต์„ ์žฌ์‚ฌ์šฉํ•ด ์‹ค์ œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์‹ ๊ฒฝ๋ง์„ ๋งŒ๋“ค๊ณ  ๋ ˆ์ด๋ธ”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ํ›ˆ๋ จํ•  ์ˆ˜ ์žˆ๋‹ค.

    ๋ถ„๋ฅ˜๊ธฐ๋ฅผ ํ›ˆ๋ จํ•  ๋•Œ ๋ ˆ์ด๋ธ”๋œ ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์ง€ ์•Š์œผ๋ฉด ์‚ฌ์ „ ํ›ˆ๋ จ๋œ ์ธต ๊ฐ€์žฅ ํ•˜์œ„์— ์žˆ๋Š” ์ธต ํ•˜๋‚˜ ์ด์ƒ์„ ๋™๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

    ๋ชจ๋“  ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ํ›ˆ๋ จํ•˜๊ณ  ์ธ์ฝ”๋” ์ธต์„ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ์‹ ๊ฒฝ๋ง์„ ๋งŒ๋“ค๋ฉด ๋œ๋‹ค.

    17.3.5 ๊ฐ€์ค‘์น˜ ๋ฌถ๊ธฐ

    ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์™„๋ฒฝํ•˜๊ฒŒ ๋Œ€์นญ์ผ ๋• ๋””์ฝ”๋”์˜ ๊ฐ€์ค‘์น˜์™€ ์ธ์ฝ”๋”์˜ ๊ฐ€์ค‘์น˜๋ฅผ ๋ฌถ๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์ด๋‹ค.

    → ๋ชจ๋ธ์— ์žˆ๋Š” ๊ฐ€์ค‘์น˜์˜ ์ˆ˜๊ฐ€ ์ ˆ๋ฐ˜์œผ๋กœ ์ค„์–ด๋“ค์–ด ํ›ˆ๋ จ ์†๋„๊ฐ€ ์ฆ๊ฐ€ํ•˜๊ณ  ๊ณผ๋Œ€์ ํ•ฉ์˜ ์œ„ํ—˜์ด ์ค„์–ด๋“ ๋‹ค.

    class DenseTranspose(tf.keras.layers.Layer):
        def __init__(self, dense, activation=None, **kwargs):
            super().__init__(**kwargs)
            self.dense = dense
            self.activation = tf.keras.activations.get(acitvation)
        
        def build(self, batch_input_shape):
            self.biases = self.add_weight(name="bias",
                                          shape=self.dense.input_shape[-1],
                                          initializer="zeros")
            super().build(batch_input_shape)
    
        def call(self, inputs):
            Z = tf.matmul(inputs, self.dense.weights[0], transpose_b=True)
            return self.activation(Z + self.biases)

    ์ด ์‚ฌ์šฉ์ž ์ •์˜ ์ธต์€ ์ผ๋ฐ˜์ ์ธ Dense ์ธต๊ณผ ๋‹ค๋ฅธ Dense ์ธต์˜ ์ „์น˜๋œ ๊ฐ€์ค‘์น˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

    ๋…์ž์ ์ธ ํŽธํ–ฅ ๋ฒกํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

    dense_1 = tf.keras.layers.Dense(100, activation="relu")
    dense_2 = tf.keras.layers.Dense(30, activation="relu")
    
    tied_encoder = tf.keras.Sequential([
        tf.keras.layers.Flatten(),
        dense_1,
        dense_2
    ])
    
    tied_decoder = tf.keras.Sequential([
        DenseTranspose(dense_2, activation="relu"),
        DenseTranspose(dense_1),
        tf.keras.layers.Reshape([28, 28])
    ])
    
    tied_ae = tf.keras.Sequential([tied_encoder, tied_decoder])

    ์ด์ „๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ƒˆ๋กœ์šด ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ๋งŒ๋“ ๋‹ค.

    ์ด ๋””์ฝ”๋”์˜ Dense ์ธต์€ ์ธ์ฝ”๋”์˜ Dense ์ธต๊ณผ ๋ฌถ์—ฌ์žˆ๋‹ค.

    17.3.6 ์˜คํ† ์ธ์ฝ”๋” ํ•œ ๊ฐœ์”ฉ ํ›ˆ๋ จํ•˜๊ธฐ

    ํ•œ ๋ฒˆ์— ์ „์ฒด ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ํ›ˆ๋ จํ•˜๋Š” ๋Œ€์‹  ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ํ•˜๋‚˜์”ฉ ํ›ˆ๋ จํ•˜๊ณ  ์ด๋ฅผ ์Œ“์•„์˜ฌ๋ ค์„œ ํ•œ ๊ฐœ์˜ ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

    ๋‹จ๊ณ„ 1์—์„œ ์ฒซ ๋ฒˆ์งธ ์˜คํ† ์ธ์ฝ”๋”๋Š” ์ž…๋ ฅ์„ ์žฌ๊ตฌ์„ฑํ•˜๋„๋ก ํ›ˆ๋ จ๋œ๋‹ค.

    ๊ทธ๋‹ค์Œ ์ด ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ์‚ฌ์šฉํ•ด ์ „์ฒด ํ›ˆ๋ จ ์„ธํŠธ๋ฅผ ์ธ์ฝ”๋”ฉํ•˜์—ฌ ์••์ถ•๋œ ์ƒˆ ํ›ˆ๋ จ ์„ธํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค. 

    ์ด ์ƒˆ๋กœ์šด ํ›ˆ๋ จ ์„ธํŠธ์—์„œ ๋‘ ๋ฒˆ์งธ ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ํ›ˆ๋ จํ•œ๋‹ค. (๋‹จ๊ณ„ 2)

    ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ชจ๋“  ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ์‚ฌ์šฉํ•ด ์ „์ฒด ๋„คํŠธ์›Œํฌ๋ฅผ ๋งŒ๋“ ๋‹ค. (๊ฐ ์˜คํ† ์ธ์ฝ”๋”์˜ ์€๋‹‰ ์ธต์„ ๋จผ์ € ์Œ“๊ณ  ์ถœ๋ ฅ ์ธต์„ ๋ฐ˜๋Œ€๋กœ ์Œ“๋Š”๋‹ค.)

    ์ด๋ ‡๊ฒŒ ํ•ด์„œ ์ตœ์ข… ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ๋งŒ๋“ ๋‹ค. ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๋” ๋งŽ์€ ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ํ›ˆ๋ จํ•ด ์•„์ฃผ ๊นŠ์€ ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.


    17.4 ํ•ฉ์„ฑ๊ณฑ ์˜คํ† ์ธ์ฝ”๋”

    ์ด๋ฏธ์ง€๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฒฝ์šฐ์—๋Š” ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์ข‹์€ ์„ฑ๋Šฅ์„ ๋‚ด์ง€ ๋ชปํ•˜๊ธฐ ๋–„๋ฌธ์— ํ•ฉ์„ฑ๊ณฑ ์‹ ๊ฒฝ๋ง์ด ๋ฐ€์ง‘ ๋„คํŠธ์›Œํฌ๋ณด๋‹ค ํ›จ์”ฌ ์ž˜ ๋งž๋Š”๋‹ค. 

    ๋”ฐ๋ผ์„œ ๋น„์ง€๋„ ์‚ฌ์ „ ํ›ˆ๋ จ์ด๋‚˜ ์ฐจ์› ์ถ•์†Œ๋ฅผ ์œ„ํ•ด ์ด๋ฏธ์ง€์— ๋Œ€ํ•œ ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ๋งŒ๋“œ๋ ค๋ฉด ํ•ฉ์„ฑ๊ณฑ ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. 

    ์ธ์ฝ”๋”๋Š” ํ•ฉ์„ฑ๊ณฑ ์ธต๊ณผ ํ’€๋ง ์ธต์œผ๋กœ ๊ตฌ์„ฑ๋œ ์ผ๋ฐ˜์ ์ธ CNN์ด๋‹ค. 

    ์ธ์ฝ”๋”๋Š” ์ „ํ˜•์ ์œผ๋กœ ์ž…๋ ฅ์—์„œ ๊ณต๊ฐ„ ๋ฐฉํ–ฅ์˜ ์ฐจ์›(๋†’์ด์™€ ๋„ˆ๋น„)์„ ์ค„์ด๊ณ  ๊นŠ์ด(ํŠน์„ฑ ๋งต์˜ ๊ฐœ์ˆ˜)๋ฅผ ๋Š˜๋ฆฐ๋‹ค. 

    ๋””์ฝ”๋”๋Š” ๊ฑฐ๊พธ๋กœ ์ž‘๋™ํ•˜๋ฉฐ, ์ด๋ฏธ์ง€์˜ ์Šค์ผ€์ผ์„ ๋Š˜๋ฆฌ๊ณ  ๊นŠ์ด๋ฅผ ์›๋ณธ ์ฐจ์›์œผ๋กœ ๋˜๋Œ๋ฆฐ๋‹ค.

    ์ด๋ฅผ ์œ„ํ•ด์„  ์ „์น˜ ํ•ฉ์„ฑ๊ณฑ ์ธต์„ ์‚ฌ์šฉํ•œ๋‹ค. (๋˜๋Š” ํ•ฉ์„ฑ๊ณฑ ์ธต๊ณผ ์—…์ƒ˜ํ”Œ๋ง ์ธต์„ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.)

    conv_encoder = tf.keras.Sequential([
        tf.keras.layers.Reshape([28, 28, 1]),
        tf.keras.layers.Conv2D(16, 3, padding="same", activation="relu"),
        tf.keras.layers.MaxPool2D(pool_size=2), # ์ถœ๋ ฅ: 14 x 14 x 16
        tf.keras.layers.Conv2D(32, 3, padding="smae", activation="relu"),
        tf.keras.layers.MaxPool2D(pool_size=2), # ์ถœ๋ ฅ: 7 x 7 x 32
        tf.keras.layers.Conv2D(64, 3, padding="same", activation="relu"),
        tf.keras.layers.MaxPool2D(pool_size=2), # ์ถœ๋ ฅ: 3 x 3 x 64
        tf.keras.layers.Conv2D(30, 3, padding="same", activation="relu"),
        tf.keras.layers.GlobalAvgPool2D() # ์ถœ๋ ฅ: 30
    ])
    conv_decoder = tf.keras.Sequential([
        tf.keras.layers.Dense(3 * 3 * 16),
        tf.keras.layers.Reshape((3, 3, 16)),
        tf.keras.layers.Conv2DTranspose(32, 3, strides=2, activation="relu"),
        tf.keras.layers.Conv2DTranspose(16, 3, strides=2, padding="same",
                                        activation="relu"),
        tf.keras.layers.Conv2DTranspose(1, 3, strides=2, padding="same"),
        tf.keras.layers.Reshape([28, 28])
    ])
    conv_ae = tf.keras.Sequential([conv_encoder, conv_decoder])

     

    ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ํฅ๋ฏธ๋กœ์šด ํŠน์„ฑ์„ ํ•™์Šตํ•˜๋„๋ก ๊ฐ•์ œํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋”ฉ ์ธต์˜ ํฌ๊ธฐ๋ฅผ ์ œํ•œํ•˜์—ฌ ๊ณผ์†Œ์™„์ „์œผ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค. 

    ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ์ œ์•ฝ๋„ ๋งŽ๋‹ค.

    ์ž…๋ ฅ ํฌ๊ธฐ๋งŒํผ ๋˜๋Š” ์ž…๋ ฅ๋ณด๋‹ค ํฐ ์ฝ”๋”ฉ ์ธต์„ ๋‘์–ด ๊ณผ๋Œ€์™„์ „ ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. 

    ์žก์Œ ์ œ๊ฑฐ ์˜คํ† ์ธ์ฝ”๋”, ํฌ์†Œ ์˜คํ† ์ธ์ฝ”๋”, ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”์™€ ๊ฐ™์€ ์ข…๋ฅ˜๋„ ์žˆ๋‹ค.


    17.5 ์žก์Œ ์ œ๊ฑฐ ์˜คํ† ์ธ์ฝ”๋”

    ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์œ ์šฉํ•œ ํŠน์„ฑ์„ ํ•™์Šตํ•˜๋„๋ก ๊ฐ•์ œํ•˜๊ธฐ ์œ„ํ•ด ์ž…๋ ฅ์— ์žก์Œ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์žก์Œ์ด ์—†๋Š” ์›๋ณธ ์ž…๋ ฅ์„ ๋ณต์›ํ•˜๋„๋ก ํ›ˆ๋ จํ•œ๋‹ค.

    ์ ์ธต ์žก์Œ ์ œ๊ฑฐ ์˜คํ† ์ธ์ฝ”๋”

     

    ์žก์Œ์€ ์ž…๋ ฅ์— ์ˆœ์ˆ˜ํ•œ ๊ฐ€์šฐ์Šค ์žก์Œ์„ ์ž…๋ ฅ์— ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋“œ๋กญ์•„์›ƒ์ฒ˜๋Ÿผ ๋žœ๋ค์œผ๋กœ ์ž…๋ ฅ์„ ๊บผ์„œ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. 

    dropout_encoder = tf.keras.Sequential([
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dropout(0.5),
        tf.keras.layers.Dense(100, activation="relu"),
        tf.keras.layers.Dense(30, activation="relu")
    ])
    dropout_decoder = tf.keras.Sequential([
        tf.keras.layers.Dense(100, activation="relu"),
        tf.keras.layers.Dense(28 * 28),
        tf.keras.layers.Reshape([28, 28])
    ])
    dropout_ae = tf.keras.Sequential([dropout_encoder, dropout_decoder])

    ์ธ์ฝ”๋”์˜ ์ž…๋ ฅ์— ์ ์šฉํ•œ Dropout ์ธต์ด ์žˆ๋Š”(๋˜๋Š” GaussianNoise ์ธต์„ ์‚ฌ์šฉํ•œ) ์ผ๋ฐ˜์ ์ธ ์ ์ธต ์˜คํ† ์ธ์ฝ”๋”์ด๋‹ค.

    Dropout ์ธต์€ ํ›ˆ๋ จํ•˜๋Š” ๋™์•ˆ์—๋งŒ ํ™œ์„ฑํ™”๋œ๋‹ค. (GaussianNoise ์ธต๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค.)


    17.6 ํฌ์†Œ ์˜คํ† ์ธ์ฝ”๋”

    ๋น„์šฉ ํ•จ์ˆ˜์— ์ ์ ˆํ•œ ํ•ญ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์ฝ”๋”ฉ ์ธต์—์„œ ํ™œ์„ฑํ™”๋˜๋Š” ๋‰ด๋Ÿฐ ์ˆ˜๋ฅผ ๊ฐ์†Œ์‹œํ‚ค๋„๋ก ๋งŒ๋“ ๋‹ค.

    → ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์ ์€ ์ˆ˜์˜ ํ™œ์„ฑํ™”๋œ ๋‰ด๋Ÿฐ์„ ์กฐํ•ฉํ•˜์—ฌ ์ž…๋ ฅ์„ ํ‘œํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ์ฝ”๋”ฉ ์ธต์˜ ๊ฐ ๋‰ด๋Ÿฐ์€ ์œ ์šฉํ•œ ํŠน์„ฑ์„ ํ‘œํ˜„ํ•˜๊ฒŒ ๋œ๋‹ค.

    sparse_l1_encoder = tf.keras.Sequential([
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(100, activation="relu"),
        tf.keras.layers.Dense(300, activation="sigmoid"),
        tf.keras.layers.ActivityRegularization(l1=1e-4)
    ])
    sparse_l1_decoder = tf.keras.Sequential([
        tf.keras.layers.Dense(100, activation="relu"),
        tf.keras.layers.Dense(28 * 28),
        tf.keras.layers.Reshape([28, 28])
    ])
    sparse_l1_ae = tf.keras.Sequential([sparse_l1_encoder, sparse_l1_decoder])

    ActivityRegularization ์ธต์€ ์ž…๋ ฅ์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๋ฉด์„œ ํ›ˆ๋ จ ์†์‹ค์— ์ž…๋ ฅ์˜ ์ ˆ๋Œ“๊ฐ’์„ ๋”ํ•œ๋‹ค. (์ด ์ธต์€ ํ›ˆ๋ จํ•˜๋Š” ๋™์•ˆ์—๋งŒ ์ž‘๋™ํ•œ๋‹ค.)

    ActivityRegularization ์ธต์„ ์ œ๊ฑฐํ•˜๊ณ  ์ด์ „ ์ธต์—์„œ activity_regularier=tf.keras.regularizers.l1(1e-4)๋กœ ์ง€์ •ํ•ด๋„ ๋™์ผํ•˜๋‹ค.

    ์ด ๊ทœ์ œ๋Š” ์‹ ๊ฒฝ๋ง์ด 0์— ๊ฐ€๊นŒ์šด ์ฝ”๋”ฉ์„ ๋งŒ๋“ค๋„๋ก ์œ ๋„ํ•˜์ง€๋งŒ ์ž…๋ ฅ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์žฌ๊ตฌ์„ฑํ•˜์ง€ ๋ชปํ•˜๋ฉด ๋ฒŒ์น™์„ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ์ ์–ด๋„ 0์ด ์•„๋‹Œ ๊ฐ’์ด ์กฐ๊ธˆ์€ ์ถœ๋ ฅ๋˜์–ด์•ผ ํ•œ๋‹ค. 

    l2 ๋…ธ๋ฆ„ ๋Œ€์‹  l1 ๋…ธ๋ฆ„์„ ์‚ฌ์šฉํ•˜๋ฉด ์‹ ๊ฒฝ๋ง์ด ๋ชจ๋“  ์ฝ”๋”ฉ์„ ๊ฐ์†Œ์‹œํ‚ค๋Š” ๋Œ€์‹  ์ž…๋ ฅ ์ด๋ฏธ์ง€์—์„œ ๋ถˆํ•„์š”ํ•œ ๊ฒƒ์„ ์ œ๊ฑฐํ•˜๊ณ  ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ฝ”๋”ฉ์„ ๋ณด์ „ํ•˜๋„๋ก ๋งŒ๋“ ๋‹ค. 

     

    ํ›ˆ๋ จ ๋ฐ˜๋ณต๋งˆ๋‹ค ์ฝ”๋”ฉ ์ธต์˜ ์‹ค์ œ ํฌ์†Œ ์ •๋„๋ฅผ ์ธก์ •ํ•˜๊ณ  ์ธก์ •๋œ ํฌ์†Œ ์ •๋„๊ฐ€ ํƒ€๊นƒ ํฌ์†Œ ์ •๋„์™€ ๋‹ค๋ฅด๋ฉด ๋ชจ๋ธ์— ๋ฒŒ์น™์„ ๋ถ€๊ณผํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.

    ์ด๋ฅผ ์œ„ํ•ด ์ „์ฒด ํ›ˆ๋ จ ๋ฐฐ์น˜์— ๋Œ€ํ•ด ์ฝ”๋”ฉ ์ธต์— ์žˆ๋Š” ๊ฐ ๋‰ด๋Ÿฐ์˜ ํ‰๊ท ์ ์ธ ํ™œ์„ฑํ™”๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.

    ๋ฐฐ์น˜ ํฌ๊ธฐ๋Š” ๋„ˆ๋ฌด ์ž‘์ง€ ์•Š์•„์•ผ ํ•˜๋ฉฐ ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ‰๊ท ๊ฐ’์ด ์ •ํ™•ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. 

     

    ๊ฐ ๋‰ด๋Ÿฐ์— ๋Œ€ํ•œ ํ‰๊ท  ํ™œ์„ฑํ™” ์ •๋„๋ฅผ ์•Œ๋ฉด ๋น„์šฉ ํ•จ์ˆ˜์— ํฌ์†Œ ์†์‹ค์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๋„ˆ๋ฌด ํ™œ์„ฑํ™”๋˜๊ฑฐ๋‚˜ ์ถฉ๋ถ„ํžˆ ํ™œ์„ฑํ™”๋˜์ง€ ์•Š์€ ๋‰ด๋Ÿฐ์— ๋ฒŒ์น™์„ ๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.  ๋น„์šฉ ํ•จ์ˆ˜์— ์ œ๊ณฑ ์˜ค์ฐจ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. 

    → ์‹ค์ „์—์„œ ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ํ‰๊ท  ์ œ๊ณฑ ์˜ค์ฐจ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ•ํ•œ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ๊ฐ€์งˆ ์ฟจ๋ฐฑ-๋ผ์ž…๋ฅด๋Ÿฌ ๋ฐœ์‚ฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 

     

    ๋‘ ๊ฐœ์˜ ์ด์‚ฐ ํ™•๋ฅ  ๋ถ„ํฌ P์™€ Q๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ์ด ๋‘ ๋ถ„์‚ฐ ์‚ฌ์ด์˜ ์ฟจ๋ฐฑ-๋ผ์ด๋ธ”๋Ÿฌ ๋ฐœ์‚ฐ์˜ ์‹์ด๋‹ค.

    ์ฝ”๋”ฉ ์ธต์—์„œ ๋‰ด๋Ÿฐ์ด ํ™œ์„ฑํ™”๋  ๋ชฉํ‘œ ํ™•๋ฅ  p์™€ ์‹ค์ œ ํ™•๋ฅ  q(ํ›ˆ๋ จ ๋ฐฐ์น˜์— ๋Œ€ํ•œ ํ‰๊ท  ํ™œ์„ฑํ™”) ์‚ฌ์ด์˜ ๋ฐœ์‚ฐ์„ ์ธก์ •ํ•œ๋‹ค.

     

    ์ฝ”๋”ฉ ์ธต์˜ ๊ฐ ๋‰ด๋Ÿฐ์— ๋Œ€ํ•ด ํฌ์†Œ ์†์‹ค์„ ๊ณ„์‚ฐํ–ˆ๋‹ค๋ฉด ์ด ์†์‹ค๋“ค์„ ๋ชจ๋‘ ํ•ฉํ•ด์„œ ๋น„์šฉ ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ์— ๋”ํ•œ๋‹ค.

    ํฌ์†Œ ์†์‹ค๊ณผ ์žฌ๊ตฌ์„ฑ ์†์‹ค์˜ ์ƒ๋Œ€์  ์ค‘์š”๋„๋ฅผ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด ํฌ์†Œ ์†์‹ค์— ํฌ์†Œ ๊ฐ€์ค‘์น˜ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ณฑํ•œ๋‹ค.

    ์ด ๊ฐ€์ค‘์น˜๊ฐ€ ๋„ˆ๋ฌด ํฌ๋ฉด ๋ชจ๋ธ์ด ๋ชฉํ‘œ ํฌ์†Œ์— ๊ฐ€๊น๊ฒŒ ๋˜๊ฒ ์ง€๋งŒ ์ž…๋ ฅ์„ ์ ์ ˆํžˆ ์žฌ๊ตฌ์„ฑํ•˜์ง€ ๋ชปํ•ด์„œ ์“ธ๋ชจ์—†๋Š” ๋ชจ๋ธ์ด ๋  ์ˆ˜ ์žˆ๋‹ค.

    ๋ฐ˜๋Œ€๋กœ ๊ฐ€์ค‘์น˜๊ฐ€ ๋„ˆ๋ฌด ์ž‘์œผ๋ฉด ํฌ์†Œ ๋ชฉํ‘œ๋ฅผ ๊ฑฐ์˜ ๋ฌด์‹œํ•  ๊ฒƒ์ด๋ฏ€๋กœ ์–ด๋–ค ํฅ๋ฏธ๋กœ์šด ํŠน์„ฑ๋„ ํ•™์Šตํ•˜์ง€ ๋ชปํ•  ๊ฒƒ์ด๋‹ค. 

     

    kl_divergence = tf.keras.losses.kullback_leibler_divergence
    
    class KLDivergenceRegularizer(tf.keras.regularizers.Regularizer):
        def __init__(self, weight, target):
            self.weight = weight
            self.target = target
            
        def __call__(self, inputs):
            mean_activities = tf.reduce_mean(inputs, axis=0)
            return self.weight * (
                kl_divergence(self.target, mean)activities) +
                kl_divergence(1. - self.target, 1. - mean_activities))

    KL ๋ฐœ์‚ฐ ๊ทœ์ œ๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ๊ทœ์ œ์ด๋‹ค.

    kld_reg = KLDivergenceRegularizer(weight=5e-3, target=0.1)
    sparse_kl_encoder = tf.keras.Sequential([
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(100, activation="relu"),
        tf.keras.layers.Dense(300, activation="sigmoid",
                              activity_regularizer=kld_reg)
    ])
    sparse_kl_decoder = tf.keras.Seqeuntial([
        tf.keras.layers.Dense(100, activation="relu"),
        tf.keras.layers.Dense(28 * 28),
        tf.keras.layers.Reshape([28, 28])
    ])
    sparse_kl_ae = tf.keras.Sequential([sparse_kl_encoder, sparse_kl_decoder])

    ์ฝ”๋”ฉ ์ธต์˜ ํ™œ์„ฑํ™”์— KLDivergenceRegularizer๋ฅผ ์ ์šฉํ•ด ํฌ์†Œ ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ๋งŒ๋“ ๋‹ค.


    17.7 ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”

    ํ™•๋ฅ ์  ์˜คํ† ์ธ์ฝ”๋”์ด๋‹ค. ํ›ˆ๋ จ์ด ๋๋‚œ ํ›„์—๋„ ์ถœ๋ ฅ์ด ๋ถ€๋ถ„์ ์œผ๋กœ ์šฐ์—ฐ์— ์˜ํ•ด ๊ฒฐ์ •๋œ๋‹ค. ↔ ์žก์Œ ์ œ๊ฑฐ ์˜คํ† ์ธ์ฝ”๋”๋Š” ํ›ˆ๋ จ ์‹œ์—๋งŒ ๋ฌด์ž‘์œ„์„ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค.

    ์ƒ์„ฑ ์˜คํ† ์ธ์ฝ”๋”์ด๋‹ค. ํ›ˆ๋ จ ์„ธํŠธ์—์„œ ์ƒ˜ํ”Œ๋ง๋œ ๊ฒƒ ๊ฐ™์€ ์ƒˆ๋กœ์šด ์ƒ˜ํ”Œ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    ์ด๋Ÿฐ ๋‘ ์†์„ฑ์ด ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”๋ฅผ RBM๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ๋งŒ๋“ค์ง€๋งŒ ํ›ˆ๋ จ์ด ๋” ์‰ฝ๊ณ  ์ƒ˜ํ”Œ๋ง ๊ณผ์ •์ด ํ›จ์”ฌ ๋น ๋ฅด๋‹ค.

    ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”๋Š” ํšจ์œจ์ ์ธ ๊ทผ์‚ฌ ๋ฒ ์ด์ฆˆ ์ถ”๋ก  ๋ฐฉ์‹์ธ ๋ณ€๋ถ„ ๋ฒ ์ด์ฆˆ ์ถ”๋ก ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

    ๋ฒ ์ด์ฆˆ ์ถ”๋ก ์€ ๋ฒ ์ด์ฆˆ ์ •๋ฆฌ์—์„œ ์œ ๋„๋œ ๋ฐฉ์ •์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ™•๋ฅ  ๋ถ„ํฌ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

    ์›๋ž˜ ๋ถ„ํฌ๋ฅผ ์‚ฌ์ „ ๋ถ„ํฌ๋ผ๊ณ  ํ•˜๊ณ  ์—…๋ฐ์ดํŠธ๋œ ๋ถ„ํฌ๋ฅผ ์‚ฌํ›„ ๋ถ„ํฌ๋ผ๊ณ  ํ•œ๋‹ค. 

    ๋ฐ์ดํ„ฐ ๋ถ„ํฌ์˜ ์ข‹์€ ๊ทผ์‚ฟ๊ฐ’์„ ์ฐพ๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ด๋ฉฐ ๊ทผ์‚ฟ๊ฐ’์„ ์ฐพ์œผ๋ฉด ์ด๋กœ๋ถ€ํ„ฐ ์ƒ˜ํ”Œ์„ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์™ผ์ชฝ์€ ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”์ด๋‹ค. ์˜คํ† ์ธ์ฝ”๋”์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ์ธ ์ธ์ฝ”๋”์™€ ๊ทธ ๋’ค๋ฅผ ๋”ฐ๋ฅด๋Š” ๋””์ฝ”๋”๊ฐ€ ์žˆ๋‹ค.

    ์ฃผ์–ด์ง„ ์ž…๋ ฅ์— ๋Œ€ํ•œ ์ฝ”๋”ฉ์„ ๋ฐ”๋กœ ๋งŒ๋“œ๋Š” ๋Œ€์‹  ์ธ์ฝ”๋”๋Š” ํ‰๊ท  ์ฝ”๋”ฉ μ์™€ ํ‘œ์ค€ ํŽธ์ฐจ σ๋ฅผ ๋งŒ๋“ ๋‹ค.

    ์‹ค์ œ ์ฝ”๋”ฉ์€ ํ‰๊ท ์ด μ์ด๊ณ  ํ‘œ์ค€ ํŽธ์ฐจ๊ฐ€ σ์ธ ๊ฐ€์šฐ์Šค ๋ถ„ํฌ์—์„œ ๋žœ๋คํ•˜๊ฒŒ ์ƒ˜ํ”Œ๋ง๋œ๋‹ค.

    ๊ทธ ํ›„ ๋””์ฝ”๋”๊ฐ€ ์ƒ˜ํ”Œ๋ง๋œ ์ฝ”๋”ฉ์„ ๋ณดํ†ต์ฒ˜๋Ÿผ ๋””์ฝ”๋”ฉํ•œ๋‹ค.

     

    ์˜ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์€ ์ด ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ํ†ต๊ณผํ•˜๋Š” ํ›ˆ๋ จ ์ƒ˜ํ”Œ์„ ๋ณด์—ฌ์ค€๋‹ค.

    ์ธ์ฝ”๋”๊ฐ€ μ์™€ σ๋ฅผ ๋งŒ๋“ค๋ฉด ์ฝ”๋”ฉ์ด ๋žœ๋คํ•˜๊ฒŒ ์ƒ์„ฑ๋œ๋‹ค. ๋งˆ์ง๊ฐ€์œผ๋กœ ์ด ์ฝ”๋”ฉ์ด ๋””์ฝ”๋”ฉ๋˜์–ด ํ›ˆ๋ จ ์ƒ˜ํ”Œ์„ ๋‹ฎ์€ ์ตœ์ข… ์ถœ๋ ฅ์„ ๋งŒ๋“ ๋‹ค. 

     

    ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”๋Š” ์ž…๋ ฅ์ด ๋งค์šฐ ๋ณต์žกํ•œ ๋ถ„ํฌ๋ฅผ ๊ฐ€์ง€๋”๋ผ๋„ ๊ฐ„๋‹จํ•œ ๊ฐ€์šฐ์Šค ๋ถ„ํฌ์—์„œ ์ƒ˜ํ”Œ๋ง๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ์ฝ”๋”ฉ์„ ๋งŒ๋“œ๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๋‹ค.

    ํ›ˆ๋ จํ•œ๋А ๋™์•ˆ ๋น„์šฉ ํ•จ์ˆ˜๊ฐ€ ์ฝ”๋”ฉ์„ ๊ฐ€์šฐ์Šค ์ƒ˜ํ”Œ๋“ค์˜ ๊ตฐ์ง‘์ฒ˜๋Ÿผ ๋ณด์ด๋„๋ก ์ฝ”๋”ฉ ๊ณต๊ฐ„(์ž ์žฌ ๊ณต๊ฐ„) ์•ˆ์œผ๋กœ ์ ์ง„์ ์œผ๋กœ ์ด๋™์‹œํ‚จ๋‹ค.

    → ํ›ˆ๋ จ์ด ๋๋‚œ ๋’ค ์ƒˆ๋กœ์šด ์ƒ˜ํ”Œ์„ ๋งค์šฐ ์‰ฝ๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ€์šฐ์Šค ๋ถ„ํฌ์—์„œ ๋žœ๋คํ•œ ์ฝ”๋”ฉ์„ ์ƒ˜ํ”Œ๋งํ•ด ๋””์ฝ”๋”ฉํ•˜๋ฉด ๋œ๋‹ค. 

     

    ๋น„์šฉ ํ•จ์ˆ˜๋Š” ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

    ์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์ž…๋ ฅ์„ ์žฌ์ƒ์‚ฐํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ์ผ๋ฐ˜์ ์ธ ์žฌ๊ตฌ์„ฑ ์†์‹ค(์ด์ „์ฒ˜๋Ÿผ MSE๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.)๊ณผ ๋‹จ์ˆœํ•œ ๊ฐ€์šฐ์Šค ๋ถ„ํฌ์—์„œ ์ƒ˜ํ”Œ๋ง๋œ ๊ฒƒ ๊ฐ™์€ ์ฝ”๋”ฉ์„ ๊ฐ€์ง€๋„๋ก ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ๊ฐ•์ œํ•˜๋Š” ์ž ์žฌ ์†์‹ค์ด๋‹ค. 

    ๋ชฉํ‘œ ๋ถ„ํฌ(๊ฐ€์šฐ์Šค ๋ถ„ํฌ)์™€ ์‹ค์ œ ์ฝ”๋”ฉ ๋ถ„ํฌ ์‚ฌ์ด์˜ KL ๋ฐœ์‚ฐ์„ ์‚ฌ์šฉํ•œ๋‹ค. 

    ํฌ์†Œ ์ธ์ฝ”๋”๋ณด๋‹ค ์ˆ˜์‹์ด ์กฐ๊ธˆ ๋” ๋ณต์žกํ•˜๋‹ค. ์ฝ”๋”ฉ ์ธต์œผ๋กœ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ๋Š” ์ •๋ณด๋Ÿ‰์„ ์ œํ•œํ•˜๋Š” (→์˜คํ† ์ธ์ฝ”๋”๊ฐ€ ์œ ์šฉํ•œ ํŠน์„ฑ์„ ํ•™์Šต) ๊ฐ€์šฐ์Šค ์žก์Œ ๋•Œ๋ฌธ์ด๋‹ค. ์ด ์‹์„ ๊ฐ„์†Œํ™”ํ•˜์—ฌ ์ž ์žฌ ์†์‹ค์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    class Sampling(tf.keras.layers.Layer):
        def call(self, inputs):
            mean, log_var = inputs
            return tf.random.normal(tf.shape(log_var)) * tf.exp(log_var / 2) + mean

     

    μ์™€ γ๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ ์ฝ”๋”ฉ์„ ์ƒ˜ํ”Œ๋งํ•˜๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์ธต์ด๋‹ค. 

    ์ด Sampling ์ธต์€ mean(μ)์™€ log_var(γ)๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๋Š”๋‹ค.

    tf.random_normal() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ํ‰๊ท ์ด 0์ด๊ณ  ํ‘œ์ค€ ํŽธ์ฐจ๊ฐ€ 1์ธ ์ •๊ทœ ๋ถ„ํฌ์—์„œ ๋žœ๋คํ•œ ๋ฒกํ„ฐ๋ฅผ ์ƒ˜ํ”Œ๋งํ•œ๋‹ค. 

    ๊ทธ๋‹ค์Œ (σ์— ํ•ด๋‹นํ•˜๋Š”) exp(γ / 2)๋ฅผ ๊ณฑํ•˜๊ณ  μ๋ฅผ ๋”ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    ์ด๋Š” ํ‰๊ท ์ด μ์ด๊ณ  ํ‘œ์ค€ ํŽธ์ฐจ๊ฐ€ σ์ธ ์ •๊ทœ ๋ถ„ํฌ์—์„œ ์ฝ”๋”ฉ ๋ฒกํ„ฐ๋ฅผ ์ƒ˜ํ”Œ๋งํ•œ๋‹ค.

    codings_size = 10
    
    inputs = tf.keras.layers.Input(shape=[28, 28])
    Z = tf.keras.layers.Flatten()(inputs)
    Z = tf.keras.layers.Dense(150, activation="relu")(Z)
    Z = tf.keras.layers.Dense(100, activation="relu")(Z)
    codings_mean = tf.keras.layers.Dense(codings_size)(Z)
    codings_log_var = tf.keras.layers.Dense(codings_size)(Z)
    codings = Sampling()([codings_mean, codings_log_var])
    variational_encoder = tf.ekras.Model(
        inputs=[inputs], outputs=[codings_mean, codings_log_var, codings])

    ์ด ๋ชจ๋ธ์€ ์™„์ „ํžˆ ์ˆœ์ฐจ์ ์ด์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜ํ˜• API๋ฅผ ์‚ฌ์šฉํ•ด ์ธ์ฝ”๋”๋ฅผ ๋งŒ๋“ ๋‹ค.

    codings_mean(μ)์™€ codings_log_var(γ)๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๋‘ Dense ์ธต์ด ๋™์ผํ•œ ์ž…๋ ฅ(๋‘ ๋ฒˆ์งธ Dense ์ธต์˜ ์ถœ๋ ฅ)์„ ์‚ฌ์šฉํ•œ๋‹ค.

    ๊ทธ๋‹ค์Œ codings_mean๊ณผ codings_log_var๋ฅผ Sampling ์ธต์œผ๋กœ ์ „๋‹ฌํ•œ๋‹ค.

    ๋งˆ์ง€๋ง‰์œผ๋กœ variational_encoder ๋ชจ๋ธ์€ ์ถœ๋ ฅ ์„ธ ๊ฐœ๋ฅผ ๋งˆ๋“ ๋‹ค.

    ํ•„์š”ํ•œ ๊ฒƒ์€ codings๋ฟ์ด์ง€๋งŒ ์กฐ์‚ฌ ๋ชฉ์ ์œผ๋กœ codings_mean๊ณผ codings_log_var๋„ ์ถœ๋ ฅํ•œ๋‹ค.

    decoder_inputs = tf.keras.layers.Input(shape=[codings_size])
    x = tf.keras.layers.Dense(100, activation="relu")(decoder_inputs)
    x = tf.keras.layers.Dense(150, activation-"relu")(x)
    x = tf.keras.layers.Dense(28 * 28)(x)
    outputs = tf.keras.layers.Reshape([28, 28])(x)
    variational_decoder = tf.keras.Model(inputs=[decoder_inputs], outputs=[outputs])

    ๋””์ฝ”๋”๋Š” ํ•จ์ˆ˜ํ˜• API ๋Œ€์‹  ์‹œํ€€์…œ API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์ง€๊ธˆ๊นŒ์ง€ ๋งŒ๋“ค์—ˆ๋˜ ์—ฌ๋Ÿฌ ๋””์ฝ”๋”์™€ ๋™์ผํ•˜๊ฒŒ ์ธต์„ ์Œ“์€ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

    _, _, codings = variational_encoder(inputs)
    reconstructions = variational_decoder(codings)
    variational_ae = tf.keras.Model(inputs=[inputs], outputs=[reconstructions])

    ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋” ๋ชจ๋ธ์„ ๋งŒ๋“ ๋‹ค.

    ์ธ์ฝ”๋”์˜ ์ฒ˜์Œ ๋‘ ๊ฐœ ์ถœ๋ ฅ์„ ๋ฌด์‹œํ•œ๋‹ค. (์ฝ”๋”ฉ์— ๋””์ฝ”๋”๋งŒ ์ฃผ์ž…ํ•œ๋‹ค.) ๋งˆ์ง€๋ง‰์œผ๋กœ ์ž ์žฌ ์†์‹ค๊ณผ ์žฌ๊ตฌ์„ฑ ์†์‹ค์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

    latent_loss = -0.5 * tf.reduce_sum(
        1 + codings_log_var - tf.exp(codings_log_var) - tf.square(codings_mean),
        axis=-1)
    variational_ae.add_loss(tf.reduce_mean(latent_loss) / 784.)

    ์˜คํ† ์ธ์ฝ”๋”์˜ ์ž ์žฌ ์†์‹ค ์‹์„ ์ ์šฉํ•ด ๋งˆ์ง€๋ง‰ ์ถ•์„ ๋”ฐ๋ผ ๋”ํ•ด์„œ ๋ฐฐ์น˜์— ์žˆ๋Š” ๊ฐ ์ƒ˜ํ”Œ์˜ ์ž ์žฌ ์†์‹ค์„ ๊ณ„์‚ฐํ•œ๋‹ค.

    ๊ทธ๋‹ค์Œ ๋ฐฐ์น˜์— ์žˆ๋Š” ๋ชจ๋“  ์ƒ˜ํ”Œ์˜ ํ‰๊ท  ์†์‹ค์„ ๊ณ„์‚ฐํ•˜๊ณ  ์žฌ๊ตฌ์„ฑ ์†์‹ค์— ๋น„๋ก€ํ•ด ์ ์ ˆํ•œ ํฌ๊ธฐ๊ฐ€ ๋˜๋„๋ก ๋‚˜๋ˆˆ๋‹ค.

    ์‹ค์ œ๋กœ ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”์˜ ์žฌ๊ตฌ์„ฑ ์†์‹ค์€ ํ”ฝ์…€๋งˆ๋‹ค ์žฌ๊ตฌ์„ฑ ์˜ค์ฐจ์˜ ํ•ฉ์ด๋‹ค. 

    ํ•˜์ง€๋งŒ ์ผ€๋ผ์Šค๊ฐ€ mse ์†์‹ค์„ ๊ณ„์‚ฐํ•  ๋•Œ ํ•ฉ์ด ์•„๋‹ˆ๋ผ n๊ฐœ ์ „์ฒด ํ”ฝ์…€์˜ ํ‰๊ท ์„ ๊ณ„์‚ฐํ•œ๋‹ค. -> ํ•„์š”ํ•œ ๊ฒƒ๋ณด๋‹ค ์žฌ๊ตฌ์„ฑ ์†์‹ค์ด n๋ฐฐ ์ž‘๋‹ค. 

    variational_ae.compile(loss="mse", optimizer="nadam")
    history = variational_ae.fit(X_train, X_train, epochs=25, batch_size=128,
                                 validation_data=(X_valid, X_valid))

    ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  ํ›ˆ๋ จํ•œ๋‹ค.

    17.7.1 ํŒจ์…˜ MNIST ์ด๋ฏธ์ง€ ์ƒ์„ฑํ•˜๊ธฐ

    codings = tf.random.normal(shape=[3 * 7, codings_size])
    images = variational_decoder(codings).numpy()

    ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ์‚ฌ์šฉํ•ด ํŒจ์…˜ ์˜๋ฅ˜์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

    ๊ฐ€์šฐ์Šค ๋ถ„ํฌ์—์„œ ๋žœ๋คํ•œ ์ฝ”๋”ฉ์„ ์ƒ˜ํ”Œ๋งํ•˜์—ฌ ๋””์ฝ”๋”ฉํ•œ๋‹ค.

     

    ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”๋Š” ์‹œ๋งจํ‹ฑ ๋ณด๊ฐ„์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. 

    ๋‘ ์ด๋ฏธ์ง€๊ฐ€ ๊ฒน์ณ ๋ณด์ด๋Š” ๊ฒƒ ๊ฐ™์€ ํ”ฝ์…€ ์ˆ˜์ค€์˜ ๋ณด๊ฐ„ ๋Œ€์‹  ์ฝ”๋”ฉ ์ˆ˜์ค€์—์„œ ๋‘ ์ด๋ฏธ์ง€๋ฅผ ๋ณด๊ฐ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์˜ˆ) ์ž ์žฌ ๊ณต๊ฐ„์— ์žˆ๋Š” ์ž„์˜์˜ ์„ ๋ถ„์„ ๋”ฐ๋ผ ๋ช‡ ๊ฐœ์˜ ์ฝ”๋”ฉ์„ ์„ ํƒํ•˜์—ฌ ๋””์ฝ”๋”ฉํ•˜๋ฉด, ์ ์ง„์ ์œผ๋กœ ๋ฐ”๋€Œ๋Š” ์—ฐ์†๋œ ์ด๋ฏธ์ง€๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. 

    codings = np.zeros([7, codings_size])
    codings[:, 3] = np.,inspace(-0.8, 0.8, 7)
    images = variational_decoder(codings).numpy()


    17.8 ์ƒ์„ฑ์  ์ ๋Œ€ ์‹ ๊ฒฝ๋ง

    ์ƒ์„ฑ์ž : ๋žœ๋คํ•œ ๋ถ„ํฌ(์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ€์šฐ์Šค ๋ถ„ํฌ)๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๊ณ  ์ด๋ฏธ์ง€์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. 

    ๋žœ๋คํ•œ ์ž…๋ ฅ์€ ์ƒ์„ฑํ•  ์ด๋ฏธ์ง€์˜ ์ž ์žฌ ํ‘œํ˜„(์ฝ”๋”ฉ)์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์ƒ์„ฑ์ž๋Š” ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”์˜ ๋””์ฝ”๋”์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

    → ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.(๊ฐ€์šฐ์Šค ์žก์Œ์„ ์ฃผ์ž…ํ•˜์—ฌ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.)

    ํŒ๋ณ„์ž : ์ƒ์„ฑ์ž์—์„œ ์–ป์€ ๊ฐ€์งœ ์ด๋ฏธ์ง€๋‚˜ ํ›ˆ๋ จ ์„ธํŠธ์—์„œ ์ถ”์ถœํ•œ ์ง„์งœ ์ด๋ฏธ์ง€๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์•„ ์ž…๋ ฅ๋œ ์ด๋ฏธ์ง€๊ฐ€ ๊ฐ€์งœ์ธ์ง€ ์ง„์งœ์ธ์ง€ ๊ตฌ๋ถ„ํ•œ๋‹ค.

     

    ํ›ˆ๋ จํ•˜๋Š” ๋™์•ˆ ์ƒ์„ฑ์ž์™€ ํŒ๋ณ„์ž์˜ ๋ชฉํ‘œ๋Š” ๋ฐ˜๋Œ€์ด๋‹ค.

    ํŒ๋ณ„์ž๋Š” ์ง„์งœ ์ด๋ฏธ์ง€์™€ ๊ฐ€์งœ ์ด๋ฏธ์ง€๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ณ  ์ƒ์„ฑ์ž๋Š” ํŒ๋ณ„์ž๋ฅผ ์†์ผ ๋งŒํผ ์ง„์งœ ๊ฐ™์€ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ ๋‹ค.

    GAN์€ ๋‹ค๋ฅธ ๋ชฉํ‘œ๋ฅผ ๊ฐ€์ง„ ๋‘ ๊ฐœ์˜ ๋„คํŠธ์›Œํฌ๋กœ ๊ตฌ์„ฑ๋˜๋ฏ€๋กœ ์ผ๋ฐ˜์ ์ธ ์‹ ๊ฒฝ๋ง์ฒ˜๋Ÿผ ํ›ˆ๋ จํ•  ์ˆ˜ ์—†๋‹ค.

     

    ๋จผ์ € ํŒ๋ณ„์ž๋ฅผ ํ›ˆ๋ จํ•œ๋‹ค. ํ›ˆ๋ จ ์„ธํŠธ์—์„œ ์‹ค์ œ ์ด๋ฏธ์ง€ ๋ฐฐ์น˜๋ฅผ ์ƒ˜ํ”Œ๋งํ•˜๊ณ  ์ƒ์„ฑ์ž์—์„œ ์ƒ์„ฑํ•œ ๋™์ผํ•œ ์ˆ˜์˜ ๊ฐ€์งœ ์ด๋ฏธ์ง€๋ฅผ ํ•ฉ์นœ๋‹ค. ๊ฐ€์งœ ์ด๋ฏธ์ง€์˜ ๋ ˆ์ด๋ธ”์€ 0์œผ๋กœ, ์ง„์งœ ์ด๋ฏธ์ง€๋Š” 1๋กœ ์„ค์ •ํ•œ๋‹ค. ํŒ๋ณ„์ž๋Š” ์ด์ง„ ํฌ๋กœ์Šค ์—”ํŠธ๋กœํ”ผ๋ฅผ ์‚ฌ์šฉํ•ด ํ•œ ์Šคํ… ๋™์•ˆ ์ด๋ ‡๊ฒŒ ๋ ˆ์ด๋ธ”๋œ ๋ฐฐ์น˜๋กœ ํ›ˆ๋ จ๋œ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ ์—ญ์ „ํŒŒ๋Š” ํŒ๋ณ„์ž์˜ ๊ฐ€์ค‘์น˜๋งŒ ์ตœ์ ํ™”ํ•œ๋‹ค.

    ๊ทธ๋‹ค์Œ ์ƒ์„ฑ์ž๋ฅผ ํ›ˆ๋ จํ•œ๋‹ค. ๋จผ์ € ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ด ๋‹ค๋ฅธ ๊ฐ€์งœ ์ด๋ฏธ์ง€ ๋ฐฐ์น˜๋ฅผ ๋งŒ๋“ ๋‹ค. ๋‹ค์‹œ ํŒ๋ณ„์ž๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฏธ์ง€๊ฐ€ ์ง„์งœ์ธ์ง€ ๊ฐ€์งœ์ธ์ง€ ํŒ๋ณ„ํ•œ๋‹ค. ๋ฐฐ์น˜์— ์ง„์งœ ์ด๋ฏธ์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ๋ ˆ์ด๋ธ”์„ ๋ชจ๋‘ 1(์ง„์งœ)๋กœ ์„ค์ •ํ•œ๋‹ค. ์ƒ์„ฑ์ž๊ฐ€ ํŒ๋ณ„์ž๊ฐ€ ์ง„์งœ๋ผ๊ณ  ๋ฏฟ์„ ๋งŒํ•œ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ์ด ๋‹จ๊ณ„ ๋™์•ˆ์—๋Š” ํŒ๋ณ„์ž์˜ ๊ฐ€์ค‘์น˜๋ฅผ ๋™๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋ฉฐ ์—ญ์ „ํŒŒ๋Š” ์ƒ์„ฑ์ž์˜ ๊ฐ€์ค‘์น˜์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค. 

     

    codings_size = 30
    
    Dense = tf.keras.layers.Dense
    generator = tf.keras.Sequential([
        Dense(100, activation="relu", kernel_initializer="he_normal"),
        Dense(150, activation="relu", kernel_initializer="he_normal"),
        Dense(28 * 28, activation="sigmoid"),
        tf.keras.layers.Reshape([28, 28])
    ])
    
    discriminator = tf.keras.Sequential([
        tf.keras.layers.Flatten(),
        Dense(150, activation="relu", kernel_initializer="he_normal"),
        Dense(100, activation="relu", kernel_initializer="he_normal"),
        Dense(1, activation="sigmoid")
    ])
    gan = tf.keras.Sequential([generator, discriminator])

    ์ƒ์„ฑ์ž์™€ ํŒ๋ณ„์ž๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

    ์ƒ์„ฑ์ž๋Š” ์˜คํ† ์ธ์ฝ”๋”์˜ ๋””์ฝ”๋”์™€ ๋น„์Šทํ•˜๋ฉฐ ์ผ๋ฐ˜์ ์ธ ์ด์ง„ ๋ถ„๋ฅ˜๊ธฐ์ด๋‹ค.

    (์ด๋ฏธ์ง€๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๊ณ  ํ•˜๋‚˜์˜ ์œ ๋‹›๊ณผ ์‹œ๊ทธ๋ชจ์ด๋“œ ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ Dense ์ธต์œผ๋กœ ๋๋‚œ๋‹ค.)

    ๊ฐ ํ›ˆ๋ จ ๋ฐ˜๋ณต์˜ ๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ ์ƒ์„ฑ์ž์™€ ํŒ๋ณ„์ž๊ฐ€ ์—ฐ๊ฒฐ๋œ ์ „์ฒด GAN ๋ชจ๋ธ์ด ํ•„์š”ํ•˜๋‹ค. 

    discriminator.compile(loss="binary_crossentropy", optimizer="rmsprop")
    discriminator.trainable = False
    gan.compile(loss="binary_crossentropy", optimizer="rmsprop")

    ์ด ๋ชจ๋ธ๋“ค์„ ์ปดํŒŒ์ผํ•œ๋‹ค.

    ํŒ๋ณ„์ž๋Š” ์ด์ง„ ๋ถ„๋ฅ˜๊ธฐ์ด๋ฏ€๋กœ ์ด์ง„ ํฌ๋กœ์Šค ์—”ํŠธ๋กœํ”ผ ์†์‹ค์„ ์‚ฌ์šฉํ•œ๋‹ค.

    gan ๋ชจ๋ธ๋„ ์ด์ง„ ๋ถ„๋ฅ˜๊ธฐ์ด๋ฏ€๋กœ ์ด์ง„ ํฌ๋กœ์Šค ์—”ํŠธ๋กœํ”ผ ์†์‹ค์„ ์‚ฌ์šฉํ•œ๋‹ค.

    ํ•˜์ง€๋งŒ ์ƒ์„ฑ์ž๋Š” gan ๋ชจ๋ธ์„ ํ†ตํ•ด์„œ๋งŒ ํ›ˆ๋ จ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ์ปดํŒŒ์ผํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

    ๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ ํŒ๋ณ„์ž๋ฅผ ํ›ˆ๋ จํ•˜๋ฉด ์•ˆ ๋œ๋‹ค. (์ค‘์š”)

    → gan ๋ชจ๋ธ์„ ์ปดํŒŒ์ผํ•˜๊ธฐ ์ „์— ํŒ๋ณ„์ž๊ฐ€ ํ›ˆ๋ จ๋˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค.

    batch_size = 32
    dataset = tf.data.Dataset.from_tensor_slices(X_train).shuffle(buffer_size=1000)
    dataset = dataset.batch(batch_size, drop_remainder=True).prefetch(1)

    ํ›ˆ๋ จ์ด ์ผ๋ฐ˜์ ์ธ ๋ฐ˜๋ณต์ด ์•„๋‹ˆ๋ฏ€๋กœ fit() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

    ๋Œ€์‹  ์‚ฌ์šฉ์ž ์ •์˜ ํ›ˆ๋ จ ๋ฐ˜๋ณต๋ฌธ์„ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋ฉฐ ๋จผ์ € ์ด๋ฏธ์ง€๋ฅผ ์ˆœํšŒํ•˜๋Š” Dataset์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

    def train_gan(gan, dataset, batch_size, codings_size, n_epochs):
        generator, discriminator = gan.layers
        
        for epoch in range(n_epochs):
            for X_batch in dataset:
                # ๋‹จ๊ณ„ 1 - ํŒ๋ณ„์ž ํ›ˆ๋ จ
                noise = tf.random.normal(shape=[batch_size, codings_size])
                generated_images = generator(noise)
                X_fake_and_real = tf.concat([generated_images, X_batch], axis=0)
                y1 = tf.constant([[0.]] * batch_size + [[1.]] * batch_size)
                discriminator.train_on_batch(X_fake_and_real, y1)
                # ๋‹จ๊ณ„ 2 - ์ƒ์„ฑ์ž ํ›ˆ๋ จ
                noise = tf.random.normal(shape=[batch_size, codings_size])
                y2 = tf.constant([[1.]] * batch_size)
                gan.train_on_batch(noise, y2)
                
    train_gan(gan, dataset, batch_size, codings_size, n_epochs=50)

    ๊ฐ ๋ฐ˜๋ณต๋งˆ๋‹ค ๋‘ ๋‹จ๊ณ„๊ฐ€ ์žˆ๋‹ค. 

    ๊ฐ€์šฐ์Šค ์žก์Œ์„ ์ƒ์„ฑ์ž์— ์ฃผ์ž…ํ•˜์—ฌ ๊ฐ€์งœ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ด์™€ ๋™์ผํ•œ ๊ฐœ์ˆ˜์˜ ์ง„์งœ ์ด๋ฏธ์ง€๋ฅผ ํ•ฉ์ณ์„œ ๋ฐฐ์น˜๋ฅผ ์™„์„ฑํ•œ๋‹ค. ํƒ€๊นƒ y1๋Š” ๊ฐ€์งœ ์ด๋ฏธ์ง€์ผ ๊ฒฝ์šฐ 0, ์ง„์งœ ์ด๋ฏธ์ง€๋Š” 1๋กœ ์„ค์ •ํ•œ๋‹ค. ์ด ๋ฐฐ์น˜์—์„œ ํŒ๋ณ„์ž๋ฅผ ํ›ˆ๋ จํ•œ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ๋Š” ํŒ๋ณ„์ž๋งŒ ํ›ˆ๋ จ๋œ๋‹ค.

    GAN์— ๊ฐ€์šฐ์Šค ์žก์Œ์„ ์ฃผ์ž…ํ•œ๋‹ค. ์ƒ์„ฑ์ž๊ฐ€ ๋จผ์ € ๊ฐ€์งœ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํŒ๋ณ„์ž๊ฐ€ ์ด ์ด๋ฏธ์ง€๊ฐ€ ๊ฐ€์งœ์ธ์ง€ ์ง„์งœ์ธ์ง€ ์ถ”์ธกํ•œ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ ์ƒ์„ฑ์ž๋ฅผ ํ–ฅ์ƒ์‹œ์ผœ์•ผ ํ•œ๋‹ค. ์ฆ‰, ํŒ๋ณ„์ž๊ฐ€ ์‹คํŒจํ•ด์•ผ ํ•œ๋‹ค. ์ด ๋•Œ๋ฌธ์— ํƒ€๊นƒ y2๋ฅผ 1๋กœ ์ง€์ •ํ•œ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ๋Š” ํŒ๋ณ„์ž๊ฐ€ ํ›ˆ๋ จ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ gan ๋ชจ๋ธ์—์„œ ํ–ฅ์ƒ๋˜๋Š” ๋ถ€๋ถ„์€ ์ƒ์„ฑ์ž๋ฟ์ด๋‹ค.

    codings = tf.random.normal(shape=[batch_size, codings_size])
    generated_images = generator.predict(codings)

    ํ›ˆ๋ จ์ด ๋๋‚œ ํ›„์— ๊ฐ€์šฐ์Šค ๋ถ„ํฌ์—์„œ ๋žœ๋คํ•˜๊ฒŒ ์ฝ”๋”ฉ์„ ์ƒ˜ํ”Œ๋งํ•˜์—ฌ ์ƒ์„ฑ์ž์— ์ฃผ์ž…ํ•˜๋ฉด ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

    17.8.1 GAN ํ›ˆ๋ จ์˜ ์–ด๋ ค์›€

    ํ›ˆ๋ จ์ด ์ง„ํ–‰๋จ์— ๋”ฐ๋ผ ๋‚ด์‹œ ๊ท ํ˜•์ด๋ผ ๋ถ€๋ฅด๋Š” ์ƒํƒœ์— ๋‹ค๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค.

    ๋‹ค๋ฅธ ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์ „๋žต์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ฏ€๋กœ ์–ด๋–ค ํ”Œ๋ ˆ์ด์–ด๋„ ์ž์‹ ์˜ ์ „๋žต์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š์œผ๋ ค๋Š” ์ƒํƒœ๋ฅผ ๋งํ•œ๋‹ค.

    GAN์„ ์ถฉ๋ถ„ํžˆ ์˜ค๋ž˜ ํ›ˆ๋ จํ•˜๋ฉด ์™„๋ฒฝํ•œ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด ์ด ๊ท ํ˜•์— ๋„๋‹ฌํ•  ๊ฒƒ์ด์ง€๋งŒ ์–ด๋–ค ๊ฒƒ๋„ ์ด ๊ท ํ˜•์— ๋„๋‹ฌํ•  ๊ฒƒ์ด๋ผ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

    ์ƒ์„ฑ์ž์˜ ์ถœ๋ ฅ์˜ ๋‹ค์–‘์„ฑ์ด ์ค„์–ด๋“ค ๋•Œ ๋ชจ๋“œ ๋ถ•๊ดด๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. 

    ์ƒ์„ฑ์ž์™€ ํŒ๋ณ„์ž๊ฐ€ ์ง€์†์ ์œผ๋กœ ์„œ๋กœ์—๊ฒŒ ์˜ํ–ฅ์„ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ํŒŒ๋ผ๋ฏธํ„ฐ ๋ณ€๋™์ด ํฌ๊ณ  ๋ถˆ์•ˆ์ •ํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

     

    ๊ฒฝํ—˜ ์žฌ์ƒ ๊ธฐ๋ฒ•์€ ๋งค ๋ฐ˜๋ณต์—์„œ ์ƒ์„ฑ์ž๊ฐ€ ๋งŒ๋“  ์ด๋ฏธ์ง€๋ฅผ (์˜ค๋ž˜๋œ ์ด๋ฏธ์ง€๋Š” ์‚ญ์ œํ•˜๋ฉด์„œ) ์žฌ์ƒ ๋ฒ„ํผ์— ์ €์žฅํ•˜๊ณ  ์‹ค์ œ ์ด๋ฏธ์ง€์™€ (ํ˜„์žฌ ์ƒ์„ฑ์ž๊ฐ€ ๋งŒ๋“  ๊ฐ€์งœ ์ด๋ฏธ์ง€๊ฐ€ ์•„๋‹ˆ๋ผ) ์ด ๋ฒ„ํผ์—์„œ ๋ฝ‘์€ ๊ฐ€์งœ ์ด๋ฏธ์ง€๋ฅผ ๋”ํ•ด์„œ ํŒ๋ณ„์ž๋ฅผ ํ›ˆ๋ จํ•œ๋‹ค. 

    ์ด๋Š” ํŒ๋ณ„์ž๊ฐ€ ์ƒ์„ฑ์ž์˜ ๊ฐ€์žฅ ์ตœ๊ทผ ์ถœ๋ ฅ์— ๊ณผ๋Œ€์ ํ•ฉ๋  ๊ฐ€๋Šฅ์„ฑ์„ ์ค„์ธ๋‹ค. 

    ๋ฏธ๋‹ˆ๋ฐฐ์น˜ ํŒ๋ณ„ ๊ธฐ๋ฒ•์€ ๋ฐฐ์น˜ ๊ฐ„์— ์–ผ๋งˆ๋‚˜ ๋น„์Šทํ•œ ์ด๋ฏธ์ง€๊ฐ€ ์žˆ๋Š”์ง€ ์ธก์ •ํ•˜์—ฌ ํŒ๋ณ„์ž์—๊ฒŒ ์ œ๊ณตํ•œ๋‹ค. 

    ํŒ๋ณ„์ž๋Š” ๋‹ค์–‘์„ฑ์ด ๋ถ€์กฑํ•œ ๊ฐ€์งœ ์ด๋ฏธ์ง€ ๋ฐฐ์น˜ ์ „์ฒด๋ฅผ ์‰ฝ๊ฒŒ ๊ฑฐ๋ถ€ํ•  ์ˆ˜ ์žˆ๋‹ค. -> ๋ชจ๋“œ ๋ถ•๊ดด ์œ„ํ—˜์„ ์ค„์ธ๋‹ค.

    17.8.2 ์‹ฌ์ธต ํ•ฉ์„ฑ๊ณฑ GAN

    [์•ˆ์ •์ ์ธ ํ•ฉ์„ฑ๊ณฑ GAN์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ์ œ์•ˆ๋œ ์ฃผ์š” ๊ฐ€์ด๋“œ๋ผ์ธ]

    ํŒ๋ณ„์ž์— ์žˆ๋Š” ํ’€๋ง ์ธต์„ ์ŠคํŠธ๋ผ์ด๋“œ ํ•ฉ์„ฑ๊ณฑ์œผ๋กœ ๋ฐ”๊พธ๊ณ  ์ƒ์„ฑ์ž์— ์žˆ๋Š” ํ’€๋ง ์ธต์€ ์ „์น˜ ํ•ฉ์„ฑ๊ณฑ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

    ์ƒ์„ฑ์ž์™€ ํŒ๋ณ„์ž์— ๋ฐฐ์น˜ ์ •๊ทœํ™”๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ƒ์„ฑ์ž์˜ ์ถœ๋ ฅ ์ธต๊ณผ ํŒ๋ณ„์ž์˜ ์ž…๋ ฅ ์ธต์€ ์ œ์™ธํ•œ๋‹ค.

    ์ธต์„ ๊นŠ๊ฒŒ ์Œ“๊ธฐ ์œ„ํ•ด ์™„์ „ ์—ฐ๊ฒฐ ์€๋‹‰ ์ธต์„ ์ œ๊ฑฐํ•œ๋‹ค.

    tanh ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ถœ๋ ฅ ์ธต์„ ์ œ์™ธํ•˜๊ณ  ์ƒ์„ฑ์ž์˜ ๋ชจ๋“  ์ธต์€ ReLU ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

    ํŒ๋ณ„์ž์˜ ๋ชจ๋“  ์ธต์€ LeakyReLU ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

    17.8.3 ProGAN

    ํ›ˆ๋ จ ์ดˆ๊ธฐ์— ์ž‘์€ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ ์ง„์ ์œผ๋กœ ์ƒ์„ฑ์ž์™€ ํŒ๋ณ„์ž์— ํ•ฉ์„ฑ๊ณฑ ์ธต์„ ์ถ”๊ฐ€ํ•ด ๊ฐˆ์ˆ˜๋ก ํฐ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ ๋‹ค.

    ์ด์ „์— ํ›ˆ๋ จ๋œ ์ธต์€ ๊ทธ๋Œ€๋กœ ํ›ˆ๋ จ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋‘๊ณ  ์ƒ์„ฑ์ž์˜ ๋๊ณผ ํŒ๋ณ„์ž์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— ์ธต์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

    ์ƒ์„ฑ์ž์˜ ์ถœ๋ ฅ์„ 4x4์—์„œ 8x8๋กœ ํฌ๊ฒŒ ํ•˜๋ ค๋ฉด ๊ธฐ์กด ํ•ฉ์„ฑ๊ณฑ ์ธต(ํ•ฉ์„ฑ๊ณฑ ์ธต 1)์— (์ตœ๊ทผ์ ‘ ์ด์›ƒ ํ•„ํ„ฐ๋ง์„ ์‚ฌ์šฉํ•œ) ์—…์ƒ˜ํ”Œ๋ง ์ธต์„ ์ถ”๊ฐ€ํ•˜์—ฌ 8x8 ํฌ๊ธฐ ํŠน์„ฑ ๋งต์„ ์ถœ๋ ฅํ•œ๋‹ค.

    ์ด ํŠน์„ฑ ๋งต์ด ์ƒˆ๋กœ์šด ํ•ฉ์„ฑ๊ณฑ ์ธต(ํ•ฉ์„ฑ๊ณฑ ์ธต 2)์œผ๋กœ ์ฃผ์ž…๋˜๊ณ  ๋‹ค์‹œ ์ƒˆ๋กœ์šด ์ถœ๋ ฅ์ด ํ•ฉ์„ฑ๊ณฑ ์ธต์œผ๋กœ ์ฃผ์ž…๋œ๋‹ค.

    ํ•ฉ์„ฑ๊ณฑ ์ธต 1์˜ ํ›ˆ๋ จ๋œ ๊ฐ€์ค‘์น˜๋ฅผ ์žƒ์ง€ ์•Š๊ธฐ ์œ„ํ•ด ๋‘ ๊ฐœ์˜ ์ƒˆ๋กœ์šด ํ•ฉ์„ฑ๊ณฑ ์ธต์„ ์ ์ง„์ ์œผ๋กœ ํŽ˜์ด๋“œ-์ธํ•˜๊ณ  ์›๋ž˜ ์ถœ๋ ฅ ์ธต์„ ํŽ˜์ด๋“œ-์•„์›ƒํ•œ๋‹ค.

    ์ด๋ ‡๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ์šด ์ถœ๋ ฅ(๊ฐ€์ค‘์น˜ α)๊ณผ ์›๋ž˜ ์ถœ๋ ฅ(๊ฐ€์ค‘์น˜ 1 - α)์˜ ๊ฐ€์ค‘์น˜ ํ•ฉ์œผ๋กœ ์ตœ์ข… ์ถœ๋ ฅ์„ ๋งŒ๋“ ๋‹ค.

    ๋น„์Šทํ•œ ํŽ˜์ด๋“œ-์ธ/ํŽ˜์ด๋“œ-์•„์›ƒ ๊ธฐ๋ฒ„์ด ํŒ๋ณ„์ž์— ์ƒˆ๋กœ์šด ํ•ฉ์„ฑ๊ณฑ ์ธต์„ ์ถ”๊ฐ€ํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. (๋‹ค์šด์ƒ˜ํ”Œ๋ง์„ ์œ„ํ•ด ํ‰๊ท  ํ’€๋ง ์ธต์ด ๋’ค๋”ฐ๋ฅธ๋‹ค.)

    ๋ชจ๋“  ํ•ฉ์„ฑ๊ณฑ ์ธต์€ "same" ์ŠคํŠธ๋ผ์ด๋“œ 1์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์ž…๋ ฅ์˜ ๋†’์ด์™€ ๋„ˆ๋น„๋ฅผ ๋ณด์กดํ•œ๋‹ค.

    ์›๋ž˜ ํ•ฉ์„ฑ๊ณฑ ์ธต๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค.

    ๋”ฐ๋ผ์„œ 8x8 ์ถœ๋ ฅ์„ ๋งŒ๋“ ๋‹ค.

    ์ถœ๋ ฅ ์ธต์˜ ์ปค๋„ ํฌ๊ธฐ๋Š” 1์ด๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•ด ์ž…๋ ฅ์„ ํ•„์š”ํ•œ ์ปฌ๋Ÿฌ ์ฑ„๋„ ์ˆ˜๋กœ ํˆฌ์˜ํ•œ๋‹ค. 

     

    ๋ฏธ๋‹ˆ๋ฐฐ์น˜ ํ‘œ์ค€ ํŽธ์ฐจ ์ธต

    ํŒ๋ณ„์ž์˜ ๋งˆ์ง€๋ง‰ ์ธต ๊ทผ์ฒ˜์— ์ถ”๊ฐ€ํ•œ๋‹ค.

    S = tf.math.reduce_std(inputs, axis=[0, -1]))

    ์ž…๋ ฅ์— ์žˆ๋Š” ๋ชจ๋“  ์œ„์น˜์— ๋Œ€ํ•ด ๋ชจ๋“  ์ฑ„๋„๊ณผ ๋ฐฐ์น˜์˜ ๋ชจ๋“  ์ƒ˜ํ”Œ์— ๊ฑธ์ณ ํ‘œ์ค€ํŽธ์ฐจ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.

     

    v = tf.reduce_mean(S))

    ์ด ํ‘œ์ค€ ํŽธ์ฐจ๋ฅผ ๋ชจ๋“  ํ”ฝ์…€์— ๋Œ€ํ•ด ํ‰๊ท ํ•˜์—ฌ ํ•˜๋‚˜์˜ ๊ฐ’์„ ์–ป๋Š”๋‹ค.

    tf.concat([inputs, tf.fill([batch_size, height, width, 1], v)], axis=-1)

    ์ถ”๊ฐ€์ ์ธ ํŠน์„ฑ ๋งต์ด ๋ชจ๋“  ์ƒ˜ํ”Œ์— ์ถ”๊ฐ€๋˜๊ณ  ์•ž์„œ ๊ณ„์‚ฐ๋œ ํ•˜๋‚˜์˜ ๊ฐ’์œผ๋กœ ์ฑ„์›Œ์ง„๋‹ค. 

     

    ์ด ์ธต ๋•๋ถ„์— ํŒ๋ณ„์ž๋Š” ์ด๋Ÿฌํ•œ ํ†ต๊ณ„๋ฅผ ์‰ฝ๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ๊ณ  ๋‹ค์–‘์„ฑ์ด ์•„์ฃผ ์ ์€ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“œ๋Š” ์ƒ์„ฑ์ž์—๊ฒŒ ์†์„ ๊ฐ€๋Šฅ์„ฑ์ด ์ค„์–ด๋“ ๋‹ค.

     

    ๋™์ผํ•œ ํ•™์Šต ์†๋„

    He ์ดˆ๊ธฐํ™” ๋Œ€์‹  ํ‰๊ท ์ด 0์ด๊ณ  ํ‘œ์ค€ ํŽธ์ฐจ๊ฐ€ 1์ธ ๊ฐ€์šฐ์Šค ๋ถ„ํฌ๋ฅผ ์‚ฌ์šฉํ•ด ๋ชจ๋“  ๊ฐ€์ค‘์น˜๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

    ํ•˜์ง€๋งŒ ๋Ÿฐํƒ€์ž„์—(์ธต์ด ์‹คํ–‰๋  ๋•Œ๋งˆ๋‹ค) He ์ดˆ๊ธฐํ™”์— ์žˆ๋Š” ๋™์ผํ•œ ์ธ์ž๋กœ ๊ฐ€์ค‘์น˜์˜ ์Šค์ผ€์ผ์„ ๋‚ฎ์ถ˜๋‹ค.

    ์˜ตํ‹ฐ๋งˆ์ด์ €๋“ค์€ ๊ฐ์ž ์ถ”์ •ํ•œ ํ‘œ์ค€ ํŽธ์ฐจ๋กœ ๊ทธ๋ž˜์ด๋””์–ธํŠธ ์—…๋ฐ์ดํŠธ๋ฅผ ์ •๊ทœํ™”ํ•œ๋‹ค.

    → ๋‹ค์ด๋‚ด๋ฏน ๋ ˆ์ธ์ง€๊ฐ€ ํฐ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ํ›ˆ๋ จํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๊ณ , ์ž‘์€ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋„ˆ๋ฌด ๋น ๋ฅด๊ฒŒ ์—…๋ฐ์ดํŠธ๋˜์–ด ๋ถˆ์•ˆ์ •ํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค. 

    ๊ฐ€์ค‘์น˜ ์ดˆ๊ธฐํ™”์—์„œ ์Šค์ผ€์ผ์„ ๋งž์ถ”์ง€ ์•Š๊ณ  ๋ชจ๋ธ์˜ ํ•œ ๋ถ€๋ถ„์œผ๋กœ ๊ฐ€์ค‘์น˜๋ฅผ ์กฐ์ ˆํ•จ์œผ๋กœ์จ ํ›ˆ๋ จ ๋‚ด๋‚ด ๋ชจ๋“  ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๋‹ค์ด๋‚ด๋ฏน ๋ ˆ์ธ์ง€๋ฅผ ๋™์ผํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

    ๋”ฐ๋ผ์„œ ๋ชจ๋“  ๊ฐ€์ค‘์น˜๊ฐ€ ๋™์ผํ•œ ์†๋„๋กœ ํ•™์Šต๋œ๋‹ค.

     

    ํ”ฝ์…€๋ณ„ ์ •๊ทœํ™” ์ธต

    ์ƒ์„ฑ์ž์˜ ํ•ฉ์„ฑ๊ณฑ ์ธต ๋’ค์— ์ถ”๊ฐ€ํ•œ๋‹ค.

    ๋™์ผํ•œ ์ด๋ฏธ์ง€์˜ ๋™์ผ ์œ„์น˜์— ์žˆ๋Š” ๋ชจ๋“  ํ™œ์„ฑํ™”๋ฅผ ์ฑ„๋„์— ๋Œ€ํ•ด ์ •๊ทœํ™”๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค. (ํ™œ์„ฑํ™”์˜ ์ œ๊ณฑ ํ‰๊ท ์˜ ์ œ๊ณฑ๊ทผ์œผ๋กœ ๋‚˜๋ˆˆ๋‹ค.)

    inputs / tf.sqrt(tf.reduce_mean(tf.square(X), axis=-1, keepdims=True) + 1e - 8)

    ์ƒ์„ฑ์ž์™€ ํŒ๋ณ„์ž ์‚ฌ์ด์˜ ๊ณผ๋„ํ•œ ๊ฒฝ์Ÿ์œผ๋กœ ํ™œ์„ฑํ™” ๊ฐ’์ด ํญ์ฃผํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š”๋‹ค. 

     

    ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€์˜ ๋‹ค์–‘์„ฑ์„ ์ž๋™์œผ๋กœ ํ‰๊ฐ€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ’ˆ์งˆ์„ ํŒ๋‹จํ•˜๋Š” ๊ฒƒ์€ ํ›จ์”ฌ ๊นŒ๋‹ค๋กญ๊ณ  ์ฃผ๊ด€์ ์ธ ๋ฌธ์ œ์ด๋‹ค.

    ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€์™€ ํ›ˆใ„น๋…€ ์ด๋ฏธ์ง€์˜ ๊ตญ๋ถ€์ ์ธ ๊ตฌ์กฐ ์‚ฌ์ด์˜ ์œ ์‚ฌ๋„๋ฅผ ์—ฌ๋Ÿฌ ๊ทœ๋ชจ๋กœ ์ธก์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์ œ์•ˆ๋˜์—ˆ๋‹ค.

    17.8.4 StyleGAN

    ์ƒ์„ฑ์ž์— ์Šคํƒ€์ผ ํŠธ๋žœ์Šคํผ ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ด ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€๊ฐ€ ํ›ˆ๋ จ๋œ ์ด๋ฏธ์ง€์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ํฌ๊ธฐ์˜ ๊ตญ๋ถ€์ ์ธ ๊ตฌ์กฐ๋ฅผ ๊ฐ–๋„๋ก ๋งŒ๋“ค์–ด์กŒ๋‹ค.

    ํŒ๋ณ„์ž์™€ ์†์‹คํ•จ์ˆ˜๋Š” ๊ทธ๋Œ€๋กœ ๊ตฌ๋„ ์ƒ์„ฑ์ž๋งŒ ๋ณ€๊ฒฝํ–ˆ์œผ๋ฉฐ, ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€์˜ ํ’ˆ์งˆ์„ ํฌ๊ฒŒ ๋†’์—ฌ์ค€๋‹ค. 

    ๋„คํŠธ์›Œํฌ ๋‘ ๊ฐœ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

     

    ๋งคํ•‘ ๋„คํŠธ์›Œํฌ

    8๊ฐœ์˜ MLP๊ฐ€ ์ž ์žฌ ํ‘œํ˜„ z(์ฝ”๋”ฉ)๋ฅผ ๋ฒกํ„ฐ w๋กœ ๋งคํ•‘ํ•œ๋‹ค.

    ์ด ๋ฒกํ„ฐ๋Š” ์—ฌ๋Ÿฌ ์•„ํ•€ ๋ณ€ํ™˜์œผ๋กœ ์ „๋‹ฌ๋˜์–ด ๋ฒกํ„ฐ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. 

    ์ด ๋ฒกํ„ฐ๋Š” ๋ฏธ์„ธํ•œ ํ…์Šค์ฒ˜๋ถ€ํ„ฐ ๊ณ ์ˆ˜์ค€ ํŠน์„ฑ๊นŒ์ง€ ๊ฐ๊ธฐ ๋‹ค๋ฅธ ์ˆ˜์ค€์œผ๋กœ ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€์˜ ์Šคํƒ€์ผ์„ ์ œ์–ดํ•œ๋‹ค.

    ์ฝ”๋”ฉ์„ ์—ฌ๋Ÿฌ ์Šคํƒ€์ผ ๋ฒกํ„ฐ๋กœ ๋งคํ•‘ํ•œ๋‹ค. 

    ํ•ฉ์„ฑ ๋„คํŠธ์›Œํฌ

    ์ด๋ฏธ์ง€ ์ƒ์„ฑ์„ ์ฑ…์ž„์ง„๋‹ค.

    ์ผ์ •ํ•˜๊ฒŒ ํ•™์Šต๋œ ์ž…๋ ฅ์„ ๋ฐ›๋Š”๋‹ค. (ํ›ˆ๋ จ์ด ๋๋‚œ ํ›„์— ์ž…๋ ฅ์ด ์ผ์ •ํ•ด์ง€๊ณ  ํ›ˆ๋ จํ•˜๋Š” ๋™์•ˆ์—๋Š” ์—ญ์ „ํŒŒ์— ์˜ํ•ด ๊ณ„์† ๋ฐ”๋€๋‹ค.)

    ์ด ์ž…๋ ฅ์„ ํ•ฉ์„ฑ๊ณฑ ์ธต ์—ฌ๋Ÿฌ ๊ฐœ์™€ ์—…์ƒ˜ํ”Œ๋ง ์ธต์— ํ†ต๊ณผ์‹œํ‚จ๋‹ค.

    ์ž…๋ ฅ๊ณผ ํ™œ์„ฑํ™” ํ•จ์ˆ˜ ์ „์— ์žˆ๋Š” ๋ชจ๋“  ํ•ฉ์„ฑ๊ณฑ ์ธต์˜ ์ถœ๋ ฅ์— ์žก์Œ์ด ์กฐ๊ธˆ ์„ž์ธ๋‹ค.

    ์žก์Œ์ด ์„ž์ธ ๋‹ค์Œ์— ์ ์‘์  ์ธ์Šคํ„ด์Šค ์ •๊ทœํ™”(AdaIN) ์ธต์ด ๋”ฐ๋ฅธ๋‹ค.

    ๊ฐ ํŠน์„ฑ ๋งต์„ ๋…๋ฆฝ์ ์œผ๋กœ ํ‘œ์ค€ํ™”ํ•œ ๋‹ค์Œ ์Šคํƒ€์ผ ๋ฒกํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ ํŠน์„ฑ ๋งต์˜ ์Šค์ผ€์ผ๊ณผ ์ด๋™์„ ๊ฒฐ์ •ํ•œ๋‹ค

    ์Šคํƒ€์ผ ๋ฒกํ„ฐ์—๋Š” ํŠน์„ฑ ๋งต๋งˆ๋‹ค ํ•˜๋‚˜์˜ ์Šค์ผ€์ผ๊ณผ ํ•˜๋‚˜์˜ ํŽธํ–ฅ์ด ํฌํ•จ๋œ๋‹ค.

     

    [StyleGAN์˜ ์ƒ์„ฑ์ž ๊ตฌ์กฐ]

     

    ์ฝ”๋”ฉ๊ณผ ๋…๋ฆฝ์ ์œผ๋กœ ์žก์Œ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•˜๋‹ค.

    ์ดˆ๊ธฐ GAN์—์„œ๋Š” ์ด๋Ÿฐ ๋ฌด์ž‘์œ„์„ฑ์ด ์ฝ”๋”ฉ์ด๋‚˜ ์ƒ์„ฑ์ž ์ž์ฒด์—์„œ ๋งŒ๋“  ๋žœ๋คํ•œ ์žก์Œ์—์„œ ์™”๋‹ค.

    ์žก์Œ์ด ์ฝ”๋”ฉ์—์„œ ์˜จ๋‹ค๋Š” ๊ฒƒ์€ ์ƒ์„ฑ์ž๊ฐ€ ์ฝ”๋”ฉ์˜ ํ‘œํ˜„ ๋Šฅ๋ ฅ์˜ ์ƒ๋‹น ๋ถ€๋ถ„์„ ์žก์Œ์„ ์ €์žฅํ•˜๋Š” ๋ฐ ํ• ์• ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. (์†ํ•ด)

    ์ด ์žก์Œ์ด ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ต๊ณผํ•˜์—ฌ ์ƒ์„ฑ์ž์˜ ๋งˆ์ง€๋ง‰ ์ธต์— ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. (ํ›ˆ๋ จ ์†๋„๋ฅผ ๋А๋ฆฌ๊ฒŒ ํ•˜๋Š” ๋ถˆํ•„์š”ํ•œ ์ œ์•ฝ ์‚ฌํ•ญ)

    ๊ฐ๊ธฐ ๋‹ค๋ฅธ ์ˆ˜์ค€์—์„œ ๋™์ผํ•œ ์žก์Œ์ด ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ถ€ ์ธ๊ณต์ ์ธ ์š”์†Œ๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ๋‹ค.

    ์ƒ์„ฑ์ž๊ฐ€ ๋žœ๋คํ•œ ์žก์Œ์„ ์Šค์Šค๋กœ ๋งŒ๋“ค์–ด๋‚ธ๋‹ค๋ฉด ์‹ค์ œ์ฒ˜๋Ÿผ ๋ณด์ด์ง€ ์•Š๊ณ  ๋”์šฑ ์ธ๊ณต์ ์œผ๋กœ ๋ณด์ผ ๊ฒƒ์ด๋‹ค. (๋„คํŠธ์›Œํฌ ๋Šฅ๋ ฅ ๋‚ญ๋น„)

    → ๋ณ„๋„์˜ ์žก์Œ ์ž…๋ ฅ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ชจ๋“  ์ด์Šˆ๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค.

    GAN์€ ์ถ”๊ฐ€๋œ ์žก์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€์˜ ๊ฐ ๋ถ€๋ถ„์— ์ •ํ™•ํ•œ ์–‘์˜ ๋ฌด์ž‘์œ„์„ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. 

     

    ์ถ”๊ฐ€๋œ ์žก์Œ์€ ๊ฐ ์ˆ˜์ค€๋งˆ๋‹ค ๋‹ค๋ฅด๋‹ค.

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

    ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ถ”๊ฐ€๋˜๊ธฐ ์ „์— ํ•™์Šต๋œ ํŠน์„ฑ๋ณ„ ์Šค์ผ€์ผ๋ง ์ธ์ž๋กœ ์กฐ์ •๋œ๋‹ค.

     

    StyleGAN์€ ์ผ์ • ๋น„์œจ์˜ ์ด๋ฏธ์ง€๋ฅผ ๋‘ ๊ฐœ์˜ ๋‹ค๋ฅธ ์ฝ”๋”ฉ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋ฏน์‹ฑ ๊ทœ์ œ(์Šคํƒ€์ผ ๋ฏน์‹ฑ) ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค. 

    ์ฝ”๋”ฉ c_1๊ณผ c_2๊ฐ€ ๋งคํ•‘ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ต๊ณผํ•˜์—ฌ ๋‘ ์Šคํƒ€์ผ ๋ฒกํ„ฐ w_1๊ณผ w_2๋ฅผ ๋งŒ๋“ ๋‹ค.

    ๊ทธ๋‹ค์Œ ํ•ฉ์„ฑ ๋„คํŠธ์›Œํฌ๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ๋Š” ์Šคํƒ€์ผ w_1, ๋‚˜๋จธ์ง€ ๋‹จ๊ณ„์—์„œ๋Š” ์Šคํƒ€์ผ w_2๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

    ๋ณ€๊ฒฝ๋˜๋Š” ๋‹จ๊ณ„๋Š” ๋žœ๋คํ•˜๊ฒŒ ์„ ํƒ๋œ๋‹ค.

    → ๋„คํŠธ์›Œํฌ๊ฐ€ ์ธ์ ‘ํ•œ ์ˆ˜์ค€์˜ ์Šคํƒ€์ผ์ด ์ƒ๊ด€๊ด€๊ณ„๋ฅผ ๊ฐ€์ง„๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰๋Š”๋‹ค.

    ๊ฐ ์Šคํƒ€์ผ ๋ฒกํ„ฐ๊ฐ€ ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€์— ์žˆ๋Š” ์ œํ•œ๋œ ๊ฐœ์ˆ˜์˜ ์†์„ฑ์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” StyleGAN์˜ ๊ตญ์ง€์„ฑ์„ ์ด‰์ง„์‹œํ‚จ๋‹ค.


    17.9 ํ™•์‚ฐ ๋ชจ๋ธ

    ์žก์Œ ์ œ๊ฑฐ ํ™•์‚ฐ ํ™•๋ฅ  ๋ชจ๋ธ(DDPM)์€ GAN๋ณด๋‹ค ํ›ˆ๋ จํ•˜๊ธฐ ํ›จ์”ฌ ์‰ฝ๊ณ  ์ƒ์„ฑ๋˜๋Š” ์ด๋ฏธ์ง€๊ฐ€ ๋” ๋‹ค์–‘ํ•˜๊ณ  ํ’ˆ์งˆ์ด ํ›จ์”ฌ ๋” ๋†’๋‹ค.

    ํ•˜์ง€๋งŒ GAN์ด๋‚˜ VAE์— ๋น„ํ•ด ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๋งค์šฐ ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค.

    ํƒ€์ž„ ์Šคํ… t๋งˆ๋‹ค ํ‰๊ท ์ด 0์ด๊ณ  ๋ถ„์‚ฐ์ด β_t์ธ ๊ฐ€์šฐ์Šค ์žก์Œ์„ ์ด๋ฏธ์ง€์— ์กฐ๊ธˆ์”ฉ ์ถ”๊ฐ€ํ•œ๋‹ค. ์ด ์žก์Œ์Œ ๊ฐ ํ”ฝ์…€๋งˆ๋‹ค ๋…๋ฆฝ์ ์ด๋‹ค. (๋“ฑ๋ฐฉ์„ฑ)

    x_1, x_2 ๋“ฑ์œผ๋กœ ์‹œ์ž‘ํ•ด์„œ ๊ณ ์–‘์ด๊ฐ€ ์žก์Œ์— ์™„์ „ํžˆ ๊ฐ€๋ ค์ ธ ๋ณด์ด์ง€ ์•Š๋Š” ์ด๋ฏธ์ง€๋ฅผ ์–ป๋Š”๋‹ค. ๋งˆ์ง€๋ง‰ ํƒ€์ž„ ์Šคํ…์€ T๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค.

    ์ฆ‰, ์ ์ง„์ ์œผ๋กœ ๊ณ ์–‘์ด๋ฅผ ์žก์Œ์œผ๋กœ ๋’ค๋ฎ๋Š”๋‹ค. (์ •๋ฐฉํ–ฅ ๊ณผ์ •)

     

    ์ •๋ฐฉํ–ฅ ๊ณผ์ •์—์„œ ๊ฐ€์šฐ์Šค ์žก์Œ์„ ์ ์  ๋” ๋งŽ์ด ์ถ”๊ฐ€ํ•˜๋ฉด ํ”ฝ์…€๊ฐ’์ด ์ ์  ๋” ๊ฐ€์šฐ์Šค ๋ถ„ํฌ๊ฐ€ ๋œ๋‹ค.

    ๋งค ๋‹จ๊ณ„๋งˆ๋‹ค ํ”ฝ์…€๊ฐ’์ด root_(1 - β_t) ๋น„์œจ๋กœ ์กฐ๊ธˆ์”ฉ ์กฐ์ •๋œ๋‹ค.

    ์Šค์ผ€์ผ๋ง ๊ณ„์ˆ˜๊ฐ€ 1๋ณด๋‹ค ์•ฝ๊ฐ„ ์ž‘๊ธฐ ๋•Œ๋ฌธ์— ํ”ฝ์…€๊ฐ’์˜ ํ‰๊ท ์ด ์ ์ฐจ 0์— ๊ฐ€๊นŒ์›Œ์ง„๋‹ค.

    ๋˜ํ•œ ๋ถ„์‚ฐ์ด ์ ์ฐจ 1์— ์ˆ˜๋ ดํ•˜๋„๋ก ๋ณด์žฅํ•œ๋‹ค.

    ํ”ฝ์…€๊ฐ’์˜ ํ‘œ์ค€ ํŽธ์ฐจ๊ฐ€ root_(1 - β_t)๋กœ ์Šค์ผ€์ผ ์กฐ์ •๋˜๋ฏ€๋กœ ๋ถ„์‚ฐ์€ 1 - β_t(์Šค์ผ€์ผ๋ง ๊ณ„์ˆ˜์˜ ์ œ๊ณฑ)๋กœ ์Šค์ผ€์ผ ์กฐ์ •๋œ๋‹ค.

    ๊ฐ ๋‹จ๊ณ„์—์„œ ๋ถ„์‚ฐ β_t๋ฅผ ๊ฐ–๋Š” ๊ฐ€์šฐ์Šค ์žก์Œ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ๋–„๋ฌธ์— ๋ถ„์‚ฐ์€ 0์œผ๋กœ ์ค„์–ด๋“ค ์ˆ˜ ์—†๋‹ค. 

     

    [์ •๋ฐฉํ–ฅ ํ™•์‚ฐ ๊ณผ์ •์˜ ํ™•๋ฅ  ๋ถ„ํฌ q]

    x_0์ด ์ฃผ์–ด์ง€๋ฉด x_1, x_2, ..., x_t-1์„ ๊ณ„์‚ฐํ•  ํ•„์š” ์—†์ด ์ด๋ฏธ์ง€ x_t๋ฅผ ์ƒ˜ํ”Œ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์—ฌ๋Ÿฌ ๊ฐ€์šฐ์Šค ๋ถ„ํฌ์˜ ํ•ฉ๋„ ๊ฐ€์šฐ์Šค ๋ถ„ํฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ์žก์Œ์„ ํ•œ ๋ฒˆ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    x_t์—์„œ x_(t - 1)๋กœ ๊ฐ€๋Š” ์—ญ๋ฐฉํ–ฅ ๊ณผ์ •์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋ธ์„ ํ›ˆ๋ จ์‹œ์ผœ์•ผ ํ•œ๋‹ค. 

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

    ๊ณ ์–‘์ด ์ด๋ฏธ์ง€๊ฐ€ ๋งŽ์ด ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ์…‹์—์„œ ๋ชจ๋ธ์„ ํ›ˆ๋ จ์‹œํ‚จ ๋‹ค์Œ ๊ฐ€์šฐ์Šค ์žก์Œ์œผ๋กœ ๊ฐ€๋“ ์ฐฌ ์‚ฌ์ง„์„ ์ œ๊ณตํ•˜๋ฉด ๋ชจ๋ธ์ด ์ ์ฐจ ์ƒˆ๋กœ์šด ๊ณ ์–‘์ด๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋งŒ๋“ค ๊ฒƒ์ด๋‹ค. 

     

    ์ •๋ฐฉํ–ฅ ๊ณผ์ •์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„  ๋ถ„์‚ฐ ์Šค์ผ€์ค„์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

    def variance_schedule(T, s=0.008, max_veta=0.999):
        t = np.arrange(T + 1)
        f = np.cos((t / T + s) / (1 + s) * np.pi / 2) ** 2
        alpha = np.clip(f[1:] / f[:-1], 1 - max_beta, 1)
        alpha = np.append(1, alpha).astype(np.float32)
        beta = 1 - alpha
        alpha_cumprod = np.cumprod(alpha)
        return alpha, alpha_cumprod, beta
        
    T = 4000
    alpha, alpha_cumprod, beta = variance_schedule(T)
    def prepare_batch(X):
        X = tf.cast(X[..., tf.newaxis]. tf.float32) * 2 - 1
        X_shape = tf.shape(X)
        t = tf.random.uniform([X_shape[0]], minval=1, maxval=T + 1, dtype=tf.int32)
        alpha_cm = tf.gather(alpha_cumprod, t)
        alpha_cm = tf.reshape(alpha_cm, [X_shape[0]] + [1] * (len(X_shape) - 1))
        noise = tf.random.normal(X_shape)
        return {
            "X_noisy": alpha_cm ** 0.5 * X + (1 - alpha_cm) ** 0.5 * noise,
            "time": t,
        }, noise

    ์ฑ„๋„ ์ถ•์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค. ํ”ฝ์…€๊ฐ’์„ -1์—์„œ 1๋กœ ์Šค์ผ€์ผ ์กฐ์ •ํ•˜์—ฌ ํ‰๊ท ์ด 0์ด๊ณ  ๋ถ„์‚ฐ์ด 1์ธ ์ตœ์ข… ๊ฐ€์šฐ์Šค ๋ถ„ํฌ์— ๊ฐ€๊น๊ฒŒ ๋งŒ๋“ ๋‹ค.

    ๋ฐฐ์น˜์˜ ๊ฐ ์ด๋ฏธ์ง€์— ๋Œ€ํ•ด 1์—์„œ T ์‚ฌ์ด์˜ ์ž„์˜์˜ ํƒ€์ž„ ์Šคํ…์„ ํฌํ•จํ•˜๋Š” ๋ฒกํ„ฐ t๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

    tf.gather()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒกํ„ฐ t์˜ ๊ฐ ํƒ€์ž„ ์Šคํ…์— ๋Œ€ํ•œ alpha_cumprod ๊ฐ’์„ ์ถ”์ถœํ•œ๋‹ค. ๊ฐ ์ด๋ฏธ์ง€์— ๋Œ€ํ•ด ์ง๋Œ€๊ธฐ α_t ๊ฐ’์ด ํ•˜๋‚˜์”ฉ ํฌํ•จ๋œ ๋ฒกํ„ฐ alpha_cm์ด ๋งŒ๋“ค์–ด์ง„๋‹ค.

    alpha_cm์„ [๋ฐฐ์น˜ ํฌ๊ธฐ]์—์„œ [๋ฐฐ์น˜ ํฌ๊ธฐ, 1, 1, 1]๋กœ ํฌ๊ธฐ๋ฅผ ๋ฐ”๊พผ๋‹ค. (๋ฐฐ์น˜ X์— alpha_cm์„ ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…ํ•˜๊ธฐ ์œ„ํ•ด)

    ํ‰๊ท ์ด 0์ด๊ณ  ๋ถ„์‚ฐ์ด 1์ธ ๊ฐ€์šฐ์Šค ์žก์Œ์„ ์ƒ์„ฑํ•œ๋‹ค.

    ์œ„์˜ ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€์— ํ™•์‚ฐ ๊ณผ์ •์„ ์ ์šฉํ•œ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์ž…๋ ฅ๊ณผ ํƒ€๊นƒ์„ ํฌํ•จํ•˜๋Š” ํŠœํ”Œ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ž…๋ ฅ์€ ์žก์Œ ์ด๋ฏธ์ง€์™€ ์ด๋ฏธ์ง€ ์ƒ์„ฑ์— ์‚ฌ์šฉ๋œ ํƒ€์ž„ ์Šคํ…์ด ํฌํ•จ๋œ ํŒŒ์ด์ฌ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ํ‘œํ˜„๋œ๋‹ค. ํƒ€๊นƒ์€ ๊ฐ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ ๊ฐ€์šฐ์Šค ์žก์Œ์ด๋‹ค. 

     

    ์ด๋Ÿฐ ์„ค์ •์œผ๋กœ ๋ชจ๋ธ์€ ์›๋ณธ ์ด๋ฏธ์ง€๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ์ž…๋ ฅ ์ด๋ฏธ์ง€์—์„œ ๋นผ์•ผ ํ•˜๋Š” ์žก์Œ์„ ์˜ˆ์ธกํ•œ๋‹ค.

     

    def prepare_dataset(X, batch_size=32, shuffle=False):
        ds = tf.data.Datase.from_tensor_slices(X)
        if shuffle:
            ds = ds.shuffle(buffer_size=10_000)
        return ds.batch(batch_size).map(prepare_batch).prefetch(1)
    
    train_set = prepare_dataset(X_train, batch_size=32, shuffle=True)
    valid_set = prepare_dataset(X_valid, batch_size=32)

    ํ›ˆ๋ จ ๋ฐ์ดํ„ฐ์…‹๊ณผ ๊ฒ€์ฆ ๋ฐ์ดํ„ฐ์…‹์„ ๋งŒ๋“ค๊ณ  ๋ชจ๋“  ๋ฐฐ์น˜์— prepare_batch() ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•œ๋‹ค.

    ์ด์ „์ฒ˜๋Ÿผ X_train๊ณผ X_valid์—๋Š” ํ”ฝ์…€๊ฐ’์ด 0์—์„œ 1 ์‚ฌ์ด์ธ ํŒจ์…˜ MNIST ์ด๋ฏธ์ง€๊ฐ€ ๋‹ด๊ฒจ์žˆ๋‹ค.

    def build_diffusion_model():
        X_noisy = tf.keras.layers.Input(shape=[28, 28, 1], name="X_noisy")
        time_input = tf.keras.layers.Input(shape=[], dtype=tf.int32, name="time")
        [...]
        outputs = [...]
        return tf.keras.Model(inputs=[X_noisy, time_input], outputs=[outputs])

    ํ™•์‚ฐ ๋ชจ๋ธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์žก์Œ ์ด๋ฏธ์ง€์™€ ํƒ€์ž„ ์Šคํ…์„ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๊ณ  ์ž…๋ ฅ์—์„œ ๋บ„ ์žก์Œ์„ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์–ด๋–ค ๋ชจ๋ธ์ด๋“  ๊ฐ€๋Šฅํ•˜๋‹ค.

    model = build_deffusion_model()
    model.compile(loss=tf.keras.losses.Huber(), optimizer="nadam")
    history = model.fit(train_set, validation_data=valid_set, epochs=100)

    ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•  ์ˆ˜ ์ž‡๋‹ค.

     

    ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•˜๊ณ  ๋‚˜๋ฉด ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์—ญ๋ฐฉํ–ฅ ํ™•์‚ฐ ๊ณผ์ •์—๋Š” ์ง€๋ฆ„๊ธธ์ด ์—†๋‹ค.

    ํ‰๊ท ์ด 0์ด๊ณ  ๋ถ„์‚ฐ์ด 1์ธ ๊ฐ€์šฐ์Šค ๋ถ„ํฌ์—์„œ x_T๋ฅผ ๋žœ๋ค์œผ๋กœ ์ƒ˜ํ”Œ๋งํ•œ ๋‹ค์Œ ๋ชจ๋ธ์— ์ „๋‹ฌํ•˜์—ฌ ์žก์Œ์„ ์˜ˆ์ธกํ•œ๋‹ค.

    ๊ทธ๋‹ค์Œ ์‹์„ ์ด์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€์—์„œ ์žก์Œ์„ ๋บ€๋‹ค.

    x_0๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

    ์ด ์‹์—์„œ ε_θ(x_t, t)๋Š” ์ž…๋ ฅ ์ด๋ฏธ์ง€ x_t์™€ ํƒ€์ž„ ์Šคํ… t๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ ๋ชจ๋ธ์ด ์˜ˆ์ธกํ•œ ์žก์Œ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. 

    θ์€ ๋ชจ๋ธ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. z๋Š” ํ‰๊ท ์ด 0์ด๊ณ  ๋ถ„์‚ฐ์ด 1์ธ ๊ฐ€์šฐ์Šค ์žก์Œ์ด๋‹ค.

     

    def generate(model, batch_size=32):
        X = tf.random.normal([batch_size, 28, 28, 1])
        for t in range(T, 0, -1):
            noise = (tf.random.normal if t > 1 else tf.zeros)(tf.shape(X))
            X_noise = model({"X_noisy": X, "time": tf.constant([t] * batch_size)})
            X = (
                1 / alpha[t] ** 0.5
                * (X - beta[t] / (1 - alpha_cumprod[t]) ** 0.5 * X_noise)
                + (1 - alpha[t]) ** 0.5 * noise
            )
        return X
    
    X_gen = generate(model)

    ๋ชจ๋ธ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์†๋„๊ฐ€ ๋А๋ฆฌ๋‹ค. 

     

    ์ž ์žฌ ํ™•์‚ฐ ๋ชจ๋ธ : ๊ฐ•๋ ฅํ•œ ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ›ˆ๋ จ ์ด๋ฏธ์ง€๋ฅผ ํ›จ์”ฌ ๋” ์ž‘์€ ์ž ์žฌ ๊ณต๊ฐ„์œผ๋กœ ์••์ถ•ํ•˜์—ฌ ํ™•์‚ฐ ๊ณผ์ •์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

    ๊ทธ๋‹ค์Œ ์˜คํ† ์ธ์ฝ”๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ข… ์ž ์žฌ ํ‘œํ˜„์˜ ์••์ถ•์„ ํ’€๊ณ  ์ถœ๋ ฅ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

    ์ด๋ฏธ์ง€ ์ƒ์„ฑ ์†๋„๊ฐ€ ์ƒ๋‹นํžˆ ๋นจ๋ผ์ง€๊ณ  ํ›ˆ๋ จ ์‹œ๊ฐ„๊ณผ ๋น„์šฉ์ด ํฌ๊ฒŒ ์ค„์–ด๋“ค๋ฉฐ ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€์˜ ํ’ˆ์งˆ์ด ์•„์ฃผ ๋›ฐ์–ด๋‚˜๋‹ค. 

Designed by Tistory.