.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/basics/demo_physics.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_basics_demo_physics.py: Creating a forward operator. ==================================================================================================== While deepinv offers a large number of forward operators in the physics module, you might want to create your own forward operator for your specific imaging problem. This example walks you through the creation of a custom forward operator. We will create a simple forward operator that converts RGB images to grayscale images by averaging the color channels. We also show you how to exploit the singular value decomposition of the operator to speed up the evaluation of the pseudo-inverse and proximal operators. .. GENERATED FROM PYTHON SOURCE LINES 14-18 .. code-block:: Python import deepinv as dinv import torch .. GENERATED FROM PYTHON SOURCE LINES 19-27 Creating a custom forward operator. ---------------------------------------------------------------------------------------- Defining a new linear operator only requires a forward function and its transpose operation, inheriting the remaining structure of the :class:`deepinv.physics.LinearPhysics` class. Once the operator is defined, we can use any of the functions in the :class:`deepinv.physics.Physics` class and :class:`deepinv.physics.LinearPhysics` class, such as computing the norm of the operator, testing the adjointness, computing the proximal operator, etc. .. GENERATED FROM PYTHON SOURCE LINES 27-60 .. code-block:: Python # define an operator that converts color images into grayscale ones. class Decolorize(dinv.physics.LinearPhysics): r""" Converts RGB images to grayscale. Signals must be tensors with 3 colour (RGB) channels, i.e. [*,3,*,*] The measurements are grayscale images. """ def __init__(self, **kwargs): super().__init__(**kwargs) self.noise_model = dinv.physics.GaussianNoise(sigma=0.1) # the RGB to grayscale coefficients coefficients = torch.tensor([0.2989, 0.5870, 0.1140], dtype=torch.float32) # register the coefficients as a buffer self.register_buffer("coefficients", coefficients) def A(self, x, theta=None): # theta is an optional parameter that is not used here y = ( x * self.coefficients[None, :, None, None] ) # apply coefficients to each channel return torch.sum(y, dim=1, keepdim=True) # sum over the color channels def A_adjoint(self, y, theta=None): return y * self.coefficients[None, :, None, None] physics = Decolorize() .. GENERATED FROM PYTHON SOURCE LINES 61-65 Generate toy image -------------------------------------------------------------------- This example uses a toy image with 3 color channels. .. GENERATED FROM PYTHON SOURCE LINES 65-78 .. code-block:: Python x = torch.zeros(1, 3, 96, 128) x[:, 0, :32, :] = 1 x[:, 1, 32:64, :] = 1 x[:, 2, 64:, :] = 1 y = physics(x) xlin = physics.A_dagger(y) # compute the linear pseudo-inverse dinv.utils.plot([x, y, xlin], titles=["image", "meas.", "linear rec."]) .. image-sg:: /auto_examples/basics/images/sphx_glr_demo_physics_001.png :alt: image, meas., linear rec. :srcset: /auto_examples/basics/images/sphx_glr_demo_physics_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 79-85 Verifying our linear operator -------------------------------------------- If the operator is linear, it is recommended to verify that the transpose well-defined using :func:`deepinv.physics.LinearPhysics.adjointness_test`, and that it has a unit norm using :func:`deepinv.physics.LinearPhysics.compute_norm`. .. GENERATED FROM PYTHON SOURCE LINES 85-92 .. code-block:: Python print(f"The linear operator has norm={physics.compute_norm(x):.2f}") if physics.adjointness_test(x) < 1e-5: print("The linear operator has a well defined transpose") .. rst-class:: sphx-glr-script-out .. code-block:: none Power iteration converged at iteration 2, value=0.45 The linear operator has norm=0.45 The linear operator has a well defined transpose .. GENERATED FROM PYTHON SOURCE LINES 93-100 Creating a decomposable forward operator. -------------------------------------------- If the forward operator has a closed form singular value decomposition (SVD), it is recommended to implement the operator using the :class:`deepinv.physics.DecomposablePhysics` method. The operator in this example is decomposable, so we can implement it using :class:`deepinv.physics.DecomposablePhysics`. .. GENERATED FROM PYTHON SOURCE LINES 100-142 .. code-block:: Python class DecolorizeSVD(dinv.physics.DecomposablePhysics): r""" Converts RGB images to grayscale. Signals must be tensors with 3 colour (RGB) channels, i.e. [*,3,*,*] The measurements are grayscale images. """ def __init__(self, **kwargs): super().__init__(mask=0.447, **kwargs) self.noise_model = dinv.physics.GaussianNoise(sigma=0.1) # the RGB to grayscale coefficients coefficients = torch.tensor([0.6687, 1.3132, 0.2550], dtype=torch.float32) # register the coefficients as a buffer self.register_buffer("coefficients", coefficients) def V_adjoint(self, x): y = x * self.coefficients[None, :, None, None] return torch.sum(y, dim=1, keepdim=True) def V(self, y): return y * self.coefficients[None, :, None, None] physics2 = DecolorizeSVD() y2 = physics2(x) xlin2 = physics.A_dagger(y2) # compute the linear pseudo-inverse dinv.utils.plot([x, y2, xlin2], titles=["image", "meas.", "linear rec."]) print(f"The decomposable operator has norm={physics.compute_norm(x):.2f}") if physics.adjointness_test(x) < 1e-5: print("The decomposable operator has a well defined transpose") .. image-sg:: /auto_examples/basics/images/sphx_glr_demo_physics_002.png :alt: image, meas., linear rec. :srcset: /auto_examples/basics/images/sphx_glr_demo_physics_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Power iteration converged at iteration 2, value=0.45 The decomposable operator has norm=0.45 The decomposable operator has a well defined transpose .. GENERATED FROM PYTHON SOURCE LINES 143-154 Benefits of using a decomposable forward operator. ---------------------------------------------------------------------------------------- If the forward operator has a closed form singular value decomposition (SVD), it is recommended to implement the operator using :class:`deepinv.physics.DecomposablePhysics`. The operator in this example is decomposable, so we can implement it using :class:`deepinv.physics.DecomposablePhysics`. The main benefit of using a decomposable forward operator is that it provides closed form solutions for the proximal operator and the linear pseudo-inverse. Moreover, some algorithms, such as :class:`deepinv.sampling.DDRM` require the forward operator to be decomposable. .. GENERATED FROM PYTHON SOURCE LINES 154-173 .. code-block:: Python import time start = time.time() for i in range(10): xlin = physics.A_dagger(y) xprox = physics.prox_l2(x, y, 0.1) end = time.time() print(f"Elapsed time for LinearPhysics: {end - start:.2f} seconds") start = time.time() for i in range(10): xlin2 = physics2.A_dagger(y) xprox2 = physics2.prox_l2(x, y2, 0.1) end = time.time() print(f"Elapsed time for DecomposablePhysics: {end - start:.2e} seconds") .. rst-class:: sphx-glr-script-out .. code-block:: none Elapsed time for LinearPhysics: 0.01 seconds Elapsed time for DecomposablePhysics: 1.99e-03 seconds .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.121 seconds) .. _sphx_glr_download_auto_examples_basics_demo_physics.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: demo_physics.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: demo_physics.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: demo_physics.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_