如何在将Keras层的输出馈送到下一层之前对其进行洗牌?



我有一个多层模型。我想在把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)>

最新更新