我目前正在使用一个LSTM模型,用Tensorflow 2.2.0来进行时间序列预测。
我一直在使用一个大型的数据集,一切都很好.然而,数据集的创建需要大量的RAM,我想使用一个新的数据集。tensorflow.keras.utils.Sequence
为了解决这个问题,我的问题是这样的:当使用序列时,我的模型不再学习(它预测整个数据集的真实信号的平均值)。
当使用序列时,我的模型不再学习(它预测的是整个数据集中真实信号的平均值)。
我的数据集是由两个python列表创建的 x_train_flights
和 y_train_flights
,每个人都有大熊猫 DataFrame
s. 对于每个 (x_train_flight, y_train_flight)
的这个名单。
x_train_flight
形状 (-1, features)
含有 features
信号y_train_flight
形状 (-1, 1)
含有一个信号,在时间上与来自美国的信号一致。x_train_flights
系统如下(我不允许分享真实数据,我用伪随机信号代替重新制作了图形)。
这里: features=2
(蓝线和橙线),以及 look_back=5
. 也就是说,这10分(来自于 x_train_flights
)用于预测矩形中的黄金点(它与矩形中的相应点进行比较,并在 y_train_flights
在训练阶段)。) 灰色的点是之前的预测值。
为了创建我的数据集,我一直在使用这些函数。
def lstm_shapify(sequence, look_back, features):
res = np.empty((look_back, len(sequence), features), dtype=np.float32)
for i in range(look_back):
res[i] = np.roll(sequence, -i * features)
return np.transpose(res, axes=(1, 0, 2))[:-look_back + 1]
def make_dataset(x_flights, y_flights, look_back, features):
x = np.empty((0, look_back, features), dtype=np.float32)
y = np.empty((0, 1), dtype=np.float32)
for i in range(len(x_flights)):
x_sample = x_flights[i].values
y_sample = y_flights[i].values[look_back - 1:]
x = np.concatenate([x, lstm_shapify(x_sample, look_back, features)])
y = np.concatenate([y, y_sample])
return x, y
我用下面的函数来拟合我的网络
model.fit(
x_train,
y_train,
epochs=7,
batch_size=batch_size
)
所以,我创建了这个自定义序列。
class LSTMGenerator(Sequence):
def __init__(
self,
x_flights: List[DataFrame],
y_flights: List[DataFrame],
look_back: int,
batch_size: int,
features: int
):
self.x_flights = x_flights
self.y_flights = []
self.look_back = look_back
self.batch_size = batch_size
self.features = features
self.length = 0
for y_flight in y_flights:
y = y_flight.iloc[look_back - 1:].to_numpy()
self.y_flights.append(y)
self.length += len(y) // batch_size
def __getitem__(self, index):
flight_index = 0
while True:
n = len(self.y_flights[flight_index]) // self.batch_size
if index < n:
break
flight_index += 1
index = index - n
start_index = index * self.batch_size
x_batch = lstm_shapify(
self.x_flights[flight_index]
.iloc[start_index:start_index + self.batch_size + self.look_back - 1]
.to_numpy(),
self.look_back,
self.features
)
y_batch = self.y_flights[flight_index][start_index:start_index + self.batch_size]
return x_batch, y_batch
def __len__(self):
return self.length
每个元组(x
, y
),它返回的是两个numpy数组,形状是 (batch_size, look_back, features)
和 (batch_size, 1)
分别。
而现在我正试图用它来配合。
model.fit(
LSTMGenerator(x_train_flights, y_train_flights, look_back, batch_size, features),
epochs=epochs
)
这是我的模型。
model = Sequential()
model.add(LSTM(
100,
input_shape=(look_back, features),
kernel_regularizer=regularizers.l2(1e-3),
bias_regularizer=regularizers.l2(1e-4)
))
model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(Dense(1, activation='tanh'))
model.compile(optimizer='adam', loss='mse')
希望你能帮助我
EDIT:更多关于数据集的细节。
这是一个工作实例。
from tensorflow.keras import *
from tensorflow.keras.layers import *
from tensorflow.keras.utils import *
import numpy as np
import tensorflow as tf
np.random.seed(1234)
tf.random.set_seed(1234)
features = 3
lookback = 7
model = Sequential()
model.add(LSTM(500, input_shape = (lookback, features)))
model.add(Dense(1, activation='tanh'))
XS = np.random.randn(200, features)
YS = np.random.randn(200)
class LookbackSeq(Sequence):
def __init__(self, XS, YS, batch_size, lookback):
self.XS = XS
self.YS = YS
self.batch_size = batch_size
self.lookback = lookback
def __len__(self):
n_windows = self.XS.shape[0] - self.lookback
return int(np.ceil(n_windows / self.batch_size))
def __getitem__(self, i):
base = i * self.batch_size
n_windows = self.XS.shape[0] - self.lookback
batch_size = min(n_windows - base, self.batch_size)
X = np.zeros((batch_size, self.lookback, self.XS.shape[1]))
Y = np.zeros((batch_size, 1))
for i in range(batch_size):
for j in range(self.lookback):
X[i, j] = self.XS[base + i + j]
Y[i] = self.YS[base + i + self.lookback]
return X, Y
model.compile(optimizer='adam', loss='mse')
# ALL SAMPLES IN MEMORY
X, Y = [], []
for i in range(len(XS) - lookback):
X.append(XS[i:i+lookback])
Y.append(YS[i+lookback])
X, Y = np.array(X), np.array(Y)
model.fit(X, Y, epochs = 10, batch_size = 4, shuffle = False)
# GENERATED ON THE FLY
# gen = LookbackSeq(XS, YS, 4, lookback)
# model.fit(x = gen,
# steps_per_epoch = len(gen),
# shuffle = False,
# epochs = 10)
我假设你的输入数据的形状是: X = (n_points, n_features)
和 Y = (n_points,)
. LookbackSeq
为你做批处理和窗口化(回看)。
你可以对相关的行进行注释和取消注释,以便用飞行中生成的样本或全部存储在内存中的样本进行训练。你应该得到相同的结果。