在张量流中,有没有一种方法可以以给定的方式从给定的张量生成新的张量



在下面的代码中:

import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import keras.backend as kb
ip1 = keras.Input((20,), name='ip1')
ip2 = keras.Input((20,), name='ip2')
ip3 = keras.Input((20,), name='ip3')
ip4 = keras.Input((20,), name='ip4')
ip5 = keras.Input((20,), name='ip5')
ip6 = keras.Input((20,), name='ip6')
ip7 = keras.Input((20,), name='ip7')
ip8 = keras.Input((20,), name='ip8')
ip9 = keras.Input((20,), name='ip9')
ip_concat = kb.stack([ip1, ip2, ip3, ip4, ip5, ip6, ip7, ip8, ip9], axis=1)
rel_features = layers.Dense(128, input_shape=(9, 20))(ip_concat)
f1_enc = layers.Dense(64, activation='tanh', input_shape=(9, 128))(rel_features)

这里,f1_enc具有9x64的形状。现在,我需要做的可以从下面的例子中理解。为了简单起见,我将初始张量保持为3x3:,而不是9x64张量

[[a, b, c],
[d, e, f],
[g, h, i]]

需要转换为3x3x6张量,如下所示:

[[[a, b, c, a, b, c],
[a, b, c, d, e, f],
[a, b, c, g, h, i]],
[[d, e, f, a, b, c],
[d, e, f, d, e, f],
[d, e, f, g, h, i]],
[[g, h, i, a, b, c],
[g, h, i, d, e, f],
[g, h, i, g, h, i]]]

我知道张量在张量流中是不可变的,所以在张量上循环并将值重新分配给新的张量是行不通的。

此外,我还试着处理急切的执行,因为张量到numpy矩阵的转换不起作用。根据我现在的理解,将张量转换为numpy矩阵的策略不起作用,因为我们使用的是keras层。

虽然代码将需要反向传播到ip_concat,但它将而不需要通过新的张量反向传播。稍后将有一个从ip_concat到另一个keras层的连接。

这可能不是最有效的方法,但:

import numpy as np
import tensorflow as tf
tensor = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(tensor)
# tf.Tensor(
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]], shape=(3, 3), dtype=int32)
x = tensor.numpy()
tensor = tf.constant([[np.concatenate((j, i)) for i in x] for j in x])
print(tensor)
# tf.Tensor(
# [[[1 2 3 1 2 3]
#   [1 2 3 4 5 6]
#   [1 2 3 7 8 9]]
#  [[4 5 6 1 2 3]
#   [4 5 6 4 5 6]
#   [4 5 6 7 8 9]]
#  [[7 8 9 1 2 3]
#   [7 8 9 4 5 6]
#   [7 8 9 7 8 9]]], shape=(3, 3, 6), dtype=int32)

使用tf.unstacktf.tiletf.reshapetf.concat的组合。我们的初始张量A:

<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]], dtype=int32)>

首先,展开行:

A1, A2, A3 = tf.unstack(A, axis=0)

输出:

(<tf.Tensor: shape=(3,), dtype=int32, numpy=array([1, 2, 3], dtype=int32)>,
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([4, 5, 6], dtype=int32)>,
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([7, 8, 9], dtype=int32)>)

然后tilereshape:

L1, L2, L3 = [tf.reshape(tf.tile(X, [3]), (3,3)) for X in [A1, A2, A3]]

输出:

(<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]], dtype=int32)>,
<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
array([[4, 5, 6],
[4, 5, 6],
[4, 5, 6]], dtype=int32)>,
<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
array([[7, 8, 9],
[7, 8, 9],
[7, 8, 9]], dtype=int32)>)

然后与初始张量连接:

R1, R2, R3 = [tf.concat([X, A], axis=1) for X in [L1, L2, L3]]

输出:

(<tf.Tensor: shape=(3, 6), dtype=int32, numpy=
array([[1, 2, 3, 1, 2, 3],
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 7, 8, 9]], dtype=int32)>,
<tf.Tensor: shape=(3, 6), dtype=int32, numpy=
array([[4, 5, 6, 1, 2, 3],
[4, 5, 6, 4, 5, 6],
[4, 5, 6, 7, 8, 9]], dtype=int32)>,
<tf.Tensor: shape=(3, 6), dtype=int32, numpy=
array([[7, 8, 9, 1, 2, 3],
[7, 8, 9, 4, 5, 6],
[7, 8, 9, 7, 8, 9]], dtype=int32)>)

最新更新