此刻,我尝试为张量流中的时间序列数据构建一个自动编码器。我有将近500天的数据,每天有24个数据点。由于这是我的第一次尝试,因此我的体系结构非常简单。在输入大小24
后,隐藏层的大小为10; 3; 10
,输出又为24
。我对数据进行了规范化(数据点在[-0.5; 0.5]
范围内),使用S型激活函数和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]
** 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})
答案 0 :(得分:2)
仅是一个建议,我在使用sigmoid
函数的自动编码器中遇到了一些问题。
我切换到tanh
或relu
,这些改善了结果。
使用自动编码器,基本上是在学习通过编码和解码从输入重新创建输出。如果您的意思与输入相同,那么您将得到想要的东西。它已经学会了数据集。
最终,您可以通过检查输入和输出之间的均方误差来进行比较,看看是否完全相同。如果您的意思是不管输入如何,输出都是完全相同的,那我就没有遇到过。我想如果您的输入每天变化不大,那么我可以想象会产生一些影响。您在寻找异常吗?
此外,如果您有时间序列进行训练,在这种特殊情况下,我不会整理数据。如果时间顺序很重要,则根据要实现的目标而引入数据泄漏(基本上是将将来的数据引入训练集中)。
啊,我最初没有看到带有图形结果的帖子。.感谢您的添加。
答案 1 :(得分:1)
S型输出的底限为0,因此它无法重现小于0的数据。
如果要使用S型输出,请在[0; 1](不包括0和1)之间重新缩放数据。
答案 2 :(得分:0)
我知道这是一篇很老的帖子,所以这只是试图帮助那些再次遇到同样问题的人......如果自动编码器为所有不同的实例收敛到相同的编码,可能有损失函数中的问题......检查损失函数返回的大小和形状,因为它可能会感到困惑并评估错误的张量(即您可能需要在某处转置某些东西)基本上,假设您正在使用使用自动编码器对 N 个训练实例的 M 个特征进行编码,您的损失函数应返回 N 个值。损失张量的大小应该是训练集中的实例数量。我发现这很难.....