python - 如何在张量流中创建给定索引的二进制矩阵
问题描述
假设我有一个带有两个样本索引的 tf 张量:
x = [[2,3,5], [5,7,5]]
我想创建一个具有特定形状的张量(samples, 10)
,其中每个样本的索引x
设置为 1,其余的设置为 0,如下所示:
output = [[0, 0, 1, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 1, 0, 0]]
在不创建大量中间矩阵的情况下,最好的方法是什么?
我得到的最接近的是 using tf.scatter_nd
,但我无法弄清楚如何正确转换x
,updates
除了手动添加这样的附加信息:
>>> tf.cast(tf.scatter_nd([[0,2], [0,3], [0,5], [1,5], [1,7], [1,5]], [1, 1, 1, 1, 1, 1] ,
[2, 10]) > 0, dtype="int64")
<tf.Tensor: id=1191, shape=(2, 10), dtype=int64, numpy=
array([[0, 0, 1, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 1, 0, 0]])>
此外,这种方法首先会聚合重复的索引,这使得中间布尔矩阵成为必要。(虽然我可以忍受,但主要问题是从x
一个形状的矩阵开始,(samples, 10)
其中每个样本的不存在索引为 0。)
谢谢你的帮助!:)
解决方案
我找到了一个解决方案(tensorflow 2.2.0):
class BinarizeSequence(tf.keras.layers.Layer):
"""
Transforms an integer sequence into a binary representation
with shape (samples, vocab_size).
Example:
In: [[2,3,5], [5,7,5]]
Out: [[0, 0, 1, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 1, 0, 0]]
By default the output is returned as SparseTensor.
Use dense_output=True if you need a dense representation.
"""
def __init__(self, vocab_size, dense_output=False, **kwargs):
super(BinarizeSequence, self).__init__(**kwargs)
self.vocab_size = vocab_size
self.dense_output = dense_output
def get_config(self):
config = super().get_config().copy()
config.update(
{"vocab_size": self.vocab_size, "dense_output": self.dense_output}
)
return config
def call(self, x, mask=None):
# create indices for binarized representation
x = tf.cast(x, dtype=tf.int32)
x_1d = tf.reshape(x, [-1])
sample_dim = tf.repeat(
tf.range(tf.shape(x)[0], dtype=tf.int32), tf.shape(x)[1]
)
indices = tf.transpose(tf.stack([sample_dim, x_1d]))
# only keep unique indices
# (see https://stackoverflow.com/a/42245425/979377)
indices64 = tf.bitcast(indices, type=tf.int64)
unique64, idx = tf.unique(indices64)
unique_indices = tf.bitcast(unique64, type=tf.int32)
# build binarized representation
updates = tf.ones(tf.shape(unique_indices)[0])
output_shape = [tf.shape(x)[0], self.vocab_size]
if self.dense_output:
output = tf.scatter_nd(unique_indices, updates, output_shape)
else:
output = tf.sparse.SparseTensor(
tf.cast(unique_indices, tf.int64), updates, output_shape
)
return output
推荐阅读
- javascript - Ajax 方法在十进制时不命中控制器
- c++ - 在 memcpy 上添加号码
- java - Spring拦截器不拦截来自静态资源的传入HTTP请求
- android - Firebase 数据库中未找到 Glide 文件异常
- hybris - comptel eventlink 和 instantklink 使用哪种编码语言?
- reactjs - 当我控制台记录它时,event.target.value 返回带有语义 UI 的未定义
- sustainsys-saml2 - 如何在控制器操作方法中获取 SAML 响应和 SAML 令牌
- javascript - Javascript - 简单的练习
- c# - 如何在 datagridview 列的单元格编辑中保留原始值?
- c++ - 评估“QT_CONFIG(打印机)”时预处理器除以零