文章目录
- model_test(PeMS, PeMS.get_len('test'), n_his, n_pred, args.inf_mode)
model_test(PeMS, PeMS.get_len(‘test’), n_his, n_pred, args.inf_mode)
这个函数的目的是从保存的检查点(checkpoint)加载模型,并在测试集上进行预测和评估。这对于在训练完成后验证模型的性能很有用。
-
inputs
:Dataset
类的实例,它是测试数据的数据源。 -
batch_size
: 批处理的大小。 -
n_his
: 用于训练的历史记录长度。 -
n_pred
: 预测的长度。 -
inf_mode
: 推断模式,可以是 ‘sep’(单步测试)或 ‘merge’(多步测试)。 -
load_path
: 加载模型的路径。 -
实现细节
- 时间记录: 用于测量测试所需的总时间。
- 模型加载: 使用 TensorFlow 的
get_checkpoint_state
和import_meta_graph
来加载预训练模型。
这行代码的目的是从指定的 load_path 目录中获取最新的模型检查点文件的路径,以便后续可以使用这个路径来加载和恢复模型的权重和状态。
这段代码的目的是在一个指定的计算图(test_graph)中导入一个预训练的模型。主要用于导入模型的结构(计算图) - 会话恢复: 在一个新的 TensorFlow 会话中恢复模型。
在这个会话的上下文中,使用saver.restore()方法从最新的检查点文件中恢复模型的权重。主要用于实际加载模型的权重。 - 预测 Placeholder: 使用
get_collection
获取预测结果的 placeholder。
这行代码会返回一个列表,该列表包含集合 ‘y_pred’ 中的所有元素。通常,这些元素是与模型预测相关的张量。 - 推断模式选择: 根据
inf_mode
参数决定使用哪种推断模式(‘sep’ 或 ‘merge’)。
如果 inf_mode == ‘merge’,那么 step_idx 和 tmp_idx 会是 NumPy数组 [2, 5, 8]。 - 获取测试数据: 从
inputs
对象中获取测试数据和统计信息。
这行代码是在从一个名为 inputs 的对象中获取测试数据和统计信息。输入的inputs 就是Dataset类, - 多步预测: 调用
multi_pred
函数进行多步预测。
pred_array 将所有预测连接在一起,其维度应为 [n_pred, len_seq, n_route, C_0],y_test=pred_array[step_idx],len_test=pred_array.shape[1] - 评估性能: 调用
evaluation
函数来评估模型在测试集上的性能。
这是一个评估函数,用于计算预测模型的性能。具体来说,它计算三种常用的误差指标:平均绝对百分比误差(MAPE)、平均绝对误差(MAE)和均方根误差(RMSE)。 - 输出结果: 打印每个时间步的 MAPE(平均绝对百分比误差)、MAE(平均绝对误差)和 RMSE(均方根误差)。
- 时间消耗: 计算并打印模型测试所需的时间。
PeMS = data_gen(pjoin(‘./dataset’, data_file), (n_train, n_val, n_test), n, n_his + n_pred)
-
加载数据:使用
pd.read_csv
函数从CSV文件中读取数据,并将其转换为NumPy数组。 -
生成训练、验证和测试序列:
- 使用前面定义的
seq_gen
函数来生成训练、验证和测试数据。 - 对于训练数据,从源数据的开始索引(
offset=0
)生成。 - 对于验证数据,从源数据的
n_train
索引处开始生成。 - 对于测试数据,从源数据的
n_train + n_val
索引处开始生成。
- 使用前面定义的
-
计算统计数据:
- 计算训练数据集的平均值和标准差,存储在
x_stats
字典中。
- 计算训练数据集的平均值和标准差,存储在
-
标准化数据:
- 使用z分数方法(z-score)对训练、验证和测试数据进行标准化。
- 假设
z_score
函数用于进行这种标准化(虽然代码没有给出这个函数,但从上下文可以推断出这一点)。
-
组织数据和统计信息:
- 将标准化后的训练、验证和测试数据存储在
x_data
字典中。 - 使用前面定义的
Dataset
类创建一个数据集对象,并将x_data
和x_stats
作为参数传递。
- 将标准化后的训练、验证和测试数据存储在
-
返回数据集对象:最后,函数返回这个
Dataset
对象,其中包含标准化后的训练、验证和测试数据,以及关于这些数据的统计信息。
seq_test = seq_gen(n_test, data_seq, n_train + n_val, n_frame, n_route, day_slot)
这段代码定义了一个函数seq_gen,该函数用于生成标准的序列数据单元,适用于时间序列数据或图结构数据中。这种序列数据单元主要用于训练或评估机器学习模型(特别是时间序列模型,如LSTM或GRU,或者图神经网络模型)。
参数:
len_seq
:目标日期序列的长度。这个数字表示我们想从原始数据中提取多少个子序列。data_seq
:源数据或时间序列,通常是一个Numpy数组。原始数据,是一个多维数组。offset
:不同数据集类型的起始索引。这是一个偏移量,告诉我们从原始数据的哪个点开始。n_frame
:一个标准序列单元中的帧数(时间步)。这通常包括历史数据(n_his
)和预测数据(n_pred
)。每个子序列中需要包含的连续数据点的数量。n_route
:图中路由(节点)的数量。day_slot
:每天的时间槽数量,由时间窗口(默认为5分钟)控制。在一天(或其他周期)内有多少个时隙。C_0
:输入通道的大小,默认为1。
代码逻辑:
-
n_slot = day_slot - n_frame + 1
:计算每天可用于生成标准序列单元的时间槽数量。 -
tmp_seq = np.zeros((len_seq * n_slot, n_frame, n_route, C_0))
:初始化一个全零的Numpy数组,用于存储生成的序列数据。 -
双重循环:
- 外层循环:遍历目标日期序列。
- 内层循环:遍历每天内的每个可用时间槽。
在这两个循环中,对于每个时间槽和每个目标日期,函数都会:
- 计算源数据中相应序列的起始(
sta
)和结束(end
)索引。 - 从源数据中提取相应的序列,并将其重塑为
[n_frame, n_route, C_0]
的形状。 - 将这个重塑后的数组存储在
tmp_seq
中的相应位置。
-
返回生成的序列数据
tmp_seq
。
x_test = z_score(seq_test, x_stats[‘mean’], x_stats[‘std’])
该函数用于执行Z-score标准化,将数据转化为均值为0和标准差为1的形式。
参数:
x: 输入的numpy数组。
mean: 均值。
std: 标准差。
返回值: 经过Z-score标准化后的数组。
dataset = Dataset(x_data, x_stats)
这个代码定义了一个名为Dataset的Python类,该类用于存储和操作数据集。这个类特别适用于处理归一化后的数据,因为它还包括数据的统计信息(平均值和标准差)。
通过这个Dataset类,可以轻松地管理和操作您的数据,包括获取数据的不同部分(如训练、测试等)、获取数据的统计信息和长度,以及在需要时进行反归一化。
PeMS.get_len(‘test’)
在Python和NumPy中,多维数组(通常称为张量)的“长度”通常指的是最外层维度的大小。如果你有一个具有四个维度的NumPy数组,例如一个形状为(a, b, c, d)
的数组,使用Python的内置len()
函数或NumPy的shape
属性将返回该最外层维度(在这个例子中是a
)的大小。
import numpy as np
# 创建一个形状为 (4, 3, 2, 1) 的四维数组
data = np.random.rand(4, 3, 2, 1)
# 使用 len() 函数获取最外层维度的大小
length = len(data)
print(f"Length using len(): {length}")
# 或者使用 shape 属性获取所有维度的大小,并选取第一个
shape = data.shape
print(f"Shape of array: {shape}")
length_from_shape = shape[0]
print(f"Length using shape: {length_from_shape}")
这将输出:
Length using len(): 4
Shape of array: (4, 3, 2, 1)
Length using shape: 4
如果你在一个类方法get_len(self, type)
中使用这种方式,并且self.__data[type]
是一个四维数组,你可以简单地返回这个数组最外层维度的大小,就像这样:
def get_len(self, type):
return len(self.__data[type])
这里,self.__data[type]
应该是一个四维数组。这种方式计算的“长度”只是最外层维度的大小。
y_test, len_test = multi_pred(test_sess, pred, x_test, batch_size, n_his, n_pred, step_idx)
这个函数主要用于在一个时间序列数据上执行多步预测。它使用给定的模型(y_pred
placeholder)和输入序列(seq
)进行预测,并返回预测结果。
参数:
sess
: TensorFlow 的会话对象,用于执行模型预测。y_pred
: TensorFlow 的 placeholder,用于保存模型的预测结果。seq
: numpy 数组,包含输入序列,其形状为 [len_seq, n_frame, n_route, C_0]。batch_size
: 批处理大小。n_his
: 历史记录的大小,用于训练。n_pred
: 预测长度。step_idx
: 用于预测切片的索引,可以是整数或列表。dynamic_batch
: 布尔值,决定是否在最后一个批次长度小于默认批处理大小时改变批处理大小。
实现细节:
-
预测列表初始化:
pred_list
用于存储每一批次的预测结果。 -
批处理生成与预测: 对于
seq
中的每一批数据,执行以下操作:- 从
seq
中获取测试序列test_seq
。 - 初始化一个列表
step_list
,用于存储单个批次的多步预测结果。 - 在
n_pred
步内,进行预测,并将每一步的预测结果存储在step_list
中。
- 从
-
更新测试序列: 在每一步预测后,
test_seq
会更新,以包含最新的预测值,以供下一步预测使用。 -
预测结果聚合: 所有批次的预测结果都存储在
pred_list
中,然后通过np.concatenate
转换为 numpy 数组pred_array
。 -
返回结果: 最终返回预测结果
pred_array
的特定切片(由step_idx
定义)和预测的长度。
这个函数是多步时间序列预测任务的核心,它能批量地进行多步预测,并且可以处理动态批处理大小的情况。这对于在实际应用中预测交通流量、股票价格等具有时空依赖性的数据非常有用。
gen_batch(seq, min(batch_size, len(seq)), dynamic_batch=dynamic_batch):
这个函数gen_batch
用于生成批量的数据,它是一个迭代器。主要应用在机器学习和深度学习训练中,用于将大量数据分成小批量(batch)进行逐批训练。
参数:
inputs
: 一个NumPy数组,形状是[len_seq, n_frame, n_route, C_0]
,代表标准的序列单元。batch_size
: 批量的大小,即每次迭代返回多少条数据。dynamic_batch
: 一个布尔值,表示是否在最后一个批次改变批大小,如果其长度小于默认的批大小。shuffle
: 一个布尔值,表示是否需要随机打乱批次。
代码逻辑:
-
获取输入长度: 使用
len
函数获取inputs
数组的长度(即序列的总数)。 -
是否打乱数据:
- 如果
shuffle=True
,那么会生成一个从0到len_inputs-1
的整数数组,并随机打乱它。
- 如果
-
生成批次:
- 使用
for
循环从0开始,步长为batch_size
,迭代到len_inputs
。 start_idx
是每个批次的起始索引,end_idx
是终止索引。- 如果
end_idx
大于len_inputs
(超出数组长度),则根据dynamic_batch
决定是否调整最后一个批次的大小。
- 使用
-
数据切片与返回:
- 使用
yield
关键字返回每个批次的数据。 - 如果
shuffle=True
,则根据打乱后的索引返回数据。 - 否则,直接使用切片从
start_idx
到end_idx
提取数据。
- 使用
使用场景:
这种批次生成器非常适用于大规模数据集,特别是当你不能一次性将所有数据加载到内存中时。此外,通过设定shuffle=True
,模型在训练时可以接触到随机化的数据,这通常有助于提高模型的泛化能力。
总体来说,这个函数提供了一种灵活和高效的方式来迭代大规模数据集,并且还支持动态批处理和数据洗牌。
evl = evaluation(x_test[0:len_test, step_idx + n_his, :, :], y_test, x_stats)
这是一个评估函数,用于计算预测模型的性能。具体来说,它计算三种常用的误差指标:平均绝对百分比误差(MAPE)、平均绝对误差(MAE)和均方根误差(RMSE)。
函数参数:
y
: 这是模型预测的真实值(ground truth),可以是一个多维的Numpy数组或整数。y_
: 这是模型的预测值,其维度和类型应与y
相同。x_stats
: 这是一个字典,其中包含用于Z-score标准化的均值和标准差。
返回值:
- 函数返回一个Numpy数组,包含了MAPE、MAE和RMSE的值。
代码流程:
-
检查维度:
dim = len(y_.shape)
用于获取预测值y_
的维度。 -
单步预测 vs. 多步预测:根据
y_
的维度,函数会区分处理单步预测和多步预测。-
单步预测(dim==3):
- 使用
z_inverse
函数将标准化的y
和y_
逆转为原始尺度。 - 计算MAPE、MAE和RMSE。
- 返回一个包含这三个指标的Numpy数组。
- 使用
-
多步预测(dim!=3):
- 创建一个空列表
tmp_list
用于存储每一步的评估结果。 - 使用
np.swapaxes(y, 0, 1)
交换y
数组的轴以适应递归调用。 - 使用递归调用
evaluation
函数来评估每一个时间步,并将结果存储在tmp_list
中。 - 使用
np.concatenate
将所有时间步的结果合并,并返回。
- 创建一个空列表
-
总体而言,这个函数非常灵活,能够处理单步预测和多步预测,并为每种情况提供多种评估指标。这使得它成为评估时间序列预测模型性能的有力工具。