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

Mar*_*n K 5 python neural-network autoencoder tensorflow

目前,我尝试为 tensorflow 中的时间序列数据构建一个自动编码器。我有将近 500 天的数据,其中每天有 24 个数据点。因为这是我第一次尝试,所以我的架构非常简单。在我输入 size 之后24,隐藏层的 size:10; 3; 10输出为 again 24。我对数据进行了标准化(数据点在范围内[-0.5; 0.5]),使用 sigmoid 激活函数和 RMSPropOptimizer。

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

训练损失函数

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]
Run Code Online (Sandbox Code Playgroud)

*编辑:以下是一些输出示例(红色原始,蓝色重建): 在此处输入图片说明

**编辑:我刚刚看到一个自动编码器示例,其 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
Run Code Online (Sandbox Code Playgroud)

这就是我训练我的网络的方式(输入数据具有形状 (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})
Run Code Online (Sandbox Code Playgroud)

小智 3

只是一个建议,我在使用该函数的自动编码器方面遇到了一些问题sigmoid

我改用tanhor relu,结果得到了改善。使用自动编码器,它基本上是学习通过编码和解码从输入重新创建输出。如果你的意思是它与输入相同,那么你就得到了你想要的。它已经学习了数据集。

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

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

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