我正在做一个更大的项目,但能够在一个小可乐笔记本上重现这个问题,我希望有人能看一看。我能够成功地训练一个密集的网络,但不能使用时间序列发生器来训练LSTM。请参阅下面的谷歌科拉布
我知道我使用的是1的回溯长度(就在这个例子中,对于LSTM来说没有完全的意义),但是如果我能够找到如何使它工作的话,我将把它扩展到更多的n_features和更大的回溯。
在本例中,我创建了一个简单的数据框架,其中有一个名为input
的输入变量,它预测了pos_points
和neg_points
(在collab笔记本中,我概述了如何将其计算为非常简单)。
import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import *
from tensorflow.keras.models import *
tf.__version__
import pandas as pd
df = pd.DataFrame()
df['input'] = np.random.uniform(-10.0, 10.0, 50000)
# Simple rules:
# If input is positive:
# pos_points = input * input
# neg_points = -0.5 * input
#
# If input is negative:
# pos_points = -0.5 * input
# neg_points = -input * input
df['pos_points'] = df['input'].apply(lambda x: x*x if x > 0 else x * -0.5)
df['neg_points'] = df['input'].apply(lambda x: x*x*-1 if x < 0 else -x * 0.5)
target = pd.concat([df.pop(x) for x in ['pos_points', 'neg_points']], axis=1)
我能够通过以下途径成功地进行培训:
# Build a simple model to go from input to the two outputs
from tensorflow.keras import regularizers
def get_df_model():
model = tf.keras.Sequential([
tf.keras.layers.Dense(10, input_shape=[1,], activation='relu', kernel_regularizer=regularizers.l1_l2(l1=1e-5, l2=1e-4)),
tf.keras.layers.Dense(10, activation='relu', kernel_regularizer=regularizers.l1_l2(l1=1e-5, l2=1e-4)),
tf.keras.layers.Dense(2)
])
model.compile(optimizer='adam', loss=tf.keras.losses.MeanSquaredError())
return model
model = get_df_model()
model.fit(df, target, epochs=10)
它产生:
Epoch 1/10
1563/1563 [==============================] - 2s 1ms/step - loss: 194.1551
Epoch 2/10
1563/1563 [==============================] - 2s 1ms/step - loss: 26.1025
Epoch 3/10
1563/1563 [==============================] - 2s 1ms/step - loss: 7.3179
Epoch 4/10
1563/1563 [==============================] - 2s 1ms/step - loss: 1.1513
Epoch 5/10
1563/1563 [==============================] - 2s 1ms/step - loss: 0.4611
Epoch 6/10
1563/1563 [==============================] - 2s 1ms/step - loss: 0.3274
Epoch 7/10
1563/1563 [==============================] - 2s 1ms/step - loss: 0.2420
Epoch 8/10
1563/1563 [==============================] - 2s 1ms/step - loss: 0.1833
Epoch 9/10
1563/1563 [==============================] - 2s 1ms/step - loss: 0.1411
Epoch 10/10
1563/1563 [==============================] - 2s 1ms/step - loss: 0.1110
但是,当我尝试使用时间序列生成器时,我无法很好地获得LSTM的输入。注意,我使用的是1的回溯,所以它应该是模棱两可的:
# Create timeseries generator
from tensorflow.keras.preprocessing.sequence import TimeseriesGenerator
lookback = 1
n_features = 1 # If you look at df, there is just the input column, a single number
train_generator = TimeseriesGenerator(df.astype(np.float32).to_numpy(), target.astype(np.float32).to_numpy(), length=lookback, batch_size=16)
print(train_generator[0][0].shape) # input shape, should print out (16, 1, 1) = batchsize, lookback length, input_size
print(train_generator[0][1].shape) # target shape, should print out (16, 2) = batchsize, # of outputs in final dense layer
# Build a simple model to go from input to the two outputs
def get_lstm_model():
model = tf.keras.Sequential([
tf.keras.layers.LSTM(10, input_shape=[lookback, n_features,], activation='relu', kernel_regularizer=regularizers.l1_l2(l1=1e-5, l2=1e-4)),
tf.keras.layers.Dense(10, activation='relu', kernel_regularizer=regularizers.l1_l2(l1=1e-5, l2=1e-4)),
tf.keras.layers.Dense(2)
])
model.compile(optimizer='adam', loss=tf.keras.losses.MeanSquaredError())
return model
model = get_lstm_model()
model.fit(train_generator, epochs=10)
制作:
(16, 1, 1)
(16, 2)
WARNING:tensorflow:Layer lstm_33 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU.
Epoch 1/10
3125/3125 [==============================] - 9s 3ms/step - loss: 722.0089
Epoch 2/10
3125/3125 [==============================] - 10s 3ms/step - loss: 686.9944
Epoch 3/10
3125/3125 [==============================] - 10s 3ms/step - loss: 687.0886
Epoch 4/10
3125/3125 [==============================] - 10s 3ms/step - loss: 687.0521
Epoch 5/10
3125/3125 [==============================] - 10s 3ms/step - loss: 687.0247
Epoch 6/10
3125/3125 [==============================] - 10s 3ms/step - loss: 686.9836
Epoch 7/10
3125/3125 [==============================] - 10s 3ms/step - loss: 686.9711
Epoch 8/10
3125/3125 [==============================] - 10s 3ms/step - loss: 686.9208
Epoch 9/10
3125/3125 [==============================] - 9s 3ms/step - loss: 686.9716
Epoch 10/10
3125/3125 [==============================] - 9s 3ms/step - loss: 686.9753
<keras.callbacks.History at 0x7f3d09185eb8>
发布于 2022-02-28 22:24:17
好的,找到了答案,这和Keras TimeseriesGenerator有关。
我使用一个带有输入和输出列的表来组织数据。生成器中的输出总是提前映射一个行(因为它通常需要传统的时间序列格式)。
因此,为了解决这个问题,我在目标数据帧的前面放了一行NaN。然后,当我调用生成器时,我可以看到它们正确地映射结果:
adjusted_target = pd.DataFrame([[np.nan] * len(target.columns)], columns=target.columns).append(target, ignore_index=True)[:-1]
train_generator = TimeseriesGenerator(df.astype(np.float32).to_numpy(), adjusted_target.astype(np.float32).to_numpy(), length=1, batch_size=1)
您可以通过以下代码验证输入/输出是否正确地映射:
for i in range(len(train_generator)):
x, y = train_generator[i]
print('%s => %s' % (x, y))
https://stackoverflow.com/questions/71272353
复制相似问题