Тензорный тензорот для неизвестного размера партии - PullRequest
0 голосов
/ 12 января 2019

может быть очевидное решение, но я пока не нашел его. Я хочу сделать простое умножение, где у меня есть один тензор, который дает мне своего рода вектор весов, а другой - сложенные тензоры (то же число, что и у весов). Использование 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)

Таким образом, умножение работает, как и ожидалось, для первого ввода, но выполняет только этот первый, а не пакет входов. Любая помощь?

Похожие вопросы, которые не решили мою проблему:

1 Ответ

0 голосов
/ 12 января 2019

tf.tensordot в данном случае не подходит, поскольку, исходя из вашего пояснения, необходимо установить ось равную 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)
...