TensorFlow:如何将浮点序列嵌入到固定大小的向量中?

时间:2017-08-31 09:29:38

标签: tensorflow embedding autoencoder

我正在寻找将浮点值嵌入到固定大小向量的可变长度序列的方法。输入格式如下:

[f1,f2,f3,f4]->[f1,f2,f3,f4]->[f1,f2,f3,f4]-> ... -> [f1,f2,f3,f4] [f1,f2,f3,f4]->[f1,f2,f3,f4]->[f1,f2,f3,f4]->[f1,f2,f3,f4]-> ... -> [f1,f2,f3,f4] ... [f1,f2,f3,f4]-> ... -> ->[f1,f2,f3,f4]

每一行是一个可变长度的sequnece,最大长度为60.一个sequece中的每个单位是一个4浮点值的元组。我已经用零填充所有序列来填充相同的长度。

如果我将输出与输入相同,以下架构似乎解决了我的问题,我需要中心的思想向量作为序列的嵌入。

在tensorflow中,我找到了两种候选方法tf.contrib.legacy_seq2seq.basic_rnn_seq2seqtf.contrib.legacy_seq2seq.embedding_rnn_seq2seq

然而,这些两种方法似乎用于解决NLP问题,输入必须是单词的离散值。

那么,还有其他功能可以解决我的问题吗?

3 个答案:

答案 0 :(得分:2)

所有你需要的只是一个RNN,而不是seq2seq模型,因为seq2seq附带一个额外的解码器,在你的情况下是不必要的。

示例代码:

import numpy as np
import tensorflow as tf
from tensorflow.contrib import rnn

input_size = 4
max_length = 60
hidden_size=64
output_size = 4

x = tf.placeholder(tf.float32, shape=[None, max_length, input_size], name='x')
seqlen = tf.placeholder(tf.int64, shape=[None], name='seqlen')

lstm_cell = rnn.BasicLSTMCell(hidden_size, forget_bias=1.0)

outputs, states = tf.nn.dynamic_rnn(cell=lstm_cell, inputs=x, sequence_length=seqlen, dtype=tf.float32)


encoded_states = states[-1]

W = tf.get_variable(
        name='W',
        shape=[hidden_size, output_size],
        dtype=tf.float32, 
        initializer=tf.random_normal_initializer())
b = tf.get_variable(
        name='b',
        shape=[output_size],
        dtype=tf.float32, 
        initializer=tf.random_normal_initializer())

z = tf.matmul(encoded_states, W) + b
results = tf.sigmoid(z)

###########################
## cost computing and training components goes here
# e.g. 
# targets = tf.placeholder(tf.float32, shape=[None, input_size], name='targets')
# cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=targets, logits=z))
# optimizer = tf.train.AdamOptimizer(learning_rate=0.1).minimize(cost)
###############################

init = tf.global_variables_initializer()



batch_size = 4
data_in = np.zeros((batch_size, max_length, input_size), dtype='float32')
data_in[0, :4, :] = np.random.rand(4, input_size)
data_in[1, :6, :] = np.random.rand(6, input_size)
data_in[2, :20, :] = np.random.rand(20, input_size)
data_in[3, :, :] = np.random.rand(60, input_size)
data_len = np.asarray([4, 6, 20, 60], dtype='int64')



with tf.Session() as sess:
    sess.run(init)
    #########################
    # training process goes here
    #########################
    res = sess.run(results, 
            feed_dict={
                x: data_in, 
                seqlen: data_len})

print(res)

答案 1 :(得分:1)

要将序列编码为固定长度的矢量,通常使用递归神经网络(RNN)或卷积神经网络(CNN)。

如果使用递归神经网络,则可以使用最后一步的输出(序列中的最后一个元素)。这对应于您问题中的思维向量。看看tf.dynamic_rnndynamic_rnn要求您指定要使用的RNN单元格的类型。 tf.contrib.rnn.LSTMCelltf.contrib.rnn.GRUCell是最常见的。

如果您想使用CNN,则需要使用1维卷积。要构建CNN,您需要tf.layers.conv1dtf.layers.max_pooling1d

答案 2 :(得分:0)

我找到了解决我的问题的方法,使用以下架构,

下面的LSTMs层编码系列x1,x2,...,xn。最后一个输出(绿色输出)被复制到与上述解码LSTM层的输入相同的计数。张量流代码如下

series_input = tf.placeholder(tf.float32, [None, conf.max_series, conf.series_feature_num])
print("Encode input Shape", series_input.get_shape())

# encoding layer
encode_cell = tf.contrib.rnn.MultiRNNCell(
  [tf.contrib.rnn.BasicLSTMCell(conf.rnn_hidden_num, reuse=False) for _ in range(conf.rnn_layer_num)]
)
encode_output, _ = tf.nn.dynamic_rnn(encode_cell, series_input, dtype=tf.float32, scope='encode')
print("Encode output Shape", encode_output.get_shape())

# last output
encode_output = tf.transpose(encode_output, [1, 0, 2])
last = tf.gather(encode_output, int(encode_output.get_shape()[0]) - 1)

# duplite the last output of the encoding layer
decoder_input = tf.stack([last for _ in range(conf.max_series)], axis=1)
print("Decoder input shape", decoder_input.get_shape())

# decoding layer
decode_cell = tf.contrib.rnn.MultiRNNCell(
  [tf.contrib.rnn.BasicLSTMCell(conf.series_feature_num, reuse=False) for _ in range(conf.rnn_layer_num)]
)
decode_output, _ = tf.nn.dynamic_rnn(decode_cell, decoder_input, dtype=tf.float32, scope='decode')
print("Decode output", decode_output.get_shape())

# Loss Function
loss = tf.losses.mean_squared_error(labels=series_input, predictions=decode_output)
print("Loss", loss)