def fit(self, y): """ KSVD迭代过程 """ self._initialize(y) for i in range(self.max_iter): x = linear_model.orthogonal_mp( self.dictionary, y, n_nonzero_coefs=self.n_nonzero_coefs) e = np.linalg.norm(y - np.dot(self.dictionary, x)) if e < self.tol: break self._update_dict(y, self.dictionary, x) self.sparsecode = linear_model.orthogonal_mp( self.dictionary, y, n_nonzero_coefs=self.n_nonzero_coefs) return self.dictionary, self.sparsecode # im_ascent = maxminnorm(np.array(data)) # ksvd = KSVD(24) # dictionary, sparsecode = ksvd.fit(im_ascent) # # print(im_ascent[0:3]) # # print(dictionary.dot(sparsecode)[0:3]) # print(dictionary.dot(sparsecode)) # plt.figure() # plt.subplot(1, 2, 1) # plt.imshow(im_ascent) # plt.subplot(1, 2, 2) # plt.imshow(dictionary.dot(sparsecode)) # plt.show()
def test_omp_return_path_prop_with_gram(): path = orthogonal_mp(X, y, n_nonzero_coefs=5, return_path=True, precompute=True) last = orthogonal_mp(X, y, n_nonzero_coefs=5, return_path=False, precompute=True) assert path.shape == (n_features, n_targets, 5) assert_array_almost_equal(path[:, :, -1], last)
def test_n_nonzero_coefs(): assert_true( count_nonzero(orthogonal_mp(X, y[:, 0], n_nonzero_coefs=5)) <= 5) assert_true( count_nonzero( orthogonal_mp(X, y[:, 0], n_nonzero_coefs=5, precompute=True)) <= 5)
def test_omp_return_path_prop_with_gram(): path = orthogonal_mp(X, y, n_nonzero_coefs=5, return_path=True, precompute=True) last = orthogonal_mp(X, y, n_nonzero_coefs=5, return_path=False, precompute=True) assert_equal(path.shape, (n_features, n_targets, 5)) assert_array_almost_equal(path[:, :, -1], last)
def fit(self, img): """ KSVD迭代过程 """ #以防图片不是256*256,先进行一reshape img = cv2.resize(img, (256, 256), img) print(img.shape, type(img)) #将图像按8*8的块转化列向量,合起来成为64*1024的矩阵 #img保存原始图像转化的矩阵,y用于保存img减去列均值后的矩阵 y = np.zeros((8 * 8, 32 * 32)) img_reshape = np.zeros((8 * 8, 32 * 32)) patch_num = (256 / 8)**2 for patch_index in range(patch_num): #按先行后列,将图片分解成32*32个8*8的小块并装换为列向量 r = (patch_index / 32) * 8 c = (patch_index % 32) * 8 patch = img[r:r + 8, c:c + 8].flat normalize = np.linalg.norm(patch) mean = np.sum(patch) / 64 #print mean img_reshape[:, patch_index] = patch #y[:, patch_index]=(patch/mean) y[:, patch_index] = (patch - mean * np.ones(64)) / normalize #字典初始化 self._initialize(y) for i in range(self.max_iter): #linear_model.orthogonal_mp 用法详见: #http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.orthogonal_mp.html x = linear_model.orthogonal_mp( self.dictionary, y, n_nonzero_coefs=self.n_nonzero_coefs) #OMP e = np.linalg.norm(y - np.dot(self.dictionary, x)) print '第%s次迭代,误差为:%s' % (i, e) if e < self.tol: break self._update_dict(y, self.dictionary, x) # src_rec = np.zeros(img.shape) for patch_index in range(patch_num): x = linear_model.orthogonal_mp( self.dictionary, y[:, patch_index], n_nonzero_coefs=self.n_nonzero_coefs) #x = linear_model.orthogonal_mp(self.dictionary, img_reshape[:, patch_index], n_nonzero_coefs=self.n_nonzero_coefs) nomalize = np.linalg.norm(img_reshape[:, patch_index]) mean = np.sum(img_reshape[:, patch_index]) / 64 #patch=np.dot(self.dictionary, x)+mean*np.ones(64) patch = np.dot(self.dictionary, x) * nomalize + mean * np.ones(64) r = (patch_index / 32) * 8 c = (patch_index % 32) * 8 src_rec[r:r + 8, c:c + 8] = patch.reshape((8, 8)) return self.dictionary, src_rec
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)
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)
def test_identical_regressors(): newX = X.copy() newX[:, 1] = newX[:, 0] gamma = np.zeros(n_features) gamma[0] = gamma[1] = 1. newy = np.dot(newX, gamma) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') orthogonal_mp(newX, newy, 2) assert_true(len(w) == 1)
def test_unreachable_accuracy(): assert_array_almost_equal(orthogonal_mp(X, y, tol=0), orthogonal_mp(X, y, n_nonzero_coefs=n_features)) warning_message = ("Orthogonal matching pursuit ended prematurely " "due to linear dependence in the dictionary. " "The requested precision might not have been met.") with pytest.warns(RuntimeWarning, match=warning_message): assert_array_almost_equal( orthogonal_mp(X, y, tol=0, precompute=True), orthogonal_mp(X, y, precompute=True, n_nonzero_coefs=n_features))
def test_unreachable_accuracy(): assert_array_almost_equal( orthogonal_mp(X, y, tol=0), orthogonal_mp(X, y, n_nonzero_coefs=n_features)) assert_array_almost_equal( assert_warns(RuntimeWarning, orthogonal_mp, X, y, tol=0, precompute=True), orthogonal_mp(X, y, precompute=True, n_nonzero_coefs=n_features))
def test_identical_regressors(): newX = X.copy() newX[:, 1] = newX[:, 0] gamma = np.zeros(n_features) gamma[0] = gamma[1] = 1.0 newy = np.dot(newX, gamma) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") orthogonal_mp(newX, newy, 2) assert_true(len(w) == 1)
def test_unreachable_accuracy(): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") assert_array_almost_equal(orthogonal_mp(X, y, tol=0), orthogonal_mp(X, y, n_nonzero_coefs=n_features)) assert_array_almost_equal( orthogonal_mp(X, y, tol=0, precompute_gram=True), orthogonal_mp(X, y, precompute_gram=True, n_nonzero_coefs=n_features), ) assert_greater(len(w), 0) # warnings should be raised
def test_unreachable_accuracy(): with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') assert_array_almost_equal( orthogonal_mp(X, y, tol=0), orthogonal_mp(X, y, n_nonzero_coefs=n_features)) assert_array_almost_equal( orthogonal_mp(X, y, tol=0, precompute=True), orthogonal_mp(X, y, precompute=True, n_nonzero_coefs=n_features)) assert_greater(len(w), 0) # warnings should be raised
def test_orthogonal_mp(self): diabetes = datasets.load_diabetes() df = pdml.ModelFrame(diabetes) result = df.linear_model.orthogonal_mp() expected = lm.orthogonal_mp(diabetes.data, diabetes.target) tm.assert_numpy_array_equal(result, expected) result = df.linear_model.orthogonal_mp(return_path=True) expected = lm.orthogonal_mp(diabetes.data, diabetes.target, return_path=True) tm.assert_numpy_array_equal(result, expected)
def test_identical_regressors(): check_warnings() # Skip if unsupported Python version newX = X.copy() newX[:, 1] = newX[:, 0] gamma = np.zeros(n_features) gamma[0] = gamma[1] = 1. newy = np.dot(newX, gamma) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') orthogonal_mp(newX, newy, 2) assert_true(len(w) == 1)
def test_identical_regressors(): newX = X.copy() newX[:, 1] = newX[:, 0] gamma = np.zeros(n_features) gamma[0] = gamma[1] = 1. newy = np.dot(newX, gamma) warning_message = ("Orthogonal matching pursuit ended prematurely " "due to linear dependence in the dictionary. " "The requested precision might not have been met.") with pytest.warns(RuntimeWarning, match=warning_message): orthogonal_mp(newX, newy, 2)
def test_unreachable_accuracy(): check_warnings() # Skip if unsupported Python version with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') assert_array_almost_equal( orthogonal_mp(X, y, tol=0), orthogonal_mp(X, y, n_nonzero_coefs=n_features)) assert_array_almost_equal( orthogonal_mp(X, y, tol=0, precompute_gram=True), orthogonal_mp(X, y, precompute_gram=True, n_nonzero_coefs=n_features)) assert_true(len(w) > 0) # warnings should be raised
def reconstruct(ngram_sent_vec, ngram_vecs, index2ngram, solver="omp", nnz=70): """ ngram_sent_vecs: List[np.array] output: Multiset[str] or Multiset[Tuple(str)] """ nnz = min(len(ngram_vecs), nnz) with warnings.catch_warnings(): # ignore RuntimeWarning from orthogonal_mp warnings.simplefilter("ignore") if solver == "omp": count_vec = orthogonal_mp( ngram_vecs.T, ngram_sent_vec, n_nonzero_coefs=nnz ).round() elif solver == "omp_arora": count_vec = orthogonal_mp_arora( ngram_vecs.T, ngram_sent_vec, n_nonzero_coefs=nnz ).round() elif solver == "bp": count_vec = basis_pursuit(ngram_vecs.T, ngram_sent_vec).round() else: raise NotImplementedError indices = np.argwhere(count_vec > 0).reshape(-1).astype(int) if type(count_vec) is not np.ndarray: count_vec = np.array([count_vec]) counts = count_vec[indices].astype(int) output = Multiset( { index2ngram[int(index)]: int(count) for (index, count) in zip(indices, counts) } ) return output
def _quiz5(): mat_a = [ 0.1817, 0.5394, -0.1197, 0.6404, 0.6198, 0.1994, 0.0946, -0.3121, -0.7634, -0.8181, 0.9883, 0.7018 ] mat_a = np.reshape(mat_a, (3, 4)) mat_a /= np.linalg.norm(mat_a, axis=0) b = np.array([1.1862, -0.1158, -0.1093]) n_nonzero_coefs = 2 x_sklearn = orthogonal_mp(mat_a, b, n_nonzero_coefs=n_nonzero_coefs, return_path=False) print(f"sklearn solution: {x_sklearn}, " f"residual norm: {np.linalg.norm(b - mat_a.dot(x_sklearn))}") for least_squares in (False, True): solution = orthogonal_matching_pursuit(mat_a, b, n_nonzero_coefs=n_nonzero_coefs, least_squares=least_squares) _describe(solution, method_desc="LS-OMP" if least_squares else "OMP") assert_array_almost_equal(x_sklearn, solution.x) solution_mp = matching_pursuit(mat_a, b, n_iters=n_nonzero_coefs, weak_threshold=0.5) _describe(solution_mp, method_desc="WMP(thr=0.5)") solution_thr = thresholding_algorithm(mat_a, b, n_nonzero_coefs=3) _describe(solution_thr, method_desc="Thresholding")
def recover(p, kronprod, mask): # t0 = time.monotonic() # m1, m2 = p.shape # a = 18 a = compute_best_index(p.ravel(), 0.001, 20, kronprod) # print(a) # t1 = time.monotonic() # mask = np.random.choice(range(m1 * m2), m1 * m2 - remover, replace = False) # y = np.take(p, mask, axis=1).T # y = np.take(p, mask) y = np.expand_dims(p, 1) # print(y.shape) # phikron = np.take(kronprod[a], mask, axis=0) phikron = kronprod[a] # np.savetxt('phik.txt', phikron) # y = np.take(p.ravel(),mask) # phikron = np.take(kronprod[a], mask, axis=0)#[mask, ...] # t2 = time.monotonic() # sx,_,_,_ = spg_bpdn(phikron, y.ravel(), 0.1) # sx = lasso(np.asfortranarray(y.ravel()), np.asfortranarray(phikron), lambda1=0.02, return_reg_path=False).toarray() # _,sx,_ = lasso_path(phikron, y, eps=0.0001, n_alphas=1, return_n_iter=False) # print(y.shape) msk = np.expand_dims((mask != 0), 0) # sx = ompMask(np.asfortranarray(y), np.asfortranarray(phikron), np.asfortranarray(msk), lambda1=0.01, return_reg_path=False).toarray() # sx = omp(np.asfortranarray(y), np.asfortranarray(phikron), eps=0.03, return_reg_path=False).toarray() # sx = lassoMask(np.asfortranarray(y), np.asfortranarray(phikron), np.asfortranarray(msk), lambda1=0.01).toarray() sx = orthogonal_mp(phikron, y, tol=0.03) # print(sx.shape) # t3 = time.monotonic() # t4 = time.monotonic() newp = np.matmul(kronprod[a], sx) # print(newp.shape) # print("Tempos: %.5f %.5f %.5f" % (t1 - t0, t2 - t1, t3 - t2), a) return newp
def test_reconstruction(self): np.random.seed(28) n_features, n_atoms = 10, 30 k0 = 4 mat_a = np.random.randn(n_features, n_atoms) mat_a /= np.linalg.norm(mat_a, axis=0) x_true = np.random.randn(n_atoms) x_true[np.random.choice(n_atoms, size=n_atoms - k0, replace=False)] = 0 b_true = mat_a.dot(x_true) x_omp = omp(mat_a, b=b_true, n_nonzero_coefs=k0) x_omp_ls = omp(mat_a, b=b_true, n_nonzero_coefs=k0, least_squares=True) x_mp = matching_pursuit(mat_a, b=b_true, n_iters=100) x_mp_weak = matching_pursuit(mat_a, b=b_true, n_iters=100, weak_threshold=0.5) x_thr = thresholding_algorithm(mat_a, b=b_true, n_nonzero_coefs=k0) x_sklearn = orthogonal_mp(mat_a, b_true, n_nonzero_coefs=k0) assert_array_almost_equal(x_omp_ls.x, x_sklearn) for solution in (x_omp, x_omp_ls, x_mp, x_mp_weak, x_thr): b_restored = mat_a.dot(solution.x) assert_array_almost_equal(b_restored, b_true, decimal=1)
def test_quiz5(self): mat_a = [ 0.1817, 0.5394, -0.1197, 0.6404, 0.6198, 0.1994, 0.0946, -0.3121, -0.7634, -0.8181, 0.9883, 0.7018 ] mat_a = np.reshape(mat_a, (3, 4)) mat_a /= np.linalg.norm(mat_a, axis=0) b = np.array([1.1862, -0.1158, -0.1093]) n_nonzero_coefs = 2 solution = omp(mat_a, b=b, n_nonzero_coefs=n_nonzero_coefs) solution_lse = omp(mat_a, b=b, n_nonzero_coefs=n_nonzero_coefs, least_squares=True) assert_array_almost_equal(solution.x, solution_lse.x) assert_array_equal(sorted(solution.support), sorted(solution_lse.support)) x_sklearn = orthogonal_mp(mat_a, y=b, n_nonzero_coefs=n_nonzero_coefs, return_path=False) assert_array_almost_equal(solution.x, x_sklearn) assert_array_almost_equal(solution.x, [0., 1.0000116, 0., 1.0100027]) assert_array_equal(sorted(solution.support), (1, 3))
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
def single_experiment(n, m, s, use_naive=False): """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 use_naive : if true, use naive implementation of OMP, use scikit.learn implementation otherwise. Default to False 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 use_naive: x_hat = omp_naive(D, y) else: x_hat = orthogonal_mp(D, y, s) x_hat.resize(n, 1) error = norm(x - x_hat) return error
def fit(self, y): """ KSVD迭代过程 """ self._initialize(y) for i in range(self.max_iter): x = linear_model.orthogonal_mp( self.dictionary, y, n_nonzero_coefs=self.n_nonzero_coefs) e = np.linalg.norm(y - np.dot(self.dictionary, x)) if e < self.tol: break self._update_dict(y, self.dictionary, x) self.sparsecode = linear_model.orthogonal_mp( self.dictionary, y, n_nonzero_coefs=self.n_nonzero_coefs) return self.dictionary, self.sparsecode
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)
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)
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)
def sparse_rep(self, X): """Return sparse representation of column vectors present in X, according to current self.D dictionary. We use batch OMP algorithm to find the representation""" return orthogonal_mp(self.D, X, n_nonzero_coefs=self.K, precompute=self.precompute)
def OMP(self, A, y, s): #INPUT(A,y,s) where A is the col. normalized sensing_matrix, y is observed vector, s is sparsity level. Make sure A is column normalized first. #OUTPUT: A set of s vectors, each of the form [(x_s, lambda), pi], where pi is a vector of zeros with a single one in the next column we will take. #x_S is the solution to min_z||A_Sz-y||^2_2, and lambda is the vector A^T(A_S*x_S - y). Outputted as features, labels, where each element of features is of the form (x_s, lambda), and each member of labels is of the form pi and v, where v is propagated to every (x_s, lambda) #and is constructed from the final solution #We will be generating y and then using OMP to generate all of our training for OMPbootstrapping neural net. #Call from sklearn.linear_model import orthogonal_mp and use x_star = orthogonal_mp(A, y, n_nonzero_coefs = s, return_path = True) #Initialize empty output lists features = [] labels = [] #x_star returns a shape (n, s) array where each column represents the solution to min_z||A_S*z - y||^2_2 #final_v is propagated to every label of every state x_star = orthogonal_mp(A, y, n_nonzero_coefs=s, return_path=True) if s == 1: x_star = np.reshape(x_star, ( x_star.size, 1)) #1-sparse solutions need to be reshaped for below to work. final_res = np.matmul(A, x_star[:, s - 1]) - y norm_sq = np.linalg.norm(final_res)**2 final_v = -1e-5 * np.count_nonzero(x_star[:, s - 1]) - norm_sq final_v = np.reshape(final_v, (1, )) #build each [(x_s, lambda), pi] sample and put them all into a list. First build [(x_s, lambda), pi] for no columns chosen case. x_init = np.zeros( A.shape[1] ) #initialize the first sparse vector, which is a vector of zeros residual_init = y #initialize the first residual vector lambda_vec_init = np.matmul( A.T, residual_init) #initialize the first lambda vector feature = [x_init, lambda_vec_init ] #Compute feature for initial state of no chosen columns next_index = np.argmax(np.abs(lambda_vec_init)) pi = np.zeros( A.shape[1] + 1 ) #Compute the label pi(one hot vector) of the next column chosen. +1 is for the stopping action, which is to remain consistent with alphazero algorithm. pi[next_index] = 1 label = [pi, final_v ] #NOTE THAT v is the reward received AFTER we follow pi!!! #Add initial state feature and labels into output lists features.append(feature) labels.append(label) for i in range(x_star.shape[1]): #Compute lambda residual = y - np.matmul(A, x_star[:, i]) lambda_vec = np.matmul(A.T, residual) feature = [x_star[:, i], lambda_vec] #a length two list of np arrays #Compute next chosen column and extend it to a one hot vector of size n. Also compute v. next_index = np.argmax(np.abs(lambda_vec)) pi = np.zeros(A.shape[1] + 1) #again 1 is for the stopping action. pi[next_index] = 1 label = [pi, final_v] #pi and v are both arrays here #add both feature and label into features and labels list features.append(feature) labels.append(label) return features, labels
def OMP(self, X, y, n_nonzero_coefs=None): ''' 稀疏编码 OMP算法(正交匹配追踪) ============================================= 这里借助 sklearn 模块实现 ============================================= ''' return linear_model.orthogonal_mp(X, y, n_nonzero_coefs)
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 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 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)
def OMP(self, y): ''' 2.用OMP算法计算该测试数据的稀疏表达x; ''' nrows = 3 ncols = 4 figsize = (8, 8) # _, figs = plt.subplots(nrows, ncols, figsize=figsize) # l = [] # 共self.num_class类,每类图片测试集有12张图片 for i in range(self.test_item): yy = y[:, i * self.div_num:(i + 1) * self.div_num] xx = linear_model.orthogonal_mp( self.dictionary, yy, n_nonzero_coefs=self.n_nonzero_coefs) if len(xx.shape) == 1: xx = xx[:, np.newaxis] # _, figs1 = plt.subplots(5, 5, figsize=figsize) for i in range(0, self.div_num): # TODO: 原来xx[]为0时log为-inf # t_y = np.log(xx[:,i]) t_y = xx[:, i] # t_x = list(range(35000)) t_x = list( range(self.train_item * self.num_class * self.div_num)) # figs1[i][j].bar(t_x,t_y) # 这个占用内存太大了似乎出不来啊 plt.bar(t_x, t_y) plt.show() # plt.show() l = [] print("[OMP]->i:{}: ".format(i)) for j in range(self.num_class): # (1200, 14*16) * (14*16, 16) # (120,1) - dd = self.dictionary[:, j * self.train_item * self.div_num:(j + 1) * self.train_item * self.div_num] xxx = xx[j * self.train_item * self.div_num:(j + 1) * self.train_item * self.div_num, :] e = np.linalg.norm(yy - np.dot(dd, xxx)) # print("[OMP]->i:{},j:{}->e:{}".format(i, j, e)) print("\tj:{}->e:{}".format(j, e), end='') if e == 0.0: e += 1e-6 l.append(math.log(e)) print() # figs[int(i/4)][i%4].bar(list(range(100)), l) # figs[i][j].axes.get_xaxis().set_visible(False) # figs[i][j].axes.get_yaxis().set_visible(False) plt.bar(list(range(self.num_class)), l) plt.show()
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])
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])
def test_omp_cholseky_dense_signals(dense_signal): """ Not entirely sure how to test this. Just comparing with scikit learn for now """ n_atoms = 256 n_nonzero = 10 n_threads = 1 dictionary = utils.dct_dict(n_atoms, 8) signals = dense_signal(1)[:, 12] codes = sparse.omp_cholesky(signals, dictionary, n_nonzero=n_nonzero, n_threads=n_threads) sklearn_codes = orthogonal_mp(dictionary, signals, n_nonzero) c_sig = np.dot(dictionary, codes) sk_sig = np.dot(dictionary, sklearn_codes) assert codes.shape == sklearn_codes.shape assert np.count_nonzero(codes) == np.count_nonzero(sklearn_codes) assert abs(np.linalg.norm(c_sig - signals) - np.linalg.norm(sk_sig - signals)) < 1e-12 n_nonzero = 10 n_threads = 1 dictionary = utils.dct_dict(n_atoms, 8) signals = dense_signal(2)[:, 10] codes = sparse.omp_cholesky(signals, dictionary, n_nonzero=n_nonzero, n_threads=n_threads) sklearn_codes = orthogonal_mp(dictionary, signals, n_nonzero) c_sig = np.dot(dictionary, codes) sk_sig = np.dot(dictionary, sklearn_codes) assert codes.shape == (n_atoms,) assert codes.shape == sklearn_codes.shape assert np.count_nonzero(codes) <= np.count_nonzero(sklearn_codes) assert abs(np.linalg.norm(c_sig - signals) - np.linalg.norm(sk_sig - signals)) < 1e-12
def fit(self, sample): """ KSVD迭代过程 """ self._initialize(sample) t0 = time.time() for i in range(self.max_iter): x = linear_model.orthogonal_mp(self.dictionary, sample, n_nonzero_coefs=self.n_nonzero) e = np.linalg.norm(sample - np.dot(self.dictionary, x)) dt = (time.time() - t0) print('Iteration % 3d error: %.4f (elapsed time: %ds)' % (i + 1, e, dt)) if e < self.tol: break self._update_dict(sample, self.dictionary, x) self.code = linear_model.orthogonal_mp(self.dictionary, sample, n_nonzero_coefs=self.n_nonzero) return self.dictionary, self.code
def missing_pixel_reconstruct(self, img): img_patchs=img_to_patch(img) patch_num=img_patchs.shape[1] #patch_dim=img_patchs.shape[0] for i in range(patch_num): img_col=img_patchs[:, i] index = np.nonzero(img_col)[0] #对每列去掉丢失的像素值后求平均、二阶范数,将其归一化 l2norm=np.linalg.norm(img_col[index]) mean=np.sum(img_col)/index.shape[0] img_col_norm=(img_col-mean)/l2norm x = linear_model.orthogonal_mp(self.dictionary[index, :], img_col_norm[index].T, n_nonzero_coefs=self.n_nonzero_coefs) img_patchs[:, i]=(self.dictionary.dot(x)*l2norm)+mean return patch_to_img(img_patchs)
def denoise_patches(self, X, tol): """Return denoised patches in X using the following method: - temporarily remove lines of self.D corresponding to missing pixels in each patches (ie colums on X) - compute sparse representation of remaining pixels using new dictionary - return new patch = self.D.dot(gamma) [where slef.D is real unmodified dictionary Args: - X: patches organized as columns of a matrix - tol : maximum norm of the residual TODO: set a default value """ #Check X dimensions if X.shape[0] != self.D.shape[0]: raise ValueError("X.shape[0] must be equal to " "{}!".format(X.shape[0])) #Initialize output output = np.zeros_like(X) #for each column (ie patch) in X for j in range(X.shape[1]): patch = X[:,j].ravel() #Adapt dictionary self.D to current patch tempD = self.D.copy() tempD[patch == 0] = np.zeros(self.D.shape[1]) #normalize tempD columns tempD = tempD/np.linalg.norm(tempD, axis = 0) #Compute sparse representation gamma = orthogonal_mp(tempD, X[:,j]) #Store resulting patch output[:,j] = self.D.dot(gamma) return output
def single_experiment(n, m, s, methods=["naive"]): """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 methods : list of methods to try. Each method must be in ['naive', 'scikit', 'vlad'] implementation otherwise. Default to False Return ------ errors: List with he ell_2 norm of the difference between the original and the recovered signal for each method in methods. """ D = random_dict(m, n) x = get_sparse_x(n, s) y = np.dot(D, x) errors = [] for method in methods: if method == "naive": x_hat = omp_naive(D, y) elif method == "scikit": x_hat = orthogonal_mp(D, y, s) elif method == "vlad": x_hat = omp_vlad(D, y, s) else: print "Unknown method" sys.exit(1) x_hat.resize(n, 1) errors.append(norm(x - x_hat)) return errors
def sparse_rep(self, X): """Return sparse representation of column vectors present in X, according to current self.D dictionary. We use batch OMP algorithm to find the representation""" return orthogonal_mp(self.D, X, n_nonzero_coefs = self.K, precompute = self.precompute)
def fit(self, X): """Actual implementation of K-SVD algorithm. Args: - X: numpy 2d-array of dimensions : (len(signal) = D.shape[0], n_samples) TODO: add a stopping condition like an epsilon (and return corresponding number of iterations """ #Check wether data is coherent if self.D.shape[0] != X.shape[0]: raise TypeError("Supplied X matrix is not " "coherent with dictionary dimensions: you " "should have same number of lines for " "both the dictionary and the input data ") #ProgressBar setup print "Training dictionary over {} iterations".format(self.n_iter) progress = progressbar.progress_bar(self.n_iter) #self.n_iter iterations for it in range(self.n_iter): #Step 1: Compute sparse representation of X #given current dictionary D gamma = orthogonal_mp(self.D, X, n_nonzero_coefs = self.K, precompute = self.precompute) #Step 2: Adjust dictionary D and sparse #representation gamma at the same time #column by column for j in range(self.D.shape[1]): #Compute I = {indices of the signals in X #whose representations use jth column of D I = self.find_indices(gamma, j) #If one column is not used, it won't be until #the algorithm actually stops, which is a shame #So, we use heuristics: we set teh values of the #column to the worst represented columns of #X matrix if I == []: #find worst represented column in X d = self.worst_represented(gamma, X) #normalize d = d/np.linalg.norm(d) #set D column to d self.D[:,j] = d #jump to the next column optimization continue #Set D_j to zero self.D[:,j] = np.zeros_like(self.D[:,j]) #From now, we use a certain number of tricks #explained in [1] to accelerate the (therefore #approximate) K-SVD algorithm #TODO: try to understand better... -> maybe we could #solve the equations in the report ;) g = gamma[j,:][I].T d = X[:,I].dot(g) - self.D.dot(gamma[:,I].dot(g)) if d.sum() != 0: d = d/np.linalg.norm(d) g = (X[:,I].T).dot(d) - ((self.D.dot(gamma[:,I])).T).dot(d) #Store new values self.D[:,j] = d gamma[j,:][I] = g.T #Update progress bar progress.update(it) print(' Done!')
n_nonzero_coefs=n_atoms, random_state=0) idx, = x.nonzero() # distort the clean signal y_noisy = y + 0.05*np.random.randn(len(y)) # plot the sparse signal pl.subplot(3,1,1) pl.xlim(0,512) pl.stem(idx,x[idx]) pl.title('Sparse signal') # Plot the noise-free reconstruction x_r = orthogonal_mp(D,y,n_atoms) idx_r, = x_r.nonzero() pl.subplot(3,1,2) pl.xlim(0,512) pl.stem(idx_r,x_r[idx_r]) pl.title('Recovered signal from noise-free measurements') # plot the noisy reconstruction x_r = orthogonal_mp(D,y_noisy,n_atoms) idx_r, = x_r.nonzero() pl.subplot(3,1,3) pl.xlim(0,512) pl.title('Recovered signal from noisy measurements') pl.stem(idx_r,x_r[idx_r]) pl.suptitle('Sparse signal recovery with orthogonal matching pursuit',
def compute_bench(samples_range, features_range): it = 0 results = dict() lars = np.empty((len(features_range), len(samples_range))) lars_gram = lars.copy() omp = lars.copy() omp_gram = lars.copy() max_it = len(samples_range) * len(features_range) for i_s, n_samples in enumerate(samples_range): for i_f, n_features in enumerate(features_range): it += 1 n_informative = n_features / 10 print('====================') print('Iteration %03d of %03d' % (it, max_it)) print('====================') # dataset_kwargs = { # 'n_train_samples': n_samples, # 'n_test_samples': 2, # 'n_features': n_features, # 'n_informative': n_informative, # 'effective_rank': min(n_samples, n_features) / 10, # #'effective_rank': None, # 'bias': 0.0, # } dataset_kwargs = { 'n_samples': 1, 'n_components': n_features, 'n_features': n_samples, 'n_nonzero_coefs': n_informative, 'random_state': 0 } print("n_samples: %d" % n_samples) print("n_features: %d" % n_features) y, X, _ = make_sparse_coded_signal(**dataset_kwargs) X = np.asfortranarray(X) gc.collect() print("benchmarking lars_path (with Gram):", end='') sys.stdout.flush() tstart = time() G = np.dot(X.T, X) # precomputed Gram matrix Xy = np.dot(X.T, y) lars_path(X, y, Xy=Xy, Gram=G, max_iter=n_informative) delta = time() - tstart print("%0.3fs" % delta) lars_gram[i_f, i_s] = delta gc.collect() print("benchmarking lars_path (without Gram):", end='') sys.stdout.flush() tstart = time() lars_path(X, y, Gram=None, max_iter=n_informative) delta = time() - tstart print("%0.3fs" % delta) lars[i_f, i_s] = delta gc.collect() print("benchmarking orthogonal_mp (with Gram):", end='') sys.stdout.flush() tstart = time() orthogonal_mp(X, y, precompute=True, n_nonzero_coefs=n_informative) delta = time() - tstart print("%0.3fs" % delta) omp_gram[i_f, i_s] = delta gc.collect() print("benchmarking orthogonal_mp (without Gram):", end='') sys.stdout.flush() tstart = time() orthogonal_mp(X, y, precompute=False, n_nonzero_coefs=n_informative) delta = time() - tstart print("%0.3fs" % delta) omp[i_f, i_s] = delta results['time(LARS) / time(OMP)\n (w/ Gram)'] = (lars_gram / omp_gram) results['time(LARS) / time(OMP)\n (w/o Gram)'] = (lars / omp) return results
idx, = x.nonzero() # distort the clean signal ########################## y_noisy = y + 0.05 * np.random.randn(len(y)) # plot the sparse signal ######################## pl.subplot(3, 1, 1) pl.xlim(0, 512) pl.title("Sparse signal") pl.stem(idx, x[idx]) # plot the noise-free reconstruction #################################### x_r = orthogonal_mp(D, y, n_nonzero_coefs) idx_r, = x_r.nonzero() pl.subplot(3, 1, 2) pl.xlim(0, 512) pl.title("Recovered signal from noise-free measurements") pl.stem(idx_r, x_r[idx_r]) # plot the noisy reconstruction ############################### x_r = orthogonal_mp(D, y_noisy, n_nonzero_coefs) idx_r, = x_r.nonzero() pl.subplot(3, 1, 3) pl.xlim(0, 512) pl.title("Recovered signal from noisy measurements") pl.stem(idx_r, x_r[idx_r])
print errs if __name__ == "__main__": n = 128 s = 10 m = 40 D = random_dict(m, n) k = 0 while 1: x = get_sparse_x(n, s) y = np.dot(D, x) x_naive = omp_naive(D, y) x_scikit = orthogonal_mp(D, y, s) error_naive = norm(x - x_naive.reshape(n, 1)) error_scikit = norm(x - x_scikit.reshape(n, 1)) k += 1 if error_naive < 1e-3 and error_scikit > 1: print x break print k import matplotlib.pylab as plt nr = np.arange(0, n) plt.subplot(311) plt.stem(nr, x)
def test_with_without_gram_tol(): assert_array_almost_equal( orthogonal_mp(X, y, tol=1.), orthogonal_mp(X, y, tol=1., precompute=True))
def test_with_without_gram(): assert_array_almost_equal( orthogonal_mp(X, y, n_nonzero_coefs=5), orthogonal_mp(X, y, n_nonzero_coefs=5, precompute=True))
def test_tol(): tol = 0.5 gamma = orthogonal_mp(X, y[:, 0], tol=tol) gamma_gram = orthogonal_mp(X, y[:, 0], tol=tol, precompute=True) assert_true(np.sum((y[:, 0] - np.dot(X, gamma)) ** 2) <= tol) assert_true(np.sum((y[:, 0] - np.dot(X, gamma_gram)) ** 2) <= tol)
def test_n_nonzero_coefs(): assert_true(np.count_nonzero(orthogonal_mp(X, y[:, 0], n_nonzero_coefs=5)) <= 5) assert_true(np.count_nonzero(orthogonal_mp(X, y[:, 0], n_nonzero_coefs=5, precompute=True)) <= 5)
def test_correct_shapes(): assert_equal(orthogonal_mp(X, y[:, 0], n_nonzero_coefs=5).shape, (n_features,)) assert_equal(orthogonal_mp(X, y, n_nonzero_coefs=5).shape, (n_features, 3))
def omp(patch, dic, atoms): alpha = orthogonal_mp(dic, patch, n_nonzero_coefs=atoms) return dic.dot(alpha)
idx, = x.nonzero() # distort the clean signal ########################## y_noisy = y + 0.05 * np.random.randn(len(y)) # plot the sparse signal ######################## pl.subplot(3, 1, 1) pl.xlim(0, 512) pl.title("Sparse signal") pl.stem(idx, x[idx]) # plot the noise-free reconstruction #################################### x_r = orthogonal_mp(D, y, n_components) idx_r, = x_r.nonzero() pl.subplot(3, 1, 2) pl.xlim(0, 512) pl.title("Recovered signal from noise-free measurements") pl.stem(idx_r, x_r[idx_r]) # plot the noisy reconstruction ############################### x_r = orthogonal_mp(D, y_noisy, n_components) idx_r, = x_r.nonzero() pl.subplot(3, 1, 3) pl.xlim(0, 512) pl.title("Recovered signal from noisy measurements") pl.stem(idx_r, x_r[idx_r])