我有一个多层模型。我想在把keras层的输出张量输入到下一层之前对它进行洗牌。情况解释如下:
假设某一层的输出为:
x = [[[1,2,3], [4,5,6]],
[[7,8,9], [10,11,12]]]
所以,在将它输入到下一层之前,我想以一种特定的方式随机洗牌这个张量。下面给出一个例子:
x = [[[4,5,6], [1,2,3]]
[[10,11,12], [7,8,9]]]
我不想改变单个值的顺序。因此,x[0]和x[1]的顺序改变了。
模型代码如下:我还提到了我想对张量进行洗牌的地方:
def create_model(embedding_weights, node_vocab_size, path_vocab_size, MAX_SUBTREE_LENGTH):
config = Config()
node_input = Input((MAX_SUBTREE_LENGTH,MAX_SUBTREE_LENGTH), dtype=tf.int32)
path_input = Input((MAX_SUBTREE_LENGTH,), dtype=tf.int32)
#embedding layer
nodes_embedded = Embedding(node_vocab_size+2, config.embedding_size, trainable = True, name='node_embedding')(node_input)
path_embedded = Embedding(path_vocab_size+2, config.embedding_size,
trainable = True, name='path_embedding')(path_input) #(b,max_subtree,embedsize)
# path embeddings from node embeddings
nodes_embedded_merged = K.sum(nodes_embedded, axis=2) #(b,max_subtree,embedsize)
node_path_merged = concatenate([nodes_embedded_merged, path_embedded])
subtree_vectors = TimeDistributed(Dense(config.embedding_size*2, use_bias=False, activation='tanh'))(node_path_merged)
# Here I want to change the subtree_vectors tensor sequence as mentioned above before feeding in to the next layer (the attention layer)
# Attention Layer
attention_vectors = Dense(1,)(subtree_vectors)
attention_weights = Softmax(axis=1)(attention_vectors)
# Generating code vectors
code_vectors = K.sum(subtree_vectors * attention_weights, axis=1)
# Prediction layer
output_class = Dense(config.num_classes, use_bias=False, activation='softmax')(code_vectors)
model = Model(inputs=[node_input, path_input], outputs=output_class)
return model
我已经尝试了几种方法(例如使用tf.random.shuffle),但得到错误。我可能在多轴上有问题,无法解决如何在特定轴上进行洗牌。如果有人能帮我,那就太好了!提前谢谢。
首先,我将根据您的需要对您的输入进行排序
#First we need to permute according to the axis
#For defining axis
axis = 1 # Use axis 2 if batch-size is included.
perms = list(range(len(subtree_vectors.shape)))
perms[axis], perms[0] = perms[0], perms[axis]
#Define your input x
x = tf.constant([[[1,2,3], [4,5,6]],
[[7,8,9], [10,11,12]]])
#You need to take the transpose and then shuffle it and then again take the
#transpose then shuffle it then take the transpose, well taking transpose is
#O(1) Operation in Tensorflow.
#In your case set the seed = 6 and axis = 1
tf.random.set_seed(6)
shuffled_x = tf.transpose(tf.random.shuffle(tf.transpose(tf.random.shuffle(x), perm=perms)), perm=perms)
<tf.Tensor: shape=(2, 2, 3), dtype=int32, numpy=
array([[[ 4, 5, 6],
[ 1, 2, 3]],
[[10, 11, 12],
[ 7, 8, 9]]])>
现在,您需要将此操作应用于输出
subtree_vectors = TimeDistributed(Dense(3, use_bias=False, activation='tanh'))(x)
tf.random.set_seed(6)
tf.keras.layers.Lambda(lambda x : tf.transpose(tf.random.shuffle(tf.transpose(tf.random.shuffle(x), perm=perms)), perm=perms))(subtree_vectors)
洗牌前输出
<tf.Tensor: shape=(2, 2, 3), dtype=float32, numpy=
array([[[-0.95375925, -0.9924454 , 0.63576657],
[-0.94918346, -0.99999785, 0.9297005 ]],
[[-0.94416803, -1. , 0.9881501 ],
[-0.93867296, -1. , 0.99805164]]], dtype=float32)>
洗牌后输出
<tf.Tensor: shape=(2, 2, 3), dtype=float32, numpy=
array([[[-0.94918346, -0.99999785, 0.9297005 ],
[-0.95375925, -0.9924454 , 0.63576657]],
[[-0.93867296, -1. , 0.99805164],
[-0.94416803, -1. , 0.9881501 ]]], dtype=float32)>