我正在研究功耗时间序列数据的监督回归问题。起初,我只使用功耗(一个时间序列),将其分成 180 个数据点的窗口,每分钟 1 个数据点,从而形成 3 小时长的输入数据窗口。我想预测下一小时的数据(60个数据点)。
我成功地使用 docker 在 GPU 上运行了多个模型(主要是密集、lstm 和 gru)。这样做时,在 GPU 上进行训练会比在 CPU 上进行训练大大缩短训练时间(快 4 到 5 倍)。 GPU 使用率约为 30%。
我现在想通过使用附加功能(例如星期几、一天中的小时和一小时中的分钟)来改进模型。其中每一个都已进行转换,以使用余弦和正弦函数显示这些特征的循环行为(请参阅https://towardsdatascience.com/circular-features-encoding-its-about-time-ce23581845ca)。因此,我最终得到了每个特征的正弦值和余弦值(因此总共 6 个变量加上完善值使其变为 7)。现在,每个示例都是一个
numpy
数组,其中 shape (180,7)
用于输入,(60,)
用于标签。结果,我的数据集显着增长并且不再适合内存。我有大约 90k 个用于训练的示例,30k 个用于验证,30k 个用于测试。为了解决这个问题,我尝试使用发电机。
但是,这导致了这次训练时间比在 GPU 上训练要慢,而且 GPU 的使用率低很多,在 0% 和 8~9% 之间波动。我的批量大小已经是 256,增加它似乎没有任何效果。据我了解,训练缓慢可能是读取磁盘上的文件以生成批次的结果。
如何减少训练时间?
这是发电机
import tensorflow as tf
import numpy as np
class Custom_Generator(tf.keras.utils.Sequence) :
def __init__(self, example_filenames, example_labels, batch_size, type="train") :
self.example_filenames = example_filenames
self.example_labels = example_labels
self.batch_size = batch_size
self.type = type
def __len__(self) :
return (np.ceil(len(self.example_filenames) / float(self.batch_size))).astype('int')
def __getitem__(self, idx) :
batch_x = self.example_filenames[idx * self.batch_size : (idx+1) * self.batch_size]
batch_y = self.example_labels[idx * self.batch_size : (idx+1) * self.batch_size]
return(
np.array([np.load(f'Donnees_Multivariate_to_batch/{self.type}/{str(X_file_name)}') for X_file_name in batch_x]),
np.array([np.load(f'Donnees_Multivariate_to_batch/{self.type}/{str(y_file_name)}') for y_file_name in batch_y])
)