我正在尝试编写一个使用时间序列(UNIX Epoch时间)和一个值生成预测的脚本。为了美观,我为脚本的每一部分创建了不同的方法。这里有一个例子:
def train_model(X_data, y_data): # 创建占位符X和y # 创建优化器和初始化变量 with tf.Session() as sess: init.run() for epoch in range(200): for (xh, yh) in zip(X_data, y_data): sess.run(optimizer, feed_dict={X: xh, y: yh}) # 可以将训练好的模型作为变量返回吗?def make_pred(model, date): # 使用之前的模型生成预测? with tf.Session() as sess: return sess.run(model, feed_dict={X: date})
如何在不保存到检查点文件的情况下使用generate_model
函数中创建的模型?
附加问题:
- 当学习率为0.001时,模型无法生成预测,我必须使用接近1e-20的值才能在日志中看到非NaN的值。这是否是因为我没有对时间序列数组进行缩放?缩放它们的最佳方法是什么?
- 由于我没有很多训练数据,我应该使用整个数据集来训练吗?当我只有不到100个值时,交叉验证集如何工作?我更关心预测结果而不是可视化结果。
我对这方面还比较新,如果你看到任何用词不当的地方,请随时纠正我。
提前感谢你。
回答:
问题
如何在不保存到检查点文件的情况下使用generate_model
函数中创建的模型?
回答
将你的函数改成类,并在类中保持会话活跃,如下所示:
class MyModel: def __init__(self): self.sess = tf.Session() init.run() def train_model(self, X_data, y_data): # 创建占位符X和y for epoch in range(200): for (xh, yh) in zip(X_data, y_data): sess.run(optimizer, feed_dict={X: xh, y: yh}) def make_pred(self, date): # 使用之前的模型生成预测 yp return sess.run(yp, feed_dict={X: date})
使用model = MyModel()
创建类的实例,然后像这样训练它model.train_model(X_data,y_data)
,并像这样使用它model.make_pred(date)
。
附加问题1
当学习率为0.001时,模型无法生成预测,我必须使用接近1e-20的值才能在日志中看到非NaN的值。这是否是因为我没有对时间序列数组进行缩放?缩放它们的最佳方法是什么?
附加回答1
选择合适的学习率是调整超参数的一个重要方面,使用过高的学习率得到NaN(或其他不适当的值)并不少见。
如果你能将时间序列标准化,那肯定会有所帮助。尝试将你的序列缩放到0.0到1.0或-1.0到1.0之间,看哪个最合适。
缩放它们的最佳方法取决于数据。如果你的时间序列是外部温度(例如)且在-20°C到+20°C之间,那么或许只需用T/20(除以20)来标准化就很好。如果你的时间序列是星际气体温度,范围在-270°C到50,000°C之间,那么或许使用log(T)来获取温度的量级会更好。
附加问题2
由于我没有很多训练数据,我应该使用整个数据集来训练吗?当我只有不到100个值时,交叉验证集如何工作?
附加回答2
假设你有100个训练数据点。你可以创建一个使用前20个数据点进行测试,其余用于训练的预测器。然后,你可以创建另一个使用第二个20个数据点进行测试,其余80个用于训练的预测器,依此类推,这样你就有5个分别训练和测试的预测器。这将是5折交叉测试。你知道每个预测器的测试结果,并且你有5个预测器(如果你使用N折,则有N个)。
当你使用这些预测器时,你会将新数据通过每个预测器并得到5个估计值。现在,这些估计值就成了你从你的迷你专家集合中得到的可能答案范围。你可以报告答案的平均值、均方根、最高值和最低值。这些都是很好的信息。