104 lines
3.9 KiB
Python
104 lines
3.9 KiB
Python
from __future__ import division
|
|
from __future__ import print_function
|
|
|
|
import numpy as np
|
|
import matplotlib
|
|
# noninteractive background
|
|
matplotlib.use('Agg')
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
def plot_training_curve(train_loss, validation_loss, fname='training_curve.pdf', labels=None):
|
|
"""
|
|
Plots train_loss and validation loss as a function of optimization iteration
|
|
:param train_loss: np.array of train_loss (1D or 2D)
|
|
:param validation_loss: np.array of validation loss (1D or 2D)
|
|
:param fname: output file name
|
|
:param labels: if train_loss and validation loss are 2D, then labels indicate which variable is varied
|
|
accross training curves.
|
|
:return: None
|
|
"""
|
|
|
|
plt.close()
|
|
|
|
matplotlib.rcParams.update({'font.size': 14})
|
|
matplotlib.rcParams['mathtext.fontset'] = 'stix'
|
|
matplotlib.rcParams['font.family'] = 'STIXGeneral'
|
|
|
|
if len(train_loss.shape) == 1:
|
|
# Single training curve
|
|
fig, ax = plt.subplots(nrows=1, ncols=1)
|
|
figsize = (6, 4)
|
|
|
|
if train_loss.shape[0] == validation_loss.shape[0]:
|
|
# validation score evaluated every iteration
|
|
x = np.arange(train_loss.shape[0])
|
|
ax.plot(x, train_loss, '-', lw=2., color='black', label='train')
|
|
ax.plot(x, validation_loss, '-', lw=2., color='blue', label='val')
|
|
|
|
elif train_loss.shape[0] % validation_loss.shape[0] == 0:
|
|
# validation score evaluated every epoch
|
|
x = np.arange(train_loss.shape[0])
|
|
ax.plot(x, train_loss, '-', lw=2., color='black', label='train')
|
|
|
|
x = np.arange(validation_loss.shape[0])
|
|
x = (x + 1) * train_loss.shape[0] / validation_loss.shape[0]
|
|
ax.plot(x, validation_loss, '-', lw=2., color='blue', label='val')
|
|
else:
|
|
raise ValueError('Length of train_loss and validation_loss must be equal or divisible')
|
|
|
|
miny = np.minimum(validation_loss.min(), train_loss.min()) - 20.
|
|
maxy = np.maximum(validation_loss.max(), train_loss.max()) + 30.
|
|
ax.set_ylim([miny, maxy])
|
|
|
|
elif len(train_loss.shape) == 2:
|
|
# Multiple training curves
|
|
|
|
cmap = plt.cm.brg
|
|
|
|
cNorm = matplotlib.colors.Normalize(vmin=0, vmax=train_loss.shape[0])
|
|
scalarMap = matplotlib.cm.ScalarMappable(norm=cNorm, cmap=cmap)
|
|
|
|
fig, ax = plt.subplots(nrows=1, ncols=1)
|
|
figsize = (6, 4)
|
|
|
|
if labels is None:
|
|
labels = ['%d' % i for i in range(train_loss.shape[0])]
|
|
|
|
if train_loss.shape[1] == validation_loss.shape[1]:
|
|
for i in range(train_loss.shape[0]):
|
|
color_val = scalarMap.to_rgba(i)
|
|
|
|
# validation score evaluated every iteration
|
|
x = np.arange(train_loss.shape[0])
|
|
ax.plot(x, train_loss[i], '-', lw=2., color=color_val, label=labels[i])
|
|
ax.plot(x, validation_loss[i], '--', lw=2., color=color_val)
|
|
|
|
elif train_loss.shape[1] % validation_loss.shape[1] == 0:
|
|
for i in range(train_loss.shape[0]):
|
|
color_val = scalarMap.to_rgba(i)
|
|
|
|
# validation score evaluated every epoch
|
|
x = np.arange(train_loss.shape[1])
|
|
ax.plot(x, train_loss[i], '-', lw=2., color=color_val, label=labels[i])
|
|
|
|
x = np.arange(validation_loss.shape[1])
|
|
x = (x+1) * train_loss.shape[1] / validation_loss.shape[1]
|
|
ax.plot(x, validation_loss[i], '-', lw=2., color=color_val)
|
|
|
|
miny = np.minimum(validation_loss.min(), train_loss.min()) - 20.
|
|
maxy = np.maximum(validation_loss.max(), train_loss.max()) + 30.
|
|
ax.set_ylim([miny, maxy])
|
|
|
|
else:
|
|
raise ValueError('train_loss and validation_loss must be 1D or 2D arrays')
|
|
|
|
ax.set_xlabel('iteration')
|
|
ax.set_ylabel('loss')
|
|
plt.title('Training and validation loss')
|
|
|
|
fig.set_size_inches(figsize)
|
|
fig.subplots_adjust(hspace=0.1)
|
|
plt.savefig(fname, bbox_inches='tight')
|
|
|
|
plt.close()
|