线性代数在TensorFlow中粗糙张量的应用 [英] Apply linear algebra to ragged tensor in tensorflow

查看:0
本文介绍了线性代数在TensorFlow中粗糙张量的应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用TensorFlow v2.7.0,并尝试使用粗糙张量创建一个ML模型。

问题是tf.linalg.diag、tf.matmul和tf.linalg.det不能使用粗糙张量。 我已经找到了一种变通方法,将参差不齐的张量转换为NumPy,并将其转换回参差不齐的张量,但在全局模型中应用该层时不起作用。

以下代码工作正常

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
import tensorflow as tf

class LRDet(tf.keras.layers.Layer):
    
    def __init__(self,numItems,rank=10):
        super(LRDet,self).__init__()
        self.numItems = numItems
        self.rank = rank
    
    def build(self,input_shape):
        V_init = tf.random_normal_initializer(mean=0.0,stddev=0.01)
        D_init = tf.random_normal_initializer(mean=1.0,stddev=0.01)
        self.V = tf.Variable(name='V',initial_value=V_init(shape=(self.numItems, self.rank)),trainable=True)
        self.D = tf.Variable(name='D',initial_value=D_init(shape=(self.numItems,)),trainable=True)
    
    def call(self,inputs):
        batch_size = inputs.nrows()
        subV = tf.gather(self.V,inputs)
        subD = tf.square(tf.gather(self.D,inputs,batch_dims=0))#tf.linalg.diag(tf.square(tf.gather(D,Xrag,batch_dims=0)))
        subD = tf.ragged.constant([tf.linalg.diag(subD[i]).numpy() for i in tf.range(batch_size)])
        K = tf.ragged.constant([tf.matmul(subV[i],subV[i],transpose_b=True).numpy() for i in tf.range(batch_size)])
        K = tf.add(K,subD)
        res = tf.ragged.constant([tf.linalg.det(K[i].to_tensor()).numpy() for i in tf.range(batch_size)])
        return res
        

numItems = 10
rank = 3
detX = LRDet(numItems,rank)
X = [[1,2],[3],[4,5,6]]
Xrag = tf.ragged.constant(X)
_ = detX(Xrag)

但一旦我在更全球化的模型中使用了该层,我就会出现以下错误

OPERATORNOTELWELDInGraphError:调用时遇到异常 层LR_DET_10&QOOT;(类型为LRDet)。

    in user code:
    
        File "<ipython-input-57-6b073a14386e>", line 18, in call  *
            subD = tf.ragged.constant([tf.linalg.diag(subD[i]).numpy() for i in tf.range(batch_size)])
    
        OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed: AutoGraph did convert this function. This might indicate you are trying to use an unsupported feature.

我尝试使用tf.map_fn而不是使用.numpy()进行列表理解,但没有成功。

如有任何帮助,将不胜感激。

推荐答案

这里有一个与tf.map_fn一起运行的选项;但是,由于最近关于tf.map_fn、参差不齐的张量和图形处理器的bug,它目前仅在cpu上运行:

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # do not access GPU
import tensorflow as tf

class LRDet(tf.keras.layers.Layer):
    
    def __init__(self,numItems,rank=10):
        super(LRDet,self).__init__()
        self.numItems = numItems
        self.rank = rank
    
    def build(self,input_shape):
        V_init = tf.random_normal_initializer(mean=0.0,stddev=0.01)
        D_init = tf.random_normal_initializer(mean=1.0,stddev=0.01)
        self.V = tf.Variable(name='V',initial_value=V_init(shape=(self.numItems, self.rank)),trainable=True)
        self.D = tf.Variable(name='D',initial_value=D_init(shape=(self.numItems,)),trainable=True)

    def call(self,inputs):
        batch_size = inputs.nrows()
        subV = tf.gather(self.V,inputs)
    
        subD = tf.square(tf.gather(self.D, inputs, batch_dims=0))
        subD = tf.map_fn(self.diag, subD, fn_output_signature=tf.RaggedTensorSpec(shape=[1, None, None],
                                                                    dtype=tf.type_spec_from_value(subD).dtype,
                                                                    ragged_rank=2,
                                                                    row_splits_dtype=tf.type_spec_from_value(subD).row_splits_dtype))
        subD = tf.squeeze(subD, 1)


        K = tf.map_fn(self.matmul, subV, fn_output_signature=tf.RaggedTensorSpec(shape=[1, None, None],
                                                                    dtype=tf.type_spec_from_value(subV).dtype,
                                                                    ragged_rank=2,
                                                                    row_splits_dtype=tf.type_spec_from_value(subV).row_splits_dtype))
        K = tf.squeeze(K, 1)
        K = tf.add(K,subD)

        res = tf.map_fn(self.det, K, tf.TensorSpec(shape=(), dtype=tf.float32, name=None))

        return res
        

    def diag(self, x):
      return tf.ragged.stack(tf.linalg.diag(x))

    def matmul(self, x):
      return tf.ragged.stack(tf.matmul(x, x,transpose_b=True))

    def det(self, x):
      return tf.linalg.det(x.to_tensor())


numItems = 10
rank = 3
input = tf.keras.layers.Input(shape=(None,), ragged=True, dtype=tf.int32)
detX = LRDet(numItems,rank)
output = detX(input)
model = tf.keras.Model(input, output)

X = [[1,2],[3],[4,5,6]]
Xrag = tf.ragged.constant(X)
y = tf.random.normal((3, 1))
model.compile(loss='mse', optimizer='adam')
model.fit(Xrag, y, batch_size=1, epochs=1)

这篇关于线性代数在TensorFlow中粗糙张量的应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆