Added a minimum plotting interval to model.inspect(dataset) to make it easier to not plot so much without manual intervention

This commit is contained in:
allevitan
2026-03-20 20:01:40 +01:00
parent f35141dcc8
commit bef907c032
6 changed files with 34 additions and 30 deletions
+6 -6
View File
@@ -32,9 +32,9 @@ recon = cdtools.reconstructors.AdamReconstructor(model, dataset)
# The batch size sets the minibatch size
for loss in recon.optimize(50, lr=0.02, batch_size=10):
print(model.report())
# Plotting is expensive, so we only do it every tenth epoch
if model.epoch % 10 == 0:
model.inspect(dataset)
# Because plotting can be expensive, setting a minimum plotting interval
# (in seconds) can avoid excessive replots.
model.inspect(dataset, min_interval=5)
# It's common to chain several different reconstruction loops. Here, we
# started with an aggressive refinement to find the probe in the previous
@@ -42,12 +42,12 @@ for loss in recon.optimize(50, lr=0.02, batch_size=10):
# and larger minibatch
for loss in recon.optimize(50, lr=0.005, batch_size=50):
print(model.report())
if model.epoch % 10 == 0:
model.inspect(dataset)
model.inspect(dataset, min_interval=5)
# This orthogonalizes the recovered probe modes
model.tidy_probes()
model.inspect(dataset)
# Setting replot_all will reopen any windows which were closed earlier
model.inspect(dataset, replot_all=True)
model.compare(dataset)
plt.show()
+4 -7
View File
@@ -54,13 +54,11 @@ with model.save_on_exception(
for loss in recon.optimize(20, lr=0.005, batch_size=50):
print(model.report())
if model.epoch % 10 == 0:
model.inspect(dataset)
model.inspect(dataset, min_interval=5)
for loss in recon.optimize(50, lr=0.002, batch_size=100):
print(model.report())
if model.epoch % 10 == 0:
model.inspect(dataset)
model.inspect(dataset, min_interval=5)
# We can often reset our guess of the probe positions once we have a
# good guess of probe and object, but in this case it causes the
@@ -71,8 +69,7 @@ with model.save_on_exception(
# the loss fails to improve after 10 epochs
for loss in recon.optimize(100, lr=0.001, batch_size=100, schedule=True):
print(model.report())
if model.epoch % 10 == 0:
model.inspect(dataset)
model.inspect(dataset, min_interval=5)
model.tidy_probes()
@@ -80,6 +77,6 @@ model.tidy_probes()
# This saves the final result
model.save_to_h5('example_reconstructions/gold_balls.h5', dataset)
model.inspect(dataset)
model.inspect(dataset, replot_all=True)
model.compare(dataset)
plt.show()
+3 -6
View File
@@ -40,18 +40,15 @@ recon = cdtools.reconstructors.AdamReconstructor(model, dataset)
for loss in recon.optimize(100, lr=0.04, batch_size=10):
print(model.report())
# Plotting is expensive, so we only do it every tenth epoch
if model.epoch % 10 == 0:
model.inspect(dataset)
model.inspect(dataset, min_interval=5)
for loss in recon.optimize(50, lr=0.005, batch_size=50):
print(model.report())
if model.epoch % 10 == 0:
model.inspect(dataset)
model.inspect(dataset, min_interval=5)
# This orthogonalizes the recovered probe modes
model.tidy_probes()
model.inspect(dataset)
model.inspect(dataset, replot_all=True)
model.compare(dataset)
plt.show()
+2 -4
View File
@@ -30,10 +30,8 @@ for loss in model.Adam_optimize(30, dataset, batch_size=10):
# We print a quick report of the optimization status
print(model.report())
# And liveplot the updates to the model as they happen
if model.epoch % 10 == 0:
model.inspect(dataset)
model.inspect(dataset)
# We study the results
model.inspect(dataset, replot_all=True)
# We open a comparison of the simulated and measured data
model.compare(dataset)
plt.show()
+6 -6
View File
@@ -30,20 +30,20 @@ if t.cuda.is_available():
# Note that the inspect step takes the vast majority of the time
# The regularization is an L2 regularizer that empirically helps accelerate
# convergence
for loss in model.Adam_optimize(30, dataset, lr=0.4, regularization_factor=[0.05,0.05]):
model.inspect(dataset)
for loss in model.LBFGS_optimize(30, dataset, lr=0.4, regularization_factor=[0.05,0.05]):
model.inspect(dataset, min_interval=5)
print(model.report())
# Now we use the regularizer to damp all but the top modes
for loss in model.LBFGS_optimize(50, dataset, lr=0.4, regularization_factor=[0.001,0.1]):
#model.inspect(dataset)
model.inspect(dataset, min_interval=5)
print(model.report())
# Save results to a python dictionary
results = model.save_results()
# Save results to an h5 file
model.save_to_h5('example_reconstructions/transmission_RPI.h5', dataset)
# Finally, we plot the results
model.inspect(dataset)
model.inspect(dataset, replot_all=True)
model.compare(dataset)
plt.show()
+13 -1
View File
@@ -69,6 +69,7 @@ class CDIModel(t.nn.Module):
self.panel_plot_mode = panel_plot_mode
self.plot_level = plot_level
self.has_inspect_been_called = False
self.last_inspected_time = None
def from_dataset(self, dataset):
raise NotImplementedError()
@@ -557,7 +558,7 @@ class CDIModel(t.nn.Module):
plot_list = []
def inspect(self, dataset=None, replot_all=False):
def inspect(self, dataset=None, replot_all=False, min_interval=None):
"""Plots all the plots defined in the model's plot_panel_list and plot_list attributes
Updates any previously plotted figures that are still open. Figures
@@ -586,8 +587,17 @@ class CDIModel(t.nn.Module):
Optional, a dataset matched to the model type
replot_all : bool, default: False
If True, recreate figures that were previously closed by the user.
min_interval : float, optional
If set, skip updating plots if fewer than this many seconds have
elapsed since the last call to inspect(). The time of the last
update is stored in self.last_inspected_time.
"""
if (min_interval is not None
and self.last_inspected_time is not None
and time.time() - self.last_inspected_time < min_interval):
return
plot_panel_list = getattr(self, 'plot_panel_list', None) or []
plot_list = getattr(self, 'plot_list', None) or []
@@ -624,6 +634,8 @@ class CDIModel(t.nn.Module):
fig.canvas.flush_events()
self.has_inspect_been_called = True
self.last_inspected_time = time.time()
def _is_backend_interactive(
self