我按照这里的教程,使用theano实现了逻辑回归。上述教程使用了SciPy的fmin_cg
优化过程。该函数的重要参数包括:f
是要最小化的目标/成本函数,x0
是用户提供的参数初始猜测,fprime
是提供函数f
在x
处的导数的函数,以及callback
是一个可选的用户提供的函数,在每次迭代后调用。
训练函数定义如下:
# 创建一个计算训练集上平均成本的函数def train_fn(theta_value): classifier.theta.set_value(theta_value, borrow=True) train_losses = [batch_cost(i * batch_size) for i in xrange(n_train_batches)] return numpy.mean(train_losses)
上述代码的作用是遍历训练数据集中的所有小批量,对于每个小批量计算平均批量成本(即成本函数应用于小批量中每个训练样本的平均值),并在所有批量上平均成本。值得指出的是,每个批量的成本由batch_cost
计算——这是一个theano函数。
在我看来,callback
函数的调用似乎是任意的,并不是像SciPy文档中声称的那样在每次迭代后调用。
这是我在train_fn
和callback
中分别添加了“train”和“callback”打印后得到的输出。
... 训练模型traintraintraincallback验证错误 29.989583 %traincallback验证错误 24.437500 %traincallback验证错误 20.760417 %traincallback验证错误 16.937500 %traincallback验证错误 14.270833 %traincallback验证错误 14.156250 %traincallback验证错误 13.177083 %traincallback验证错误 12.270833 %traintraincallback验证错误 11.697917 %traincallback验证错误 11.531250 %
我的问题是,既然每次调用train_fn
确实是一个训练周期,我如何改变行为,以便在train_fn
之后调用callback
?
回答:
每次调用train_fn
不一定是一个单一的训练周期。我不太确定fmin_cg
是如何实现的,但一般来说,共轭梯度方法可能在每次最小化步骤中调用成本或梯度函数不止一次。这(据我所知)有时是为了找到相对于之前步骤的共轭向量所必需的。1
所以你的回调函数是在fmin_cg
每次采取步骤时被调用的。如果你需要在每次调用成本或梯度函数时调用一个函数,你可以直接将调用放在相关函数内部。
1. 编辑:至少当它们是非线性方法时,如fmin_cg
那样。维基百科页面表明,普通的共轭梯度(CG)方法可能不需要多次调用,但我认为它们不适合优化非线性函数。我见过的CG代码——我猜应该是非线性CG的——肯定涉及每一步至少一次线性搜索。这肯定需要多次评估梯度函数。