Пример #1
0
def test_omp_gram_numerical_consistency():
    # verify numericaly consistency among np.float32 and np.float64
    coef_32 = orthogonal_mp_gram(G.astype(np.float32),
                                 Xy.astype(np.float32),
                                 n_nonzero_coefs=5)
    coef_64 = orthogonal_mp_gram(G.astype(np.float32),
                                 Xy.astype(np.float64),
                                 n_nonzero_coefs=5)
    assert_allclose(coef_32, coef_64)
Пример #2
0
def test_omp_path():
    path = orthogonal_mp(X, y, n_nonzero_coefs=5, return_path=True)
    last = orthogonal_mp(X, y, n_nonzero_coefs=5, return_path=False)
    assert path.shape == (n_features, n_targets, 5)
    assert_array_almost_equal(path[:, :, -1], last)
    path = orthogonal_mp_gram(G, Xy, n_nonzero_coefs=5, return_path=True)
    last = orthogonal_mp_gram(G, Xy, n_nonzero_coefs=5, return_path=False)
    assert path.shape == (n_features, n_targets, 5)
    assert_array_almost_equal(path[:, :, -1], last)
Пример #3
0
def test_omp_path():
    path = orthogonal_mp(X, y, n_nonzero_coefs=5, return_path=True)
    last = orthogonal_mp(X, y, n_nonzero_coefs=5, return_path=False)
    assert_equal(path.shape, (n_features, n_targets, 5))
    assert_array_almost_equal(path[:, :, -1], last)
    path = orthogonal_mp_gram(G, Xy, n_nonzero_coefs=5, return_path=True)
    last = orthogonal_mp_gram(G, Xy, n_nonzero_coefs=5, return_path=False)
    assert_equal(path.shape, (n_features, n_targets, 5))
    assert_array_almost_equal(path[:, :, -1], last)
Пример #4
0
def single_experiment(n, m, s, method='omp'):
    """Run a single experiment.

    The experiment consist on recovering an s-sparse signal of length n from m
    measurements using OMP. The original signal is generated by get_sparse_x

    Parameters
    ----------
    n : length of the signal
    m : number of measurements
    s : sparsity of the signal
    method : OMP implementation. One of {'omp', 'gram', 'naive'}. Default to
       'omp'
       
    Return
    ------
    error: The ell_2 norm of the difference between the original and the
       recovered signal
    """
    D = random_dict(m, n)
    x = get_sparse_x(n, s)
    y = np.dot(D, x)
    if method == 'omp':
        x_hat = orthogonal_mp(D, y, s)
    elif method == 'gram':
        x_hat = orthogonal_mp_gram(np.dot(D.T, D), np.dot(D.T, y), s)
    elif method == 'naive':
        x_hat = omp_naive(D, y)
    else:
        print 'Unknown method'
        sys.exit(1)

    x_hat.resize(n, 1)
    error = norm(x - x_hat)
    return error
Пример #5
0
def reconstruct(measurement, sensor, dictionary, max_sparsity):
    """

    :param measurement: [image_nums, sensing_times]
    :param sensor:
    :param dictionary:
    :param max_sparsity: int
    :return:
    """
    measurement = measurement.T

    # reconstruction matrix, gram matrix
    SD = np.dot(sensor.T, dictionary)
    SD_norm = SD / np.linalg.norm(SD, axis=0)
    gram = np.dot(SD_norm.T, SD_norm)

    reconstruction = np.zeros([dictionary.shape[0], measurement.shape[1]])
    for col in range(measurement.shape[1]):
        print('  -> Reconstructing # {} image'.format(col))
        w = orthogonal_mp_gram(gram,
                               np.dot(SD_norm.T, measurement[:, col]),
                               n_nonzero_coefs=int(max_sparsity))

        # img = dic * coef
        imgs_vec = np.matmul(dictionary, w)
        reconstruction[:, col] = imgs_vec

    return np.transpose(reconstruction)
Пример #6
0
def test_no_atoms():
    y_empty = np.zeros_like(y)
    Xy_empty = np.dot(X.T, y_empty)
    gamma_empty = orthogonal_mp(X, y_empty, 1)
    gamma_empty_gram = orthogonal_mp_gram(G, Xy_empty, 1)
    assert_equal(np.all(gamma_empty == 0), True)
    assert_equal(np.all(gamma_empty_gram == 0), True)
Пример #7
0
def test_no_atoms():
    y_empty = np.zeros_like(y)
    Xy_empty = np.dot(X.T, y_empty)
    gamma_empty = orthogonal_mp(X, y_empty, 1)
    gamma_empty_gram = orthogonal_mp_gram(G, Xy_empty, 1)
    assert_equal(np.all(gamma_empty == 0), True)
    assert_equal(np.all(gamma_empty_gram == 0), True)
Пример #8
0
def test_perfect_signal_recovery():
    idx, = gamma[:, 0].nonzero()
    gamma_rec = orthogonal_mp(X, y[:, 0], 5)
    gamma_gram = orthogonal_mp_gram(G, Xy[:, 0], 5)
    assert_array_equal(idx, np.flatnonzero(gamma_rec))
    assert_array_equal(idx, np.flatnonzero(gamma_gram))
    assert_array_almost_equal(gamma[:, 0], gamma_rec, decimal=2)
    assert_array_almost_equal(gamma[:, 0], gamma_gram, decimal=2)
Пример #9
0
def test_perfect_signal_recovery():
    idx, = gamma[:, 0].nonzero()
    gamma_rec = orthogonal_mp(X, y[:, 0], n_nonzero_coefs=5)
    gamma_gram = orthogonal_mp_gram(G, Xy[:, 0], n_nonzero_coefs=5)
    assert_array_equal(idx, np.flatnonzero(gamma_rec))
    assert_array_equal(idx, np.flatnonzero(gamma_gram))
    assert_array_almost_equal(gamma[:, 0], gamma_rec, decimal=2)
    assert_array_almost_equal(gamma[:, 0], gamma_gram, decimal=2)
Пример #10
0
def test_no_atoms():
    y_empty = np.zeros_like(y)
    Xy_empty = np.dot(X.T, y_empty)
    with warnings.catch_warnings():
        warnings.simplefilter('ignore')
        gamma_empty = orthogonal_mp(X, y_empty, 1)
        gamma_empty_gram = orthogonal_mp_gram(G, Xy_empty, 1)
    assert_equal(np.all(gamma_empty == 0), True)
    assert_equal(np.all(gamma_empty_gram == 0), True)
Пример #11
0
  def _transform(self, D, X):
    gram = D.T.dot(D)
    Xy = D.T.dot(X)

    n_nonzero_coefs = self.transform_n_nonzero_coefs
    if n_nonzero_coefs is None:
      n_nonzero_coefs = int(0.1 * X.shape[1])

    return orthogonal_mp_gram(gram, Xy, copy_Gram=False, copy_Xy=False, n_nonzero_coefs=n_nonzero_coefs)
Пример #12
0
    def _transform(self, D, Y):
        gram = D.T.dot(D)
        Xy = D.T.dot(Y)

        n_nonzero_coefs = self.sparsitythres

        return orthogonal_mp_gram(
            gram, Xy, copy_Gram=False, copy_Xy=False, n_nonzero_coefs=n_nonzero_coefs
        )
Пример #13
0
def test_no_atoms():
    y_empty = np.zeros_like(y)
    Xy_empty = np.dot(X.T, y_empty)
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        gamma_empty = orthogonal_mp(X, y_empty, 1)
        gamma_empty_gram = orthogonal_mp_gram(G, Xy_empty, 1)
    assert_equal(np.all(gamma_empty == 0), True)
    assert_equal(np.all(gamma_empty_gram == 0), True)
    def _transform(self, D, X):
        gram = D.dot(D.T)
        Xy = D.dot(X.T)

        n_nonzero_coefs = int(self.transform_n_nonzero_coefs)
        if n_nonzero_coefs is None:
            n_nonzero_coefs = int(0.1 * X.shape[1])

        return orthogonal_mp_gram(gram, Xy, n_nonzero_coefs=n_nonzero_coefs).T
Пример #15
0
def test_perfect_signal_recovery():
    # XXX: use signal generator
    idx, = gamma[:, 0].nonzero()
    gamma_rec = orthogonal_mp(X, y[:, 0], 5)
    gamma_gram = orthogonal_mp_gram(G, Xy[:, 0], 5)
    assert_equal(idx, np.flatnonzero(gamma_rec))
    assert_equal(idx, np.flatnonzero(gamma_gram))
    assert_array_almost_equal(gamma[:, 0], gamma_rec, decimal=2)
    assert_array_almost_equal(gamma[:, 0], gamma_gram, decimal=2)
Пример #16
0
    def test_orthogonal_mp_gram(self):
        diabetes = datasets.load_diabetes()
        df = pdml.ModelFrame(diabetes)

        result = df.linear_model.orthogonal_mp()

        gram = diabetes.data.T.dot(diabetes.data)
        Xy = diabetes.data.T.dot(diabetes.target)
        expected = lm.orthogonal_mp_gram(gram, Xy)
        self.assert_numpy_array_almost_equal(result, expected)
Пример #17
0
    def test_orthogonal_mp_gram(self):
        diabetes = datasets.load_diabetes()
        df = pdml.ModelFrame(diabetes)

        result = df.linear_model.orthogonal_mp()

        gram = diabetes.data.T.dot(diabetes.data)
        Xy = diabetes.data.T.dot(diabetes.target)
        expected = lm.orthogonal_mp_gram(gram, Xy)
        self.assert_numpy_array_almost_equal(result, expected)
Пример #18
0
    def _transform(self, D, X):
        gram = D.dot(D.T)
        Xy = D.dot(X.T)

        n_nonzero_coefs = self.transform_n_nonzero_coefs
        if n_nonzero_coefs is None:
            n_nonzero_coefs = int(0.1 * X.shape[1])
        print "sizes of gram and xy, ", np.shape(gram), np.shape(Xy)

        return orthogonal_mp_gram(
            gram, Xy, n_nonzero_coefs=n_nonzero_coefs).T
Пример #19
0
def test_orthogonal_mp_gram_readonly():
    # Non-regression test for:
    # https://github.com/scikit-learn/scikit-learn/issues/5956
    idx, = gamma[:, 0].nonzero()
    G_readonly = G.copy()
    G_readonly.setflags(write=False)
    Xy_readonly = Xy.copy()
    Xy_readonly.setflags(write=False)
    gamma_gram = orthogonal_mp_gram(G_readonly, Xy_readonly[:, 0], 5,
                                    copy_Gram=False, copy_Xy=False)
    assert_array_equal(idx, np.flatnonzero(gamma_gram))
    assert_array_almost_equal(gamma[:, 0], gamma_gram, decimal=2)
Пример #20
0
def test_orthogonal_mp_gram_readonly():
    # Non-regression test for:
    # https://github.com/scikit-learn/scikit-learn/issues/5956
    idx, = gamma[:, 0].nonzero()
    G_readonly = G.copy()
    G_readonly.setflags(write=False)
    Xy_readonly = Xy.copy()
    Xy_readonly.setflags(write=False)
    gamma_gram = orthogonal_mp_gram(G_readonly, Xy_readonly[:, 0], 5,
                                    copy_Gram=False, copy_Xy=False)
    assert_array_equal(idx, np.flatnonzero(gamma_gram))
    assert_array_almost_equal(gamma[:, 0], gamma_gram, decimal=2)
Пример #21
0
def get_features(img, dictionary):
    patches = image.extract_patches_2d(img, (16,16))
    signals = patches.reshape(patches.shape[0], -1)
    sample = signals[np.random.choice(range(signals.shape[0]), 1000, replace = True)]
    sparse = []
    for signal in sample:
        X = signal
        D = dictionary
        gram = D.dot(D.T)
        Xy = D.dot(X.T)
        out = orthogonal_mp_gram(gram, Xy, n_nonzero_coefs=4).T
        sparse.append(out)
    return sparse
Пример #22
0
def test_swapped_regressors():
    gamma = np.zeros(n_features)
    # X[:, 21] should be selected first, then X[:, 0] selected second,
    # which will take X[:, 21]'s place in case the algorithm does
    # column swapping for optimization (which is the case at the moment)
    gamma[21] = 1.0
    gamma[0] = 0.5
    new_y = np.dot(X, gamma)
    new_Xy = np.dot(X.T, new_y)
    gamma_hat = orthogonal_mp(X, new_y, 2)
    gamma_hat_gram = orthogonal_mp_gram(G, new_Xy, 2)
    assert_array_equal(np.flatnonzero(gamma_hat), [0, 21])
    assert_array_equal(np.flatnonzero(gamma_hat_gram), [0, 21])
Пример #23
0
def test_swapped_regressors():
    gamma = np.zeros(n_features)
    # X[:, 21] should be selected first, then X[:, 0] selected second,
    # which will take X[:, 21]'s place in case the algorithm does
    # column swapping for optimization (which is the case at the moment)
    gamma[21] = 1.0
    gamma[0] = 0.5
    new_y = np.dot(X, gamma)
    new_Xy = np.dot(X.T, new_y)
    gamma_hat = orthogonal_mp(X, new_y, n_nonzero_coefs=2)
    gamma_hat_gram = orthogonal_mp_gram(G, new_Xy, n_nonzero_coefs=2)
    assert_array_equal(np.flatnonzero(gamma_hat), [0, 21])
    assert_array_equal(np.flatnonzero(gamma_hat_gram), [0, 21])
Пример #24
0
    def fit(self, X):
        D = np.random.randn(self.n_components, X.shape[1])
        D /= np.linalg.norm(D, axis=1)[:, np.newaxis]
        for i in range(self.max_iter):
            gram = D.dot(D.T)
            Xy = D.dot(X.T)
            gamma = orthogonal_mp_gram(gram, Xy).T
            e = np.linalg.norm(X - gamma.dot(D))
            if e < self.tol:
                break
            D, gamma = self._update_dict(X, D, gamma)

        self.components_ = D
        return self
Пример #25
0
def process_y(Phi, y, s_thread):
    t0 = time.time()
    #global step
    #print len(y_input)
    #y_cur = np.reshape(y_input, (m, len(y_input)/m))
    y_cur = np.reshape(y, (n, len(y) / n))
    y_cur = y_cur.T
    gram = Phi.dot(Phi.T)
    product = Phi.dot(y_cur.T)
    x_res = orthogonal_mp_gram(gram, product, n_nonzero_coefs=s_thread)
    #x_res, _, _= mp_process(Phi, y_cur, ncoef=s_thread, verbose=False)
    td = time.time()
    #print "time to complete concatenation: ", td - ti
    return x_res, s_thread, td - t0
Пример #26
0
def test(test_img):
    patches = image.extract_patches_2d(test_img, (16,16))
    signals = patches.reshape(patches.shape[0], -1)
    sample = signals[np.random.choice(range(signals.shape[0]), 1000, replace = True)]
    dictionary_error = []
    for dictionary in dictionaries:
        sample_error = []
        for signal in sample:
            X = signal
            D = dictionary
            gram = D.dot(D.T)
            Xy = D.dot(X.T)
            out = orthogonal_mp_gram(gram, Xy, n_nonzero_coefs=4).T
            sample_error.append(np.linalg.norm(X - out.dot(D)))
        dictionary_error.append(sample_error)
    return np.argmin(np.mean(dictionary_error, axis = 1))
Пример #27
0
    def invert(self, G, d, wgt=None):
        """
        Perform inversion.

        Parameters
        ----------
        G: (M,N) np.ndarray
            Input design matrix.
        d: (M,) np.ndarray
            Input data.
        wgt: (M,) np.ndarray, optional
            Optional weights for the data.

        Returns
        -------
        status: int
            Integer flag for failure or success.
        m: (N,) np.ndarray
            Output parameter vector.
        m_wgt: (N,) np.ndarray, optional
            Weights for parameters.
        """
        # Indices for finite data
        mask = np.isfinite(d).nonzero()[0]
        if mask.size < self.n_min:
            warnings.warn('Not enough data for inversion. Returning None.')
            return FAIL, None, None
        Gf, df, wgt = self.apply_mask(mask, G, d, wgt=wgt)

        # If weight array provided, pre-multiply design matrix and data
        if wgt is not None:
            Gf = dmultl(wgt, Gf)
            df = wgt * df

        # Compute Gram matrix (X.T*X) and product (X.T*y)
        if self.regMat is not None:
            XtX = np.dot(Gf.T, Gf) + self.regMat
        else:
            XtX = np.dot(Gf.T, Gf)
        Xty = np.dot(Gf.T, df)

        # Solve
        m = orthogonal_mp_gram(XtX,
                               Xty,
                               n_nonzero_coefs=self.n_nonzero_coefs,
                               copy_Xy=False)
        return SUCCESS, m, np.eye(len(m))
Пример #28
0
    def get_sparse_representations(data, D, sparsitythres):
        """
        Sparse coding

        Args:
            data              : testing features
            D                 : learned dictionary
            sparsitythres     : sparsity threshold for KSVD
        Returns:
            gamma             : learned representation
        """
        G = D.T.dot(D)
        gamma = orthogonal_mp_gram(G,
                                   D.T.dot(data),
                                   copy_Gram=False,
                                   copy_Xy=False,
                                   n_nonzero_coefs=sparsitythres)

        return gamma
Пример #29
0
  def classification(self, D, W, data, sparsity):
    """
    Classification 
    Inputs
          D               -learned dictionary
          W               -learned classifier parameters
          data            -data to classify
          sparsity        -sparsity threshold
    outputs
          prediction      -predicted classification vectors. Perform sp.argmax(W.dot(gamma), axis=0) to get labels
          gamma           -learned representation
    """

    # sparse coding
    G = D.T.dot(D)
    gamma = orthogonal_mp_gram(G, D.T.dot(data), copy_Gram=False, copy_Xy=False, n_nonzero_coefs=sparsity)
    # # classify process
    # prediction = sp.argmax(W.dot(gamma), axis=0)

    return W.dot(gamma),gamma
Пример #30
0
def test_omp_batch_sparse_signal_n_nonzero(sparse_signal):
    signals = sparse_signal[:, :200]
    n_atoms = 256
    n_nonzero = 10
    n_threads = 1
    dictionary = utils.dct_dict(n_atoms, 8)
    sparse_c = sparse.omp_batch(signals, dictionary,
                                n_nonzero=n_nonzero, n_threads=n_threads)

    # Compare with sklearn
    Xy = np.dot(dictionary.T, signals)
    Gram = np.dot(dictionary.T, dictionary)
    sparse_sk = orthogonal_mp_gram(Gram, Xy, n_nonzero_coefs=n_nonzero)

    assert sparse_c.shape == sparse_sk.shape
    assert np.count_nonzero(sparse_c) <= n_nonzero * signals.shape[1]

    c = np.dot(dictionary, sparse_c)
    sk = np.dot(dictionary, sparse_sk)
    assert np.all(np.linalg.norm(c - sk, axis=0) < 1e-6)
Пример #31
0
def omp_batch(signals, dictionary, n_nonzero=0, tol=0):
    """
        Sparse Decomposition

        Find a sparse approximation using the OMP algorithm. This is an
        implementation of algorithm 3 in the paper reference in the ksvd
        function above

        If tolerance in zero this finds the minimum of:
            min || x - Da||_2^2 such that ||a||_0 <= n_nonzero

        If tolerance is not zero:
            min ||a||_0 such that ||x - Da||_2^2 <= tol

        Args
        ----
            signals: Signals to approximate
            dictionary:
            n_nonzero: Max number of coefficients to use
            tol: Tolerance of approximation, overwrites n_nonzero

        Returns
        -------
            Sparse approximation with shape (n_atoms, n_signals)
    """
    n = signals.shape[1]
    norms_squared = np.zeros(n)
    for k in range(n):
        norms_squared[k] = np.linalg.norm(signals[:, k]) ** 2

    gram = dictionary.T.dot(dictionary)
    Xy = dictionary.T.dot(signals)
    tol = None if tol == 0 else tol

    decomp = linear_model.orthogonal_mp_gram(
        gram, Xy, n_nonzero, tol, norms_squared
    )

    return decomp
Пример #32
0
def reconstruct(representation, sensor, dictionary, max_sparsity):
    if representation.shape[0] == 1:
        representation = representation.T
    elif representation.ndim == 1:
        representation = representation.reshape((representation.shape[0], -1))
        
    # reconstruction matrix, gram matrix
    SD = np.dot(sensor.T, dictionary)
    SD_norm = SD / np.linalg.norm(SD, axis=0)
    gram = np.dot(SD_norm.T, SD_norm)

    reconstruction = np.zeros([dictionary.shape[0], representation.shape[1]])
    for col in range(representation.shape[1]):
        w = orthogonal_mp_gram(gram, np.dot(SD_norm.T, representation[:,col]), 
            n_nonzero_coefs=max_sparsity)

        idx = np.nonzero(w)[0]
        w_hat = np.zeros(w.shape[0])
        w_hat[idx] = np.dot(np.linalg.pinv(SD[:,idx]), representation[:,col])
        reconstruction[:,col] = np.dot(dictionary, w_hat)

    return reconstruction
Пример #33
0
def ompcode(D, X, T):
    gram = dot(D.T, D);
    cov = dot(D.T, X.T);
    
    return orthogonal_mp_gram(gram, cov, T, None,);
Пример #34
0
def test_correct_shapes_gram():
    assert (orthogonal_mp_gram(G, Xy[:, 0],
                               n_nonzero_coefs=5).shape == (n_features, ))
    assert (orthogonal_mp_gram(G, Xy,
                               n_nonzero_coefs=5).shape == (n_features, 3))
Пример #35
0
 def sparse_coding(self, D, Y):
     return orthogonal_mp_gram(D.T.dot(D), D.T.dot(Y))
Пример #36
0
def test_omp_gram_dtype_match(data_type):
    # verify matching input data type and output data type
    coef = orthogonal_mp_gram(G.astype(data_type),
                              Xy.astype(data_type),
                              n_nonzero_coefs=5)
    assert coef.dtype == data_type
Пример #37
0
def ksvd(Data,
         num_atoms,
         sparsity,
         initial_D=None,
         maxiter=10,
         etol=1e-10,
         approx=False,
         debug=True):
    """
        K-SVD for Overcomplete Dictionary Learning
        Author: Alan Yang - Fall 2017

        See:
            M. Aharon, M. Elad and A. Bruckstein, "K-SVD: An 
            Algorithm for Designing Overcomplete Dictionaries 
            for Sparse Representation," in IEEE Transactions
            on Signal Processing, vol. 54, no. 11, pp. 4311-4322, 
            Nov. 2006.
            
            Rubinstein, R., Zibulevsky, M. and Elad, M., 
            "Efficient Implementation of the K-SVD Algorithm 
            using Batch Orthogonal Matching Pursuit Technical 
            Report" - CS Technion, April 2008.
                
        Data:       rows hold training data for dictionary fitting
        num_atoms:  number of dictionary atoms
        sparsity:   max sparsity of signals. Reduces to K-means
                    when sparsity=1
        initial_D:  if given, an initial dictionary. Otherwise, random
                    rows of data are chosen for initial dictionary
        maxiter:    maximum number of iterations
        err_thresh: stopping criteria; minimum residual
        approx:     True if using approximate KSVD update method.
                    Code runs faster if True, but results generally
                    in higher training error.
        
        Returns:
            D:               learned dictionary
            X:               sparse coding of input data
            error_norms:     array of training errors for each iteration
        Task: find best dictionary D to represent Data Y;
              minimize squared norm of Y - DX, constraining
              X to sparse codings.
    """
    # **implemented using column major order**
    Data = Data.T

    assert Data.shape[1] > num_atoms  # enforce this for now

    # intialization
    if initial_D is not None:
        D = initial_D / np.linalg.norm(initial_D, axis=0)
        Y = Data
        X = np.zeros([num_atoms, Data.shape[1]])
    else:
        # randomly select initial dictionary from data
        idx_set = range(Data.shape[1])
        idxs = np.random.choice(idx_set, num_atoms, replace=False)
        Y = Data[:, np.delete(idx_set, idxs)]
        X = np.zeros([num_atoms, Data.shape[1] - num_atoms])
        D = Data[:, idxs] / np.linalg.norm(Data[:, idxs], axis=0)

    # repeat until convergence or stopping criteria
    error_norms = []

    iterator = tqdm(range(1, maxiter + 1)) if debug else range(1, maxiter + 1)
    for iteration in iterator:
        # sparse coding stage: estimate columns of X
        gram = (D.T).dot(D)
        Dy = (D.T).dot(Y)
        X = orthogonal_mp_gram(gram, Dy, n_nonzero_coefs=sparsity)
        # codebook update stage
        for j in range(D.shape[1]):
            # index set of nonzero components
            index_set = np.nonzero(X[j, :])[0]
            if len(index_set) == 0:
                # for now, replace with some white noise
                if not approx:
                    D[:, j] = np.random.randn(*D[:, j].shape)
                    D[:, j] = D[:, j] / np.linalg.norm(D[:, j])
                continue
            # approximate K-SVD update
            if approx:
                E = Y[:, index_set] - D.dot(X[:, index_set])
                D[:, j] = E.dot(X[j, index_set])  # update D
                D[:, j] /= np.linalg.norm(D[:, j])
                X[j, index_set] = (E.T).dot(D[:, j])  # update X
            else:
                # error matrix E
                E_idx = np.delete(range(D.shape[1]), j, 0)
                E = Y - np.dot(D[:, E_idx], X[E_idx, :])
                U, S, VT = np.linalg.svd(E[:, index_set])
                # update jth column of D
                D[:, j] = U[:, 0]
                # update sparse elements in jth row of X
                X[j, :] = np.array([
                    S[0] * VT[0, np.argwhere(index_set == n)[0][0]]
                    if n in index_set else 0 for n in range(X.shape[1])
                ])
        # stopping condition: check error
        err = np.linalg.norm(Y - D.dot(X), 'fro')
        error_norms.append(err)
        if err < etol:
            break
    return D, X, np.array(error_norms)
Пример #38
0
def sparse_encode(X,
                  dictionary,
                  algorithm='mp',
                  fit_tol=None,
                  P_cum=None,
                  l0_sparseness=10,
                  C=0.,
                  do_sym=True,
                  verbose=0):
    """Generic sparse coding

    Each column of the result is the solution to a sparse coding problem.

    Parameters
    ----------
    X : array of shape (n_samples, n_pixels)
        Data matrix.

    dictionary : array of shape (n_dictionary, n_pixels)
        The dictionary matrix against which to solve the sparse coding of
        the data. Some of the algorithms assume normalized rows.


    algorithm : {'mp', 'lasso_lars', 'lasso_cd', 'lars', 'omp', 'threshold'}
        mp :  Matching Pursuit
        lars: uses the least angle regression method (linear_model.lars_path)
        lasso_lars: uses Lars to compute the Lasso solution
        lasso_cd: uses the coordinate descent method to compute the
        Lasso solution (linear_model.Lasso). lasso_lars will be faster if
        the estimated dictionary are sparse.
        omp: uses orthogonal matching pursuit to estimate the sparse solution
        threshold: squashes to zero all coefficients less than regularization
        from the projection dictionary * data'

    max_iter : int, 1000 by default
        Maximum number of iterations to perform if `algorithm='lasso_cd'`.

    verbose : int
        Controls the verbosity; the higher, the more messages. Defaults to 0.

    Returns
    -------
    code : array of shape (n_samples, n_dictionary)
        The sparse codes

    """
    if X.ndim == 1:
        X = X[:, np.newaxis]
    #n_samples, n_pixels = X.shape

    if algorithm == 'lasso_lars':
        alpha = float(regularization) / n_pixels  # account for scaling

        from sklearn.linear_model import LassoLars

        # Not passing in verbose=max(0, verbose-1) because Lars.fit already
        # corrects the verbosity level.
        cov = np.dot(dictionary, X.T)
        lasso_lars = LassoLars(alpha=fit_tol,
                               fit_intercept=False,
                               verbose=verbose,
                               normalize=False,
                               precompute=None,
                               fit_path=False)
        lasso_lars.fit(dictionary.T, X.T, Xy=cov)
        sparse_code = lasso_lars.coef_.T

    elif algorithm == 'lasso_cd':
        alpha = float(regularization) / n_pixels  # account for scaling

        # TODO: Make verbosity argument for Lasso?
        # sklearn.linear_model.coordinate_descent.enet_path has a verbosity
        # argument that we could pass in from Lasso.
        from sklearn.linear_model import Lasso
        clf = Lasso(alpha=fit_tol,
                    fit_intercept=False,
                    normalize=False,
                    precompute=None,
                    max_iter=max_iter,
                    warm_start=True)

        if init is not None:
            clf.coef_ = init

        clf.fit(dictionary.T, X.T, check_input=check_input)
        sparse_code = clf.coef_.T

    elif algorithm == 'lars':

        # Not passing in verbose=max(0, verbose-1) because Lars.fit already
        # corrects the verbosity level.
        from sklearn.linear_model import Lars
        cov = np.dot(dictionary, X.T)
        lars = Lars(fit_intercept=False,
                    verbose=verbose,
                    normalize=False,
                    precompute=None,
                    n_nonzero_coefs=l0_sparseness,
                    fit_path=False)
        lars.fit(dictionary.T, X.T, Xy=cov)
        sparse_code = lars.coef_.T

    elif algorithm == 'threshold':
        cov = np.dot(dictionary, X.T)
        sparse_code = ((np.sign(cov) *
                        np.maximum(np.abs(cov) - regularization, 0))).T

    elif algorithm == 'omp':
        # TODO: Should verbose argument be passed to this?
        from sklearn.linear_model import orthogonal_mp_gram
        from sklearn.utils.extmath import row_norms

        cov = np.dot(dictionary, X.T)
        gram = np.dot(dictionary, dictionary.T)
        sparse_code = orthogonal_mp_gram(Gram=gram,
                                         Xy=cov,
                                         n_nonzero_coefs=l0_sparseness,
                                         tol=None,
                                         norms_squared=row_norms(X,
                                                                 squared=True),
                                         copy_Xy=False).T

    elif algorithm == 'mp':
        sparse_code = mp(X,
                         dictionary,
                         l0_sparseness=l0_sparseness,
                         fit_tol=fit_tol,
                         P_cum=P_cum,
                         C=C,
                         do_sym=do_sym,
                         verbose=verbose)
    else:
        raise ValueError(
            'Sparse coding method must be "mp", "lasso_lars" '
            '"lasso_cd",  "lasso", "threshold" or "omp", got %s.' % algorithm)
    return sparse_code
Пример #39
0
def test_correct_shapes_gram():
    assert_equal(orthogonal_mp_gram(G, Xy[:, 0], n_nonzero_coefs=5).shape,
                 (n_features,))
    assert_equal(orthogonal_mp_gram(G, Xy, n_nonzero_coefs=5).shape,
                 (n_features, 3))