Реализация алгоритма K-SVD на Python

В настоящее время я пытаюсь применить алгоритм K-SVD с использованием Python, который основан на следующей статье здесь: http://www.cs.technion.ac.il/~elad/publications/journals/2004/32_KSVD_IEEE_TSP.pdf. До сих пор я реализовал приведенный ниже код, и он, кажется, работает довольно хорошо с точки зрения создания хорошего словаря для разреженных представлений. Код, который я создал, основан на реализации, которая существует в Python здесь, https://github.com/nel215/ksvd/blob/master/ksvd/__init__.py. Однако я изменил, поскольку я использую K-SVD для выполнения изучения словаря для сигналов другого типа по сравнению с тем, для которого предполагается использовать обычный K-SVD (я пытаюсь создать разреженный словарь для сигналов вибрации машины вместо нормальные сигналы изображения). Мой код можно увидеть ниже:

def Phi_designer_k_svd(Phi_list, y_list, index):
    '''
    # y_list is expected to have size of k x y_freq (k rows of y_freq sized horizontal signals)
    # mp_process in here is a self-implemented OMP function, loosely following
    # an implementation here: https://github.com/davebiagioni/pyomp/blob/master/omp.py
    '''
    # (mxn) = size of Phi
    Phi = Phi_list[index]

    for i in range(0,1000):
        Phi_old = np.zeros(Phi.shape)
        Phi_old[:, :] = Phi[:, :]
        x_mp = np.zeros((n,k))

        #for every column of x_mp, calculate the sparse representation of the column
        #(find the representation of x_mp that would give minimum solution for ||y - Phi*x_mp||)
        for j in range(0, k): 
            # find approximation of x signal
            x_mp[:,j], _, _ = mp_process(Phi, y_cur[:,j], ncoef=sparsity, verbose=vbose)

        '''for every t-th atom in Phi...
        update the dictionary atoms so that it minimizes errors obtained from compressed x_mp
        '''
        for t in range(0, n):

            #Choose the COLUMN indexes in the t-th ROW of x_mp that is NON zero!
            #(synonymous with picking signals (which column) of x contributed 
            # directly by the t-th atom of the dictionary)

            I = x_mp[t] != 0

            #if there are no contributions made by this atom for x_mp, then continue to the next atom.
            if np.sum(I) == 0:
                continue


            '''
            # only columns containing nonzero elements from t-th row of x_mp is used (showing indices using t-th atom in dict), 
            # rest are ignored
            '''
            x_copy = x_mp[:, I]

            #zero the t-th row as it will not be used in actual calculation
            x_copy[t] = 0

            #create a copy of Phi with the value of the t-th atom zeroed (to disable contribution from the t-th atom of Phi)
            copy = np.zeros(Phi.shape)
            copy[:] = Phi[:]
            copy[:,t] = 0

            #calculate error produced from contribution of t-th atom only (thus ignoring the rest of the zero elements in initial x_mp.
            error = y_cur[:,I] - np.dot(copy, x_copy)


            #produce a SVD decomp of the obtained error matrix
            U,s,V = np.linalg.svd(error, full_matrices=True)

            Phi[:, t] = U[:, 0]

            '''
            #update only the picked non-zero elements of x_mp (as previously mentioned) to be updated. 
            #(sizes of s and V should have already matched this indices group as well)
            '''
            x_mp[t, I] = s[0] * V[:,0]


        previous_norm = l2_norm(Phi_old)
        detected_norm = l2_norm(Phi)

        norm_diff = previous_norm - detected_norm

        #**** Convergence condition. Not sure correct or not based on paper.
        if abs(norm_diff) < tol:
            break

    Phi_list[index] = Phi
    return

Однако я обнаружил, что этот код может создать только словарь, который хорошо работает только для обучающего набора данных, а сжатие не работает для любых новых наборов данных. Я подозреваю, что, возможно, я не реализовал критерии остановки из бумаги правильно (тот, который я пометил '****' в коде выше. Последняя строка в цикле for), так как я не слишком уверен в себе какими будут соответствующие критерии остановки для алгоритма. Кто-нибудь когда-либо реализовывал свою собственную версию K-SVD на python? Если это так, я был бы очень признателен, если бы вы могли помочь мне проверить правильность моих реализованных критериев остановки и, возможно, любые дополнительные советы, которые я могу использовать, чтобы обеспечить лучшее соответствие между созданным словарем и любым новым набором сигналов.

0 ответов

Другие вопросы по тегам