In [1]:
import tensorflow as tf
tf.logging.set_verbosity(tf.logging.ERROR)
print(tf.__version__)
In [2]:
!curl -O https://raw.githubusercontent.com/DJCordhose/deep-learning-crash-course-notebooks/master/data/insurance-customers-1500.csv
In [0]:
from tensorflow import keras
from tensorflow.keras.layers import Input, Flatten, GlobalAveragePooling1D, Dense
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.utils import to_categorical
In [0]:
import pandas as pd
df = pd.read_csv('./insurance-customers-1500.csv', sep=';')
one_hot_groups = pd.DataFrame(to_categorical(df['group']), columns={'red', 'green', 'yellow'})
main = df.drop('group', axis='columns')
In [5]:
main.head()
Out[5]:
In [6]:
one_hot_groups.head()
Out[6]:
options:
In [7]:
# often does not even train, so choose a seed known to be good
from tensorflow.keras.initializers import glorot_normal
seed= 17
from tensorflow.keras.layers import concatenate, average, add
# first multi in
main_input = Input(shape=(3,), name='main_input')
group_input = Input(shape=(3,), name='group_input')
# hopefully this balances out inputs to same scale
encoded_main = Dense(units=2, activation='relu', name="main_encoder", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(main_input)
encoded_group = Dense(units=2, activation='relu', name="group_encoder", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(group_input)
# latent representation
merged = concatenate([encoded_main, encoded_group])
# this might work as well
# merged = average([encoded_main, encoded_group])
# the effective latent encoding
encoding_dim = 2
encoded = Dense(units=encoding_dim, activation='relu', name="encoder", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(merged)
# then multi out
main_output = Dense(units=3, activation='linear', name="main_output", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(encoded)
group_output = Dense(units=3, activation='softmax', name="group_output", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(encoded)
autoencoder = Model(inputs=[main_input, group_input], outputs=[main_output, group_output])
adam = keras.optimizers.Adam(lr=0.01)
# adam = keras.optimizers.Adam()
autoencoder.compile(optimizer=adam,
loss={'main_output': 'mae', 'group_output': 'categorical_crossentropy'},
loss_weights={'main_output': 1., 'group_output': 50.})
autoencoder.summary()
In [8]:
BATCH_SIZE = 1
EPOCHS=10
%time history = autoencoder.fit(\
x={'main_input': main, 'group_input': one_hot_groups},\
y={'main_output': main, 'group_output': one_hot_groups},\
epochs=EPOCHS, batch_size=BATCH_SIZE, verbose=1)
In [9]:
import matplotlib.pyplot as plt
plt.ylabel('loss')
plt.xlabel('epoch')
plt.yscale('log')
plt.plot(history.history['loss'], 'b')
plt.plot(history.history['main_output_loss'], 'r')
plt.plot(history.history['group_output_loss'], 'g')
plt.legend(['combined loss', 'main loss', 'group loss'], loc='upper right')
Out[9]:
In [0]:
samples = df.sample(10).reset_index(drop=True)
main_samples = samples.drop('group', axis='columns')
group_samples = pd.DataFrame(to_categorical(samples['group']), columns={'red', 'green', 'yellow'})
In [11]:
merged_samples = pd.concat([main_samples, group_samples], axis=1)
merged_samples
Out[11]:
In [12]:
autoencoder.predict([main_samples, group_samples])
Out[12]:
In [0]:
encoder = Model(inputs=[main_input, group_input], outputs=encoded)
latent_representation = encoder.predict(x={'main_input': main, 'group_input': one_hot_groups})
In [14]:
latent_representation.shape
Out[14]:
In [15]:
from matplotlib.colors import ListedColormap
# * 0 - red: many accidents
# * 1 - green: few or no accidents
# * 2 - yellow: in the middle
colors = df['group']
color_map = ListedColormap(['#AA4444', '#006000', '#EEEE44'])
latent_x = latent_representation[:, 0]
latent_y = latent_representation[:, 1]
plt.scatter(latent_x, latent_y, alpha=0.5, s=100, marker='o', edgecolors='w', cmap=color_map, c=colors)
Out[15]:
In [0]:
# save complete model
autoencoder.save('autoencoder-v1.h5')
del autoencoder
In [0]:
# later...
from tensorflow.keras.models import load_model
autoencoder = load_model('autoencoder-v1.h5')
In [0]:
main_input = autoencoder.get_layer('main_input').input
group_input = autoencoder.get_layer('group_input').input
encode = autoencoder.get_layer('encoder').output
encoder = Model(inputs=[main_input, group_input], outputs=encode)
In [19]:
latent_representation = encoder.predict(x={'main_input': main, 'group_input': one_hot_groups})
colors = df['group']
color_map = ListedColormap(['#AA4444', '#006000', '#EEEE44'])
latent_x = latent_representation[:, 0]
latent_y = latent_representation[:, 1]
plt.title('original data, old model')
plt.scatter(latent_x, latent_y, alpha=0.5, s=100, marker='o', edgecolors='w', cmap=color_map, c=colors)
Out[19]:
In [20]:
!curl -O https://raw.githubusercontent.com/DJCordhose/deep-learning-crash-course-notebooks/master/data/insurance-customers-300.csv
In [0]:
import pandas as pd
new_df = pd.read_csv('./insurance-customers-300.csv', sep=';')
new_one_hot_groups = pd.DataFrame(to_categorical(new_df['group']), columns={'red', 'green', 'yellow'})
new_main = new_df.drop('group', axis='columns')
In [22]:
new_df.describe()
Out[22]:
In [23]:
latent_representation = encoder.predict(x={'main_input': new_main, 'group_input': new_one_hot_groups})
colors = new_df['group']
color_map = ListedColormap(['#AA4444', '#006000', '#EEEE44'])
latent_x = latent_representation[:, 0]
latent_y = latent_representation[:, 1]
plt.title('new data, old model')
plt.scatter(latent_x, latent_y, alpha=0.5, s=100, marker='o', edgecolors='w', cmap=color_map, c=colors)
Out[23]:
In [24]:
#default lr
# adam = keras.optimizers.Adam(lr=0.001)
# we use just half of that
adam = keras.optimizers.Adam(lr=0.0005)
# even this high learning rate can not break it (moves it quite a bit, but still same overall shape)
# adam = keras.optimizers.Adam(lr=0.1)
autoencoder.compile(optimizer=adam,
loss={'main_output': 'mae', 'group_output': 'categorical_crossentropy'},
loss_weights={'main_output': 1., 'group_output': 50.})
BATCH_SIZE = 1
EPOCHS=10
%time history = autoencoder.fit(\
x={'main_input': new_main, 'group_input': new_one_hot_groups},\
y={'main_output': new_main, 'group_output': new_one_hot_groups},\
epochs=EPOCHS, batch_size=BATCH_SIZE, shuffle=True, verbose=1)
In [25]:
plt.ylabel('loss')
plt.xlabel('epoch')
plt.yscale('log')
plt.plot(history.history['loss'], 'b')
plt.plot(history.history['main_output_loss'], 'r')
plt.plot(history.history['group_output_loss'], 'g')
plt.legend(['combined loss', 'main loss', 'group loss'], loc='upper right')
Out[25]:
In [26]:
latent_representation = encoder.predict(x={'main_input': new_main, 'group_input': new_one_hot_groups})
colors = new_df['group']
color_map = ListedColormap(['#AA4444', '#006000', '#EEEE44'])
latent_x = latent_representation[:, 0]
latent_y = latent_representation[:, 1]
plt.title('updated model, new data')
plt.scatter(latent_x, latent_y, alpha=0.5, s=100, marker='o', edgecolors='w', cmap=color_map, c=colors)
Out[26]:
In [27]:
latent_representation = encoder.predict(x={'main_input': main, 'group_input': one_hot_groups})
colors = df['group']
color_map = ListedColormap(['#AA4444', '#006000', '#EEEE44'])
latent_x = latent_representation[:, 0]
latent_y = latent_representation[:, 1]
plt.title('updated model, original data')
plt.scatter(latent_x, latent_y, alpha=0.5, s=100, marker='o', edgecolors='w', cmap=color_map, c=colors)
Out[27]:
In [0]:
# start over from scratch
from tensorflow.keras.models import load_model
autoencoder = load_model('autoencoder-v1.h5')
In [0]:
main_input = autoencoder.get_layer('main_input').input
group_input = autoencoder.get_layer('group_input').input
encode = autoencoder.get_layer('encoder').output
encoder = Model(inputs=[main_input, group_input], outputs=encode)
In [0]:
new_original_latent_representation = encoder.predict(x={'main_input': new_main, 'group_input': new_one_hot_groups})
old_original_latent_representation = encoder.predict(x={'main_input': main, 'group_input': one_hot_groups})
In [31]:
latent_representation = encoder.predict(x={'main_input': main, 'group_input': one_hot_groups})
colors = df['group']
color_map = ListedColormap(['#AA4444', '#006000', '#EEEE44'])
latent_x = latent_representation[:, 0]
latent_y = latent_representation[:, 1]
plt.title('original data, original model')
plt.scatter(latent_x, latent_y, alpha=0.5, s=100, marker='o', edgecolors='w', cmap=color_map, c=colors)
Out[31]:
In [32]:
latent_representation = encoder.predict(x={'main_input': new_main, 'group_input': new_one_hot_groups})
colors = new_df['group']
color_map = ListedColormap(['#AA4444', '#006000', '#EEEE44'])
latent_x = latent_representation[:, 0]
latent_y = latent_representation[:, 1]
plt.title('new data, original model')
plt.scatter(latent_x, latent_y, alpha=0.5, s=100, marker='o', edgecolors='w', cmap=color_map, c=colors)
Out[32]:
In [33]:
# often does not even train, so choose a seed known to be good
from tensorflow.keras.initializers import glorot_normal
seed= 13
# first multi in
main_input = Input(shape=(3,), name='main_input')
group_input = Input(shape=(3,), name='group_input')
# hopefully this balances out inputs to same scale
encoded_main = Dense(units=2, activation='relu', name="main_encoder", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(main_input)
encoded_group = Dense(units=2, activation='relu', name="group_encoder", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(group_input)
# latent representation
merged = concatenate([encoded_main, encoded_group])
# this might work as well
# merged = average([encoded_main, encoded_group])
# the effective latent encoding
encoding_dim = 2
encoded = Dense(units=encoding_dim, activation='relu', name="encoder", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(merged)
# then multi out
main_output = Dense(units=3, activation='linear', name="main_output", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(encoded)
group_output = Dense(units=3, activation='softmax', name="group_output", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(encoded)
stability_output = encoded # just the latent space as output
# autoencoder = Model(inputs=[main_input, group_input], outputs=[main_output, group_output, stability_output])
autoencoder = Model(inputs=[main_input, group_input], outputs=[main_output, group_output])
# adam = keras.optimizers.Adam(lr=0.001)
adam = keras.optimizers.Adam(lr=0.01)
# autoencoder.compile(optimizer=adam,
# loss={'main_output': 'mae', 'group_output': 'categorical_crossentropy', 'encoder': 'mae' },
# loss_weights={'main_output': 1., 'group_output': 50., 'encoder': 10.})
autoencoder.compile(optimizer=adam,
loss={'main_output': 'mae', 'group_output': 'categorical_crossentropy'},
loss_weights={'main_output': 1., 'group_output': 1000.})
BATCH_SIZE = 1
EPOCHS=20
# %time history = autoencoder.fit(\
# x={'main_input': new_main, 'group_input': new_one_hot_groups},\
# y={'main_output': new_main, 'group_output': new_one_hot_groups, 'encoder': new_original_latent_representation},\
# epochs=EPOCHS, batch_size=BATCH_SIZE, shuffle=True, verbose=1)
%time history = autoencoder.fit(\
x={'main_input': new_main, 'group_input': new_one_hot_groups},\
y={'main_output': new_main, 'group_output': new_one_hot_groups},\
epochs=EPOCHS, batch_size=BATCH_SIZE, verbose=1)
In [0]:
main_input = autoencoder.get_layer('main_input').input
group_input = autoencoder.get_layer('group_input').input
encode = autoencoder.get_layer('encoder').output
encoder = Model(inputs=[main_input, group_input], outputs=encode)
In [35]:
latent_representation = encoder.predict(x={'main_input': new_main, 'group_input': new_one_hot_groups})
colors = new_df['group']
color_map = ListedColormap(['#AA4444', '#006000', '#EEEE44'])
latent_x = latent_representation[:, 0]
latent_y = latent_representation[:, 1]
plt.title('new data, new model without forcing')
plt.scatter(latent_x, latent_y, alpha=0.5, s=100, marker='o', edgecolors='w', cmap=color_map, c=colors)
Out[35]:
In [36]:
# often does not even train, so choose a seed known to be good
from tensorflow.keras.initializers import glorot_normal
seed= 13
# first multi in
main_input = Input(shape=(3,), name='main_input')
group_input = Input(shape=(3,), name='group_input')
# hopefully this balances out inputs to same scale
encoded_main = Dense(units=2, activation='relu', name="main_encoder", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(main_input)
encoded_group = Dense(units=2, activation='relu', name="group_encoder", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(group_input)
# latent representation
merged = concatenate([encoded_main, encoded_group])
# this might work as well
# merged = average([encoded_main, encoded_group])
# the effective latent encoding
encoding_dim = 2
encoded = Dense(units=encoding_dim, activation='relu', name="encoder", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(merged)
# then multi out
main_output = Dense(units=3, activation='linear', name="main_output", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(encoded)
group_output = Dense(units=3, activation='softmax', name="group_output", bias_initializer='zeros', kernel_initializer=glorot_normal(seed=seed))(encoded)
stability_output = encoded # just the latent space as output
autoencoder = Model(inputs=[main_input, group_input], outputs=[main_output, group_output, stability_output])
# adam = keras.optimizers.Adam(lr=0.001)
adam = keras.optimizers.Adam(lr=0.01)
autoencoder.compile(optimizer=adam,
loss={'main_output': 'mae', 'group_output': 'categorical_crossentropy', 'encoder': 'mae' },
loss_weights={'main_output': 1., 'group_output': 100., 'encoder': 100.})
BATCH_SIZE = 1
EPOCHS=20
%time history = autoencoder.fit(\
x={'main_input': new_main, 'group_input': new_one_hot_groups},\
y={'main_output': new_main, 'group_output': new_one_hot_groups, 'encoder': new_original_latent_representation},\
epochs=EPOCHS, batch_size=BATCH_SIZE, verbose=1)
In [37]:
main_input = autoencoder.get_layer('main_input').input
group_input = autoencoder.get_layer('group_input').input
encode = autoencoder.get_layer('encoder').output
encoder = Model(inputs=[main_input, group_input], outputs=encode)
latent_representation = encoder.predict(x={'main_input': new_main, 'group_input': new_one_hot_groups})
colors = new_df['group']
color_map = ListedColormap(['#AA4444', '#006000', '#EEEE44'])
latent_x = latent_representation[:, 0]
latent_y = latent_representation[:, 1]
plt.title('new data, new model with forcing')
plt.scatter(latent_x, latent_y, alpha=0.5, s=100, marker='o', edgecolors='w', cmap=color_map, c=colors)
Out[37]:
In [0]: