Learning curves (layer widths)

Hello world

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.initializers import GlorotUniform

from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split

from matplotlib.colors import LogNorm
from mpl_toolkits.mplot3d import Axes3D

from etudes.metrics import nmse
num_layers = 2

num_epochs = 100
batch_size = 64

val_rate = 0.2

seed = 8888  # set random seed for reproducibility
random_state = np.random.RandomState(seed)
t_grid = np.arange(num_epochs)
width_grid = np.arange(2, 65)
dataset = load_boston()
X_train, X_val, y_train, y_val = train_test_split(dataset.data, dataset.target,
                                                  test_size=val_rate,
                                                  random_state=random_state)
frames = []

for i, width in enumerate(width_grid):

    num_units = int(width)
    model = Sequential()
    for _ in range(num_layers):
        model.add(Dense(num_units, activation="relu",
                        kernel_initializer=GlorotUniform(seed=seed)))
    model.add(Dense(1, kernel_initializer=GlorotUniform(seed=seed)))

    model.compile(optimizer="adam", loss="mean_squared_error", metrics=[nmse])
    hist = model.fit(X_train, y_train, validation_data=(X_val, y_val),
                     epochs=num_epochs, batch_size=batch_size, verbose=False)

    frame = pd.DataFrame(hist.history).assign(width=width, seed=seed)
    frame.index.name = "epoch"
    frame.reset_index(inplace=True)
    frames.append(frame)
data = pd.concat(frames, axis="index", ignore_index=True, sort=True)
data.rename(lambda s: s.replace('_', ' '), axis="columns", inplace=True)
fig, ax = plt.subplots()

sns.lineplot(x="epoch", y="val nmse", hue="width",
             units="seed", estimator=None,
             palette="viridis_r", linewidth=0.4,
             data=data, ax=ax)

ax.set_xscale("log")
ax.set_yscale("log")

plt.show()
plot learning curves width
fig, ax = plt.subplots()

sns.lineplot(x="width", y="val nmse", hue="epoch",
             units="seed", estimator=None,
             palette="viridis_r", linewidth=0.4,
             data=data, ax=ax)

ax.set_xscale("log", base=2)
ax.set_yscale("log")

plt.show()
plot learning curves width
new_data = data.pivot(index="width", columns="epoch", values="val nmse")
Z = new_data.to_numpy()
fig, ax = plt.subplots()

ax.contour(*np.broadcast_arrays(width_grid.reshape(-1, 1), t_grid), Z,
           levels=np.logspace(0, 4, 25), norm=LogNorm(), cmap="viridis")

ax.set_xscale("log", base=2)

ax.set_xlabel(r"width")
ax.set_ylabel(r"epoch")

plt.show()
plot learning curves width
fig, ax = plt.subplots(subplot_kw=dict(projection="3d", azim=50))

ax.plot_surface(np.log2(width_grid).reshape(-1, 1), t_grid, np.log(Z), alpha=0.8,
                edgecolor='k', linewidth=0.4, cmap="Spectral_r")

ax.set_xlabel(r"$\log_2$ width")
ax.set_ylabel("epoch")
ax.set_zlabel(r"$\log_{10}$ val nmse")

plt.show()
plot learning curves width
new_data.rename(lambda s: s + 1, axis="columns", inplace=True)
columns = list(np.minimum(3**np.arange(6), num_epochs))
g = sns.PairGrid(new_data[columns], corner=True)
g = g.map_lower(plt.plot)
plot learning curves width
g = sns.PairGrid(new_data[columns].reset_index(),
                 hue="width", palette="Spectral", corner=True)
g = g.map_lower(plt.scatter, facecolor="none", alpha=0.8)
plot learning curves width

Total running time of the script: ( 3 minutes 6.121 seconds)

Gallery generated by Sphinx-Gallery