Алгоритм разложения на одно значение не работает - PullRequest
0 голосов
/ 26 октября 2018

Я написал следующую функцию для выполнения SVD в соответствии со страницей 45 «Книги глубокого обучения» Яна Гудфеллоу и соавторов.

def SVD(A): 

    #A^T
    AT = np.transpose(A)

    #AA^T
    AAT = A.dot(AT)

    #A^TA
    ATA = AT.dot(A)

    #Left single values
    LSV = np.linalg.eig(AAT)[1]
    U = LSV #some values of U have the wrong sign 

    #Right single values
    RSV = np.linalg.eig(ATA)[1]
    V = RSV
    V[:,0] = V[:,0] #V isnt arranged properly

    values = np.sqrt(np.linalg.eig(ata)[0])

    #descending order
    values = np.sort(values)[::-1]

    rows = A.shape[0]
    columns = A.shape[1]

    D = np.zeros((rows,columns))

    np.fill_diagonal(D,values)


    return U, D, V

Однако для любой данной матрицы результаты не совпадают с использованием

np.linalg.svd(A)

и я понятия не имею, почему.

Я проверил свой алгоритм, сказав

abs(UDV^T - A) < 0.0001 

, чтобы проверить, правильно ли он разложился, и нет.Кажется, проблема в компонентах V и U, но я не вижу, что происходит не так.Кажется, что D верен.

Если кто-нибудь увидит проблему, это будет высоко оценено.

1 Ответ

0 голосов
/ 26 октября 2018

Я думаю, что у вас есть проблема с порядком собственных пар, которые возвращают eig (ATA) и eig (AAT).В документации np.linalg.eig говорится, что заказ не гарантирован.Замена eig на восемь, которая возвращает собственные пары в порядке возрастания, должна помочь.Также не переставляйте значения.

Кстати, восемь характерно для симметричных матриц, таких как те, которые вы передаете, и не будет возвращать комплексные числа, если исходная матрица действительна.

...