-
โฑ ํธ์ฆ์จ ๋จธ์ ๋ฌ๋ 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)๋ชจ๋ธ์ ์ฌ๋ฌ ๋ฒ ํธ์ถํด์ผ ํ๋ฏ๋ก ์ด๋ฏธ์ง ์์ฑ ์๋๊ฐ ๋๋ฆฌ๋ค.

์ ์ฌ ํ์ฐ ๋ชจ๋ธ : ๊ฐ๋ ฅํ ์คํ ์ธ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ จ ์ด๋ฏธ์ง๋ฅผ ํจ์ฌ ๋ ์์ ์ ์ฌ ๊ณต๊ฐ์ผ๋ก ์์ถํ์ฌ ํ์ฐ ๊ณผ์ ์ ์ํํ๋ค.
๊ทธ๋ค์ ์คํ ์ธ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ต์ข ์ ์ฌ ํํ์ ์์ถ์ ํ๊ณ ์ถ๋ ฅ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ค.
์ด๋ฏธ์ง ์์ฑ ์๋๊ฐ ์๋นํ ๋นจ๋ผ์ง๊ณ ํ๋ จ ์๊ฐ๊ณผ ๋น์ฉ์ด ํฌ๊ฒ ์ค์ด๋ค๋ฉฐ ์์ฑ๋ ์ด๋ฏธ์ง์ ํ์ง์ด ์์ฃผ ๋ฐ์ด๋๋ค.
'๐ฎ ์ด๊ฒ์ ๊ฒ ๊ณต๋ถ > โฉ ํธ์ฆ์จ ๋จธ์ ๋ฌ๋' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ