Skip to content

Commit

Permalink
Miscellaneous changes (#227)
Browse files Browse the repository at this point in the history
* Clean up and add entry

* Address duplicate label warning

* Add support for generic loss

* Typo fix

* Split loss tests out of functional tests

* Minor edits

* New example script

* Add new example to index

* Add some references

* Update submodule

* Typo fix

* Fix import

* Fix style violations

* Docstring fix

* Fix SVMBIRExtendedLoss.__init__

* Typo fix and minor improvement

* Add pypi downloads badge

* Minor docstring fix

* Improve parameter names

* Minor docstring improvement

* Rename parameter

* Update submodule
  • Loading branch information
bwohlberg committed Feb 23, 2022
1 parent ab27646 commit 54f9b39
Show file tree
Hide file tree
Showing 22 changed files with 525 additions and 206 deletions.
6 changes: 5 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@

.. image:: https://badge.fury.io/py/scico.svg
:target: https://badge.fury.io/py/scico
:alt: Current PyPI package version
:alt: PyPI package version

.. image:: https://static.pepy.tech/personalized-badge/scico?period=month&left_color=grey&right_color=brightgreen
:target: https://pepy.tech/project/scico
:alt: PyPI download statistics

.. image:: https://raw.githubusercontent.com/jupyter/design/master/logos/Badges/nbviewer_badge.svg
:target: https://nbviewer.jupyter.org/github/lanl/scico-data/tree/main/notebooks/index.ipynb
Expand Down
2 changes: 1 addition & 1 deletion data
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def patched_parse(self):

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ["tmp", "*.tmp.*", "*.tmp", "index.ipynb"]
exclude_patterns = ["tmp", "*.tmp.*", "*.tmp", "index.ipynb", "exampledepend.rst"]

# If true, '()' will be appended to :func: etc. cross-reference text.
add_function_parentheses = False
Expand Down
2 changes: 1 addition & 1 deletion docs/source/exampledepend.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.. _example_dependencies:
.. _example_depend:

Example Dependencies
--------------------
Expand Down
3 changes: 3 additions & 0 deletions docs/source/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Miscellaneous
:maxdepth: 1

examples/demosaic_ppp_bm3d_admm
examples/denoise_l1tv_iso_admm
examples/denoise_tv_iso_admm
examples/denoise_tv_iso_pgm
examples/denoise_tv_iso_multi
Expand Down Expand Up @@ -109,6 +110,7 @@ Total Variation
examples/deconv_microscopy_allchn_tv_admm
examples/deconv_tv_admm
examples/deconv_tv_admm_tune
examples/denoise_l1tv_iso_admm
examples/denoise_tv_iso_admm
examples/denoise_tv_iso_pgm
examples/denoise_tv_iso_multi
Expand Down Expand Up @@ -153,6 +155,7 @@ ADMM
examples/deconv_tv_admm
examples/deconv_tv_admm_tune
examples/demosaic_ppp_bm3d_admm
examples/denoise_l1tv_iso_admm
examples/denoise_tv_iso_admm
examples/denoise_tv_iso_multi
examples/sparsecode_admm
Expand Down
2 changes: 1 addition & 1 deletion docs/source/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ The instructions above install a CPU-only version of SCICO. To install a version
Additional Dependencies
-----------------------

For instructions on installing dependencies related to the examples please see :ref:`example_dependencies`.
For instructions on installing dependencies related to the examples please see :ref:`example_depend`.


For Developers
Expand Down
93 changes: 76 additions & 17 deletions docs/source/references.bib
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
@Article {alliney-1992-digital,
author = {Alliney, Stefano},
journal = {IEEE Transactions on Signal Processing},
title = {Digital filters as absolute norm regularizers},
year = 1992,
volume = 40,
number = 6,
pages = {1548--1562},
doi = {10.1109/78.139258},
month = Jun
}

@Article {almeida-2013-deconvolving,
author = {Almeida, Mariana S. C. and Figueiredo, M\'ario},
journal = {IEEE Transactions on Image Processing},
Expand Down Expand Up @@ -71,6 +83,19 @@ @Book {beck-2017-first
isbn = 1611974984
}

@Software {bradbury-2018-jax,
author = {James Bradbury and Roy Frostig and Peter Hawkins and
Matthew James Johnson and Chris Leary and Dougal
Maclaurin and George Necula and Adam Paszke and Jake
Vander{P}las and Skye Wanderman-{M}ilne and Qiao
Zhang},
title = {{JAX}: composable transformations of
{P}ython+{N}um{P}y programs},
url = {http://github.com/google/jax},
version = {0.2.5},
year = {2018}
}

@Article {boyd-2010-distributed,
title = {Distributed optimization and statistical learning
via the alternating direction method of multipliers},
Expand Down Expand Up @@ -114,7 +139,7 @@ @Article {chambolle-2010-firstorder
author = {Antonin Chambolle and Thomas Pock},
title = {A First-Order Primal-Dual Algorithm for Convex
Problems with~Applications to Imaging},
journal = {Journal of Mathematical Imaging and Vision},
journal = {Journal of Mathematical Imaging and Vision},
doi = {10.1007/s10851-010-0251-1},
year = 2010,
month = Dec,
Expand All @@ -137,7 +162,7 @@ @Article {clinthorne-1993-preconditioning
doi = {10.1109/42.222670}
}

@InProceedings{dabov-2008-image,
@InProceedings {dabov-2008-image,
author = {Kostadin Dabov and Alessandro Foi and Vladimir
Katkovnik and Karen Egiazarian},
title = {Image restoration by sparse {3D} transform-domain
Expand Down Expand Up @@ -173,14 +198,23 @@ @Article {esser-2010-general
Primal-Dual Algorithms for Convex Optimization in
Imaging Science},
journal = {SIAM Journal on Imaging Sciences},
doi = {10.1137/09076934x},
doi = {10.1137/09076934x},
year = 2010,
month = Jan,
volume = 3,
number = 4,
pages = {1015--1046}
}

@PhDThesis {esser-2010-primal,
author = {Ernie Esser},
title = {Primal Dual Algorithms for Convex Models and
Applications to Image Restoration, Registration and
Nonlocal Inpainting},
school = {University of California Los Angeles},
year = 2010
}

@InProceedings {florea-2017-robust,
title = {A Robust {FISTA}-Like Algorithm},
author = {Mihai I. Florea and Sergiy A. Vorobyov},
Expand Down Expand Up @@ -222,6 +256,18 @@ @Article {glowinski-1975-approximation
url = {http://eudml.org/doc/193269}
}

@Article {goldstein-2009-split,
author = {Tom Goldstein and Stanley Osher},
title = {The Split {B}regman Method for L1-Regularized
Problems},
journal = {SIAM Journal on Imaging Sciences},
volume = 2,
number = 2,
pages = {323--343},
year = 2009,
doi = {10.1137/080725891}
}

@Misc {goldstein-2014-fasta,
title = {A Field Guide to Forward-Backward Splitting with a
{FASTA} Implementation},
Expand Down Expand Up @@ -308,7 +354,7 @@ @Article {parikh-2014-proximal
}

@Misc {pfister-2021-scico,
author = {Luke Pfister and Thilo Balke and Fernando Davis and
author = {Luke Pfister and Thilo Balke and Fernando Davis and
Cristina Garcia-Cardona and Michael McCann and
Brendt Wohlberg},
title = {{S}cientific {C}omputational {I}maging {CO}de
Expand All @@ -324,13 +370,35 @@ @InProceedings {pock-2011-diagonal
algorithms in convex optimization},
booktitle = {Proceedings of the International Conference on
Computer Vision (ICCV)},
doi = {10.1109/iccv.2011.6126441},
doi = {10.1109/iccv.2011.6126441},
pages = {1762--1769},
year = 2011,
month = Nov,
address = {Barcelona, Spain}
}

@Misc {pyabel-2022,
author = {Stephen Gibson and Daniel Hickstein and Roman
Yurchak, Mikhail Ryazanov and Dhrubajyoti Das and
Gilbert Shih},
title = {PyAbel},
howpublished = {PyAbel/PyAbel: v0.8.5},
year = 2022,
doi = {10.5281/zenodo.5888391}
}

@Article {rudin-1992-nonlinear,
author = {Leonid I. Rudin and Stanley Osher and Emad Fatemi},
title = {Nonlinear total variation based noise removal
algorithms},
journal = {Physica D: Nonlinear Phenomena},
volume = 60,
number = {1--4},
pages = {259-268},
year = 1992,
doi = {10.1016/0167-2789(92)90242-F}
}

@Article {sauer-1993-local,
title = {A local update strategy for iterative reconstruction
from projections},
Expand Down Expand Up @@ -369,15 +437,6 @@ @Misc {svmbir-2020
year = 2020
}

@Misc {pyabel-2022,
author = {Stephen Gibson and Daniel Hickstein and Roman Yurchak,
Mikhail Ryazanov and Dhrubajyoti Das and Gilbert Shih},
title = {PyAbel},
howpublished = {PyAbel/PyAbel: v0.8.5},
year = 2022,
doi = {10.5281/zenodo.5888391}
}

@InProceedings {venkatakrishnan-2013-plugandplay2,
author = {Singanallur V. Venkatakrishnan and Charles A. Bouman
and Brendt Wohlberg},
Expand Down Expand Up @@ -414,14 +473,14 @@ @Book {voelz-2011-computational
isbn = 9780819482044,
}

@article{yang-2012-linearized,
@Article {yang-2012-linearized,
author = {Junfeng Yang and Xiaoming Yuan},
title = {Linearized augmented {L}agrangian and alternating
direction methods for nuclear norm minimization},
journal = {Mathematics of Computation},
doi = {10.1090/s0025-5718-2012-02598-1},
doi = {10.1090/s0025-5718-2012-02598-1},
year = 2012,
month = mar,
month = Mar,
volume = 82,
number = 281,
pages = {301--329}
Expand Down
6 changes: 6 additions & 0 deletions examples/scripts/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ Miscellaneous

`demosaic_ppp_bm3d_admm.py <demosaic_ppp_bm3d_admm.py>`_
Image Demosaicing (ADMM Plug-and-Play Priors w/ BM3D)
`denoise_l1tv_iso_admm.py <denoise_l1tv_iso_admm.py>`_
ℓ1 Total Variation (ADMM)
`denoise_tv_iso_admm.py <denoise_tv_iso_admm.py>`_
Isotropic Total Variation (ADMM)
`denoise_tv_iso_pgm.py <denoise_tv_iso_pgm.py>`_
Expand Down Expand Up @@ -118,6 +120,8 @@ Total Variation
Image Deconvolution (ADMM w/ Total Variation)
`deconv_tv_admm_tune.py <deconv_tv_admm_tune.py>`_
Image Deconvolution Parameter Tuning
`denoise_l1tv_iso_admm.py <denoise_l1tv_iso_admm.py>`_
ℓ1 Total Variation (ADMM)
`denoise_tv_iso_admm.py <denoise_tv_iso_admm.py>`_
Isotropic Total Variation (ADMM)
`denoise_tv_iso_pgm.py <denoise_tv_iso_pgm.py>`_
Expand Down Expand Up @@ -174,6 +178,8 @@ ADMM
Image Deconvolution Parameter Tuning
`demosaic_ppp_bm3d_admm.py <demosaic_ppp_bm3d_admm.py>`_
Image Demosaicing (ADMM Plug-and-Play Priors w/ BM3D)
`denoise_l1tv_iso_admm.py <denoise_l1tv_iso_admm.py>`_
ℓ1 Total Variation (ADMM)
`denoise_tv_iso_admm.py <denoise_tv_iso_admm.py>`_
Isotropic Total Variation (ADMM)
`denoise_tv_iso_multi.py <denoise_tv_iso_multi.py>`_
Expand Down
126 changes: 126 additions & 0 deletions examples/scripts/denoise_l1tv_iso_admm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of the SCICO package. Details of the copyright
# and user license can be found in the 'LICENSE.txt' file distributed
# with the package.

r"""
ℓ1 Total Variation (ADMM)
=========================
This example demonstrates impulse noise removal via ℓ1 total variation
:cite:`alliney-1992-digital` :cite:`esser-2010-primal` (Sec. 2.4.4)
(i.e. total variation regularization with an ℓ1 data fidelity term),
minimizing the functional
$$\mathrm{argmin}_{\mathbf{x}} \; \| \mathbf{y} - \mathbf{x}
\|_1 + \lambda \| C \mathbf{x} \|_1 \;,$$
where $\mathbf{y}$ is the noisy image, $C$ is a 2D finite difference
operator, and $\mathbf{x}$ is the denoised image.
"""

import jax

from xdesign import SiemensStar, discrete_phantom

import scico.numpy as snp
from scico import functional, linop, loss, metric, plot
from scico.examples import spnoise
from scico.optimize.admm import ADMM, LinearSubproblemSolver
from scico.util import device_info
from scipy.ndimage import median_filter

"""
Create a ground truth image and impose salt & pepper noise to create a
noisy test image.
"""
N = 256 # image size
phantom = SiemensStar(16)
x_gt = snp.pad(discrete_phantom(phantom, 240), 8)
x_gt = 0.5 * x_gt / x_gt.max()
x_gt = jax.device_put(x_gt) # convert to jax type, push to GPU
y = spnoise(x_gt, 0.5)


"""
Denoise with median filtering.
"""
x_med = median_filter(y, size=(5, 5))


"""
Denoise with ℓ1 total variation.
"""
λ = 1.5e0
g_loss = loss.Loss(y=y, f=functional.L1Norm())
g_tv = λ * functional.L21Norm()
# The append=0 option makes the results of horizontal and vertical finite
# differences the same shape, which is required for the L21Norm.
C = linop.FiniteDifference(input_shape=x_gt.shape, append=0)

solver = ADMM(
f=None,
g_list=[g_loss, g_tv],
C_list=[linop.Identity(input_shape=y.shape), C],
rho_list=[5e0, 5e0],
x0=y,
maxiter=100,
subproblem_solver=LinearSubproblemSolver(cg_kwargs={"tol": 1e-3, "maxiter": 20}),
itstat_options={"display": True, "period": 10},
)

print(f"Solving on {device_info()}\n")
x_tv = solver.solve()
hist = solver.itstat_object.history(transpose=True)


"""
Plot results.
"""
plt_args = dict(norm=plot.matplotlib.colors.Normalize(vmin=0, vmax=1.0))
fig, ax = plot.subplots(nrows=2, ncols=2, sharex=True, sharey=True, figsize=(13, 12))
plot.imview(x_gt, title="Ground truth", fig=fig, ax=ax[0, 0], **plt_args)
plot.imview(y, title="Noisy image", fig=fig, ax=ax[0, 1], **plt_args)
plot.imview(
x_med,
title=f"Median filtering: {metric.psnr(x_gt, x_med):.2f} (dB)",
fig=fig,
ax=ax[1, 0],
**plt_args,
)
plot.imview(
x_tv,
title=f"ℓ1-TV denoising: {metric.psnr(x_gt, x_tv):.2f} (dB)",
fig=fig,
ax=ax[1, 1],
**plt_args,
)
fig.show()


"""
Plot convergence statistics.
"""
fig, ax = plot.subplots(nrows=1, ncols=2, figsize=(12, 5))
plot.plot(
hist.Objective,
title="Objective function",
xlbl="Iteration",
ylbl="Functional value",
fig=fig,
ax=ax[0],
)
plot.plot(
snp.vstack((hist.Prml_Rsdl, hist.Dual_Rsdl)).T,
ptyp="semilogy",
title="Residuals",
xlbl="Iteration",
lgnd=("Primal", "Dual"),
fig=fig,
ax=ax[1],
)
fig.show()


input("\nWaiting for input to close figures and exit")
Loading

0 comments on commit 54f9b39

Please sign in to comment.