赞
踩
参考:
#显示所有列(参数设置为None代表显示所有行,也可以自行设置数字) pd.set_option('display.max_columns',None) #禁止自动换行(设置为Flase不自动换行,True反之) pd.set_option('expand_frame_repr', False) def loadWeatherData(): # 如果直接下载不了,将提前下载好的数据集放到指定的dataset目录(xx\.keras\datasets\) zip_path = tf.keras.utils.get_file( origin='https://storage.googleapis.com/tensorflow/tf-keras-datasets/jena_climate_2009_2016.csv.zip', fname='jena_climate_2009_2016.csv.zip', extract=True) csv_path, _ = os.path.splitext(zip_path) print(csv_path) # 使用pands读取csv文件 df = pd.read_csv(csv_path) print(df.head())
每10分钟一条记录
如上所示,每10分钟记录一次观察。这意味着,在一个小时内,你将有6次观察。同样,一天将包含144 (6x24)次观测。
给定一个特定的时间,假设你想预测未来6小时的温度。为了做出预测,你选择使用5天的观测。因此,您将创建一个包含最后720(5x144)次观察的窗口来训练模型。可能有许多这样的配置,这使这个数据集成为一个很好的实验对象。
下面的函数返回上面描述的模型训练时间窗口。参数history_size
是信息的过去窗口的大小。target_size是需要预测的标签。
def univariate_data(dataset, start_index, end_index, history_size, target_size): ''' dataset: start_index: end_index: history_size: target_size: @return: 特征, 标签 ''' data = [] labels = [] start_index = start_index + history_size if end_index is None: end_index = len(dataset) - target_size for i in range(start_index, end_index): indices = range(i-history_size, i) # Reshape data from (history_size,) to (history_size, 1) data.append(np.reshape(dataset[indices], (history_size, 1))) labels.append(dataset[i+target_size]) return np.array(data), np.array(labels)
# 抽取单一变量, 此处为温度,以供使用预测
uni_data = df['T (degC)']
# 线性的数据结构, series是一个一维数组
# Pandas 会默然用0到n-1来作为series的index, 但也可以自己指定index( 可以把index理解为dict里面的key )
uni_data.index = df['Date Time']
print(type(uni_data), '\n' ,uni_data.head())
数据可视化
#可视化
uni_data.plot(subplots=True)
plt.show()
Note: The mean and standard deviation should only be computed using the training data.
# 训练数据的平均及标准差
uni_train_mean = uni_data[:TRAIN_SPLIT].mean()
uni_train_std = uni_data[:TRAIN_SPLIT].std()
# 归一化
uni_data = (uni_data - uni_train_mean)/uni_train_std
# 训练集
x_train_uni, y_train_uni = univariate_data(uni_data, 0, TRAIN_SPLIT,
univariate_past_history,
univariate_future_target)
# 验证集
x_val_uni, y_val_uni = univariate_data(uni_data, TRAIN_SPLIT, None,
univariate_past_history,
univariate_future_target)
print ('Single window of past history')
print (x_train_uni[0])
print ('\n Target temperature to predict')
print (y_train_uni[0])
下图中蓝色线是给网络训练的数据, 红色叉叉是要预测的数据
def create_time_steps(length): return list(range(-length, 0)) def baseline(history): # 历史的平均值,作为预测的对比基线 return np.mean(history) def show_plot(plot_data, delta, title): labels = ['History', 'True Future', 'Model Prediction'] marker = ['.-', 'rx', 'go'] time_steps = create_time_steps(plot_data[0].shape[0]) if delta: future = delta else: future = 0 plt.title(title) for i, x in enumerate(plot_data): if i: plt.plot(future, plot_data[i], marker[i], markersize=10, label=labels[i]) else: plt.plot(time_steps, plot_data[i].flatten(), marker[i], label=labels[i]) plt.legend() plt.xlim([time_steps[0], (future+5)*2]) plt.xlabel('Time-Step') return plt show_plot([x_train_uni[0], y_train_uni[0]], 0, 'Sample Example') plt.show()
在继续训练模型之前,让我们首先设置一个简单的基线。给定一个输入点,基线方法查看所有历史记录,并预测下一个点是最近20个观察值的平均值。
show_plot([x_train_uni[0], y_train_uni[0], baseline(x_train_uni[0])], 0,
'Baseline Prediction Example')
plt.show()
让我们看看你是否可以使用递归神经网络来超越这个基线。
BATCH_SIZE = 256
BUFFER_SIZE = 10000
train_univariate = tf.data.Dataset.from_tensor_slices((x_train_uni, y_train_uni))
train_univariate = train_univariate.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()
val_univariate = tf.data.Dataset.from_tensor_slices((x_val_uni, y_val_uni))
val_univariate = val_univariate.batch(BATCH_SIZE).repeat()
# 创建一个LSTM模型 simple_lstm_model = tf.keras.models.Sequential([ tf.keras.layers.LSTM(8, input_shape=x_train_uni.shape[-2:]), tf.keras.layers.Dense(1) ]) # 编译模型 simple_lstm_model.compile(optimizer='adam', loss='mae') for x, y in val_univariate.take(1): print(simple_lstm_model.predict(x).shape) # 训练模型 EVALUATION_INTERVAL = 200 EPOCHS = 10 simple_lstm_model.fit(train_univariate, epochs=EPOCHS, steps_per_epoch=EVALUATION_INTERVAL, validation_data=val_univariate, validation_steps=50)
# 预测
for x, y in val_univariate.take(3):
plot = show_plot([x[0].numpy(), y[0].numpy(),
simple_lstm_model.predict(x)[0]], 0, 'Simple LSTM model')
plot.show()
# 原数据集中有14个特征, 此处为了方便,暂时只提取3个特征 features_considered = ['p (mbar)', 'T (degC)', 'rho (g/m**3)'] uni_data = df[features_considered] # 线性的数据结构, series是一个一维数组 # Pandas 会默然用0到n-1来作为series的index, 但也可以自己指定index( 可以把index理解为dict里面的key ) uni_data.index = df['Date Time'] print(type(uni_data), '\n', uni_data.head()) # 可视化 uni_data.plot(subplots=True) plt.show() print(type(uni_data)) uni_data = uni_data.values # 数据的平均及标准差 axis=0 按照列计算 uni_train_mean = uni_data[:TRAIN_SPLIT].mean(axis=0) uni_train_std = uni_data[:TRAIN_SPLIT].std(axis=0) # 归一化 uni_data = (uni_data - uni_train_mean) / uni_train_std print(uni_data.shape, uni_train_mean.shape, uni_train_std.shape)
在单一步骤设置中,模型会根据提供的历史预测未来的单一点。
下面的函数执行与下面相同的窗口任务,但是,这里它根据给定的步长采样过去的观察结果。
def multivariate_data(dataset, target, start_index, end_index, history_size, target_size, step, single_step=False): data = [] labels = [] start_index = start_index + history_size if end_index is None: end_index = len(dataset) - target_size for i in range(start_index, end_index): indices = range(i - history_size, i, step) # 五天数据, 每小时抽取一次, 本来5天720份数据,现在使用120份数据代替过去5天的历史 data.append(dataset[indices]) if single_step: labels.append(target[i + target_size]) else: labels.append(target[i:i + target_size]) return np.array(data), np.array(labels)
BATCH_SIZE = 256
BUFFER_SIZE = 10000
train_univariate = tf.data.Dataset.from_tensor_slices((x_train_single, y_train_single))
train_univariate = train_univariate.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()
val_univariate = tf.data.Dataset.from_tensor_slices((x_val_single, y_val_single))
val_univariate = val_univariate.batch(BATCH_SIZE).repeat()
# 创建一个LSTM模型 simple_lstm_model = tf.keras.models.Sequential([ tf.keras.layers.LSTM(32, input_shape=x_train_single.shape[-2:]), tf.keras.layers.Dense(1) ]) # 编译模型 simple_lstm_model.compile(optimizer=tf.keras.optimizers.RMSprop(), loss='mae') for x, y in val_univariate.take(1): print(simple_lstm_model.predict(x).shape, simple_lstm_model.predict(x)) # 训练模型 EVALUATION_INTERVAL = 200 EPOCHS = 10 history = simple_lstm_model.fit(train_univariate, epochs=EPOCHS, steps_per_epoch=EVALUATION_INTERVAL, validation_data=val_univariate, validation_steps=50)
训练与验证数据集的损失
# 绘制训练、验证数据的损失 def plot_train_history(history, title): loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(len(loss)) plt.figure() plt.plot(epochs, loss, 'b', label='Training loss') plt.plot(epochs, val_loss, 'r', label='Validation loss') plt.title(title) plt.legend() plt.show() plot_train_history(history, 'Single Step Training and validation loss')
for x, y in val_univariate.take(3):
plot = show_plot([x[0][:, 1].numpy(), y[0].numpy(),
simple_lstm_model.predict(x)[0]], 12,
'Single Step Prediction')
plot.show()
在多步预测模型中,给定过去的历史,模型需要学习预测未来的一系列值。因此,与只预测单个未来点的单步模型不同,多步模型预测未来的序列。对于多步骤模型,训练数据同样由过去5天每小时采样的记录组成。然而,在这里,模型需要学习预测未来12小时的温度。由于每10分钟进行一次对话,因此输出72个预测。对于这个任务,需要相应地准备数据集,因此第一步只是再次创建它,但是使用不同的目标窗口。
# 原数据集中有14个特征, 此处为了方便,暂时只提取3个特征 features_considered = ['p (mbar)', 'T (degC)', 'rho (g/m**3)'] uni_data = df[features_considered] # 线性的数据结构, series是一个一维数组 # Pandas 会默然用0到n-1来作为series的index, 但也可以自己指定index( 可以把index理解为dict里面的key ) uni_data.index = df['Date Time'] uni_data = uni_data.values # 数据的平均及标准差 uni_train_mean = uni_data[:TRAIN_SPLIT].mean(axis=0) uni_train_std = uni_data[:TRAIN_SPLIT].std(axis=0) # 归一化 dataset = (uni_data - uni_train_mean) / uni_train_std print(dataset.shape, dataset[0: 1]) past_history = 720 # 过去5天总共有720份观测数据(每10分钟一次) future_target = 72 # 由于60min不会出现大的巨变,所以进行抽样,每小时一次 STEP = 6 # future_target = 72 x_train_multi, y_train_multi = multivariate_data(dataset, dataset[:, 1], 0, TRAIN_SPLIT, past_history, future_target, STEP) x_val_multi, y_val_multi = multivariate_data(dataset, dataset[:, 1], TRAIN_SPLIT, None, past_history, future_target, STEP) print('Single window of past history : {}'.format(x_train_multi[0].shape)) print('\n Target temperature to predict : {}'.format(y_train_multi[0].shape)) BATCH_SIZE = 256 BUFFER_SIZE = 10000 train_data_multi = tf.data.Dataset.from_tensor_slices((x_train_multi, y_train_multi)) train_data_multi = train_data_multi.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat() val_data_multi = tf.data.Dataset.from_tensor_slices((x_val_multi, y_val_multi)) val_data_multi = val_data_multi.batch(BATCH_SIZE).repeat() for x, y in train_data_multi.take(1): multi_step_plot(x[0], y[0], np.array([0]))
在此图和随后的类似图中,每小时对历史和未来数据进行采样。
def multi_step_plot(history, true_future, prediction, STEP=6):
plt.figure(figsize=(12, 6))
num_in = create_time_steps(len(history))
num_out = len(true_future)
plt.plot(num_in, np.array(history[:, 1]), label='History')
plt.plot(np.arange(num_out) / STEP, np.array(true_future), 'bo', label='True Future')
if prediction.any(): # 预测
plt.plot(np.arange(num_out) / STEP, np.array(prediction), 'ro', label='Predicted Future')
plt.legend(loc='upper left')
plt.show()
# 构建模型 multi_step_model = tf.keras.models.Sequential() multi_step_model.add(tf.keras.layers.LSTM(32, return_sequences=True, input_shape=x_train_multi.shape[-2:])) multi_step_model.add(tf.keras.layers.LSTM(16, activation='relu')) multi_step_model.add(tf.keras.layers.Dense(72)) # 训练模型 multi_step_model.compile(optimizer=tf.keras.optimizers.RMSprop(clipvalue=1.0), loss='mae') EVALUATION_INTERVAL = 200 EPOCHS = 10 multi_step_history = multi_step_model.fit(train_data_multi, epochs=EPOCHS, steps_per_epoch=EVALUATION_INTERVAL, validation_data=val_data_multi, validation_steps=50)
loss
# loss
plot_train_history(multi_step_history, 'Multi-Step Training and validation loss')
# 预测
for x, y in val_data_multi.take(3):
multi_step_plot(x[0], y[0], multi_step_model.predict(x)[0])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。