Producto de tensor bilineal en TensorFlow
(2)
Puede realizar un tensor de rango 3 y una multiplicación vectorial entre W y e2 que produce una matriz 2D y luego multiplicar el resultado con e1. La siguiente función hace uso del producto tensor y la contracción del tensor para definir este producto (por ejemplo, W * e3)
import sympy as sp
def tensor3_vector_product(T, v):
"""Implements a product of a rank 3 tensor (3D array) with a
vector using tensor product and tensor contraction.
Parameters
----------
T: sp.Array of dimensions n x m x k
v: sp.Array of dimensions k x 1
Returns
-------
A: sp.Array of dimensions n x m
"""
assert(T.rank() == 3)
# reshape v to ensure a 1D vector so that contraction do
# not contain x 1 dimension
v.reshape(v.shape[0], )
p = sp.tensorproduct(T, v)
return sp.tensorcontraction(p, (2, 3))
Puede verificar esta multiplicación utilizando los ejemplos proporcionados en la ref . La función anterior contrae el segundo y el tercer eje; en su caso, creo que debería contraer (1, 2) porque W se define como dxdxk y no kxdxd como en mi caso.
Estoy trabajando en la reimplementación de este documento y la operación clave es un producto de tensor bilineal. Apenas sé lo que eso significa, pero el papel tiene un pequeño y bonito gráfico, que entiendo.
La operación clave es e_1 * W * e_2 , y quiero saber cómo implementarla en tensorflow, porque el resto debería ser fácil.
Básicamente, dado el tensor 3D W, divídalo en matrices, y para el j''th slice (una matriz), multiplíquelo en cada lado por e_1 y e_2 , lo que resulta en un escalar, que es la jth entrada en el vector resultante (el salida de esta operación).
Así que quiero realizar un producto de e_1 , un vector d-dimensional, W , el tensor dxdxk, y e_2 , otro vector d-dimensional. ¿Podría este producto expresarse de manera concisa en TensorFlow como lo es ahora, o tendría que definir mi propia operación de alguna manera?
EDICIONES ANTERIORES
¿Por qué la multiplicación de estos tensores no funciona, y hay alguna manera de definirlo más explícitamente para que funcione?
>>> import tensorflow as tf
>>> tf.InteractiveSession()
>>> a = tf.ones([3, 3, 3])
>>> a.eval()
array([[[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]],
[[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]],
[[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]]], dtype=float32)
>>> b = tf.ones([3, 1, 1])
>>> b.eval()
array([[[ 1.]],
[[ 1.]],
[[ 1.]]], dtype=float32)
>>>
El mensaje de error es
ValueError: Shapes TensorShape([Dimension(3), Dimension(3), Dimension(3)]) and TensorShape([Dimension(None), Dimension(None)]) must have the same rank
ACTUALMENTE
Resulta que multiplicar dos tensores 3D tampoco funciona con tf.matmul
, así que tf.batch_matmul
sí tf.batch_matmul
hace. tf.batch_matmul
también hará tensores y matrices 3D. Entonces probé 3D y un vector:
ValueError: Dimensions Dimension(3) and Dimension(1) are not compatible
Puedes hacer esto con una simple remodelación. Para el primero de los dos multiplicados de matrices, tiene k * d, longitud d vectores para puntear el producto.
Esto debería estar cerca:
temp = tf.matmul(E1,tf.reshape(Wddk,[d,d*k]))
result = tf.matmul(E2,tf.reshape(temp,[d,k]))