Exemple #1
0
import torch

from data_management import load_dataset
from networks import IterativeNet, Tiramisu
from operators import TVAnalysis, get_tikhonov_matrix

# --- load configuration -----
import config  # isort:skip

# ----- general setup -----
mpl.use("agg")
device = torch.device("cuda:0")

# ----- operators -----
OpA = config.meas_op(config.m, config.n, device=device, **config.meas_params)
OpTV = TVAnalysis(config.n, device=device)

# ----- build linear inverter  ------
reg_fac = 2e-2

inverter = torch.nn.Linear(OpA.m, OpA.n, bias=False)
inverter.weight.requires_grad = False
inverter.weight.data = get_tikhonov_matrix(OpA, OpTV, reg_fac)

# ----- network configuration -----
subnet_params = {
    "in_channels": 1,
    "out_channels": 1,
    "drop_factor": 0.0,
    "down_blocks": (5, 7, 9, 12, 15),
    "up_blocks": (15, 12, 9, 7, 5),
def sample_tv_signal(
    n,
    j_min=10,
    j_max=20,
    min_dist=5,
    bound=5,
    min_height=0.2,
    n_seed=None,
    t_seed=None,
):
    """ Creates a random piecewise constant signal.

    Creates a piecewise constant signal of shape (n,) with a random number of
    "jumps" (discontinuities).
    With minimal jump size and zero boundaries.

    Parameters
    ----------
    n : int
        Size of the signal.
    j_min : int, optional
        Minimum number of jumps in the signal. (Default 10)
    j_max : int, optional
        Maximum number of jumps in teh signal (Default 20)
    min_dist : int, optional
        Minimum distance between the jump positions. (Default 5)
    bound : int, optional
        Pads each side with boundary zeros.
    min_height : double, optional
        Minimal jump height of jumps in the interior.
    n_seed : int, optional
        Seed for the numpy random number generator for drawing the jump
        positions. Set to `None` for not setting any seed and keeping the
        current state of the random number generator. (Default `None`)
    t_seed : int, optional
        Seed for the troch random number generator for drawing the jump
        heights. Set to `None` for not setting any seed and keeping the
        current state of the random number generator. (Default `None`)

    Returns
    -------
    torch.Tensor
        Will be of shape (n,).
    """
    if n_seed is not None:
        np.random.seed(n_seed)
    if t_seed is not None:
        torch.manual_seed(t_seed)

    # restricted dimension
    n_restr = n - 2 * bound

    # check if jump distance condition can be satisfied
    if (n_restr) / (min_dist) <= (j_max + 1):
        raise ValueError(
            "The signal size {} is not large enough to contain {} "
            "jumps with minimum distance {}.".format(n_restr, j_max, min_dist))

    # draw the number of jumps
    num = np.random.randint(j_min - 2, j_max - 1)  # +2 jumps whp for 0s

    # draw the jump positions
    pos = np.sort(
        np.random.choice(
            np.arange(min_dist, n_restr - min_dist - (num - 1) *
                      (min_dist - 1)),
            num,
            False,
        )) + np.arange(num) * (min_dist - 1)

    # synthesize signal
    coefs = torch.zeros(n_restr)
    coefs[-1] = torch.randn(1)  # random signal mean (constant shift)
    coefs[pos] = torch.randn(num)  # random jump heights around the mean
    coefs[torch.abs(coefs) < min_height] = (
        torch.sign(coefs[torch.abs(coefs) < min_height]) * min_height
    )  # minimal height
    x_restr = TVSynthesis(n_restr)(coefs)

    # pad with 0s
    x = torch.zeros(n)
    x[bound:n_restr + bound] = x_restr

    # real coefs
    coefs = TVAnalysis(n)(x)

    return x, coefs