å
容
æåŸã®éšåã§ã¯ãé ã倿°ãšã¯äœãã«ã€ããŠèª¬æãããã®ååžã調ã¹ãŸããããŸããéåžžã®èªåãšã³ã³ãŒããŒã§ã¯é ã倿°ã®ååžããæ°ãããªããžã§ã¯ããçæããããšã¯å°é£ã§ããããšã«æ°ä»ããŸããã æ°ãããªããžã§ã¯ããçæããã«ã¯ã
æœåšå€æ°ã®ã¹ããŒã¹ãäºæž¬å¯èœã§ãªããã°ãªããŸããã
å€åãªãŒããšã³ã³ãŒããŒã¯ãç¹å®ã®é ããã空éã«ãªããžã§ã¯ãã衚瀺ããããã«å¿ããŠãããããµã³ããªã³ã°ããããšãåŠç¿ãã
ãªãŒããšã³ã³ãŒããŒã§ãã ãããã£ãŠã
å€åãªãŒããšã³ã³ãŒããŒãçæã¢ãã«ã®ãã¡ããªãŒã«å±ããŸãã
[2]ããã®å³
ãããã1ã€ã®ãã£ã¹ããªãã¥ãŒã·ã§ã³ãæã€

ãããªãã¯ä»»æã®ä»ã®ãã®ãåŸãããšãã§ããŸã

ããšãã°ã¿ãŸããã

-æ£èŠæ£èŠååžã

-ã©ã³ãã ååžããèŠãç®ã¯å®å
šã«ç°ãªããŸã
ã³ãŒãimport numpy as np import matplotlib.pyplot as plt %matplotlib inline import seaborn as sns Z = np.random.randn(150, 2) X = Z/(np.sqrt(np.sum(Z*Z, axis=1))[:, None]) + Z/10 fig, axs = plt.subplots(1, 2, sharex=False, figsize=(16,8)) ax = axs[0] ax.scatter(Z[:,0], Z[:,1]) ax.grid(True) ax.set_xlim(-5, 5) ax.set_ylim(-5, 5) ax = axs[1] ax.scatter(X[:,0], X[:,1]) ax.grid(True) ax.set_xlim(-2, 2) ax.set_ylim(-2, 2)

äžèšã®äŸ
[1]ãããã£ãŠãæ£ãã颿°ãéžæãããšãéåžžã®ãªãŒããšã³ã³ãŒããŒã®é ã倿°ã®ã¹ããŒã¹ããããšãã°ååžãæ£èŠã®å Žæãªã©ãé©åãªã¹ããŒã¹ã«ãããã³ã°ã§ããŸãã ãããŠæ»ã£ãŠã
äžæ¹ãé ãããã¹ããŒã¹ãå¥ã®ã¹ããŒã¹ã«è¡šç€ºããããšãç¹ã«åŠã¶å¿
èŠã¯ãããŸããã æçšãªé ãã¹ããŒã¹ãããå Žåãæ£ããèªåãšã³ã³ãŒããŒã¯ããããéäžã§åŠç¿ããŸãããæçµçã«å¿
èŠãªã¹ããŒã¹ã«è¡šç€ºããŸãã
以äžã¯
VAEã®åºç€ãšãªãè€éã§ããå¿
èŠãªçè«ã§ãã ç§ã¯ã
[1ãVariation Autoencodersã®ãã¥ãŒããªã¢ã«ãCarl Doerschã2016]ããæãéèŠãªãã®ã
çµãåºãããšããŸããã
ããã

é ããã倿°ã§ããã

-ããŒã¿ã äŸãšããŠæãããæ°åã䜿çšããŠããµã³ãã«ãçæããèªç¶ãªçæããã»ã¹ãèããŸãã
åçå
ã®æ°åã®ç»åã®ç¢ºççååžãããªãã¡ ååãšããŠå³ã®ç¹å®ã®ç»åãæããã確çïŒçµµãå³ã®ããã«èŠããªãå Žåããã®ç¢ºçã¯éåžžã«å°ãããéãåæ§ã§ãïŒ
-é ããèŠå ã®ç¢ºçååžãããšãã°ãã¹ãããŒã¯ã®å€ªãã®ååžã
-äžããããé ãããèŠå ã®ç»åã®ç¢ºçååžãåãèŠå ã¯ç°ãªãç»åã«ã€ãªããå¯èœæ§ããããŸãïŒåãæ¡ä»¶ã§åãäººãæ£ç¢ºã«åãæ°åãæãããã§ã¯ãããŸããïŒã
æ³åããŠã¿ãŠ

ããã€ãã®çæé¢æ°ã®åèšãšããŠ

ãããŠããã€ãã®è€éãªãã€ãº

ç§ãã¡ã¯ãããã€ãã®ã¡ããªãã¯ããã¬ãŒãã³ã°ã«è¿ããªããžã§ã¯ããäœæãã人工çãªçæããã»ã¹ãæ§ç¯ããã

ã
ãããŠãŸã

-ã¢ãã«ã衚ã颿°ã®ãã¡ããªãŒãããã³

-ãã®ãã©ã¡ãŒã¿ãŒã ã¡ããªãã¯ãéžæããŠãã©ã®ãããªãã€ãºãç§ãã¡ã«èŠããããéžæããŸã

ã ã¡ããªãã¯

ããã®åŸãéåžžã®ãã€ãºãèæ
®ããŠããïŒ
æå°€æ³ã®åçã«åºã¥ããŠãæé©åããããšã¯ç§ãã¡ã«æ®ã£ãŠããŸã

æå€§åããããã«

ãã€ãŸã ãµã³ãã«ããã®ãªããžã§ã¯ãã®åºçŸã®ç¢ºçã
åé¡ã¯ãç©åãçŽæ¥æé©åã§ããªãããšã§ãïŒ1ïŒã空éã¯é«æ¬¡å
ã§ããå¯èœæ§ããããå€ãã®ãªããžã§ã¯ãããããã¡ããªãã¯ã¯æªãã§ãã äžæ¹ãèããŠã¿ããšãããããã®ç¹å®ã®

éåžžã«å°ããªãµãã»ããã®ã¿ãçµæãšããŠåŸãããŸã

æ®ãã®ããã«

ãŒãã«éåžžã«è¿ããªããŸãã
æé©åãããšãã¯ãè¯ããã®ããã®ã¿ãµã³ããªã³ã°ããã ãã§ååã§ãã

ã
ç¥ãããã«

ãµã³ããªã³ã°ããæ°ãããã£ã¹ããªãã¥ãŒã·ã§ã³ãå°å
¥ããå¿
èŠããããŸã

ã©ã®äŸå

ååžã衚瀺ããŸã

ããã¯ããã«ã€ãªããå¯èœæ§ããããŸã

ã
æåã«ãKullback â Leiblerè·é¢ïŒ2ã€ã®ååžã®ãé¡äŒŒæ§ãã®é察称尺床ã詳现
[3] ïŒãèšè¿°ããŸãã

ãããŠæ¬ç©ã®

ïŒ
ãã€ãºå
¬åŒãé©çšããŸãã
ã«ã«ããã¯ã»ã©ã€ãã©ãŒè·é¢ããã1ã€éžã³ãŸãã
ãã®çµæãIDãååŸããŸãã
ãã®ã¢ã€ãã³ãã£ãã£ã¯ã
ããªãšãŒã·ã§ã³èªåãšã³ã³ãŒããŒã®åºç€ã§ããã

ãããŠ

ã
ããã

ãããŠ

ãã©ã¡ãŒã¿ãŒã«äŸåããŸãã

ãããŠ

ããããŠ

-éåžž

次ã«ååŸããŸãïŒ
ååŸãããã®ã詳ããèŠãŠã¿ãŸãããã
- 第äžã«
ã
çãæ·±ããšã³ã³ãŒããŒãšãã³ãŒããŒã«äŒŒãŠããŸãïŒããæ£ç¢ºã«ã¯ããã³ãŒããŒã¯
åŒã§
ïŒã
- ã¢ã€ãã³ãã£ãã£ã®å·ŠåŽ-ãã¬ãŒãã³ã°ãµã³ãã«ã®èŠçŽ ã«å¯ŸããŠæå€§åããå€
+äœããã®ãšã©ãŒ
ããŸãããã°ãååãªå®¹éãæã€
0ã«ãªã
- å³åŽã¯åŸé
éäžæ³ã§æé©åã§ããå€ã§ããæåã®é
ã¯äºæž¬ã®è³ªã®æå³ãæã¡ãŸã
å€ãã³ãŒã
2çªç®ã®é
ã¯ãååžéã®è·é¢KL
ãšã³ã³ãŒããŒãç¹å®ã®ãã®ã«ã€ããŠäºæž¬ãããã®
ãããã³é
åž
ãã¹ãŠã®ããã«
ããã«ã
åŸé
éäžã§å³åŽãæé©åã§ããããã«ããããã«ã次ã®2ã€ã®ããšã«å¯ŸåŠããŸãã
1.ããæ£ç¢ºã«ã¯ã 
éåžž

æ£èŠååžã«ããéžæïŒ
ã€ãŸããããããã®ãšã³ã³ãŒã

2ã€ã®å€ãäºæž¬ïŒå¹³å

ãšããªãšãŒã·ã§ã³

å€ãæ¢ã«ãµã³ããªã³ã°ãããŠããæ£èŠååžã ãã¹ãŠãã®ããã«æ©èœããŸãïŒ
[2]ããã®å³
åã
ã®ããŒã¿ãã€ã³ãããš

ãšã³ã³ãŒãã¯æ£èŠååžãäºæž¬ããŸã
éçååžã®å Žå

ïŒ

ããã¯åŒã«ç±æ¥ããããã¯é©ãã¹ãããšã§ãã
[2]ããã®å³
åæã«
![KL [QïŒZ | X; \ theta_1ïŒ|| NïŒ0ãIïŒ]](https://habrastorage.org/getpro/habr/post_images/403/70d/4e3/40370d4e34e3a0bf6f0335e84ae19e6f.svg)
次ã®åœ¢åŒãåããŸãã
2.ãšã©ãŒãæ¡æ£ããæ¹æ³ãèŠã€ããŸã ![\ mathbb {E} _ {Z \ sim Q} [\ log PïŒX | Z; \ theta_2ïŒ]](https://habrastorage.org/getpro/habr/post_images/b30/2f5/5e4/b302f55e4a85ec37343537c4ed1119aa.svg)
äºå®ã¯ãããã§ã©ã³ãã ãªå€ããšãããšã§ã

ãã³ãŒããŒã«éä¿¡ããŸãã
ã©ã³ãã ãªå€ãä»ããŠãšã©ãŒãçŽæ¥äŒæããããšã¯äžå¯èœã§ããããšã¯æããã§ããããããããã
åãã©ã¡ãŒã¿ãŒåã® ããªãã¯ã䜿çšãããŸãã
ã¹ããŒã ã¯æ¬¡ã®ãšããã§ãã
[1]ããã®å³
å·Šã®åçã¯ããªãã¯ã®ãªãã¹ããŒã ã§ãå³ã®åçã¯ããªãã¯ã®ããã¹ããŒã ã§ãã
ãµã³ããªã³ã°ã¯èµ€ã§ããšã©ãŒèšç®ã¯éã§è¡šç€ºãããŸãã
ã€ãŸããå®éã«ã¯ããšã³ã³ãŒããŒã«ãã£ãŠäºæž¬ãããæšæºåå·®ãååŸããã ãã§ã

ããä¹±æ°ãæãã

äºæž¬å¹³åã远å ããŸã

ã
äž¡æ¹ã®ã¹ããŒã ã§ã®çŽæ¥äŒæã¯ãŸã£ããåãã§ããããšã©ãŒã®éååžã¯æ£ããã¹ããŒã ã§æ©èœããŸãã
ãã®ãããªå€åãªãŒããšã³ã³ãŒããŒããã¬ãŒãã³ã°ããåŸããã³ãŒããŒã¯æ¬æ Œçãªçæã¢ãã«ã«ãªããŸãã å®éãäž»ã«ãã³ãŒããçæã¢ãã«ãšããŠåå¥ã«ãã¬ãŒãã³ã°ããããã«ããšã³ã³ãŒããå¿
èŠã§ãã
[2]ããã®å³
[1]ããã®å³
ãããããšã³ã³ãŒããŒãšãã³ãŒããŒããã«ãªãŒããšã³ã³ãŒããŒã圢æãã代ããã«äœ¿çšã§ãããšããäºå®ã¯ãéåžžã«åªããŠããŸãã
ã±ã©ã¹ã®VAE
ããªãšãŒã·ã§ã³ãªãŒããšã³ã³ãŒããŒãšã¯äœããçè§£ããã®ã§ã
Kerasã§äœæããŸãã
å¿
èŠãªã©ã€ãã©ãªãšããŒã¿ã»ãããã€ã³ããŒãããŸãã
import sys import numpy as np import matplotlib.pyplot as plt %matplotlib inline import seaborn as sns from keras.datasets import mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() x_train = x_train.astype('float32') / 255. x_test = x_test .astype('float32') / 255. x_train = np.reshape(x_train, (len(x_train), 28, 28, 1)) x_test = np.reshape(x_test, (len(x_test), 28, 28, 1))
äž»ãªãã©ã¡ãŒã¿ãèšå®ããŸãã ãã£ã¡ã³ã·ã§ã³2ã®é ãããã¹ããŒã¹ã䜿çšããŠãåŸã§ããããçæããçµæãèŠèŠåããŸãã
泚 ïŒDimension 2ã¯éåžžã«å°ãããããæ°å€ãéåžžã«ãŒãããŠãããšäºæ³ããå¿
èŠããããŸãã
batch_size = 500 latent_dim = 2 dropout_rate = 0.3 start_lr = 0.0001
å€åãªãŒããšã³ã³ãŒããŒã®ã¢ãã«ãæžããŸãããã
ãã¬ãŒãã³ã°ãããéããããè¯ãè¡ãããã«ã
ããããã¢ãŠããš
ãããæ£èŠåã¬ã€ã€ãŒã远å ããŸãã
ãã³ãŒããŒã§ã¯ãã¢ã¯ãã£ããŒã·ã§ã³ãšããŠ
æŒããããReLUã䜿çšããŸããããã¯ãã¢ã¯ãã£ããŒã·ã§ã³ãªãã®
å¯ãªã¬ã€ã€ãŒã®åŸã«å¥ã®ã¬ã€ã€ãŒãšããŠè¿œå ããŸãã
ãµã³ããªã³ã°é¢æ°ã¯ãµã³ããªã³ã°å€ãå®è£
ããŸã

ãã

åãã©ã¡ãŒã¿åããªãã¯ã䜿çšããŸãã
vae_lossã¯æ¹çšåŒã®å³åŽã§ãïŒ
æå€±ãšããŠããã«äœ¿çšãããŸãã
from keras.layers import Input, Dense from keras.layers import BatchNormalization, Dropout, Flatten, Reshape, Lambda from keras.models import Model from keras.objectives import binary_crossentropy from keras.layers.advanced_activations import LeakyReLU from keras import backend as K def create_vae(): models = {}
泚 ïŒãããµã³ããªã³ã°ãã颿°ãæã€
Lambdaã¬ã€ã€ãŒã䜿çšããŸãã

åºç€ãšãªããã¬ãŒã ã¯ãŒã¯ãããããã«ã¯æããã«ããããµã€ãºãå¿
èŠã§ãã ãã®ã¬ã€ã€ãŒãååšãããã¹ãŠã®ã¢ãã«ã§ããããã®ãµã€ãºã ããéä¿¡ããããã«åŒ·å¶ãããŸãïŒã€ãŸãã
ãšã³ã³ãŒããŒãš
vaeã§ ïŒã
æé©å颿°ã¯
AdamãŸãã¯
RMSpropã䜿çšã ãäž¡æ¹ãšãè¯å¥œãªçµæã瀺ããŸãã
from keras.optimizers import Adam, RMSprop vae.compile(optimizer=Adam(start_lr), loss=vae_loss)
ããŸããŸãªæ°åãšæ°åã®è¡ãæç»ããããã®ã³ãŒã
ã³ãŒã digit_size = 28 def plot_digits(*args, invert_colors=False): args = [x.squeeze() for x in args] n = min([x.shape[0] for x in args]) figure = np.zeros((digit_size * len(args), digit_size * n)) for i in range(n): for j in range(len(args)): figure[j * digit_size: (j + 1) * digit_size, i * digit_size: (i + 1) * digit_size] = args[j][i].squeeze() if invert_colors: figure = 1-figure plt.figure(figsize=(2*n, 2*len(args))) plt.imshow(figure, cmap='Greys_r') plt.grid(False) ax = plt.gca() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) plt.show() n = 15
å€ãã®å Žåãã¢ãã«ããã¬ãŒãã³ã°ããããã»ã¹ã§ã¯ã
learning_rateã®å€æŽãäžéçµæã®ä¿åãã¢ãã«ã®ä¿åãç»åã®æç»ãªã©ãããã€ãã®ã¢ã¯ã·ã§ã³ãå®è¡ããå¿
èŠããããŸãã
ãããè¡ãããã«ã
kerasã«ã¯ããã¬ãŒãã³ã°ãå§ãŸãåã«
fitã¡ãœããã«æž¡ãããã³ãŒã«ããã¯ããããŸãã ããšãã°ãåŠç¿ããã»ã¹ã§
åŠç¿çã«åœ±é¿ãäžããããã«ã
LearningRateScheduler ã
ReduceLROnPlateauãªã©ã®ã³ãŒã«ããã¯ããããã¢ãã«ãä¿åããŸã
-ModelCheckpoint ã
TensorBoardã§åŠç¿ããã»ã¹ãç£èŠããã«ã¯ãå¥ã®ã³ãŒã«ããã¯ãå¿
èŠã§ãã ããã¯èªåçã«ãã°ãã¡ã€ã«ã«æä»£ã®éã§èæ
®ããããã¹ãŠã®ã¡ããªãã¯ãšæå€±ã远å ããŸãã
åŠç¿ããã»ã¹ã§ä»»æã®æ©èœãå®è¡ããå¿
èŠãããå Žåã®ããã«ã
LambdaCallbackããããŸãã ããšãã°ãæä»£ããããã®éãªã©ãäžãããããã¬ãŒãã³ã°ã®ç¬éã«ä»»æã®é¢æ°ã®å®è¡ãéå§ããŸãã
åŠç¿ããã»ã¹ã«åŸããæ°åãã©ã®ããã«çæãããããç ç©¶ããŸã

ã
from IPython.display import clear_output from keras.callbacks import LambdaCallback, ReduceLROnPlateau, TensorBoard
ããã§ã
TensorBoardãã€ã³ã¹ããŒã«ãããŠããå ŽåãåŠç¿ããã»ã¹ã«åŸãããšãã§ããŸãã
ãã®ãšã³ã³ãŒããŒãç»åã埩å
ããæ¹æ³ã¯æ¬¡ã®ãšããã§ãã

ãããŠãããã¯ããã®ãµã³ããªã³ã°çµæã§ã


æ°åãçæããåŠç¿ããã»ã¹ã¯æ¬¡ã®ãšããã§ãã
é ããã空éã§ã®ã³ãŒãã®é
åžïŒ
å®å
šã«æ£åžžã§ã¯ãããŸããããããªãè¿ãã§ãïŒç¹ã«ãé ãããã¹ããŒã¹ã®å¯žæ³ã2ã ãã§ããããšãèæ
®ããŠïŒã
TensorBoardã®åŠç¿æ²ç·

GIFäœæã³ãŒã from matplotlib.animation import FuncAnimation from matplotlib import cm import matplotlib def make_2d_figs_gif(figs, epochs, fname, fig): norm = matplotlib.colors.Normalize(vmin=0, vmax=1, clip=False) im = plt.imshow(np.zeros((28,28)), cmap='Greys_r', norm=norm) plt.grid(None) plt.title("Epoch: " + str(epochs[0])) def update(i): im.set_array(figs[i]) im.axes.set_title("Epoch: " + str(epochs[i])) im.axes.get_xaxis().set_visible(False) im.axes.get_yaxis().set_visible(False) return im anim = FuncAnimation(fig, update, frames=range(len(figs)), interval=100) anim.save(fname, dpi=80, writer='imagemagick') def make_2d_scatter_gif(zs, epochs, c, fname, fig): im = plt.scatter(zs[0][:, 0], zs[0][:, 1], c=c, cmap=cm.coolwarm) plt.colorbar() plt.title("Epoch: " + str(epochs[0])) def update(i): fig.clear() im = plt.scatter(zs[i][:, 0], zs[i][:, 1], c=c, cmap=cm.coolwarm) im.axes.set_title("Epoch: " + str(epochs[i])) im.axes.set_xlim(-5, 5) im.axes.set_ylim(-5, 5) return im anim = FuncAnimation(fig, update, frames=range(len(zs)), interval=150) anim.save(fname, dpi=80, writer='imagemagick') make_2d_figs_gif(figs, epochs, "./figs3/manifold.gif", plt.figure(figsize=(10,10))) make_2d_scatter_gif(latent_distrs, epochs, y_test, "./figs3/z_distr.gif", plt.figure(figsize=(10,10)))
ãã®ãããªã¿ã¹ã¯ã®æ¬¡å
2ã¯éåžžã«å°ãããæ°å€ã¯éåžžã«ãŒãããŠãããè¯ãæ°å€ãšæ°å€ã®éã«ã¯ç Žããæ°å€ã倿°ããããšãããããŸãã
次ã®ããŒãã§ã¯ãç®çã®ã©ãã«ã®çªå·ãçæããæ¹æ³ãç Žããã©ãã«ãåãé€ãæ¹æ³ãããã³ã¹ã¿ã€ã«ãããæ°åããå¥ã®æ°åã«è»¢éããæ¹æ³ã«ã€ããŠèª¬æããŸãã
圹ç«ã€ãªã³ã¯ãšæç®
çè«çãªéšåã¯æ¬¡ã®èšäºã«åºã¥ããŠããŸãã
[1] Variation Autoencodersã®ãã¥ãŒããªã¢ã«ãCarl Doerschã2016幎ã
httpsïŒ //arxiv.org/abs/1606.05908
ãããŠå®éã«ã¯ããã®èŠçŽã§ã
Isaac Dykemanããã°ããå€ãã®åçãæ®åœ±ãããŠããŸãã
[2] Isaac Dykemanã
httpïŒ //ijdykeman.imtqy.com/ml/2016/12/21/cvae.html
ãã·ã¢èªã®ã«ã«ããã¯ã»ã©ã€ãã©ãŒè·é¢ã®è©³çްã«ã€ããŠã¯ããã¡ããã芧ãã ããã
[3]
http://www.machinelearning.ru/wiki/images/d/d0/BMMO11_6.pdfã³ãŒãã¯ã
Francois Cholletã®èšäºã«éšåçã«åºã¥ããŠããŸãã
[4]
https://blog.keras.io/building-autoencoders-in-keras.htmlä»ã®è峿·±ããªã³ã¯ïŒ
http://blog.fastforwardlabs.com/2016/08/12/introducing-variational-autoencoders-in-prose-and.htmlhttp://kvfrans.com/variational-autoencoders-explained/