Updated 21/Nov/2021 by Yoshihisa Nitta
Train Variational Auto Encoder further on CelebA dataset. It is assumed that it is in the state after executing VAE_CelebA_Train2.ipynb.
CelebA データセットに対して変分オートエンコーダを学習させた結果を解析する。 VAE_CelebA_Train2.ipynb を実行した後の状態であることを前提としている。
#! pip install tensorflow==2.7.0
%tensorflow_version 2.x
import tensorflow as tf
print(tf.__version__)
! nvidia-smi
! cat /proc/cpuinfo
! cat /etc/issue
! free -h
from google.colab import drive
drive.mount('/content/drive')
! ls /content/drive
Download from nw.tsuda.ac.jp above only if the specifications of Google Drive change and you cannot download from Google Drive.
Google Drive の仕様が変わってダウンロードができない場合にのみ、上の nw.tsuda.ac.jp からダウンロードすること。
# Download source file
nw_path = './nw'
! rm -rf {nw_path}
! mkdir -p {nw_path}
if True: # from Google Drive
url_model = 'https://drive.google.com/uc?id=1ZCihR7JkMOity4wCr66ZCp-3ZOlfwwo3'
! (cd {nw_path}; gdown {url_model})
else: # from nw.tsuda.ac.jp
URL_NW = 'https://nw.tsuda.ac.jp/lec/GoogleColab/pub'
url_model = f'{URL_NW}/models/VariationalAutoEncoder.py'
! wget -nd {url_model} -P {nw_path}
! cat {nw_path}/VariationalAutoEncoder.py
Official WWW of CelebA dataset: https://mmlab.ie.cuhk.edu.hk/projects/CelebA.html
Google Drive of CelebA dataset: https://drive.google.com/drive/folders/0B7EVK8r0v71pWEZsZE9oNnFzTm8?resourcekey=0-5BR16BdXnb8hVj6CNHKzLg
img_align_celeba.zip mirrored on my Google Drive:
https://drive.google.com/uc?id=1LFKeoI-hb96jlV0K10dO1o04iQPBoFdx
CelebA データセットの公式ページ: https://mmlab.ie.cuhk.edu.hk/projects/CelebA.html
CelebA データセットのGoogle Drive: https://drive.google.com/drive/folders/0B7EVK8r0v71pWEZsZE9oNnFzTm8?resourcekey=0-5BR16BdXnb8hVj6CNHKzLg
自分の Google Drive 上にミラーした img_align_celeba.zip:
https://drive.google.com/uc?id=1LFKeoI-hb96jlV0K10dO1o04iQPBoFdx
# Download img_align_celeba.zip from GoogleDrive
MIRRORED_URL = 'https://drive.google.com/uc?id=1LFKeoI-hb96jlV0K10dO1o04iQPBoFdx'
! gdown {MIRRORED_URL}
! ls -l
DATA_DIR = 'data'
DATA_SUBDIR = 'img_align_celeba'
! rm -rf {DATA_DIR}
! unzip -d {DATA_DIR} -q {DATA_SUBDIR}.zip
! ls -l {DATA_DIR}/{DATA_SUBDIR} | head
! ls {DATA_DIR}/{DATA_SUBDIR} | wc
# paths to all the image files.
import os
import glob
import numpy as np
all_file_paths = np.array(glob.glob(os.path.join(DATA_DIR, DATA_SUBDIR, '*.jpg')))
n_all_images = len(all_file_paths)
print(n_all_images)
# slect some image files.
n_to_show = 10
selected_indices = np.random.choice(range(n_all_images), n_to_show)
selected_paths = all_file_paths[selected_indices]
# Display some images.
%matplotlib inline
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, n_to_show, figsize=(1.4 * n_to_show, 1.4))
for i, path in enumerate(selected_paths):
img = tf.keras.preprocessing.image.load_img(path)
ax[i].imshow(img)
ax[i].axis('off')
plt.show()
TRAIN_DATA_DIR = 'train_data'
TEST_DATA_DIR = 'test_data'
import os
split = 0.05
indices = np.arange(n_all_images)
np.random.shuffle(indices)
train_indices = indices[: -int(n_all_images * split)]
test_indices = indices[-int(n_all_images * split):]
! rm -rf {TRAIN_DATA_DIR} {TEST_DATA_DIR}
dst=f'{TRAIN_DATA_DIR}/celeba'
if not os.path.exists(dst):
os.makedirs(dst)
for idx in train_indices:
path = all_file_paths[idx]
dpath, fname = os.path.split(path)
os.symlink(f'../../{path}', f'{dst}/{fname}')
dst=f'{TEST_DATA_DIR}/celeba'
if not os.path.exists(dst):
os.makedirs(dst)
for idx in test_indices:
path = all_file_paths[idx]
dpath, fname = os.path.split(path)
os.symlink(f'../../{path}', f'{dst}/{fname}')
INPUT_DIM = (128, 128, 3)
BATCH_SIZE = 32
data_gen = tf.keras.preprocessing.image.ImageDataGenerator(
rescale = 1.0/255
)
data_flow = data_gen.flow_from_directory(
TRAIN_DATA_DIR,
target_size = INPUT_DIM[:2],
batch_size = BATCH_SIZE,
shuffle=True,
class_mode = 'input'
)
val_data_flow = data_gen.flow_from_directory(
TEST_DATA_DIR,
target_size = INPUT_DIM[:2],
batch_size = BATCH_SIZE,
shuffle=True,
class_mode = 'input'
)
print(len(data_flow))
print(len(val_data_flow))
save_path3 = '/content/drive/MyDrive/ColabRun/VAE_CelebA03/'
# Load the parameters and model weights saved before
# 保存したパラメータと重みを読み込む
from nw.VariationalAutoEncoder import VariationalAutoEncoder
vae3 = VariationalAutoEncoder.load(save_path3)
print(vae3.epoch)
n_val_data = len(val_data_flow)
print(n_val_data)
data, _ = next(val_data_flow)
_, _, z = vae3.encoder.predict(data)
print(z.shape)
z_dim = 200
data, _ = next(val_data_flow)
_, _, z = vae3.encoder.predict(data)
z_max = z.max(axis=0)
z_min = z.min(axis=0)
print(len(z_max))
print(len(z_min))
for i in range(len(val_data_flow)):
data, _ = next(val_data_flow)
_, _, z = vae3.encoder.predict(data)
tmp_max = z.max(axis=0)
tmp_min = z.min(axis=0)
z_max = np.amax([z_max, tmp_max], axis=0)
z_min = np.amin([z_min, tmp_min], axis=0)
print(len(z_max))
print(len(z_min))
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(1, 1, figsize=(12, 12))
for i in range(n_val_data):
data, _ = next(val_data_flow)
_, _, z = vae3.encoder.predict(data)
ax.scatter(z[:,0], z[:,1], c='black', alpha=0.5, s=2)
plt.show()
# Generate 30 points in 200-dimensional latent space.
# 200次元の潜在空間の点を30個生成する。
import numpy as np
table_row = 10 # 表の横方向サイズ
table_line = 3 #表の縦方向サイズ
n_to_show = table_row * table_line
mat = np.array([ np.random.uniform(z_min[j], z_max[j], n_to_show) for j in range(z_dim)])
z_points = mat.transpose()
print(z_points.shape)
# Display 200-dimensional points on 2-dimensional space.
# 生成した200次元の点を2次元平面に表示する
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(1, 1, figsize=(12, 12))
for i in range(n_val_data):
data, _ = next(val_data_flow)
_, _, z = vae3.encoder.predict(data)
ax.scatter(z[:,0], z[:,1], c='black', alpha=0.5, s=2)
ax.scatter(z_points[:, 0], z_points[:, 1], c='red', alpha=1, s=20)
for i in range(len(z_points)):
ax.text(z_points[i][0], z_points[i][1], str(i))
plt.show()
# Generate images from the points in 200-dimensional latent space.
# 200次元の潜在空間内の点から画像を生成する
reconst = vae3.decoder.predict(z_points)
# Display generated images.
# 生成した画像を表示する
%matplotlib inline
import matplotlib.pyplot as plt
VSKIP=0.5 # vertical space between subplots
fig, ax = plt.subplots(table_line, table_row, figsize=(2.8 * table_row, 2.8 * table_line * (1+VSKIP)))
plt.subplots_adjust(hspace = VSKIP)
for y in range(table_line):
for x in range(table_row):
idx = table_row * y + x
img = reconst[idx].squeeze()
ax[y][x].imshow(img, cmap='gray')
ax[y][x].text(0.5, -0.35, f'{idx} ({z_points[idx][0]:.2f}, {z_points[idx][1]:.2f})', fontsize=16, ha='center', transform=ax[y][x].transAxes)
ax[y][x].axis('off')
plt.show()
z_mid = np.mean([z_min, z_max], axis=0)
print(z_mid.shape)
n_grid = 20
x = np.linspace(z_min[0], z_max[0], n_grid)
y = np.linspace(z_min[1], z_max[1], n_grid)
xv, yv = np.meshgrid(x, y)
xv = xv.flatten()
yv = yv.flatten()
z_points2 = np.zeros((xv.shape[0], z_dim))
print(z_points2.shape)
for i in range(z_points2.shape[0]):
z_points2[i] = z_mid
for j in range(20):
z_points2[i,2*j+0] = xv[i]
z_points2[i,2*j+1] = yv[i]
reconst2 = vae3.decoder.predict(z_points2)
%matplotlib inline
import matplotlib.pyplot as plt
fig, ax = plt.subplots(n_grid, n_grid, figsize=(0.7*n_grid, 0.7*n_grid))
for i in range(len(reconst2)):
img = reconst2[i]
line = i // n_grid
row = i % n_grid
ax[line][row].imshow(img)
ax[line][row].axis('off')
plt.show()
# Display 200-dimensional points on 2-dimensional space.
# 生成した200次元の点を2次元平面に表示する
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(1, 1, figsize=(12, 12))
for i in range(n_val_data):
data, _ = next(val_data_flow)
_, _, z = vae3.encoder.predict(data)
ax.scatter(z[:,0], z[:,1], c='black', alpha=0.5, s=2)
ax.scatter(z_points2[:, 0], z_points2[:, 1], c='red', alpha=1, s=20)
for i in range(len(z_points2)):
ax.text(z_points2[i][0], z_points2[i][1], str(i))
plt.show()