-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlogger.py
More file actions
executable file
·177 lines (146 loc) · 6.82 KB
/
logger.py
File metadata and controls
executable file
·177 lines (146 loc) · 6.82 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
"""
logger.py
Tensor ops-free logger to Tensorboard.
Written by Phil Ferriere
Licensed under the MIT License (see LICENSE for details)
Based on:
- https://gist.github.com/gyglim/1f8dfb1b5c82627ae3efcfbbadb9f514
Written by Michael Gygli
License: Copyleft
To look at later:
- Display Image1 and Image2 as an animated GIF rather than side-by-side? Demonstrated below:
https://github.com/djl11/PWC_Net_TensorFlow/blob/e321b0ee825416a84258559fc90e13cf722e4608/custom_ops/native.py#L216-L242
- Add error between predicted flow and gt? Demonstrated below:
https://github.com/djl11/PWC_Net_TensorFlow/blob/e321b0ee825416a84258559fc90e13cf722e4608/custom_ops/native.py#L198-L214
"""
from __future__ import absolute_import, division, print_function
import tensorflow as tf
from io import BytesIO
import matplotlib.pyplot as plt
import numpy as np
from visualize import plot_img_pairs_w_flows
class TBLogger(object):
"""Logging in tensorboard without tensorflow ops."""
def __init__(self, log_dir, tag=None, graph=None):
"""Creates a summary writer logging to log_dir.
Args:
log_dir: Tensorboard logging directory
tag: Suggested logger types: ('train', 'val', 'test')
graph: Optional, TF graph
"""
if graph is None:
graph = tf.get_default_graph()
if tag is not None:
log_dir = log_dir + tag
self.writer = tf.summary.FileWriter(log_dir, graph=graph)
self._tag = tag
@property
def tag(self):
if self._tag is None:
return self._tag
else:
return ""
def log_scalar(self, tag, value, step):
"""Log a scalar variable.
Args:
tag: name of the scalar
value: scalar value to log
step: training iteration
"""
summary = tf.Summary(value=[tf.Summary.Value(tag=tag, simple_value=value)])
self.writer.add_summary(summary, step)
def log_images(self, tag, images, step, IDs=None):
"""Logs a list of images.
Args:
tag: format for the name of the summary (will format ID accordingly)
images: list of images
step: training iteration
IDs: list of IDs
"""
if images is None:
return
im_summaries = []
for n in range(len(images)):
# Write the image to a string
faux_file = BytesIO() # StringIO()
if len(images[n].shape) == 3 and images[n].shape[2] == 1:
image = np.squeeze(images[n], axis=-1) # (H, W, 1) -> (H, W)
cmap = 'gray'
else:
image = images[n]
cmap = None
plt.imsave(faux_file, image, cmap=cmap, format='png') # (?, H, W, ?)
# Create an Image object
img_sum = tf.Summary.Image(encoded_image_string=faux_file.getvalue(), height=image.shape[0],
width=image.shape[1])
# Create a Summary value
img_tag = tag.format(IDs[n]) if IDs is not None else tag.format(n)
im_summaries.append(tf.Summary.Value(tag=img_tag, image=img_sum))
# Create and write Summary
summary = tf.Summary(value=im_summaries)
self.writer.add_summary(summary, step)
def log_histogram(self, tag, values, step, bins=1000):
"""Logs the histogram of a list/vector of values."""
# Convert to a numpy array
values = np.array(values)
# Create histogram using numpy
counts, bin_edges = np.histogram(values, bins=bins)
# Fill fields of histogram proto
hist = tf.HistogramProto()
hist.min = float(np.min(values))
hist.max = float(np.max(values))
hist.num = int(np.prod(values.shape))
hist.sum = float(np.sum(values))
hist.sum_squares = float(np.sum(values ** 2))
# Requires equal number as bins, where the first goes from -DBL_MAX to bin_edges[1]
# See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/summary.proto#L30
# Thus, we drop the start of the first bin
bin_edges = bin_edges[1:]
# Add bin edges and counts
for edge in bin_edges:
hist.bucket_limit.append(edge)
for c in counts:
hist.bucket.append(c)
# Create and write Summary
summary = tf.Summary(value=[tf.Summary.Value(tag=tag, histo=hist)])
self.writer.add_summary(summary, step)
self.writer.flush()
class OptFlowTBLogger(TBLogger):
"""Logging of optical flows and pyramids in tensorboard without tensorflow ops."""
def __init__(self, log_dir, tag=None, graph=None):
"""Creates a summary writer logging to log_dir. See base class inplementation for details.
"""
super().__init__(log_dir, tag, graph)
def log_imgs_w_flows(self, tag, img_pairs, flow_pyrs, num_lvls, flow_preds, flow_gts, step, IDs=None, info=None):
"""Logs a list of optical flows.
Args:
tag: format for the name of the summary (will format ID accordingly)
img_pairs: list of image pairs in [batch_size, 2, H, W, 3]
flow_pyrs: predicted optical flow pyramids [batch_size, H, W, 2] or list([H, W, 2]) format.
num_lvls: number of levels per pyramid (flow_pyrs must be set)
flow_preds: list of predicted flows in [batch_size, H, W, 2]
flow_gts: optional, list of groundtruth flows in [batch_size, H, W, 2]
step: training iteration
IDs: optional, list of IDs
"""
assert(len(img_pairs) == len(flow_preds))
im_summaries = []
for n in range(len(img_pairs)):
# Combine image pair, predicted flow, flow pyramid, and groundtruth flow in a single plot
img_pair = np.expand_dims(img_pairs[n], axis=0)
flow_pyr = np.expand_dims(flow_pyrs[n], axis=0) if flow_pyrs is not None else None
flow_pred = np.expand_dims(flow_preds[n], axis=0) if flow_preds is not None else None
gt_flow = np.expand_dims(flow_gts[n], axis=0) if flow_gts is not None else None
plt = plot_img_pairs_w_flows(img_pair, flow_pyr, num_lvls, flow_pred, gt_flow, None, info)
# Write the image to a string
faux_file = BytesIO() # StringIO()
plt.savefig(faux_file, bbox_inches='tight', pad_inches=0.1)
plt.close()
# Create an Image object
img_sum = tf.Summary.Image(encoded_image_string=faux_file.getvalue())
# Create a Summary value
img_tag = tag.format(IDs[n]) if IDs is not None else tag.format(n)
im_summaries.append(tf.Summary.Value(tag=img_tag, image=img_sum))
# Create and write Summary
summary = tf.Summary(value=im_summaries)
self.writer.add_summary(summary, step)