Stochastic Engines#
Learning more about stochastic engines/algorithms such as the popular ePIE algorithm.
The most popular stochastic algorithm is the extended Ptychographic Iterative Engine (ePIE). The exit wave update in standard ePIE is basically like alternating projections in that
where \(\mathcal{O}\) and \(\mathcal{F}\) are again the overlap and Fourier update, respectively. In contrast to projectional methods ePIE is following a stochastic approach where the exit wave is updated sequentially for randomly selected views. In each of these randomized steps as part of the overlap update, the probe \(P_{j}\) and object \(O_{j}\) are modified like this
where \(\Psi_{\prime} = \mathcal{O}(\Psi_{j}) = P_{j} \cdot O_{j}\) is the exit wave from the previously updated view, \(^{*}\) is the complex conjugate and \(||\cdot||_{max}\) is the maximum norm. The parameters \(\alpha\) and \(\beta\) control the strength of object and probe update, respectively and are both equal to \(1\) by default. Lowering \(\alpha\) or \(\beta\) will lower the impact of the object/probe update in each stochastic update, which slows down convergence but might help in escaping artefacts that can occur in some cases. In practice, \(\alpha=0.1\) and \(\beta=0.9\) seems to be a good alternative choicefor for some tricky experimental datasets. In our moonflower example we can stick to the default values for alpha
and beta
p.engines.engine00 = u.Param()
p.engines.engine00.name = "EPIE"
p.engines.engine00.numiter = 200
p.engines.engine00.alpha = 1
p.engines.engine00.beta = 1
During the probe update of the original ePIE algorithm, the maximum norm is calculated and applied seperately for each view which can lead to big changes in the probe depending on the random sequence of views. A different approach is to always calculate the maximum norm over the entire object resulting in less jumpy changes during the probe update. This can be controlled using object_norm_is_global
which is False
by default.
p.engines.engine00.object_norm_is_global = False
Challenge
Modify different ePIE engine parameters and observe their impact on the outcome of the reconstruction.
import ptypy
import ptypy.utils as u
p = u.Param()
p.verbose_level = "interactive"
p.io = u.Param()
p.io.rfile = None
p.io.autosave = u.Param(active=False)
p.io.interaction = u.Param(active=False)
# Live-plotting
p.io.autoplot = u.Param()
p.io.autoplot.active=True
p.io.autoplot.threaded = False
p.io.autoplot.layout = "jupyter"
p.io.autoplot.interval = 10
p.scans = u.Param()
p.scans.MF = u.Param()
p.scans.MF.name = "Full"
p.scans.MF.data= u.Param()
p.scans.MF.data.name = "MoonFlowerScan"
p.scans.MF.data.shape = 128
p.scans.MF.data.num_frames = 200
p.scans.MF.data.save = None
p.scans.MF.data.density = 0.2
p.scans.MF.data.photons = 1e8
p.scans.MF.data.psf = 0.
# Define reconstruction engines
p.engines = u.Param()
# ePIE engine
p.engines.engine00 = u.Param()
p.engines.engine00.name = "EPIE"
p.engines.engine00.numiter = 200
p.engines.engine00.numiter_contiguous = 10
p.engines.engine00.alpha = 1
p.engines.engine00.beta = 1
p.engines.engine00.object_norm_is_global = False
P = ptypy.core.Ptycho(p,level=5)