张量流自动编码器的输出始终相同

时间:2018-11-07 14:26:00

标签: python tensorflow neural-network autoencoder

此刻,我尝试为张量流中的时间序列数据构建一个自动编码器。我有将近500天的数据,每天有24个数据点。由于这是我的第一次尝试,因此我的体系结构非常简单。在输入大小24后,隐藏层的大小为10; 3; 10,输出又为24。我对数据进行了规范化(数据点在[-0.5; 0.5]范围内),使用S型激活函数和RMSPropOptimizer。

训练后(图片中的损失函数),我输入网络的每个时间的输出都是相同的。有人知道这是什么原因吗?我的数据集是否可能是问题所在(下面的代码)?

loss function of training

class TimeDataset:
def __init__(self,data):
    self._index_in_epoch = 0
    self._epochs_completed = 0
    self._data = data
    self._num_examples = data.shape[0]
    pass


@property
def data(self):
    return self._data

def next_batch(self, batch_size, shuffle=True):
    start = self._index_in_epoch

    # first call
    if start == 0 and self._epochs_completed == 0:
        idx = np.arange(0, self._num_examples)  # get all possible indexes
        np.random.shuffle(idx)  # shuffle indexe
        self._data = self.data[idx]  # get list of `num` random samples

    if start + batch_size > self._num_examples:
        # not enough samples left -> go to the next batch
        self._epochs_completed += 1
        rest_num_examples = self._num_examples - start
        data_rest_part = self.data[start:self._num_examples]
        idx0 = np.arange(0, self._num_examples)  # get all possible indexes
        np.random.shuffle(idx0)  # shuffle indexes
        self._data = self.data[idx0]  # get list of `num` random samples

        start = 0
        self._index_in_epoch = batch_size - rest_num_examples #avoid the case where the #sample != integar times of batch_size
        end =  self._index_in_epoch  
        data_new_part =  self._data[start:end]  
        return np.concatenate((data_rest_part, data_new_part), axis=0)
    else:
        # get next batch
        self._index_in_epoch += batch_size
        end = self._index_in_epoch
        return self._data[start:end]

* edit:这是输出的一些示例(红色原始,蓝色重建): enter image description here

** edit:我刚刚看到了一个自动编码器示例,它的luss函数比我的更复杂。有人知道损失函数self.loss = tf.reduce_mean(tf.pow(self.X - self.decoded, 2))是否足够?

***编辑:更多代码来描述我的训练 这是我的自动编码器类:

class AutoEncoder():
def __init__(self):
    # Training Parameters
    self.learning_rate = 0.005
    self.alpha = 0.5

    # Network Parameters
    self.num_input = 24 # one day as input
    self.num_hidden_1 = 10 # 2nd layer num features
    self.num_hidden_2 = 3 # 2nd layer num features (the latent dim)

    self.X = tf.placeholder("float", [None, self.num_input])

    self.weights = {
        'encoder_h1': tf.Variable(tf.random_normal([self.num_input, self.num_hidden_1])),
        'encoder_h2': tf.Variable(tf.random_normal([self.num_hidden_1, self.num_hidden_2])),
        'decoder_h1': tf.Variable(tf.random_normal([self.num_hidden_2, self.num_hidden_1])),
        'decoder_h2': tf.Variable(tf.random_normal([self.num_hidden_1, self.num_input])),
    }
    self.biases = {
        'encoder_b1': tf.Variable(tf.random_normal([self.num_hidden_1])),
        'encoder_b2': tf.Variable(tf.random_normal([self.num_hidden_2])),
        'decoder_b1': tf.Variable(tf.random_normal([self.num_hidden_1])),
        'decoder_b2': tf.Variable(tf.random_normal([self.num_input])),
    }    

    self.encoded = self.encoder(self.X)
    self.decoded = self.decoder(self.encoded)

    # Define loss and optimizer, minimize the squared error
    self.loss = tf.reduce_mean(tf.pow(self.X - self.decoded, 2))

    self.optimizer = tf.train.RMSPropOptimizer(self.learning_rate).minimize(self.loss)

def encoder(self, x):
    # sigmoid, tanh, relu
    en_layer_1 = tf.nn.sigmoid (tf.add(tf.matmul(x, self.weights['encoder_h1']),
                                   self.biases['encoder_b1']))

    en_layer_2 = tf.nn.sigmoid (tf.add(tf.matmul(en_layer_1, self.weights['encoder_h2']),
                                   self.biases['encoder_b2']))

    return en_layer_2

def decoder(self, x):
    de_layer_1 = tf.nn.sigmoid (tf.add(tf.matmul(x, self.weights['decoder_h1']),
                                   self.biases['decoder_b1']))

    de_layer_2 = tf.nn.sigmoid (tf.add(tf.matmul(de_layer_1, self.weights['decoder_h2']),
                                   self.biases['decoder_b2']))

    return de_layer_2

这就是我训练网络的方式(输入数据具有形状(number_days,24)):

model = autoencoder.AutoEncoder()

num_epochs = 3
batch_size = 50
num_batches = 300

display_batch = 50
examples_to_show = 16

loss_values = []

with tf.Session() as sess:

sess.run(tf.global_variables_initializer())

#training
for e in range(1, num_epochs+1):
    print('starting epoch {}'.format(e))
    for b in range(num_batches):
        # get next batch of data
        batch_x = dataset.next_batch(batch_size)

        # Run optimization op (backprop) and cost op (to get loss value)
        l = sess.run([model.loss], feed_dict={model.X: batch_x})
        sess.run(model.optimizer, feed_dict={model.X: batch_x})            

        # Display logs
        if b % display_batch == 0:
            print('Epoch {}: Batch ({}) Loss: {}'.format(e, b, l))
            loss_values.append(l)


# testing
test_data = dataset.next_batch(batch_size)
decoded_test_data = sess.run(model.decoded, feed_dict={model.X: test_data})

3 个答案:

答案 0 :(得分:2)

仅是一个建议,我在使用sigmoid函数的自动编码器中遇到了一些问题。

我切换到tanhrelu,这些改善了结果。 使用自动编码器,基本上是在学习通过编码和解码从输入重新创建输出。如果您的意思与输入相同,那么您将得到想要的东西。它已经学会了数据集。

最终,您可以通过检查输入和输出之间的均方误差来进行比较,看看是否完全相同。如果您的意思是不管输入如何,输出都是完全相同的,那我就没有遇到过。我想如果您的输入每天变化不大,那么我可以想象会产生一些影响。您在寻找异常吗?

此外,如果您有时间序列进行训练,在这种特殊情况下,我不会整理数据。如果时间顺序很重要,则根据要实现的目标而引入数据泄漏(基本上是将将来的数据引入训练集中)。

啊,我最初没有看到带有图形结果的帖子。.感谢您的添加。

答案 1 :(得分:1)

S型输出的底限为0,因此它无法重现小于0的数据。

如果要使用S型输出,请在[0; 1](不包括0和1)之间重新缩放数据。

答案 2 :(得分:0)

我知道这是一篇很老的帖子,所以这只是试图帮助那些再次遇到同样问题的人......如果自动编码器为所有不同的实例收敛到相同的编码,可能有损失函数中的问题......检查损失函数返回的大小和形状,因为它可能会感到困惑并评估错误的张量(即您可能需要在某处转置某些东西)基本上,假设您正在使用使用自动编码器对 N 个训练实例的 M 个特征进行编码,您的损失函数应返回 N 个值。损失张量的大小应该是训练集中的实例数量。我发现这很难.....