Линейная алгебра в слое Кераса - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь реализовать модуль scipy.lingalg.null_space как лямбда-слой в keras. Мой ввод в виде пакетов numpy массивов формы (5,5), но простое

def ns(x_array):
    x_array = np.array(x_array)
    return null_space(x_array)

null = keras.layers.Lambda(lambda x: ns(x) )(input)

выдает сообщение об ошибке:


~/miniconda3/lib/python3.7/site-packages/scipy/linalg/decomp_svd.py in null_space(A, rcond)
    382 
    383     """
--> 384     u, s, vh = svd(A, full_matrices=True)
    385     M, N = u.shape[0], vh.shape[1]
    386     if rcond is None:

~/miniconda3/lib/python3.7/site-packages/scipy/linalg/decomp_svd.py in svd(a, full_matrices, compute_uv, overwrite_a, check_finite, lapack_driver)
    107 
    108     """
--> 109     a1 = _asarray_validated(a, check_finite=check_finite)
    110     if len(a1.shape) != 2:
    111         raise ValueError('expected matrix')

~/miniconda3/lib/python3.7/site-packages/scipy/_lib/_util.py in _asarray_validated(a, check_finite, sparse_ok, objects_ok, mask_ok, as_inexact)
    240     if not objects_ok:
    241         if a.dtype is np.dtype('O'):
--> 242             raise ValueError('object arrays are not supported')
    243     if as_inexact:
    244         if not np.issubdtype(a.dtype, np.inexact):

ValueError: object arrays are not supported

Я думаю, что я должен заставить ввод null_space быть 2-мерным массивом (а не 3-мерной формой каждой партии), но я не уверен, как это сделать.

1 Ответ

1 голос
/ 14 февраля 2020

Вы можете повторно реализовать null_space с помощью кераса / тензорного потока. См. Источник scipy https://github.com/scipy/scipy/blob/v1.4.1/scipy/linalg/decomp_svd.py#L333 -L391

Реализация выглядит просто. Вы должны будете использовать svd, поэтому вы можете использовать tf.linalg.svd .


Редактировать: Обычно я этого не делаю, но мне было любопытно, поэтому здесь реализация тензорного потока null_space. Выходы близки, но не совсем совпадают с таковыми у Сципи.

import numpy as np
import tensorflow as tf

float32_eps = np.finfo(np.float32).eps

def tf_null_space(A, rcond=None):
    s, u, vh = tf.linalg.svd(A, full_matrices=True)
    vh = tf.transpose(vh)
    M, N = u.shape[0], vh.shape[1]
    if rcond is None:
        rcond = float32_eps * max(M, N)
    tol = tf.reduce_max(s) * rcond
    num = tf.reduce_sum(tf.cast(s > tol, tf.int32))
    Q = tf.math.conj(tf.transpose(vh[num:, :]))
    return Q
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...