Özkodlama (Autoencoding)
Özkodlamanın yaptığının bir tür "veriyi sıkıştırma" işlemi olduğu söylenebilir. Yapay öğrenmede algoritmaların denetimli ve denetimsiz olarak ikiye ayrıldığından bahsetmiştik, özkodlama denetimsiz çalışır yani ortada etiket yoktur, daha doğrusu özkodlama verinin kendisini etiket olarak kullanır.
Yani girdi olarak verilen veriyi çıktı olarak ta kullanırsak, YSA'yı kendi çıktısını tekrar oluşturmayı öğrenmeye zorlamış oluruz, bu YSA'yı veriyi özetlemeye doğru yöneltecektir, ve bu tekrar oluşturma için ileri besleme sırasında veriyi dar bir noktadan geçmeye zorlarsak (üstteki resimde görülüyor, 7 nöronluk girdi 5 nöronluk "daha dar" bir katmandan geçmeye zorlanıyor), bu YSA'yı "sıkıştırma" yapmaya daha da meyillendirecektir.
from keras.layers import Input, Dense
from keras.models import Model
# gizli katman
encoding_dim = 32
def get_model():
# girdi
input_img = Input(shape=(784,))
# kodlanmis temsil
encoded = Dense(encoding_dim, activation='relu')(input_img)
# kodcozulmus temsil
decoded = Dense(784, activation='sigmoid')(encoded)
# bu model girdiyi tekrar olusturulmus hale cevirir
autoencoder = Model(input_img, decoded)
# bu model girdiyi kodlanmis hale getirir
encoder = Model(input_img, encoded)
encoded_input = Input(shape=(encoding_dim,))
# ozkodlayicinin son tabakasini al bu kodcozulmus katman
decoder_layer = autoencoder.layers[-1]
# kodcozucu model
decoder = Model(encoded_input, decoder_layer(encoded_input))
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
return autoencoder, encoder, decoder
if __name__ == "__main__":
autoencoder, encoder, decoder = get_model()
from keras.datasets import mnist
import numpy as np
(x_train, _), (x_test, _) = mnist.load_data()
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
print (x_train.shape)
print (x_test.shape)
autoencoder.fit(x_train, x_train,
epochs=50,
batch_size=256,
shuffle=True,
validation_data=(x_test, x_test))
autoencoder.save('mod-autoenc-1.h5')
encoder.save('mod-enc-1.h5')
decoder.save('mod-dec-1.h5')
Üstteki kodla modeli eğittikten sonra herhangi bir sayı resmini alıyoruz, kodluyoruz, kodçözme yapıyoruz ve tekrar oluşturulmuş hali ekrana basıyoruz,
from keras.datasets import mnist
import mnist_autoenc
(x_train, _), (x_test, y_test) = mnist.load_data()
x_test = x_test.astype('float32') / 255.
autoencoder, encoder, decoder = mnist_autoenc.get_model()
encoder.load_weights("mod-enc-1.h5")
decoder.load_weights("mod-dec-1.h5")
idx = 1090 # herhangi bir sayi resmini al
print y_test[idx]
tmp = x_test[idx, :, :].reshape(1,28*28)
encoded = encoder.predict(tmp)
print (encoded.shape)
decoded = decoder.predict(encoded).reshape(28,28)
print (decoded.shape)
plt.imshow(decoded)
plt.gray()
plt.savefig('autoenc_01.png')
9
(1, 32)
(28, 28)
9 resmini elde ettik.
Biraz onceki resmin kodlanmis halini gosterelim,
print (encoded)
[[ 13.18540382 9.90277767 2.81214857 14.67686176 3.90287089
0.95043498 4.25797892 13.59305477 8.71218967 2.61786652
8.67911053 5.27269077 3.68898463 6.26301765 0. 3.73920846
4.90339994 6.61260319 8.80308342 5.41205883 0. 6.12768221
11.42174625 3.13173342 3.79943371 11.27116108 6.003757
10.82552242 8.44533443 4.84582376 5.63021088 11.27607727]]
32 boyutlu bir vektör içinde reel sayılar bunlar. Şimdi bu sayıları alıp başka bir sınıflayıcı içinde kullanabilirdim. Öyle bir uygulama düşünelim ki mesela müşterilerin yaşı, cinsiyeti bilgisi var, biz ayrıca herkesin fotoğrafları üzerinden bir özkodlayıcı eğitiyoruz, ve müşterinin resmi üzerinden elde edilen üstteki gibi bir temsili sıkıştırılmış gizli tabaka verisini yaş, cinsiyet ile beraber bu ayrı sınıflayıcıya verip cevap bekliyoruz. Bu sınıflayıcı "potansiyel yaz alışverişçisi mi / değil mi" şeklinde bir sınıflama yapıyor olabilir mesela, belki kişilerin resminde bu sınıflayıcıya yardım edecek bir şeyler vardır.. Bu ayrı sınıflayıcı bir YSA olabilir, ama çoğu zaman basit lojistik regresyon bile kullanılabiliyor. Ayrıca sadece bir değil, farklı veriler üzerinde işletilmiş pek çok özkodlayıcıdan gelen özet bilgisini de yan yana aynı lojistik regresyona verebiliriz.
Zaman Serisi Özkodlaması, RNN
Eğer zamana bağlı bir veri yapısını özkodlamak istesek nasıl bir model kullanırdık? Mesela birkaç boyutlu bir finans verisini (bir andaki hisse fiyatı, satım miktarı çok boyutlu bir vektörde olabilirdi) modelliyor olabilidiik. MNIST verisini bu şekilde kullanabiliriz aslında, 28 x 28 boyutlu veride sanki 28 tane 28 boyutlu veriyi zamana bağlı alıyormuşuz gibi görebilirdik, sanki resimde soldan sağa doğru dikey şeritler alıp teker teker bunları işlediğimizi düşünebiliriz. MNIST sayı görüntülerine bu şekilde bakmak aslında çok anlamsız değil, mesela bir altı görüntüsünü düşünürsek soldan sağa giderken kavisli yukarı doğru bir gidiş vardır, bu gidişi zamana bağlı bir NN yakalayabilir.
from keras.layers import Input, Dense, concatenate
from keras.layers import LSTMCell, RNN
from keras.layers import Input, LSTM, RepeatVector
from keras.models import Model
latent_dim = 20; timesteps = 28; input_dim = 28; hist_dim = 5
def get_model():
inputs = Input(shape=(timesteps, input_dim))
encoded = LSTM(latent_dim,return_sequences=True)(inputs)
decoded = encoded
decoded = LSTM(input_dim, return_sequences=True)(decoded)
seq_autoencoder = Model(inputs, decoded)
encoder = Model(inputs, encoded)
return seq_autoencoder, encoder
if __name__ == "__main__":
from keras.datasets import mnist
import numpy as np
(x_train, _), (x_test, _) = mnist.load_data()
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
print (x_train.shape)
print (x_test.shape)
seq_autoencoder, encoder = get_model()
seq_autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
seq_autoencoder.fit(x_train, x_train,
epochs=50,
batch_size=256,
shuffle=True,
validation_data=(x_test, x_test))
seq_autoencoder.save('mod-rnn-autoenc-sim.h5')
encoder.save('mod-rnn-enc-sim.h5')
import mnist_autoenc_rnn_simple
seq_autoencoder, encoder = mnist_autoenc_rnn_simple.get_model()
seq_autoencoder.load_weights("mod-rnn-autoenc-sim.h5")
encoder.load_weights("mod-rnn-enc-sim.h5")
decoded = seq_autoencoder.predict(tmp).reshape(28,28)
print (decoded.shape)
plt.imshow(decoded)
plt.gray()
plt.savefig('autoenc_03.png')
Varyasyonel Özkodlayıcılar (Variational Autoencoder -VAE-)
Standard özkodlayıcıların bir problemi kodlama yaptıkları daralmış alandaki vektörlerin sürekli olmayabileceği, ve buradaki değerlerin kolay bir şekilde interpolasyon yapılmasındaki bazı zorluklar.
VAE özkodlayıcılarda, kodlayıcı tabaka bir tamamen bağlanmış / yoğun (dense) bir katmandan geçiyor ama bir değişiklik var; yoğun katman $\mu,\sigma$ rasgele değişkenleri haline geliyor ve ondan bir sonraki katman bu değişkenlerden örneklem alıyor! Bu dahiyene bir düşünce. Fakat akla gelebilir - YSA yapısı deterministik bir yapıdır, örneklem, yani zar atma rasgele (stochastic) bir hesap. Bu kavramı YSA mekanizmasına nasıl dahil ediyoruz?
Çözüm örneklem operasyonunu gürültü, yani Gaussian $N(0,1)$ + $\mu$ çarpı $\sigma$ olarak modellemek, bu şekilde sanki $N(\mu,\sigma)$'dan örneklem alıyoruz, ama eğitilen, optimize edilen çarpma, toplama üzerinden $\mu,\sigma$ değişkenleri, ve halen YSA mekanizması devrede ve bu değişkenler deterministik değişkenler. Gürültü işin içinde var, ama gürültü eh, Gaussian sıfır merkezli bir stardart sapmalı gürültü. Bir gürültü bir diğerinden farklı değil, model için hepsi aynı gürültü.
Üstteki mantığın temelinde şu bilgi var: Biliyoruz ki herhangi bir dağılıma sahip rasgele değişken $z$'yi bir $g$ fonksiyonu kullanarak $X=g(z)$ ile başka bir dağılıma çevirebiliyoruz. Altta örneği görülüyor, soldaki resim Gaussian dağılımdan, sağdaki resim soldaki verilerin $g(z) = z/10 + z/||z||$ ile başka bir dağılıma eşlenmiş hali ve bu yeni dağılım bir çember şeklini oluşturmuş. VAE'nin rasgele dağılımlar yaratabilmesinin arkasında yatan gizem bu işte. Eğitim ile VAE $g$'yi öğrenmiş oluyor, ki bu bir determinstik fonksiyon.
import random, numpy.linalg as lin, pandas as pd
x = np.random.randn(1000,2)
x = pd.DataFrame(x)
x['n'] = np.sqrt(x[0]*x[0] + x[1]*x[1])
x['g0'] = (x[0]/10.0) + x[0]/x['n']
x['g1'] = (x[1]/10.0) + x[1]/x['n']
plt.figure()
ax = plt.subplot(1, 2, 1)
plt.plot(x[0],x[1],'.')
ax = plt.subplot(1, 2, 2)
plt.plot(x['g0'],x['g1'],'.')
plt.xlim(-4,4)
plt.ylim(-4,4)
plt.savefig('autoenc_10.png')
"""
Based on https://github.com/keras-team/keras/blob/master/examples/variational_autoencoder.py
"""
import keras
from keras.datasets import mnist
import numpy as np
from keras import backend as K
from keras.models import Sequential, Model
from keras.layers import Input, LSTM, RepeatVector
from keras.layers.core import Flatten, Dense, Dropout, Lambda
from keras.optimizers import SGD, RMSprop, Adam
from keras import objectives
import numpy as np
timesteps = 28; input_dim = 28;
batch_size = 1
latent_dim = 30
def create_lstm_vae(input_dim,
timesteps,
batch_size,
intermediate_dim,
latent_dim,
epsilon_std=1.):
x = Input(shape=(timesteps, input_dim,))
print (x)
# LSTM encoding
h = LSTM(intermediate_dim)(x)
print (h)
# VAE Z layer
z_mean = Dense(latent_dim)(h)
z_log_sigma = Dense(latent_dim)(h)
def sampling(args):
z_mean, z_log_sigma = args
epsilon = K.random_normal(shape=(batch_size, latent_dim),
mean=0., stddev=epsilon_std)
return z_mean + z_log_sigma * epsilon
z = Lambda(sampling, output_shape=(latent_dim,))([z_mean, z_log_sigma])
print (z)
# decoded LSTM layer
decoder_h = LSTM(intermediate_dim, return_sequences=True)
decoder_mean = LSTM(input_dim, return_sequences=True)
h_decoded = RepeatVector(timesteps)(z)
print (h_decoded)
h_decoded = decoder_h(h_decoded)
print (h_decoded)
# decoded layer
x_decoded_mean = decoder_mean(h_decoded)
print (x_decoded_mean)
# end-to-end autoencoder
vae = Model(x, x_decoded_mean)
# encoder, from inputs to latent space
encoder = Model(x, z_mean)
# generator, from latent space to reconstructed inputs
decoder_input = Input(shape=(latent_dim,))
print (decoder_input)
_h_decoded = RepeatVector(timesteps)(decoder_input)
print (_h_decoded)
_h_decoded = decoder_h(_h_decoded)
print (_h_decoded)
_x_decoded_mean = decoder_mean(_h_decoded)
generator = Model(decoder_input, _x_decoded_mean)
def vae_loss(x, x_decoded_mean):
xent_loss = objectives.mse(x, x_decoded_mean)
kl_loss = - 0.5 * K.mean(1 + z_log_sigma - K.square(z_mean) - K.exp(z_log_sigma))
loss = xent_loss + kl_loss
return loss
vae.compile(optimizer='rmsprop', loss=vae_loss)
return vae, encoder, generator
if __name__ == "__main__":
(x_train, _), (x_test, _) = mnist.load_data()
x_train = x_train.astype('float32') / 255.
#x_train = x_train[:200]
x_test = x_test.astype('float32') / 255.
#x_test = x_test[:200]
print (x_train.shape)
print (x_test.shape)
x = x_train
vae, enc, gen = create_lstm_vae(input_dim,
timesteps=timesteps,
batch_size=batch_size,
intermediate_dim=latent_dim,
latent_dim=latent_dim,
epsilon_std=1.)
vae.fit(x, x, validation_data=(x_test, x_test), epochs=30)
vae.save('mnist_lstm_vae.h5')
enc.save('mnist_lstm_enc.h5')
gen.save('mnist_lstm_gen.h5')
#preds = vae.predict(x, batch_size=batch_size)
import mnist_lstm_vae
vae, enc, gen = mnist_lstm_vae.create_lstm_vae(mnist_lstm_vae.input_dim,
timesteps=mnist_lstm_vae.timesteps,
batch_size=mnist_lstm_vae.batch_size,
intermediate_dim=mnist_lstm_vae.latent_dim,
latent_dim=mnist_lstm_vae.latent_dim,
epsilon_std=1.)
vae.load_weights('mnist_lstm_vae.h5')
enc.load_weights('mnist_lstm_enc.h5')
import random
idx = 400 # herhangi bir imaji sec
print (tmp.shape)
x_test_tmp = x_test[idx]
res = vae.predict(x_test_tmp.reshape((1, 28, 28)))
plt.figure()
ax = plt.subplot(1, 2, 1)
pixels = res.reshape((28, 28))
plt.imshow(pixels)
plt.gray()
ax = plt.subplot(1, 2, 2)
plt.imshow(x_test_tmp)
plt.gray()
plt.savefig('autoenc_04.png')
Gördüğümüz gibi zamansal işlem yaptık ama VAE çok iyi sonuç verdi. Hatta test imajını daha netleştirdi!
Hasımsal Özkodlayıcı (Adverserial Autoencoder -AA-)
Üretici Hasımsal Ağlar (Generative Adverserial Networks -GAN-) kavramının özkodlayıcılara uygulanmış hali AA olur.
Burada bir kodlayıcı / kodçözücü yapısı var (üst blok) bu yapıdan kodlanmış ara tabaka $z \sim q(z)$ "kötü" örnekler çekilip $p(z)$'den gelen "iyi" örnekler ile birleştiriliyor ve ayırdedici yine bu iki grup arasında ayırım yapmayı öğreniyor. Bu durumda üst bloktaki kodçözücü GAN'deki üretici gibi olur, ona dönüşür bir bakıma, çünkü öyle iyi üretim yapmaya çalışacaktır ki $p(z)$ gürültüsü ile onun aldığı kodlanmış tabaka verisi ayiredilemez hale gelmelidir. Tabii ki üst soldaki kodlayıcı bu ara tabakaya o şekilde temsili veri üretmeye çalışacaktır, bu arada kodlayıcı / kodçözücü yapısı da eğitilmiş olur. Yani $z$ bir anlamda alt soldaki gerçek gürültüye yaklaşır, bu gürültüden sayı üretebilir hale geliriz, bu klasik GAN, ayrıca bu "kodlanmış" gürültüyü üreten kodlayıcı / kodçözücü tabaka da ayrı bir şekilde kendini optimize eder ve kodlama işini yapar hale gelir.
# import os
# os.environ["THEANO_FLAGS"] = "mode=FAST_COMPILE,device=cpu,floatX=float32"
# This line allows mpl to run with no DISPLAY defined
from keras.layers import Dense, Reshape, Flatten, Input, merge
from keras.models import Sequential, Model
from keras.optimizers import Adam
from legacy import l1l2
import keras.backend as K
import pandas as pd, os
import numpy as np
from adversarial_model import AdversarialModel
from adversarial_utils import fix_names, n_choice, normal_latent_sampling
from adversarial_optimizers import AdversarialOptimizerSimultaneous
from keras.layers import LeakyReLU, Activation
import numpy as np
from keras.datasets import mnist
def mnist_process(x):
x = x.astype(np.float32) / 255.0
return x
def mnist_data():
(xtrain, ytrain), (xtest, ytest) = mnist.load_data()
return mnist_process(xtrain), mnist_process(xtest)
def model_generator(latent_dim, input_shape,
hidden_dim=512,
reg=lambda: l1l2(1e-7, 0)):
return Sequential([
Dense(hidden_dim, name="generator_h1",
input_dim=latent_dim,
W_regularizer=reg()),
LeakyReLU(0.2),
Dense(hidden_dim,
name="generator_h2",
W_regularizer=reg()),
LeakyReLU(0.2),
Dense(np.prod(input_shape),
name="generator_x_flat",
W_regularizer=reg()),
Activation('sigmoid'),
Reshape(input_shape, name="generator_x")],
name="generator")
def model_encoder(latent_dim, input_shape,
hidden_dim=512,
reg=lambda: l1l2(1e-7, 0)):
x = Input(input_shape, name="x")
h = Flatten()(x)
h = Dense(hidden_dim, name="encoder_h1", W_regularizer=reg())(h)
h = LeakyReLU(0.2)(h)
h = Dense(hidden_dim, name="encoder_h2", W_regularizer=reg())(h)
h = LeakyReLU(0.2)(h)
mu = Dense(latent_dim, name="encoder_mu", W_regularizer=reg())(h)
log_sigma_sq = Dense(latent_dim, name="encoder_log_sigma_sq", W_regularizer=reg())(h)
z = merge([mu, log_sigma_sq], mode=lambda p: p[0] + K.random_normal(K.shape(p[0])) * K.exp(p[1] / 2),
output_shape=lambda p: p[0])
return Model(x, z, name="encoder")
def model_discriminator(latent_dim, output_dim=1, hidden_dim=512,
reg=lambda: l1l2(1e-7, 1e-7)):
z = Input((latent_dim,))
h = z
h = Dense(hidden_dim, name="discriminator_h1", W_regularizer=reg())(h)
h = LeakyReLU(0.2)(h)
h = Dense(hidden_dim, name="discriminator_h2", W_regularizer=reg())(h)
h = LeakyReLU(0.2)(h)
y = Dense(output_dim, name="discriminator_y", activation="sigmoid", W_regularizer=reg())(h)
return Model(z, y)
def train(adversarial_optimizer):
# z \in R^100
latent_dim = 100
# x \in R^{28x28}
input_shape = (28, 28)
# generator (z -> x)
generator = model_generator(latent_dim, input_shape)
# encoder (x ->z)
encoder = model_encoder(latent_dim, input_shape)
# autoencoder (x -> x')
autoencoder = Model(encoder.inputs, generator(encoder(encoder.inputs)))
# discriminator (z -> y)
discriminator = model_discriminator(latent_dim)
# assemple AAE
x = encoder.inputs[0]
z = encoder(x)
xpred = generator(z)
zreal = normal_latent_sampling((latent_dim,))(x)
yreal = discriminator(zreal)
yfake = discriminator(z)
aae = Model(x, fix_names([xpred, yfake, yreal], ["xpred", "yfake", "yreal"]))
# print summary of models
generator.summary()
encoder.summary()
discriminator.summary()
autoencoder.summary()
# build adversarial model
generative_params = generator.trainable_weights + encoder.trainable_weights
model = AdversarialModel(base_model=aae,
player_params=[generative_params, discriminator.trainable_weights],
player_names=["generator", "discriminator"])
model.adversarial_compile(adversarial_optimizer=adversarial_optimizer,
player_optimizers=[Adam(1e-4, decay=1e-4), Adam(1e-3, decay=1e-4)],
loss={"yfake": "binary_crossentropy", "yreal": "binary_crossentropy",
"xpred": "mean_squared_error"},
player_compile_kwargs=[{"loss_weights": {"yfake": 1e-2, "yreal": 1e-2, "xpred": 1}}] * 2)
# load mnist data
xtrain, xtest = mnist_data()
# callback for image grid of generated samples
def generator_sampler():
zsamples = np.random.normal(size=(10 * 10, latent_dim))
return generator.predict(zsamples).reshape((10, 10, 28, 28))
# callback for image grid of autoencoded samples
def autoencoder_sampler():
xsamples = n_choice(xtest, 10)
xrep = np.repeat(xsamples, 9, axis=0)
xgen = autoencoder.predict(xrep).reshape((10, 9, 28, 28))
xsamples = xsamples.reshape((10, 1, 28, 28))
samples = np.concatenate((xsamples, xgen), axis=1)
return samples
# train network
# generator, discriminator; pred, yfake, yreal
n = xtrain.shape[0]
y = [xtrain, np.ones((n, 1)), np.zeros((n, 1)), xtrain, np.zeros((n, 1)), np.ones((n, 1))]
ntest = xtest.shape[0]
ytest = [xtest, np.ones((ntest, 1)), np.zeros((ntest, 1)), xtest, np.zeros((ntest, 1)), np.ones((ntest, 1))]
history = model.fit(x=xtrain, y=y, validation_data=(xtest, ytest), nb_epoch=100, batch_size=32)
# save model
encoder.save("aae-norm-encoder.h5")
generator.save("aae-norm-generator.h5")
discriminator.save("aae-norm-discriminator.h5")
if __name__ == "__main__":
train(AdversarialOptimizerSimultaneous())
import aae_normal
latent_dim = 100
input_shape = (28, 28)
encoder = aae_normal.model_encoder(latent_dim, input_shape)
encoder.load_weights('aae-norm-encoder.h5')
generator = aae_normal.model_generator(latent_dim, input_shape)
generator.load_weights('aae-norm-generator.h5')
idx = 100 # herhangi bir imaji sec
print (x_test[idx, :].shape)
res = encoder.predict(x_test[idx, :].reshape(1,28,28))
print (res.shape)
pixels = generator.predict(res)
pixels = pixels.reshape((28, 28))
plt.imshow(pixels)
plt.gray()
plt.savefig('autoenc_05.png')
# import os
# os.environ["THEANO_FLAGS"] = "mode=FAST_COMPILE,device=cpu,floatX=float32"
# This line allows mpl to run with no DISPLAY defined
from keras.layers import Dense, Reshape, Flatten, Input, merge
from keras.models import Sequential, Model
from keras.optimizers import Adam
from legacy import l1l2
import keras.backend as K
from keras.datasets import mnist
import numpy as np, os, pandas as pd
from adversarial_model import AdversarialModel
from adversarial_utils import fix_names, n_choice, normal_latent_sampling
from adversarial_optimizers import AdversarialOptimizerSimultaneous
from keras.layers import LeakyReLU, Activation, LSTM, GRU, RepeatVector
def mnist_process(x):
x = x.astype(np.float32) / 255.0
return x
def mnist_data():
(xtrain, ytrain), (xtest, ytest) = mnist.load_data()
return mnist_process(xtrain), mnist_process(xtest)
activation='relu'
def model_generator(latent_dim, input_shape,
hidden_dim=100,
reg=lambda: l1l2(1e-7, 0)):
return Sequential([
Dense(np.prod(input_shape), activation=activation,
name="generator_h1", input_dim=latent_dim,
W_regularizer=reg()),
Reshape(input_shape, name="generator_x"),
GRU(latent_dim,return_sequences=True),
GRU(28,return_sequences=True),
],
name="generator")
def model_encoder(latent_dim, input_shape,
hidden_dim=100,
reg=lambda: l1l2(1e-7, 0)):
x = Input(input_shape, name="x")
h = GRU(hidden_dim, return_sequences=True)(x)
h = GRU(hidden_dim)(h)
h = Dense(hidden_dim, activation=activation,
name="encoder_h3",
W_regularizer=reg())(h)
mu = Dense(latent_dim, name="encoder_mu", W_regularizer=reg())(h)
log_sigma_sq = Dense(latent_dim, name="encoder_log_sigma_sq",
W_regularizer=reg())(h)
z = merge([mu, log_sigma_sq],
mode=lambda p: p[0] + K.random_normal(K.shape(p[0])) * K.exp(p[1] / 2),
output_shape=lambda p: p[0])
return Model(x, z, name="encoder")
def model_discriminator(latent_dim, output_dim=1, hidden_dim=100,
reg=lambda: l1l2(1e-7, 1e-7)):
z = Input((latent_dim,))
h = z
h = Dense(hidden_dim, name="discriminator_h1", W_regularizer=reg())(h)
h = LeakyReLU(0.2)(h)
h = Dense(hidden_dim, name="discriminator_h2", W_regularizer=reg())(h)
h = LeakyReLU(0.2)(h)
y = Dense(output_dim, name="discriminator_y", activation="sigmoid", W_regularizer=reg())(h)
return Model(z, y)
def example_aae(adversarial_optimizer):
# z \in R^100
latent_dim = 200
# x \in R^{28x28}
input_shape = (28, 28)
# generator (z -> x)
generator = model_generator(latent_dim, input_shape)
# encoder (x ->z)
encoder = model_encoder(latent_dim, input_shape)
# autoencoder (x -> x')
print (encoder.inputs)
e = encoder(encoder.inputs)
g = generator(e)
autoencoder = Model(encoder.inputs, g)
# discriminator (z -> y)
discriminator = model_discriminator(latent_dim)
# assemple AAE
x = encoder.inputs[0]
z = encoder(x)
xpred = generator(z)
zreal = normal_latent_sampling((latent_dim,))(x)
yreal = discriminator(zreal)
yfake = discriminator(z)
aae = Model(x, fix_names([xpred, yfake, yreal], ["xpred", "yfake", "yreal"]))
# print summary of models
generator.summary()
encoder.summary()
discriminator.summary()
autoencoder.summary()
# build adversarial model
generative_params = generator.trainable_weights + encoder.trainable_weights
model = AdversarialModel(base_model=aae,
player_params=[generative_params, discriminator.trainable_weights],
player_names=["generator", "discriminator"])
model.adversarial_compile(adversarial_optimizer=adversarial_optimizer,
player_optimizers=[Adam(1e-4, decay=1e-4), Adam(1e-3, decay=1e-4)],
loss={"yfake": "binary_crossentropy", "yreal": "binary_crossentropy",
"xpred": "mean_squared_error"},
player_compile_kwargs=[{"loss_weights": {"yfake": 1e-2, "yreal": 1e-2, "xpred": 1}}] * 2)
# load mnist data
xtrain, xtest = mnist_data()
# callback for image grid of generated samples
def generator_sampler():
zsamples = np.random.normal(size=(10 * 10, latent_dim))
return generator.predict(zsamples).reshape((10, 10, 28, 28))
# callback for image grid of autoencoded samples
def autoencoder_sampler():
xsamples = n_choice(xtest, 10)
xrep = np.repeat(xsamples, 9, axis=0)
xgen = autoencoder.predict(xrep).reshape((10, 9, 28, 28))
xsamples = xsamples.reshape((10, 1, 28, 28))
samples = np.concatenate((xsamples, xgen), axis=1)
return samples
# train network
# generator, discriminator; pred, yfake, yreal
n = xtrain.shape[0]
y = [xtrain, np.ones((n, 1)), np.zeros((n, 1)), xtrain, np.zeros((n, 1)), np.ones((n, 1))]
ntest = xtest.shape[0]
ytest = [xtest, np.ones((ntest, 1)), np.zeros((ntest, 1)), xtest, np.zeros((ntest, 1)), np.ones((ntest, 1))]
history = model.fit(x=xtrain, y=y, validation_data=(xtest, ytest), nb_epoch=50, batch_size=32)
# save model
encoder.save("aae-lstm-encoder.h5")
generator.save("aae-lstm-generator.h5")
discriminator.save("aae-lstm-discriminator.h5")
if __name__ == "__main__":
example_aae(AdversarialOptimizerSimultaneous())
import aae_lstm
latent_dim = 200
input_shape = (28, 28)
encoder = aae_lstm.model_encoder(latent_dim, input_shape)
encoder.load_weights('aae-lstm-encoder.h5')
generator = aae_lstm.model_generator(latent_dim, input_shape)
generator.load_weights('aae-lstm-generator.h5')
idx = 1030 # herhangi bir imaji sec
res = encoder.predict(x_test[idx, :].reshape(1, 28,28))
pixels = generator.predict(res)
pixels = pixels.reshape((28, 28))
plt.imshow(pixels)
plt.gray()
plt.savefig('autoenc_08.png')
Kaynaklar
[1] https://blog.keras.io/building-autoencoders-in-keras.html
[2] Adverserial Autoencoder Keras, https://github.com/bstriner/keras-adversarial/blob/master/examples/example_aae.py
[3] https://towardsdatascience.com/intuitively-understanding-variational-autoencoders-1bfe67eb5daf
[4] https://hsaghir.github.io/data_science/denoising-vs-variational-autoencoder/
[5] Doersch, Tutorial on Variational Autoencoders, https://arxiv.org/pdf/1606.05908.pdf
[6] Goodfellow, Adversarial Autoencoders, https://arxiv.org/pdf/1511.05644.pdf
[7] What is Adversarial Autoencoder?, https://www.quora.com/What-is-Adversarial-Autoencoder
[8] http://www.inference.vc/adversarial-autoencoders/
Yukarı