sklearn中lbfgs解算器的MLPrePressor learning_rate_init

2024-06-25 06:08:35 发布

您现在位置:Python中文网/ 问答频道 /正文

对于学校项目,我需要评估具有不同学习率的神经网络。我选择sklearn来实现神经网络(使用MLPRegressor类)。由于训练数据非常小(20个实例,每个实例2个输入和1个输出),我决定使用lbfgs解算器,因为像sgdadam这样的随机解算器对于这种大小的数据没有意义

该项目要求以不同的学习率测试神经网络。但是,根据文档,使用lbfgs解算器是不可能的:

learning_rate_init double, default=0.001 The initial learning rate used. It controls the step-size in updating the weights. Only used when solver=’sgd’ or ‘adam’.

有没有一种方法可以让我以某种方式访问lbfgs解算器的学习率并对其进行修改,或者这个问题根本没有意义


Tags: the数据项目实例rate神经网络sklearn学校
2条回答

不是一个完整的答案,但希望是一个好的指针

sklearn.neural_network.MLPRegressor是在github上的multilayer_perceptron模块上实现的

通过检查模块,我注意到与其他解算器不同,scitkit在基类本身中实现了lbfgs算法。所以你可以很容易地适应它

他们似乎不使用任何学习率,因此您可以修改此代码,并将损失乘以您想要测试的学习率。我只是不完全确定在lbfgs环境下增加学习率是否有意义

我相信如果在这里使用,损失是:

        opt_res = scipy.optimize.minimize(
                self._loss_grad_lbfgs, packed_coef_inter,
                method="L-BFGS-B", jac=True,
                options={
                    "maxfun": self.max_fun,
                    "maxiter": self.max_iter,
                    "iprint": iprint,
                    "gtol": self.tol
                },

代码位于_多层_perceptron.py模块的第430行

def _fit_lbfgs(self, X, y, activations, deltas, coef_grads,
                   intercept_grads, layer_units):
        # Store meta information for the parameters
        self._coef_indptr = []
        self._intercept_indptr = []
        start = 0

        # Save sizes and indices of coefficients for faster unpacking
        for i in range(self.n_layers_ - 1):
            n_fan_in, n_fan_out = layer_units[i], layer_units[i + 1]

            end = start + (n_fan_in * n_fan_out)
            self._coef_indptr.append((start, end, (n_fan_in, n_fan_out)))
            start = end

        # Save sizes and indices of intercepts for faster unpacking
        for i in range(self.n_layers_ - 1):
            end = start + layer_units[i + 1]
            self._intercept_indptr.append((start, end))
            start = end

        # Run LBFGS
        packed_coef_inter = _pack(self.coefs_,
                                  self.intercepts_)

        if self.verbose is True or self.verbose >= 1:
            iprint = 1
        else:
            iprint = -1

        opt_res = scipy.optimize.minimize(
                self._loss_grad_lbfgs, packed_coef_inter,
                method="L-BFGS-B", jac=True,
                options={
                    "maxfun": self.max_fun,
                    "maxiter": self.max_iter,
                    "iprint": iprint,
                    "gtol": self.tol
                },
                args=(X, y, activations, deltas, coef_grads, intercept_grads))
        self.n_iter_ = _check_optimize_result("lbfgs", opt_res, self.max_iter)
        self.loss_ = opt_res.fun
        self._unpack(opt_res.x)

LBFGS是一种优化算法,它不使用学习率。在学校项目中,您应该使用sgdadam。关于它是否更有意义,我想说的是,在20个数据点上训练一个神经网络,除了学习基础知识之外,没有什么意义

LBFGS是一种拟牛顿优化方法。它基于这样一个假设,即您寻求优化的函数可以通过二阶泰勒展开局部近似。大致如下:

  • 从最初的猜测开始
  • 使用雅可比矩阵计算最陡下降方向
  • 使用Hessian矩阵计算下降步长,并到达下一点
  • 重复,直到收敛

与牛顿法的不同之处在于,拟牛顿法使用雅可比矩阵和/或海森矩阵的近似值

与梯度下降法相比,牛顿法和拟牛顿法对优化函数的平滑度要求更高,但收敛速度更快。事实上,使用Hessian矩阵计算下降步长更有效,因为它可以预测到局部最优值的距离,因此不会在其周围振荡或收敛得非常缓慢。另一方面,梯度下降仅使用雅可比矩阵(一阶导数)计算最陡下降的方向,并使用学习率作为下降步骤

实际上,梯度下降法用于深度学习,因为计算Hessian矩阵的成本太高

在这里,谈论牛顿方法(或拟牛顿方法)的学习率是没有意义的,它只是不适用

相关问题 更多 >