我需要一个与tf.one_hot
给我的有些相似的张量,但我(有时)每行需要多一个1
。
更具体地说,给定2d张量AI需要在某个位置具有1
的2d张量,当且仅当A包含列索引作为同一行中的值时。
更糟糕的是,我给定的张量A具有动态尺寸和填充,但额外的1d张量为我提供了实际长度。
这样做的有效(记忆和时间)方式是什么?
问题的一些背景: 我正在进行多类分类,每个示例都带有可变的标签子集。 因此,我计算softmax的指数,并希望从非相关类标签中减去一个大数字。
作为一个例子,给定输入:
indices = [[1, 4, 2, 5], [0, 4, 2, 0], [2, 4, 0, 0]]
real_length = [4, 3, 2]
shape = [3, 5]
其中indices
是我的填充2d张量(末尾为0填充),其中每个值指示在输出张量中应将哪个值设置为1
。
real_length
表示indices
每行中有多少个值(左起)是非填充值。
shape
是我需要的输出张量的形状,其中第一个维度与indices
相同,第二个维度是indices
中任何值可能采用的最大值,但不一定最大值超过indices
。
我需要:
[[0, 1, 1, 0, 1, 1], [1, 0, 1, 0, 1, 0], [0, 0, 1, 0, 1, 0]]
答案 0 :(得分:0)
对于多个热编码:
方法1
您可以使用tf.nn.embeddings_lookup执行此操作,如下所示:
embeddings = tf.constant([[0,0,0], [0,0,1], [0,1,1], [1,1,1]])
labels = np.array([0,3,1,2,0])
encode_tensors = tf.nn.embedding_lookup(embeddings,labels)
sess.run(encode_tensors)
输出:
array([[0, 0, 0],
[1, 1, 1],
[0, 0, 1],
[0, 1, 1],
[0, 0, 0]], dtype=int32)
方法2
labels = np.array([1, 2, 0, 3, 0])
sess.run(tf.sequence_mask(labels, 3, dtype=tf.int8))
输出:
array([[1, 0, 0],
[1, 1, 0],
[0, 0, 0],
[1, 1, 1],
[0, 0, 0]], dtype=int8)
希望这有帮助!
答案 1 :(得分:0)
我不确定我是否完全理解您的问题的所有细节,一个很好的起点(将从索引中产生您想要的输出)将是
indices = [[1, 4, 2, 5], [0, 4, 2, 0], [2, 4, 0, 0]]
one_hots = tf.one_hot(indices, 6)
tf.reduce_max(one_hots, axis=1)
(其中6是所需输出的第二维) 会产生:
[[0., 1., 1., 0., 1., 1.],
[1., 0., 1., 0., 1., 0.],
[1., 0., 1., 0., 1., 0.]]
因此,使用one_hot
,您基本上创建了一个形状为(3,4,6)的张量,其中包含索引中每个元素的所有单个one_hot编码。
然后,将它们全部折叠为一个“多热点”表示形式,从而摆脱了索引的第二维。
由于它不执行任何查找,但是它只是一个简单的one_hot编码+一个max操作,因此我认为它会足够有效。
希望它有帮助:)