Python 如何修改tf.nn.embedding_lookup()中的返回张量?

Python 如何修改tf.nn.embedding_lookup()中的返回张量?,python,tensorflow,machine-learning,embedding,tensor,Python,Tensorflow,Machine Learning,Embedding,Tensor,我想使用scatter\u nd\u update更改从tf.nn.embedded\u lookup()返回的张量的内容。但是,返回的张量是不可变的,scatter\u nd\u update()需要可变张量作为输入。 我花了很多时间试图找到一个解决方案,包括使用gen\u state\u ops.\u temporary\u variable和使用tf.sparse\u to\u densite,不幸的是都失败了 我想知道有没有一个漂亮的解决办法 with tf.device('/cpu:0

我想使用
scatter\u nd\u update
更改从
tf.nn.embedded\u lookup()
返回的张量的内容。但是,返回的张量是不可变的,
scatter\u nd\u update()
需要可变张量作为输入。 我花了很多时间试图找到一个解决方案,包括使用
gen\u state\u ops.\u temporary\u variable
和使用
tf.sparse\u to\u densite
,不幸的是都失败了

我想知道有没有一个漂亮的解决办法

with tf.device('/cpu:0'), tf.name_scope("embedding"):
            self.W = tf.Variable(
                tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),
                name="W")
            self.embedded_chars = tf.nn.embedding_lookup(self.W, self.input_x)
            updates = tf.constant(0,shape=[embedding_size])
            for i in range(1,sequence_length - 2):
                indices = [None,i]
                tf.scatter_nd_update(self.embedded_chars,indices,updates)
            self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars, -1)
简单地返回较大矩阵的切片,因此最简单的解决方案是更新该矩阵本身的值,在您的示例中是
self.W

self.embedded_chars = tf.nn.embedding_lookup(self.W, self.input_x)
因为它是一个变量,所以它符合。请注意,不能只更新任何张量,只能更新变量

另一个选项是仅为所选切片创建一个新变量,为其分配
self.embedded_chars
,然后执行更新



警告:在这两种情况下,您都在阻止梯度来训练嵌入矩阵,因此请仔细检查覆盖学习值是否真的是您想要的。

这个问题的根源在于不清楚tensorflow上下文中的张量和变量。后来对张量有了更多的了解,我想到的解决方案是:

   with tf.device('/cpu:0'), tf.name_scope("embedding"):
        self.W = tf.Variable(
            tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),
            name="W")
        self.embedded_chars = tf.nn.embedding_lookup(self.W, self.input_x)
        for i in range(0,sequence_length - 1,2):
            self.tslice = tf.slice(self.embedded_chars,[0,i,0],[0,1,128])
            self.tslice2 = tf.slice(self.embedded_chars,[0,i+1,0],[0,1,128])
            self.tslice3 = tf.slice(self.embedded_chars,[0,i+2,0],[0,1,128])
            self.toffset1 = tf.subtract(self.tslice,self.tslice2)
            self.toffset2 = tf.subtract(self.tslice2,self.tslice3)
            self.tconcat = tf.concat([self.toffset1,self.toffset2],1)
        self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars, -1)

所使用的函数tf.slice、tf.subtract、tf.concat都接受张量作为输入。请避免使用需要变量作为输入的tf.scatter\u和\u update等函数。

非常感谢您的解释。你能多说一点警告吗。我想在输入层修改一些张量,比如做一些加法或减法。修改原始输入数据(称为预处理)是可以的。你在这个问题中描述的是在训练中改写价值。或者可能我不明白你的目的。我想我在做预处理,因为它是在卷积发生之前完成的。我想连接每个单词嵌入或进行减法以获得嵌入偏移量,然后馈送到卷积层。所以我认为这不会破坏训练。不是吗?不,这很重要。嵌入是可以学习的(除非它是预先训练和固定的),所以它已经是网络的一部分了。在输入数据之前,先对数据进行预处理,在本例中为字符索引。我使用在谷歌语料库(GoogleNews-vectors-negative300)上训练过的预训练词2VEC嵌入。它加载在self.W中。然后通过嵌入查找得到句子中每个单词的向量并作为输入。我要做的是在输入层连接或减去这些字向量,然后馈送到卷积层。我认为只有权重矩阵是可学习的,输入层的嵌入是固定的。我说得对吗?