可能有一个明显的解决方案,但我还没有找到。我想做一个简单的乘法,我有一个张量给我一种权重向量,另一个张量是堆叠张量(与权重相同)。使用 tf.tensordot 似乎很简单,但这不适用于未知的批量大小。
import collections
import tensorflow as tf
tf.reset_default_graph()
x = tf.placeholder(shape=(None, 4, 1), dtype=tf.float32, name='x')
y_true = tf.placeholder(shape=(None, 4, 1), dtype=tf.float32, name='y_true')
# These are the models that I want to combine
linear_model0 = tf.layers.Dense(units=1, name='linear_model0')
linear_model1 = tf.layers.Dense(units=1, name='linear_model1')
agents = collections.OrderedDict()
agents[0] = linear_model0(x) # shape (?,4,1)
agents[1] = linear_model1(x) # shape (?,4,1)
stacked = tf.stack(list(agents.values()), axis=1) # shape (?,2,4,1)
# This is the model that produces the weights
x_flat = tf.layers.Flatten()(x)
weight_model = tf.layers.Dense(units=2, name='weight_model')
weights = weight_model(x_flat) # shape: (?,2)
# This is the final output
y_pred = tf.tensordot(weights, stacked, axes = 2, name='y_pred')
# PROBLEM HERE: shape: (4,1) instead of (?,4,1)
# Running the whole thing
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
# Example1 (output of shape (1,4,1) expected, got (4,1))
print('model', sess.run(y_pred,
{x: [[[1], [2], [3], [4]]]}).shape)
# Example2 (output of (2,4,1) expected, got (4,1))
print('model', sess.run(y_pred,
{x: [[[1], [2], [3], [4]], [[1], [2], [3], [4]]]}).shape)
因此,对于第一个输入,乘法按预期工作,但只对第一个输入进行乘法运算,而不是对一批输入进行乘法运算。有帮助吗?
没有解决我的问题的类似问题:
请您参考如下方法:
tf.tensordot在这种情况下不合适,因为根据您的解释,有必要将 axis 设置为 1,这会导致矩阵大小不兼容。一个是 [batch_size, 2],另一个是 [batch_size, 8]。另一方面,如果您将轴设置为 [[1],[1]] 它不是您所期望的:
tf.tensordot(weights, stacks, axes=[[1],[1]]) # shape = (?,?,1,1)
如何解决这个问题?
使用tf.ensim作为任意维度张量之间的收缩:
tf.einsum('ij,ijkl->ikl', weights, stacked)
