python - 在 tensorflow 中广播 SparseTensor
问题描述
我想将具有 shape 的密集张量与具有 shape[n, n, k]
的稀疏张量相乘[n, n, 1]
。我希望稀疏张量中的值以 size 沿轴重复s
,就像我使用密集张量并依赖隐式广播一样。
但是该SparseTensor.__mul__
操作不支持广播稀疏操作数。我没有找到明确广播稀疏张量的运算符。我怎么能做到这一点?
解决方案
如果您不想只是将稀疏张量转换为密集,您可以从密集张量中提取选择正确的值以直接构建稀疏结果,如下所示:
import tensorflow as tf
import numpy as np
with tf.Graph().as_default(), tf.Session() as sess:
# Input data
x = tf.placeholder(tf.float32, shape=[None, None, None])
y = tf.sparse.placeholder(tf.float32, shape=[None, None, 1])
# Indices of sparse tensor without third index coordinate
indices2 = y.indices[:, :-1]
# Values of dense tensor corresponding to sparse tensor values
x_sp = tf.gather_nd(x, indices2)
# Values of the resulting sparse tensor
res_vals = tf.reshape(x_sp * tf.expand_dims(y.values, 1), [-1])
# Shape of the resulting sparse tensor
res_shape = tf.shape(x, out_type=tf.int64)
# Make sparse tensor indices
k = res_shape[2]
v = tf.size(y.values)
# Add third coordinate to existing sparse tensor coordinates
idx1 = tf.tile(tf.expand_dims(indices2, 1), [1, k, 1])
idx2 = tf.tile(tf.range(k), [v])
res_idx = tf.concat([tf.reshape(idx1, [-1, 2]), tf.expand_dims(idx2, 1)], axis=1)
# Make sparse result
res = tf.SparseTensor(res_idx, res_vals, res_shape)
# Dense value for testing
res_dense = tf.sparse.to_dense(res)
# Dense operation for testing
res_dense2 = x * tf.sparse.to_dense(y)
# Test
x_val = np.arange(48).reshape(4, 4, 3)
y_val = tf.SparseTensorValue([[0, 0, 0], [2, 3, 0], [3, 1, 0]], [1, 2, 3], [4, 4, 1])
res_dense_val, res_dense2_val = sess.run((res_dense, res_dense2),
feed_dict={x: x_val, y: y_val})
print(np.allclose(res_dense_val, res_dense2_val))
# True
推荐阅读
- amazon-ecs - 任务停止后ECS服务发现更新太晚
- sony-camera-api - 内容 URL - 索尼相机 API
- python - 仅在 Pandas 中将不规则日期格式转换为年份
- java - 无法自动装配 WebTestClient
- javascript - 正则表达式 C# 与 javascript 不一致
- javascript - JS / Canvas - 如何仅在按下键时更新 draw() 函数?
- html - 当我减小浏览器窗口大小时,使 2 张图像留在我背景上的固定位置
- android - 改版本为Androidx后,没有变成mqtt connect
- c++ - 我想知道缩放和轨道哪里出了问题
- javascript - 具有历史实现和主题标签功能的 ajax 页面加载内容