-
Notifications
You must be signed in to change notification settings - Fork 5.4k
/
Copy path__init__.py
113 lines (91 loc) · 3.54 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Visualization tools for tensorflow_docs.
Use this module for plotting and visualization code that is too long to inline
into a notebook.
"""
import matplotlib.pyplot as plt
import numpy as np
prop_cycle = plt.rcParams['axes.prop_cycle']
COLOR_CYCLE = prop_cycle.by_key()['color']
def _smooth(values, std):
"""Smooths a list of values by convolving with a Gaussian distribution.
Assumes equal spacing.
Args:
values: A 1D array of values to smooth.
std: The standard deviation of the Gaussian distribution. The units are
array elements.
Returns:
The smoothed array.
"""
width = std * 4
x = np.linspace(-width, width, min(2 * width + 1, len(values)))
kernel = np.exp(-(x / 5)**2)
values = np.array(values)
weights = np.ones_like(values)
smoothed_values = np.convolve(values, kernel, mode='same')
smoothed_weights = np.convolve(weights, kernel, mode='same')
return smoothed_values / smoothed_weights
class HistoryPlotter(object):
"""A class for plotting a named set of Keras-histories.
The class maintains colors for each key from plot to plot.
"""
def __init__(self, metric=None, smoothing_std=None):
self.color_table = {}
self.metric = metric
self.smoothing_std = smoothing_std
def plot(self, histories, metric=None, smoothing_std=None):
"""Plots a {name: history} dictionary of Keras histories.
Colors are assigned to the name-key, and maintained from call to call.
Training metrics are shown as a solid line, validation metrics dashed.
Args:
histories: {name: history} a dictionary of Keras histories.
metric: which metric to plot from all the histories.
smoothing_std: the standard deviation of the smoothing kernel applied
before plotting. The units are in array-indices.
"""
if metric is None:
metric = self.metric
if smoothing_std is None:
smoothing_std = self.smoothing_std
for name, history in histories.items():
# Remember name->color associations.
if name in self.color_table:
color = self.color_table[name]
else:
color = COLOR_CYCLE[len(self.color_table) % len(COLOR_CYCLE)]
self.color_table[name] = color
train_value = history.history[metric]
val_value = history.history['val_' + metric]
if smoothing_std is not None:
train_value = _smooth(train_value, std=smoothing_std)
val_value = _smooth(val_value, std=smoothing_std)
plt.plot(
history.epoch,
train_value,
color=color,
label=name.title() + ' Train')
plt.plot(
history.epoch,
val_value,
'--',
label=name.title() + ' Val',
color=color)
plt.xlabel('Epochs')
plt.ylabel(metric.replace('_', ' ').title())
plt.legend()
plt.xlim(
[0, max([history.epoch[-1] for name, history in histories.items()])])
plt.grid(True)