Python keras层中的线性代数
我试图在Python keras层中的线性代数,python,numpy,tensorflow,keras,scipy,Python,Numpy,Tensorflow,Keras,Scipy,我试图在keras中将scipy.lingalg.null\u空间模块实现为Lambda层。 我的输入是成批的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/si
keras
中将scipy.lingalg.null\u空间
模块实现为Lambda层。
我的输入是成批的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
的输入强制为二维数组(而不是每个批次的三维形状),但我不确定如何做到这一点 您可以使用keras/tensorflow重新实现null\u空间。请参阅scipy源代码
实现看起来很简单。不过,您必须使用svd,这样才能使用
编辑:我通常不这样做,但我很好奇,所以这里有一个null\u space
的tensorflow实现。输出接近但不完全等于scipy的输出
将numpy导入为np
导入tensorflow作为tf
float32_eps=np.finfo(np.float32.eps)
def tf_null_空间(A,rcond=None):
s、 u,vh=tf.linalg.svd(A,完整矩阵=True)
vh=tf.转置(vh)
M、 N=u形[0],vh形[1]
如果rcond为None:
rcond=浮动32_每股收益*最大值(M,N)
tol=tf.减少最大值*rcond
num=tf.reduce_sum(tf.cast(s>tol,tf.int32))
Q=tf.math.conj(tf.transpose(vh[num:,:]))
返回Q
如果您将其用作神经网络的一部分,则不能在Lambda层中使用numpy,因为您无法通过使用keras/tensorflow的numpy进行区分。我认为您的意思是复制null\u空间
定义,并基本上用tf
替换np
?听起来多少有道理。但是您必须弄清楚如何处理np.finfo
调用。您可以假设输入数据类型,如float32,并将其eps存储为常量。回到这里,我现在的问题是计算小于公差的奇异值的数量,并使用此数字提取由tf.linalg.svd
…@非宗教提供的v
的正确列-请参阅我更新的答案。它应该能回答你的问题,非常感谢@jakub,但我仍然在这方面发现了一些错误(我之前也尝试过类似的方法)-首先rcond
定义错误(通过移除max(m,N)来修复):在tf_null_空间(a,rcond)28 m,N=u.shape[0],vh.shape[1]29如果rcond为None:-->30 rcond=float32\u eps*max(M,N)31 tol=tf.reduce\u max(s)*rcond 32 num=tf.reduce\u sum(tf.cast(s>tol,tf.int32))。。。411 412 def\uu floordiv\uuu(self,other):类型错误:不支持*的操作数类型:'Dimension'和'float'